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 "net/third_party/quiche/src/quic/tools/quic_server.h"
6
7 #include <errno.h>
8 #include <features.h>
9 #include <netinet/in.h>
10 #include <string.h>
11 #include <sys/epoll.h>
12 #include <sys/socket.h>
13
14 #include <cstdint>
15 #include <memory>
16
17 #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h"
18 #include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
19 #include "net/third_party/quiche/src/quic/core/quic_clock.h"
20 #include "net/third_party/quiche/src/quic/core/quic_crypto_stream.h"
21 #include "net/third_party/quiche/src/quic/core/quic_data_reader.h"
22 #include "net/third_party/quiche/src/quic/core/quic_default_packet_writer.h"
23 #include "net/third_party/quiche/src/quic/core/quic_dispatcher.h"
24 #include "net/third_party/quiche/src/quic/core/quic_epoll_alarm_factory.h"
25 #include "net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.h"
26 #include "net/third_party/quiche/src/quic/core/quic_packet_reader.h"
27 #include "net/third_party/quiche/src/quic/core/quic_packets.h"
28 #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
29 #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
30 #include "net/quic/platform/impl/quic_epoll_clock.h"
31 #include "net/third_party/quiche/src/quic/tools/quic_simple_crypto_server_stream_helper.h"
32 #include "net/third_party/quiche/src/quic/tools/quic_simple_dispatcher.h"
33 #include "net/third_party/quiche/src/quic/tools/quic_simple_server_backend.h"
34
35 namespace quic {
36
37 namespace {
38
39 const int kEpollFlags = EPOLLIN | EPOLLOUT | EPOLLET;
40 const char kSourceAddressTokenSecret[] = "secret";
41
42 } // namespace
43
44 const size_t kNumSessionsToCreatePerSocketEvent = 16;
45
QuicServer(std::unique_ptr<ProofSource> proof_source,QuicSimpleServerBackend * quic_simple_server_backend)46 QuicServer::QuicServer(std::unique_ptr<ProofSource> proof_source,
47 QuicSimpleServerBackend* quic_simple_server_backend)
48 : QuicServer(std::move(proof_source),
49 quic_simple_server_backend,
50 AllSupportedVersions()) {}
51
QuicServer(std::unique_ptr<ProofSource> proof_source,QuicSimpleServerBackend * quic_simple_server_backend,const ParsedQuicVersionVector & supported_versions)52 QuicServer::QuicServer(std::unique_ptr<ProofSource> proof_source,
53 QuicSimpleServerBackend* quic_simple_server_backend,
54 const ParsedQuicVersionVector& supported_versions)
55 : QuicServer(std::move(proof_source),
56 QuicConfig(),
57 QuicCryptoServerConfig::ConfigOptions(),
58 supported_versions,
59 quic_simple_server_backend,
60 kQuicDefaultConnectionIdLength) {}
61
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)62 QuicServer::QuicServer(
63 std::unique_ptr<ProofSource> proof_source,
64 const QuicConfig& config,
65 const QuicCryptoServerConfig::ConfigOptions& crypto_config_options,
66 const ParsedQuicVersionVector& supported_versions,
67 QuicSimpleServerBackend* quic_simple_server_backend,
68 uint8_t expected_server_connection_id_length)
69 : port_(0),
70 fd_(-1),
71 packets_dropped_(0),
72 overflow_supported_(false),
73 silent_close_(false),
74 config_(config),
75 crypto_config_(kSourceAddressTokenSecret,
76 QuicRandom::GetInstance(),
77 std::move(proof_source),
78 KeyExchangeSource::Default()),
79 crypto_config_options_(crypto_config_options),
80 version_manager_(supported_versions),
81 packet_reader_(new QuicPacketReader()),
82 quic_simple_server_backend_(quic_simple_server_backend),
83 expected_server_connection_id_length_(
84 expected_server_connection_id_length) {
85 DCHECK(quic_simple_server_backend_);
86 Initialize();
87 }
88
Initialize()89 void QuicServer::Initialize() {
90 // If an initial flow control window has not explicitly been set, then use a
91 // sensible value for a server: 1 MB for session, 64 KB for each stream.
92 const uint32_t kInitialSessionFlowControlWindow = 1 * 1024 * 1024; // 1 MB
93 const uint32_t kInitialStreamFlowControlWindow = 64 * 1024; // 64 KB
94 if (config_.GetInitialStreamFlowControlWindowToSend() ==
95 kDefaultFlowControlSendWindow) {
96 config_.SetInitialStreamFlowControlWindowToSend(
97 kInitialStreamFlowControlWindow);
98 }
99 if (config_.GetInitialSessionFlowControlWindowToSend() ==
100 kDefaultFlowControlSendWindow) {
101 config_.SetInitialSessionFlowControlWindowToSend(
102 kInitialSessionFlowControlWindow);
103 }
104
105 epoll_server_.set_timeout_in_us(50 * 1000);
106
107 QuicEpollClock clock(&epoll_server_);
108
109 std::unique_ptr<CryptoHandshakeMessage> scfg(crypto_config_.AddDefaultConfig(
110 QuicRandom::GetInstance(), &clock, crypto_config_options_));
111 }
112
113 QuicServer::~QuicServer() = default;
114
CreateUDPSocketAndListen(const QuicSocketAddress & address)115 bool QuicServer::CreateUDPSocketAndListen(const QuicSocketAddress& address) {
116 QuicUdpSocketApi socket_api;
117 fd_ = socket_api.Create(address.host().AddressFamilyToInt(),
118 /*receive_buffer_size =*/kDefaultSocketReceiveBuffer,
119 /*send_buffer_size =*/kDefaultSocketReceiveBuffer);
120 if (fd_ == kQuicInvalidSocketFd) {
121 QUIC_LOG(ERROR) << "CreateSocket() failed: " << strerror(errno);
122 return false;
123 }
124
125 overflow_supported_ = socket_api.EnableDroppedPacketCount(fd_);
126 socket_api.EnableReceiveTimestamp(fd_);
127
128 sockaddr_storage addr = address.generic_address();
129 int rc = bind(fd_, reinterpret_cast<sockaddr*>(&addr), sizeof(addr));
130 if (rc < 0) {
131 QUIC_LOG(ERROR) << "Bind failed: " << strerror(errno);
132 return false;
133 }
134 QUIC_LOG(INFO) << "Listening on " << address.ToString();
135 port_ = address.port();
136 if (port_ == 0) {
137 QuicSocketAddress address;
138 if (address.FromSocket(fd_) != 0) {
139 QUIC_LOG(ERROR) << "Unable to get self address. Error: "
140 << strerror(errno);
141 }
142 port_ = address.port();
143 }
144
145 epoll_server_.RegisterFD(fd_, this, kEpollFlags);
146 dispatcher_.reset(CreateQuicDispatcher());
147 dispatcher_->InitializeWithWriter(CreateWriter(fd_));
148
149 return true;
150 }
151
CreateWriter(int fd)152 QuicPacketWriter* QuicServer::CreateWriter(int fd) {
153 return new QuicDefaultPacketWriter(fd);
154 }
155
CreateQuicDispatcher()156 QuicDispatcher* QuicServer::CreateQuicDispatcher() {
157 QuicEpollAlarmFactory alarm_factory(&epoll_server_);
158 return new QuicSimpleDispatcher(
159 &config_, &crypto_config_, &version_manager_,
160 std::unique_ptr<QuicEpollConnectionHelper>(new QuicEpollConnectionHelper(
161 &epoll_server_, QuicAllocator::BUFFER_POOL)),
162 std::unique_ptr<QuicCryptoServerStreamBase::Helper>(
163 new QuicSimpleCryptoServerStreamHelper()),
164 std::unique_ptr<QuicEpollAlarmFactory>(
165 new QuicEpollAlarmFactory(&epoll_server_)),
166 quic_simple_server_backend_, expected_server_connection_id_length_);
167 }
168
HandleEventsForever()169 void QuicServer::HandleEventsForever() {
170 while (true) {
171 WaitForEvents();
172 }
173 }
174
WaitForEvents()175 void QuicServer::WaitForEvents() {
176 epoll_server_.WaitForEventsAndExecuteCallbacks();
177 }
178
Shutdown()179 void QuicServer::Shutdown() {
180 if (!silent_close_) {
181 // Before we shut down the epoll server, give all active sessions a chance
182 // to notify clients that they're closing.
183 dispatcher_->Shutdown();
184 }
185
186 epoll_server_.Shutdown();
187
188 close(fd_);
189 fd_ = -1;
190 }
191
OnEvent(int fd,QuicEpollEvent * event)192 void QuicServer::OnEvent(int fd, QuicEpollEvent* event) {
193 DCHECK_EQ(fd, fd_);
194 event->out_ready_mask = 0;
195
196 if (event->in_events & EPOLLIN) {
197 QUIC_DVLOG(1) << "EPOLLIN";
198
199 dispatcher_->ProcessBufferedChlos(kNumSessionsToCreatePerSocketEvent);
200
201 bool more_to_read = true;
202 while (more_to_read) {
203 more_to_read = packet_reader_->ReadAndDispatchPackets(
204 fd_, port_, QuicEpollClock(&epoll_server_), dispatcher_.get(),
205 overflow_supported_ ? &packets_dropped_ : nullptr);
206 }
207
208 if (dispatcher_->HasChlosBuffered()) {
209 // Register EPOLLIN event to consume buffered CHLO(s).
210 event->out_ready_mask |= EPOLLIN;
211 }
212 }
213 if (event->in_events & EPOLLOUT) {
214 dispatcher_->OnCanWrite();
215 if (dispatcher_->HasPendingWrites()) {
216 event->out_ready_mask |= EPOLLOUT;
217 }
218 }
219 }
220
221 } // namespace quic
222