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_in_memory_cache.h"
23 #include "net/tools/quic/quic_socket_utils.h"
28 #define SO_RXQ_OVFL 40
31 const int kEpollFlags = EPOLLIN | EPOLLOUT | EPOLLET;
32 static const char kSourceAddressTokenSecret[] = "secret";
33 const uint32 kServerInitialFlowControlWindow = 100 * net::kMaxPacketSize;
38 QuicServer::QuicServer()
42 overflow_supported_(false),
44 crypto_config_(kSourceAddressTokenSecret, QuicRandom::GetInstance()),
45 supported_versions_(QuicSupportedVersions()),
46 server_initial_flow_control_receive_window_(
47 kServerInitialFlowControlWindow) {
48 // Use hardcoded crypto parameters for now.
49 config_.SetDefaults();
53 QuicServer::QuicServer(const QuicConfig& config,
54 const QuicVersionVector& supported_versions,
55 uint32 server_initial_flow_control_receive_window)
59 overflow_supported_(false),
62 crypto_config_(kSourceAddressTokenSecret, QuicRandom::GetInstance()),
63 supported_versions_(supported_versions),
64 server_initial_flow_control_receive_window_(
65 server_initial_flow_control_receive_window) {
69 void QuicServer::Initialize() {
73 epoll_server_.set_timeout_in_us(50 * 1000);
74 // Initialize the in memory cache now.
75 QuicInMemoryCache::GetInstance();
77 QuicEpollClock clock(&epoll_server_);
79 scoped_ptr<CryptoHandshakeMessage> scfg(
80 crypto_config_.AddDefaultConfig(
81 QuicRandom::GetInstance(), &clock,
82 QuicCryptoServerConfig::ConfigOptions()));
85 QuicServer::~QuicServer() {
88 bool QuicServer::Listen(const IPEndPoint& address) {
89 port_ = address.port();
90 int address_family = address.GetSockAddrFamily();
91 fd_ = socket(address_family, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
93 LOG(ERROR) << "CreateSocket() failed: " << strerror(errno);
97 int rc = QuicSocketUtils::SetGetAddressInfo(fd_, address_family);
100 LOG(ERROR) << "IP detection not supported" << strerror(errno);
104 int get_overflow = 1;
106 fd_, SOL_SOCKET, SO_RXQ_OVFL, &get_overflow, sizeof(get_overflow));
109 DLOG(WARNING) << "Socket overflow detection not supported";
111 overflow_supported_ = true;
114 // These send and receive buffer sizes are sized for a single connection,
115 // because the default usage of QuicServer is as a test server with one or
116 // two clients. Adjust higher for use with many clients.
117 if (!QuicSocketUtils::SetReceiveBufferSize(fd_,
118 TcpReceiver::kReceiveWindowTCP)) {
122 if (!QuicSocketUtils::SetSendBufferSize(fd_,
123 TcpReceiver::kReceiveWindowTCP)) {
127 // Enable the socket option that allows the local address to be
128 // returned if the socket is bound to more than on address.
129 int get_local_ip = 1;
130 rc = setsockopt(fd_, IPPROTO_IP, IP_PKTINFO,
131 &get_local_ip, sizeof(get_local_ip));
132 if (rc == 0 && address_family == AF_INET6) {
133 rc = setsockopt(fd_, IPPROTO_IPV6, IPV6_RECVPKTINFO,
134 &get_local_ip, sizeof(get_local_ip));
137 LOG(ERROR) << "Failed to set required socket options";
141 sockaddr_storage raw_addr;
142 socklen_t raw_addr_len = sizeof(raw_addr);
143 CHECK(address.ToSockAddr(reinterpret_cast<sockaddr*>(&raw_addr),
146 reinterpret_cast<const sockaddr*>(&raw_addr),
149 LOG(ERROR) << "Bind failed: " << strerror(errno);
153 DVLOG(1) << "Listening on " << address.ToString();
155 SockaddrStorage storage;
156 IPEndPoint server_address;
157 if (getsockname(fd_, storage.addr, &storage.addr_len) != 0 ||
158 !server_address.FromSockAddr(storage.addr, storage.addr_len)) {
159 LOG(ERROR) << "Unable to get self address. Error: " << strerror(errno);
162 port_ = server_address.port();
163 DVLOG(1) << "Kernel assigned port is " << port_;
166 epoll_server_.RegisterFD(fd_, this, kEpollFlags);
167 dispatcher_.reset(new QuicDispatcher(
172 server_initial_flow_control_receive_window_));
173 dispatcher_->Initialize(fd_);
178 void QuicServer::WaitForEvents() {
179 epoll_server_.WaitForEventsAndExecuteCallbacks();
182 void QuicServer::Shutdown() {
183 // Before we shut down the epoll server, give all active sessions a chance to
184 // notify clients that they're closing.
185 dispatcher_->Shutdown();
191 void QuicServer::OnEvent(int fd, EpollEvent* event) {
193 event->out_ready_mask = 0;
195 if (event->in_events & EPOLLIN) {
196 DVLOG(1) << "EPOLLIN";
199 read = ReadAndDispatchSinglePacket(
200 fd_, port_, dispatcher_.get(),
201 overflow_supported_ ? &packets_dropped_ : NULL);
204 if (event->in_events & EPOLLOUT) {
205 dispatcher_->OnCanWrite();
206 if (dispatcher_->HasPendingWrites()) {
207 event->out_ready_mask |= EPOLLOUT;
210 if (event->in_events & EPOLLERR) {
215 bool QuicServer::ReadAndDispatchSinglePacket(int fd,
217 QuicDispatcher* dispatcher,
218 uint32* packets_dropped) {
219 // Allocate some extra space so we can send an error if the client goes over
221 char buf[2 * kMaxPacketSize];
223 IPEndPoint client_address;
224 IPAddressNumber server_ip;
226 QuicSocketUtils::ReadPacket(fd, buf, arraysize(buf),
228 &server_ip, &client_address);
230 if (bytes_read < 0) {
231 return false; // We failed to read.
234 QuicEncryptedPacket packet(buf, bytes_read, false);
236 IPEndPoint server_address(server_ip, port);
237 dispatcher->ProcessPacket(server_address, client_address, packet);