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