Revert of Add support for escaped target names in isolate driver. (patchset #6 id...
[chromium-blink-merge.git] / net / quic / quic_server.cc
blob610b305f66b7ea4b0ac323e3e72f0405ca92c643
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.
5 #include "net/quic/quic_server.h"
7 #include <string.h>
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"
21 namespace net {
23 namespace {
25 const char kSourceAddressTokenSecret[] = "secret";
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;
31 } // namespace
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();
48 void QuicServer::Initialize() {
49 #if MMSG_MORE
50 use_recvmmsg_ = true;
51 #endif
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);
62 if (config_.GetInitialSessionFlowControlWindowToSend() ==
63 kMinimumFlowControlSendWindow) {
64 config_.SetInitialSessionFlowControlWindowToSend(
65 kInitialSessionFlowControlWindow);
68 // Initialize the in memory cache now.
69 QuicInMemoryCache::GetInstance();
71 scoped_ptr<CryptoHandshakeMessage> scfg(
72 crypto_config_.AddDefaultConfig(
73 helper_.GetRandomGenerator(), helper_.GetClock(),
74 QuicCryptoServerConfig::ConfigOptions()));
77 QuicServer::~QuicServer() {
80 int QuicServer::Listen(const IPEndPoint& address) {
81 scoped_ptr<UDPServerSocket> socket(
82 new UDPServerSocket(&net_log_, NetLog::Source()));
84 socket->AllowAddressReuse();
86 int rc = socket->Listen(address);
87 if (rc < 0) {
88 LOG(ERROR) << "Listen() failed: " << ErrorToString(rc);
89 return rc;
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;
102 rc = socket->SetSendBufferSize(20 * kMaxPacketSize);
103 if (rc < 0) {
104 LOG(ERROR) << "SetSendBufferSize() failed: " << ErrorToString(rc);
105 return rc;
108 rc = socket->GetLocalAddress(&server_address_);
109 if (rc < 0) {
110 LOG(ERROR) << "GetLocalAddress() failed: " << ErrorToString(rc);
111 return rc;
114 DVLOG(1) << "Listening on " << server_address_.ToString();
116 socket_.swap(socket);
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);
129 StartReading();
131 return OK;
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();
139 socket_->Close();
140 socket_.reset();
143 void QuicServer::StartReading() {
144 if (read_pending_) {
145 return;
147 read_pending_ = true;
149 int result = socket_->RecvFrom(
150 read_buffer_.get(),
151 read_buffer_->size(),
152 &client_address_,
153 base::Bind(&QuicServer::OnReadComplete, base::Unretained(this)));
155 if (result == ERR_IO_PENDING) {
156 synchronous_read_count_ = 0;
157 return;
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);
174 void QuicServer::OnReadComplete(int result) {
175 read_pending_ = false;
176 if (result == 0)
177 result = ERR_CONNECTION_CLOSED;
179 if (result < 0) {
180 LOG(ERROR) << "QuicServer read failed: " << ErrorToString(result);
181 Shutdown();
182 return;
185 QuicEncryptedPacket packet(read_buffer_->data(), result, false);
186 dispatcher_->ProcessPacket(server_address_, client_address_, packet);
188 StartReading();
191 } // namespace net