| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 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/quic/quic_server.h" | |
| 6 | |
| 7 #include <string.h> | |
| 8 | |
| 9 #include "net/base/ip_endpoint.h" | |
| 10 #include "net/base/net_errors.h" | |
| 11 #include "net/quic/crypto/crypto_handshake.h" | |
| 12 #include "net/quic/crypto/quic_random.h" | |
| 13 #include "net/quic/quic_crypto_stream.h" | |
| 14 #include "net/quic/quic_data_reader.h" | |
| 15 #include "net/quic/quic_dispatcher.h" | |
| 16 #include "net/quic/quic_in_memory_cache.h" | |
| 17 #include "net/quic/quic_protocol.h" | |
| 18 #include "net/quic/quic_server_packet_writer.h" | |
| 19 #include "net/udp/udp_server_socket.h" | |
| 20 | |
| 21 namespace net { | |
| 22 | |
| 23 namespace { | |
| 24 | |
| 25 const char kSourceAddressTokenSecret[] = "secret"; | |
| 26 | |
| 27 // Allocate some extra space so we can send an error if the client goes over | |
| 28 // the limit. | |
| 29 const int kReadBufferSize = 2 * kMaxPacketSize; | |
| 30 | |
| 31 } // namespace | |
| 32 | |
| 33 QuicServer::QuicServer(const QuicConfig& config, | |
| 34 const QuicVersionVector& supported_versions) | |
| 35 : helper_(base::MessageLoop::current()->message_loop_proxy().get(), | |
| 36 &clock_, | |
| 37 QuicRandom::GetInstance()), | |
| 38 config_(config), | |
| 39 crypto_config_(kSourceAddressTokenSecret, QuicRandom::GetInstance()), | |
| 40 supported_versions_(supported_versions), | |
| 41 read_pending_(false), | |
| 42 synchronous_read_count_(0), | |
| 43 read_buffer_(new IOBufferWithSize(kReadBufferSize)), | |
| 44 weak_factory_(this) { | |
| 45 Initialize(); | |
| 46 } | |
| 47 | |
| 48 void QuicServer::Initialize() { | |
| 49 #if MMSG_MORE | |
| 50 use_recvmmsg_ = true; | |
| 51 #endif | |
| 52 | |
| 53 // If an initial flow control window has not explicitly been set, then use a | |
| 54 // sensible value for a server: 1 MB for session, 64 KB for each stream. | |
| 55 const uint32 kInitialSessionFlowControlWindow = 1 * 1024 * 1024; // 1 MB | |
| 56 const uint32 kInitialStreamFlowControlWindow = 64 * 1024; // 64 KB | |
| 57 if (config_.GetInitialStreamFlowControlWindowToSend() == | |
| 58 kMinimumFlowControlSendWindow) { | |
| 59 config_.SetInitialStreamFlowControlWindowToSend( | |
| 60 kInitialStreamFlowControlWindow); | |
| 61 } | |
| 62 if (config_.GetInitialSessionFlowControlWindowToSend() == | |
| 63 kMinimumFlowControlSendWindow) { | |
| 64 config_.SetInitialSessionFlowControlWindowToSend( | |
| 65 kInitialSessionFlowControlWindow); | |
| 66 } | |
| 67 | |
| 68 // Initialize the in memory cache now. | |
| 69 QuicInMemoryCache::GetInstance(); | |
| 70 | |
| 71 scoped_ptr<CryptoHandshakeMessage> scfg( | |
| 72 crypto_config_.AddDefaultConfig( | |
| 73 helper_.GetRandomGenerator(), helper_.GetClock(), | |
| 74 QuicCryptoServerConfig::ConfigOptions())); | |
| 75 } | |
| 76 | |
| 77 QuicServer::~QuicServer() { | |
| 78 } | |
| 79 | |
| 80 int QuicServer::Listen(const IPEndPoint& address) { | |
| 81 scoped_ptr<UDPServerSocket> socket( | |
| 82 new UDPServerSocket(&net_log_, NetLog::Source())); | |
| 83 | |
| 84 socket->AllowAddressReuse(); | |
| 85 | |
| 86 int rc = socket->Listen(address); | |
| 87 if (rc < 0) { | |
| 88 LOG(ERROR) << "Listen() failed: " << ErrorToString(rc); | |
| 89 return rc; | |
| 90 } | |
| 91 | |
| 92 // These send and receive buffer sizes are sized for a single connection, | |
| 93 // because the default usage of QuicServer is as a test server with one or | |
| 94 // two clients. Adjust higher for use with many clients. | |
| 95 rc = socket->SetReceiveBufferSize( | |
| 96 static_cast<int32>(kDefaultSocketReceiveBuffer)); | |
| 97 if (rc < 0) { | |
| 98 LOG(ERROR) << "SetReceiveBufferSize() failed: " << ErrorToString(rc); | |
| 99 return rc; | |
| 100 } | |
| 101 | |
| 102 rc = socket->SetSendBufferSize(20 * kMaxPacketSize); | |
| 103 if (rc < 0) { | |
| 104 LOG(ERROR) << "SetSendBufferSize() failed: " << ErrorToString(rc); | |
| 105 return rc; | |
| 106 } | |
| 107 | |
| 108 rc = socket->GetLocalAddress(&server_address_); | |
| 109 if (rc < 0) { | |
| 110 LOG(ERROR) << "GetLocalAddress() failed: " << ErrorToString(rc); | |
| 111 return rc; | |
| 112 } | |
| 113 | |
| 114 DVLOG(1) << "Listening on " << server_address_.ToString(); | |
| 115 | |
| 116 socket_.swap(socket); | |
| 117 | |
| 118 dispatcher_.reset( | |
| 119 new QuicDispatcher(config_, | |
| 120 crypto_config_, | |
| 121 supported_versions_, | |
| 122 new QuicDispatcher::DefaultPacketWriterFactory(), | |
| 123 &helper_)); | |
| 124 QuicServerPacketWriter* writer = new QuicServerPacketWriter( | |
| 125 socket_.get(), | |
| 126 dispatcher_.get()); | |
| 127 dispatcher_->Initialize(writer); | |
| 128 | |
| 129 StartReading(); | |
| 130 | |
| 131 return OK; | |
| 132 } | |
| 133 | |
| 134 void QuicServer::Shutdown() { | |
| 135 // Before we shut down the epoll server, give all active sessions a chance to | |
| 136 // notify clients that they're closing. | |
| 137 dispatcher_->Shutdown(); | |
| 138 | |
| 139 socket_->Close(); | |
| 140 socket_.reset(); | |
| 141 } | |
| 142 | |
| 143 void QuicServer::StartReading() { | |
| 144 if (read_pending_) { | |
| 145 return; | |
| 146 } | |
| 147 read_pending_ = true; | |
| 148 | |
| 149 int result = socket_->RecvFrom( | |
| 150 read_buffer_.get(), | |
| 151 read_buffer_->size(), | |
| 152 &client_address_, | |
| 153 base::Bind(&QuicServer::OnReadComplete, base::Unretained(this))); | |
| 154 | |
| 155 if (result == ERR_IO_PENDING) { | |
| 156 synchronous_read_count_ = 0; | |
| 157 return; | |
| 158 } | |
| 159 | |
| 160 if (++synchronous_read_count_ > 32) { | |
| 161 synchronous_read_count_ = 0; | |
| 162 // Schedule the processing through the message loop to 1) prevent infinite | |
| 163 // recursion and 2) avoid blocking the thread for too long. | |
| 164 base::MessageLoop::current()->PostTask( | |
| 165 FROM_HERE, | |
| 166 base::Bind(&QuicServer::OnReadComplete, | |
| 167 weak_factory_.GetWeakPtr(), | |
| 168 result)); | |
| 169 } else { | |
| 170 OnReadComplete(result); | |
| 171 } | |
| 172 } | |
| 173 | |
| 174 void QuicServer::OnReadComplete(int result) { | |
| 175 read_pending_ = false; | |
| 176 if (result == 0) | |
| 177 result = ERR_CONNECTION_CLOSED; | |
| 178 | |
| 179 if (result < 0) { | |
| 180 LOG(ERROR) << "QuicServer read failed: " << ErrorToString(result); | |
| 181 Shutdown(); | |
| 182 return; | |
| 183 } | |
| 184 | |
| 185 QuicEncryptedPacket packet(read_buffer_->data(), result, false); | |
| 186 dispatcher_->ProcessPacket(server_address_, client_address_, packet); | |
| 187 | |
| 188 StartReading(); | |
| 189 } | |
| 190 | |
| 191 } // namespace net | |
| OLD | NEW |