xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/tools/quic_server.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "quiche/quic/tools/quic_server.h"
6 
7 #include <cstdint>
8 #include <memory>
9 
10 #include "quiche/quic/core/crypto/crypto_handshake.h"
11 #include "quiche/quic/core/crypto/quic_random.h"
12 #include "quiche/quic/core/io/event_loop_socket_factory.h"
13 #include "quiche/quic/core/io/quic_default_event_loop.h"
14 #include "quiche/quic/core/io/quic_event_loop.h"
15 #include "quiche/quic/core/quic_clock.h"
16 #include "quiche/quic/core/quic_crypto_stream.h"
17 #include "quiche/quic/core/quic_data_reader.h"
18 #include "quiche/quic/core/quic_default_clock.h"
19 #include "quiche/quic/core/quic_default_connection_helper.h"
20 #include "quiche/quic/core/quic_default_packet_writer.h"
21 #include "quiche/quic/core/quic_dispatcher.h"
22 #include "quiche/quic/core/quic_packet_reader.h"
23 #include "quiche/quic/core/quic_packets.h"
24 #include "quiche/quic/platform/api/quic_flags.h"
25 #include "quiche/quic/platform/api/quic_logging.h"
26 #include "quiche/quic/tools/quic_simple_crypto_server_stream_helper.h"
27 #include "quiche/quic/tools/quic_simple_dispatcher.h"
28 #include "quiche/quic/tools/quic_simple_server_backend.h"
29 #include "quiche/common/simple_buffer_allocator.h"
30 
31 namespace quic {
32 
33 namespace {
34 
35 const char kSourceAddressTokenSecret[] = "secret";
36 
37 }  // namespace
38 
39 const size_t kNumSessionsToCreatePerSocketEvent = 16;
40 
QuicServer(std::unique_ptr<ProofSource> proof_source,QuicSimpleServerBackend * quic_simple_server_backend)41 QuicServer::QuicServer(std::unique_ptr<ProofSource> proof_source,
42                        QuicSimpleServerBackend* quic_simple_server_backend)
43     : QuicServer(std::move(proof_source), quic_simple_server_backend,
44                  AllSupportedVersions()) {}
45 
QuicServer(std::unique_ptr<ProofSource> proof_source,QuicSimpleServerBackend * quic_simple_server_backend,const ParsedQuicVersionVector & supported_versions)46 QuicServer::QuicServer(std::unique_ptr<ProofSource> proof_source,
47                        QuicSimpleServerBackend* quic_simple_server_backend,
48                        const ParsedQuicVersionVector& supported_versions)
49     : QuicServer(std::move(proof_source), QuicConfig(),
50                  QuicCryptoServerConfig::ConfigOptions(), supported_versions,
51                  quic_simple_server_backend, kQuicDefaultConnectionIdLength) {}
52 
QuicServer(std::unique_ptr<ProofSource> proof_source,const QuicConfig & config,const QuicCryptoServerConfig::ConfigOptions & crypto_config_options,const ParsedQuicVersionVector & supported_versions,QuicSimpleServerBackend * quic_simple_server_backend,uint8_t expected_server_connection_id_length)53 QuicServer::QuicServer(
54     std::unique_ptr<ProofSource> proof_source, const QuicConfig& config,
55     const QuicCryptoServerConfig::ConfigOptions& crypto_config_options,
56     const ParsedQuicVersionVector& supported_versions,
57     QuicSimpleServerBackend* quic_simple_server_backend,
58     uint8_t expected_server_connection_id_length)
59     : port_(0),
60       fd_(-1),
61       packets_dropped_(0),
62       overflow_supported_(false),
63       silent_close_(false),
64       config_(config),
65       crypto_config_(kSourceAddressTokenSecret, QuicRandom::GetInstance(),
66                      std::move(proof_source), KeyExchangeSource::Default()),
67       crypto_config_options_(crypto_config_options),
68       version_manager_(supported_versions),
69       packet_reader_(new QuicPacketReader()),
70       quic_simple_server_backend_(quic_simple_server_backend),
71       expected_server_connection_id_length_(
72           expected_server_connection_id_length),
73       connection_id_generator_(expected_server_connection_id_length) {
74   QUICHE_DCHECK(quic_simple_server_backend_);
75   Initialize();
76 }
77 
Initialize()78 void QuicServer::Initialize() {
79   // If an initial flow control window has not explicitly been set, then use a
80   // sensible value for a server: 1 MB for session, 64 KB for each stream.
81   const uint32_t kInitialSessionFlowControlWindow = 1 * 1024 * 1024;  // 1 MB
82   const uint32_t kInitialStreamFlowControlWindow = 64 * 1024;         // 64 KB
83   if (config_.GetInitialStreamFlowControlWindowToSend() ==
84       kDefaultFlowControlSendWindow) {
85     config_.SetInitialStreamFlowControlWindowToSend(
86         kInitialStreamFlowControlWindow);
87   }
88   if (config_.GetInitialSessionFlowControlWindowToSend() ==
89       kDefaultFlowControlSendWindow) {
90     config_.SetInitialSessionFlowControlWindowToSend(
91         kInitialSessionFlowControlWindow);
92   }
93 
94   std::unique_ptr<CryptoHandshakeMessage> scfg(crypto_config_.AddDefaultConfig(
95       QuicRandom::GetInstance(), QuicDefaultClock::Get(),
96       crypto_config_options_));
97 }
98 
~QuicServer()99 QuicServer::~QuicServer() {
100   if (event_loop_ != nullptr) {
101     if (!event_loop_->UnregisterSocket(fd_)) {
102       QUIC_LOG(ERROR) << "Failed to unregister socket: " << fd_;
103     }
104   }
105   (void)socket_api::Close(fd_);
106   fd_ = kInvalidSocketFd;
107 
108   // Should be fine without because nothing should send requests to the backend
109   // after `this` is destroyed, but for extra pointer safety, clear the socket
110   // factory from the backend before the socket factory is destroyed.
111   quic_simple_server_backend_->SetSocketFactory(nullptr);
112 }
113 
CreateUDPSocketAndListen(const QuicSocketAddress & address)114 bool QuicServer::CreateUDPSocketAndListen(const QuicSocketAddress& address) {
115   event_loop_ = CreateEventLoop();
116 
117   socket_factory_ = std::make_unique<EventLoopSocketFactory>(
118       event_loop_.get(), quiche::SimpleBufferAllocator::Get());
119   quic_simple_server_backend_->SetSocketFactory(socket_factory_.get());
120 
121   QuicUdpSocketApi socket_api;
122   fd_ = socket_api.Create(address.host().AddressFamilyToInt(),
123                           /*receive_buffer_size =*/kDefaultSocketReceiveBuffer,
124                           /*send_buffer_size =*/kDefaultSocketReceiveBuffer);
125   if (fd_ == kQuicInvalidSocketFd) {
126     QUIC_LOG(ERROR) << "CreateSocket() failed: " << strerror(errno);
127     return false;
128   }
129 
130   overflow_supported_ = socket_api.EnableDroppedPacketCount(fd_);
131   socket_api.EnableReceiveTimestamp(fd_);
132 
133   bool success = socket_api.Bind(fd_, address);
134   if (!success) {
135     QUIC_LOG(ERROR) << "Bind failed: " << strerror(errno);
136     return false;
137   }
138   QUIC_LOG(INFO) << "Listening on " << address.ToString();
139   port_ = address.port();
140   if (port_ == 0) {
141     QuicSocketAddress self_address;
142     if (self_address.FromSocket(fd_) != 0) {
143       QUIC_LOG(ERROR) << "Unable to get self address.  Error: "
144                       << strerror(errno);
145     }
146     port_ = self_address.port();
147   }
148 
149   bool register_result = event_loop_->RegisterSocket(
150       fd_, kSocketEventReadable | kSocketEventWritable, this);
151   if (!register_result) {
152     return false;
153   }
154   dispatcher_.reset(CreateQuicDispatcher());
155   dispatcher_->InitializeWithWriter(CreateWriter(fd_));
156 
157   return true;
158 }
159 
CreateWriter(int fd)160 QuicPacketWriter* QuicServer::CreateWriter(int fd) {
161   return new QuicDefaultPacketWriter(fd);
162 }
163 
CreateQuicDispatcher()164 QuicDispatcher* QuicServer::CreateQuicDispatcher() {
165   return new QuicSimpleDispatcher(
166       &config_, &crypto_config_, &version_manager_,
167       std::make_unique<QuicDefaultConnectionHelper>(),
168       std::unique_ptr<QuicCryptoServerStreamBase::Helper>(
169           new QuicSimpleCryptoServerStreamHelper()),
170       event_loop_->CreateAlarmFactory(), quic_simple_server_backend_,
171       expected_server_connection_id_length_, connection_id_generator_);
172 }
173 
CreateEventLoop()174 std::unique_ptr<QuicEventLoop> QuicServer::CreateEventLoop() {
175   return GetDefaultEventLoop()->Create(QuicDefaultClock::Get());
176 }
177 
HandleEventsForever()178 void QuicServer::HandleEventsForever() {
179   while (true) {
180     WaitForEvents();
181   }
182 }
183 
WaitForEvents()184 void QuicServer::WaitForEvents() {
185   event_loop_->RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(50));
186 }
187 
Shutdown()188 void QuicServer::Shutdown() {
189   if (!silent_close_) {
190     // Before we shut down the epoll server, give all active sessions a chance
191     // to notify clients that they're closing.
192     dispatcher_->Shutdown();
193   }
194 
195   dispatcher_.reset();
196   event_loop_.reset();
197 }
198 
OnSocketEvent(QuicEventLoop *,QuicUdpSocketFd fd,QuicSocketEventMask events)199 void QuicServer::OnSocketEvent(QuicEventLoop* /*event_loop*/,
200                                QuicUdpSocketFd fd, QuicSocketEventMask events) {
201   QUICHE_DCHECK_EQ(fd, fd_);
202 
203   if (events & kSocketEventReadable) {
204     QUIC_DVLOG(1) << "EPOLLIN";
205 
206     dispatcher_->ProcessBufferedChlos(kNumSessionsToCreatePerSocketEvent);
207 
208     bool more_to_read = true;
209     while (more_to_read) {
210       more_to_read = packet_reader_->ReadAndDispatchPackets(
211           fd_, port_, *QuicDefaultClock::Get(), dispatcher_.get(),
212           overflow_supported_ ? &packets_dropped_ : nullptr);
213     }
214 
215     if (dispatcher_->HasChlosBuffered()) {
216       // Register EPOLLIN event to consume buffered CHLO(s).
217       bool success =
218           event_loop_->ArtificiallyNotifyEvent(fd_, kSocketEventReadable);
219       QUICHE_DCHECK(success);
220     }
221     if (!event_loop_->SupportsEdgeTriggered()) {
222       bool success = event_loop_->RearmSocket(fd_, kSocketEventReadable);
223       QUICHE_DCHECK(success);
224     }
225   }
226   if (events & kSocketEventWritable) {
227     dispatcher_->OnCanWrite();
228     if (!event_loop_->SupportsEdgeTriggered() &&
229         dispatcher_->HasPendingWrites()) {
230       bool success = event_loop_->RearmSocket(fd_, kSocketEventWritable);
231       QUICHE_DCHECK(success);
232     }
233   }
234 }
235 
236 }  // namespace quic
237