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 32 namespace net { 33 namespace tools { 34 35 namespace { 36 37 const int kEpollFlags = EPOLLIN | EPOLLOUT | EPOLLET; 38 const char kSourceAddressTokenSecret[] = "secret"; 39 const uint32 kServerInitialFlowControlWindow = 100 * net::kMaxPacketSize; 40 41 } // namespace 42 43 QuicServer::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 56 QuicServer::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 69 void 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 88 QuicServer::~QuicServer() { 89 } 90 91 bool 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 164 QuicDispatcher* QuicServer::CreateQuicDispatcher() { 165 return new QuicDispatcher( 166 config_, 167 crypto_config_, 168 supported_versions_, 169 new QuicDispatcher::DefaultPacketWriterFactory(), 170 &epoll_server_); 171 } 172 173 void QuicServer::WaitForEvents() { 174 epoll_server_.WaitForEventsAndExecuteCallbacks(); 175 } 176 177 void 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 186 void 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 */ 210 bool 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