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