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.
5 #include "net/tools/quic/quic_server.h"
9 #include <netinet/in.h>
11 #include <sys/epoll.h>
12 #include <sys/socket.h>
14 #include "net/base/ip_endpoint.h"
15 #include "net/quic/crypto/crypto_handshake.h"
16 #include "net/quic/crypto/quic_random.h"
17 #include "net/quic/quic_clock.h"
18 #include "net/quic/quic_crypto_stream.h"
19 #include "net/quic/quic_data_reader.h"
20 #include "net/quic/quic_protocol.h"
21 #include "net/tools/quic/quic_dispatcher.h"
22 #include "net/tools/quic/quic_epoll_clock.h"
23 #include "net/tools/quic/quic_epoll_connection_helper.h"
24 #include "net/tools/quic/quic_in_memory_cache.h"
25 #include "net/tools/quic/quic_packet_reader.h"
26 #include "net/tools/quic/quic_socket_utils.h"
28 // TODO(rtenneti): Add support for MMSG_MORE.
30 // If true, QuicListener uses the QuicPacketReader to read packets instead of
32 // TODO(rtenneti): Enable this flag after MMSG_MORE is set to 1.
33 #define FLAGS_quic_use_optimized_packet_reader false
36 #define SO_RXQ_OVFL 40
43 // Specifies the directory used during QuicInMemoryCache
44 // construction to seed the cache. Cache directory can be
45 // generated using `wget -p --save-headers <url>`
46 std::string FLAGS_quic_in_memory_cache_dir
= "";
48 const int kEpollFlags
= EPOLLIN
| EPOLLOUT
| EPOLLET
;
49 const char kSourceAddressTokenSecret
[] = "secret";
53 QuicServer::QuicServer()
57 overflow_supported_(false),
59 crypto_config_(kSourceAddressTokenSecret
, QuicRandom::GetInstance()),
60 supported_versions_(QuicSupportedVersions()),
61 packet_reader_(new QuicPacketReader()) {
65 QuicServer::QuicServer(const QuicConfig
& config
,
66 const QuicVersionVector
& supported_versions
)
70 overflow_supported_(false),
73 crypto_config_(kSourceAddressTokenSecret
, QuicRandom::GetInstance()),
74 supported_versions_(supported_versions
),
75 packet_reader_(new QuicPacketReader()) {
79 void QuicServer::Initialize() {
84 // If an initial flow control window has not explicitly been set, then use a
85 // sensible value for a server: 1 MB for session, 64 KB for each stream.
86 const uint32 kInitialSessionFlowControlWindow
= 1 * 1024 * 1024; // 1 MB
87 const uint32 kInitialStreamFlowControlWindow
= 64 * 1024; // 64 KB
88 if (config_
.GetInitialStreamFlowControlWindowToSend() ==
89 kMinimumFlowControlSendWindow
) {
90 config_
.SetInitialStreamFlowControlWindowToSend(
91 kInitialStreamFlowControlWindow
);
93 if (config_
.GetInitialSessionFlowControlWindowToSend() ==
94 kMinimumFlowControlSendWindow
) {
95 config_
.SetInitialSessionFlowControlWindowToSend(
96 kInitialSessionFlowControlWindow
);
99 epoll_server_
.set_timeout_in_us(50 * 1000);
101 if (!FLAGS_quic_in_memory_cache_dir
.empty()) {
102 QuicInMemoryCache::GetInstance()->InitializeFromDirectory(
103 FLAGS_quic_in_memory_cache_dir
);
106 QuicEpollClock
clock(&epoll_server_
);
108 scoped_ptr
<CryptoHandshakeMessage
> scfg(
109 crypto_config_
.AddDefaultConfig(
110 QuicRandom::GetInstance(), &clock
,
111 QuicCryptoServerConfig::ConfigOptions()));
114 QuicServer::~QuicServer() {
117 bool QuicServer::Listen(const IPEndPoint
& address
) {
118 port_
= address
.port();
119 int address_family
= address
.GetSockAddrFamily();
120 fd_
= socket(address_family
, SOCK_DGRAM
| SOCK_NONBLOCK
, IPPROTO_UDP
);
122 LOG(ERROR
) << "CreateSocket() failed: " << strerror(errno
);
126 // Enable the socket option that allows the local address to be
127 // returned if the socket is bound to more than one address.
128 int rc
= QuicSocketUtils::SetGetAddressInfo(fd_
, address_family
);
131 LOG(ERROR
) << "IP detection not supported" << strerror(errno
);
135 int get_overflow
= 1;
137 fd_
, SOL_SOCKET
, SO_RXQ_OVFL
, &get_overflow
, sizeof(get_overflow
));
140 DLOG(WARNING
) << "Socket overflow detection not supported";
142 overflow_supported_
= true;
145 // These send and receive buffer sizes are sized for a single connection,
146 // because the default usage of QuicServer is as a test server with one or
147 // two clients. Adjust higher for use with many clients.
148 if (!QuicSocketUtils::SetReceiveBufferSize(fd_
,
149 kDefaultSocketReceiveBuffer
)) {
153 if (!QuicSocketUtils::SetSendBufferSize(fd_
, kDefaultSocketReceiveBuffer
)) {
157 sockaddr_storage raw_addr
;
158 socklen_t raw_addr_len
= sizeof(raw_addr
);
159 CHECK(address
.ToSockAddr(reinterpret_cast<sockaddr
*>(&raw_addr
),
162 reinterpret_cast<const sockaddr
*>(&raw_addr
),
165 LOG(ERROR
) << "Bind failed: " << strerror(errno
);
169 DVLOG(1) << "Listening on " << address
.ToString();
171 SockaddrStorage storage
;
172 IPEndPoint server_address
;
173 if (getsockname(fd_
, storage
.addr
, &storage
.addr_len
) != 0 ||
174 !server_address
.FromSockAddr(storage
.addr
, storage
.addr_len
)) {
175 LOG(ERROR
) << "Unable to get self address. Error: " << strerror(errno
);
178 port_
= server_address
.port();
179 DVLOG(1) << "Kernel assigned port is " << port_
;
182 epoll_server_
.RegisterFD(fd_
, this, kEpollFlags
);
183 dispatcher_
.reset(CreateQuicDispatcher());
184 dispatcher_
->InitializeWithWriter(CreateWriter(fd_
));
189 QuicDefaultPacketWriter
* QuicServer::CreateWriter(int fd
) {
190 return new QuicDefaultPacketWriter(fd
);
193 QuicDispatcher
* QuicServer::CreateQuicDispatcher() {
194 return new QuicDispatcher(
198 new QuicDispatcher::DefaultPacketWriterFactory(),
199 new QuicEpollConnectionHelper(&epoll_server_
));
202 void QuicServer::WaitForEvents() {
203 epoll_server_
.WaitForEventsAndExecuteCallbacks();
206 void QuicServer::Shutdown() {
207 // Before we shut down the epoll server, give all active sessions a chance to
208 // notify clients that they're closing.
209 dispatcher_
->Shutdown();
215 void QuicServer::OnEvent(int fd
, EpollEvent
* event
) {
217 event
->out_ready_mask
= 0;
219 if (event
->in_events
& EPOLLIN
) {
220 DVLOG(1) << "EPOLLIN";
224 if (FLAGS_quic_use_optimized_packet_reader
) {
225 read
= packet_reader_
->ReadAndDispatchPackets(
226 fd_
, port_
, dispatcher_
.get(),
227 overflow_supported_
? &packets_dropped_
: nullptr);
229 // TODO(rtenneti): Add support for ReadAndDispatchPackets.
231 read
= ReadAndDispatchPackets(
232 fd_
, port_
, dispatcher_
.get(),
233 overflow_supported_
? &packets_dropped_
: nullptr);
235 read
= ReadAndDispatchSinglePacket(
236 fd_
, port_
, dispatcher_
.get(),
237 overflow_supported_
? &packets_dropped_
: nullptr);
241 if (FLAGS_quic_use_optimized_packet_reader
) {
242 read
= QuicPacketReader::ReadAndDispatchSinglePacket(
243 fd_
, port_
, dispatcher_
.get(),
244 overflow_supported_
? &packets_dropped_
: nullptr);
246 read
= ReadAndDispatchSinglePacket(
247 fd_
, port_
, dispatcher_
.get(),
248 overflow_supported_
? &packets_dropped_
: nullptr);
253 if (event
->in_events
& EPOLLOUT
) {
254 dispatcher_
->OnCanWrite();
255 if (dispatcher_
->HasPendingWrites()) {
256 event
->out_ready_mask
|= EPOLLOUT
;
259 if (event
->in_events
& EPOLLERR
) {
264 bool QuicServer::ReadAndDispatchSinglePacket(int fd
,
266 ProcessPacketInterface
* processor
,
267 QuicPacketCount
* packets_dropped
) {
268 // Allocate some extra space so we can send an error if the client goes over
270 char buf
[2 * kMaxPacketSize
];
272 IPEndPoint client_address
;
273 IPAddressNumber server_ip
;
275 QuicSocketUtils::ReadPacket(fd
, buf
, arraysize(buf
),
277 &server_ip
, &client_address
);
279 if (bytes_read
< 0) {
280 return false; // We failed to read.
283 QuicEncryptedPacket
packet(buf
, bytes_read
, false);
285 IPEndPoint
server_address(server_ip
, port
);
286 processor
->ProcessPacket(server_address
, client_address
, packet
);
288 // The socket read was successful, so return true even if packet dispatch