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/tools/quic/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 "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"
25
26#define MMSG_MORE 0
27
28#ifndef SO_RXQ_OVFL
29#define SO_RXQ_OVFL 40
30#endif
31
32namespace net {
33namespace tools {
34
35namespace {
36
37const int kEpollFlags = EPOLLIN | EPOLLOUT | EPOLLET;
38const char kSourceAddressTokenSecret[] = "secret";
39const uint32 kServerInitialFlowControlWindow = 100 * net::kMaxPacketSize;
40
41}  // namespace
42
43QuicServer::QuicServer()
44    : port_(0),
45      fd_(-1),
46      packets_dropped_(0),
47      overflow_supported_(false),
48      use_recvmmsg_(false),
49      crypto_config_(kSourceAddressTokenSecret, QuicRandom::GetInstance()),
50      supported_versions_(QuicSupportedVersions()) {
51  // Use hardcoded crypto parameters for now.
52  config_.SetDefaults();
53  Initialize();
54}
55
56QuicServer::QuicServer(const QuicConfig& config,
57                       const QuicVersionVector& supported_versions)
58    : port_(0),
59      fd_(-1),
60      packets_dropped_(0),
61      overflow_supported_(false),
62      use_recvmmsg_(false),
63      config_(config),
64      crypto_config_(kSourceAddressTokenSecret, QuicRandom::GetInstance()),
65      supported_versions_(supported_versions) {
66  Initialize();
67}
68
69void QuicServer::Initialize() {
70#if MMSG_MORE
71  use_recvmmsg_ = true;
72#endif
73  epoll_server_.set_timeout_in_us(50 * 1000);
74  // Initialize the in memory cache now.
75  QuicInMemoryCache::GetInstance();
76
77  QuicEpollClock clock(&epoll_server_);
78
79  scoped_ptr<CryptoHandshakeMessage> scfg(
80      crypto_config_.AddDefaultConfig(
81          QuicRandom::GetInstance(), &clock,
82          QuicCryptoServerConfig::ConfigOptions()));
83
84  // Set flow control options in the config.
85  config_.SetInitialCongestionWindowToSend(kServerInitialFlowControlWindow);
86}
87
88QuicServer::~QuicServer() {
89}
90
91bool QuicServer::Listen(const IPEndPoint& address) {
92  port_ = address.port();
93  int address_family = address.GetSockAddrFamily();
94  fd_ = socket(address_family, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
95  if (fd_ < 0) {
96    LOG(ERROR) << "CreateSocket() failed: " << strerror(errno);
97    return false;
98  }
99
100  // Enable the socket option that allows the local address to be
101  // returned if the socket is bound to more than one address.
102  int rc = QuicSocketUtils::SetGetAddressInfo(fd_, address_family);
103
104  if (rc < 0) {
105    LOG(ERROR) << "IP detection not supported" << strerror(errno);
106    return false;
107  }
108
109  int get_overflow = 1;
110  rc = setsockopt(
111      fd_, SOL_SOCKET, SO_RXQ_OVFL, &get_overflow, sizeof(get_overflow));
112
113  if (rc < 0) {
114    DLOG(WARNING) << "Socket overflow detection not supported";
115  } else {
116    overflow_supported_ = true;
117  }
118
119  // These send and receive buffer sizes are sized for a single connection,
120  // because the default usage of QuicServer is as a test server with one or
121  // two clients.  Adjust higher for use with many clients.
122  if (!QuicSocketUtils::SetReceiveBufferSize(fd_,
123                                             TcpReceiver::kReceiveWindowTCP)) {
124    return false;
125  }
126
127  if (!QuicSocketUtils::SetSendBufferSize(fd_,
128                                          TcpReceiver::kReceiveWindowTCP)) {
129    return false;
130  }
131
132  sockaddr_storage raw_addr;
133  socklen_t raw_addr_len = sizeof(raw_addr);
134  CHECK(address.ToSockAddr(reinterpret_cast<sockaddr*>(&raw_addr),
135                           &raw_addr_len));
136  rc = bind(fd_,
137            reinterpret_cast<const sockaddr*>(&raw_addr),
138            sizeof(raw_addr));
139  if (rc < 0) {
140    LOG(ERROR) << "Bind failed: " << strerror(errno);
141    return false;
142  }
143
144  DVLOG(1) << "Listening on " << address.ToString();
145  if (port_ == 0) {
146    SockaddrStorage storage;
147    IPEndPoint server_address;
148    if (getsockname(fd_, storage.addr, &storage.addr_len) != 0 ||
149        !server_address.FromSockAddr(storage.addr, storage.addr_len)) {
150      LOG(ERROR) << "Unable to get self address.  Error: " << strerror(errno);
151      return false;
152    }
153    port_ = server_address.port();
154    DVLOG(1) << "Kernel assigned port is " << port_;
155  }
156
157  epoll_server_.RegisterFD(fd_, this, kEpollFlags);
158  dispatcher_.reset(CreateQuicDispatcher());
159  dispatcher_->Initialize(fd_);
160
161  return true;
162}
163
164QuicDispatcher* QuicServer::CreateQuicDispatcher() {
165  return new QuicDispatcher(
166      config_,
167      crypto_config_,
168      supported_versions_,
169      new QuicDispatcher::DefaultPacketWriterFactory(),
170      &epoll_server_);
171}
172
173void QuicServer::WaitForEvents() {
174  epoll_server_.WaitForEventsAndExecuteCallbacks();
175}
176
177void QuicServer::Shutdown() {
178  // Before we shut down the epoll server, give all active sessions a chance to
179  // notify clients that they're closing.
180  dispatcher_->Shutdown();
181
182  close(fd_);
183  fd_ = -1;
184}
185
186void QuicServer::OnEvent(int fd, EpollEvent* event) {
187  DCHECK_EQ(fd, fd_);
188  event->out_ready_mask = 0;
189
190  if (event->in_events & EPOLLIN) {
191    DVLOG(1) << "EPOLLIN";
192    bool read = true;
193    while (read) {
194        read = ReadAndDispatchSinglePacket(
195            fd_, port_, dispatcher_.get(),
196            overflow_supported_ ? &packets_dropped_ : NULL);
197    }
198  }
199  if (event->in_events & EPOLLOUT) {
200    dispatcher_->OnCanWrite();
201    if (dispatcher_->HasPendingWrites()) {
202      event->out_ready_mask |= EPOLLOUT;
203    }
204  }
205  if (event->in_events & EPOLLERR) {
206  }
207}
208
209/* static */
210bool QuicServer::ReadAndDispatchSinglePacket(int fd,
211                                             int port,
212                                             ProcessPacketInterface* processor,
213                                             uint32* packets_dropped) {
214  // Allocate some extra space so we can send an error if the client goes over
215  // the limit.
216  char buf[2 * kMaxPacketSize];
217
218  IPEndPoint client_address;
219  IPAddressNumber server_ip;
220  int bytes_read =
221      QuicSocketUtils::ReadPacket(fd, buf, arraysize(buf),
222                                  packets_dropped,
223                                  &server_ip, &client_address);
224
225  if (bytes_read < 0) {
226    return false;  // We failed to read.
227  }
228
229  QuicEncryptedPacket packet(buf, bytes_read, false);
230
231  IPEndPoint server_address(server_ip, port);
232  processor->ProcessPacket(server_address, client_address, packet);
233
234  return true;
235}
236
237}  // namespace tools
238}  // namespace net
239