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/congestion_control/tcp_receiver.h"
16 #include "net/quic/crypto/crypto_handshake.h"
17 #include "net/quic/crypto/quic_random.h"
18 #include "net/quic/quic_clock.h"
19 #include "net/quic/quic_crypto_stream.h"
20 #include "net/quic/quic_data_reader.h"
21 #include "net/quic/quic_protocol.h"
22 #include "net/tools/quic/quic_dispatcher.h"
23 #include "net/tools/quic/quic_in_memory_cache.h"
24 #include "net/tools/quic/quic_socket_utils.h"
29 #define SO_RXQ_OVFL 40
37 const int kEpollFlags
= EPOLLIN
| EPOLLOUT
| EPOLLET
;
38 const char kSourceAddressTokenSecret
[] = "secret";
39 const uint32 kServerInitialFlowControlWindow
= 100 * net::kMaxPacketSize
;
43 QuicServer::QuicServer()
47 overflow_supported_(false),
49 crypto_config_(kSourceAddressTokenSecret
, QuicRandom::GetInstance()),
50 supported_versions_(QuicSupportedVersions()) {
54 QuicServer::QuicServer(const QuicConfig
& config
,
55 const QuicVersionVector
& supported_versions
)
59 overflow_supported_(false),
62 crypto_config_(kSourceAddressTokenSecret
, QuicRandom::GetInstance()),
63 supported_versions_(supported_versions
) {
67 void QuicServer::Initialize() {
71 epoll_server_
.set_timeout_in_us(50 * 1000);
72 // Initialize the in memory cache now.
73 QuicInMemoryCache::GetInstance();
75 QuicEpollClock
clock(&epoll_server_
);
77 scoped_ptr
<CryptoHandshakeMessage
> scfg(
78 crypto_config_
.AddDefaultConfig(
79 QuicRandom::GetInstance(), &clock
,
80 QuicCryptoServerConfig::ConfigOptions()));
82 // Set flow control options in the config.
83 config_
.SetInitialCongestionWindowToSend(kServerInitialFlowControlWindow
);
86 QuicServer::~QuicServer() {
89 bool QuicServer::Listen(const IPEndPoint
& address
) {
90 port_
= address
.port();
91 int address_family
= address
.GetSockAddrFamily();
92 fd_
= socket(address_family
, SOCK_DGRAM
| SOCK_NONBLOCK
, IPPROTO_UDP
);
94 LOG(ERROR
) << "CreateSocket() failed: " << strerror(errno
);
98 // Enable the socket option that allows the local address to be
99 // returned if the socket is bound to more than one address.
100 int rc
= QuicSocketUtils::SetGetAddressInfo(fd_
, address_family
);
103 LOG(ERROR
) << "IP detection not supported" << strerror(errno
);
107 int get_overflow
= 1;
109 fd_
, SOL_SOCKET
, SO_RXQ_OVFL
, &get_overflow
, sizeof(get_overflow
));
112 DLOG(WARNING
) << "Socket overflow detection not supported";
114 overflow_supported_
= true;
117 // These send and receive buffer sizes are sized for a single connection,
118 // because the default usage of QuicServer is as a test server with one or
119 // two clients. Adjust higher for use with many clients.
120 if (!QuicSocketUtils::SetReceiveBufferSize(fd_
,
121 TcpReceiver::kReceiveWindowTCP
)) {
125 if (!QuicSocketUtils::SetSendBufferSize(fd_
,
126 TcpReceiver::kReceiveWindowTCP
)) {
130 sockaddr_storage raw_addr
;
131 socklen_t raw_addr_len
= sizeof(raw_addr
);
132 CHECK(address
.ToSockAddr(reinterpret_cast<sockaddr
*>(&raw_addr
),
135 reinterpret_cast<const sockaddr
*>(&raw_addr
),
138 LOG(ERROR
) << "Bind failed: " << strerror(errno
);
142 DVLOG(1) << "Listening on " << address
.ToString();
144 SockaddrStorage storage
;
145 IPEndPoint server_address
;
146 if (getsockname(fd_
, storage
.addr
, &storage
.addr_len
) != 0 ||
147 !server_address
.FromSockAddr(storage
.addr
, storage
.addr_len
)) {
148 LOG(ERROR
) << "Unable to get self address. Error: " << strerror(errno
);
151 port_
= server_address
.port();
152 DVLOG(1) << "Kernel assigned port is " << port_
;
155 epoll_server_
.RegisterFD(fd_
, this, kEpollFlags
);
156 dispatcher_
.reset(CreateQuicDispatcher());
157 dispatcher_
->Initialize(fd_
);
162 QuicDispatcher
* QuicServer::CreateQuicDispatcher() {
163 return new QuicDispatcher(
167 new QuicDispatcher::DefaultPacketWriterFactory(),
171 void QuicServer::WaitForEvents() {
172 epoll_server_
.WaitForEventsAndExecuteCallbacks();
175 void QuicServer::Shutdown() {
176 // Before we shut down the epoll server, give all active sessions a chance to
177 // notify clients that they're closing.
178 dispatcher_
->Shutdown();
184 void QuicServer::OnEvent(int fd
, EpollEvent
* event
) {
186 event
->out_ready_mask
= 0;
188 if (event
->in_events
& EPOLLIN
) {
189 DVLOG(1) << "EPOLLIN";
192 read
= ReadAndDispatchSinglePacket(
193 fd_
, port_
, dispatcher_
.get(),
194 overflow_supported_
? &packets_dropped_
: nullptr);
197 if (event
->in_events
& EPOLLOUT
) {
198 dispatcher_
->OnCanWrite();
199 if (dispatcher_
->HasPendingWrites()) {
200 event
->out_ready_mask
|= EPOLLOUT
;
203 if (event
->in_events
& EPOLLERR
) {
208 bool QuicServer::ReadAndDispatchSinglePacket(int fd
,
210 ProcessPacketInterface
* processor
,
211 uint32
* packets_dropped
) {
212 // Allocate some extra space so we can send an error if the client goes over
214 char buf
[2 * kMaxPacketSize
];
216 IPEndPoint client_address
;
217 IPAddressNumber server_ip
;
219 QuicSocketUtils::ReadPacket(fd
, buf
, arraysize(buf
),
221 &server_ip
, &client_address
);
223 if (bytes_read
< 0) {
224 return false; // We failed to read.
227 QuicEncryptedPacket
packet(buf
, bytes_read
, false);
229 IPEndPoint
server_address(server_ip
, port
);
230 processor
->ProcessPacket(server_address
, client_address
, packet
);