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