Fix more MSVC warnings, courgette/ edition.
[chromium-blink-merge.git] / net / quic / quic_server.cc
blobb8013c441e6b2c6345dde20b974c9e77ae15804c
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/congestion_control/tcp_receiver.h"
12 #include "net/quic/crypto/crypto_handshake.h"
13 #include "net/quic/crypto/quic_random.h"
14 #include "net/quic/quic_crypto_stream.h"
15 #include "net/quic/quic_data_reader.h"
16 #include "net/quic/quic_dispatcher.h"
17 #include "net/quic/quic_in_memory_cache.h"
18 #include "net/quic/quic_protocol.h"
19 #include "net/quic/quic_server_packet_writer.h"
20 #include "net/udp/udp_server_socket.h"
22 namespace net {
24 namespace {
26 const char kSourceAddressTokenSecret[] = "secret";
28 // Allocate some extra space so we can send an error if the client goes over
29 // the limit.
30 const int kReadBufferSize = 2 * kMaxPacketSize;
32 const uint32 kServerInitialFlowControlWindow = 100 * kMaxPacketSize;
34 } // namespace
36 QuicServer::QuicServer(const QuicConfig& config,
37 const QuicVersionVector& supported_versions)
38 : helper_(base::MessageLoop::current()->message_loop_proxy().get(),
39 &clock_,
40 QuicRandom::GetInstance()),
41 config_(config),
42 crypto_config_(kSourceAddressTokenSecret, QuicRandom::GetInstance()),
43 supported_versions_(supported_versions),
44 read_pending_(false),
45 synchronous_read_count_(0),
46 read_buffer_(new IOBufferWithSize(kReadBufferSize)),
47 weak_factory_(this) {
48 Initialize();
51 void QuicServer::Initialize() {
52 // Initialize the in memory cache now.
53 QuicInMemoryCache::GetInstance();
55 scoped_ptr<CryptoHandshakeMessage> scfg(
56 crypto_config_.AddDefaultConfig(helper_.GetRandomGenerator(),
57 helper_.GetClock(),
58 QuicCryptoServerConfig::ConfigOptions()));
60 config_.SetInitialCongestionWindowToSend(kServerInitialFlowControlWindow);
63 QuicServer::~QuicServer() {
66 int QuicServer::Listen(const IPEndPoint& address) {
67 scoped_ptr<UDPServerSocket> socket(
68 new UDPServerSocket(&net_log_, NetLog::Source()));
70 socket->AllowAddressReuse();
72 int rc = socket->Listen(address);
73 if (rc < 0) {
74 LOG(ERROR) << "Listen() failed: " << ErrorToString(rc);
75 return rc;
78 // These send and receive buffer sizes are sized for a single connection,
79 // because the default usage of QuicServer is as a test server with one or
80 // two clients. Adjust higher for use with many clients.
81 rc = socket->SetReceiveBufferSize(TcpReceiver::kReceiveWindowTCP);
82 if (rc < 0) {
83 LOG(ERROR) << "SetReceiveBufferSize() failed: " << ErrorToString(rc);
84 return rc;
87 rc = socket->SetSendBufferSize(20 * kMaxPacketSize);
88 if (rc < 0) {
89 LOG(ERROR) << "SetSendBufferSize() failed: " << ErrorToString(rc);
90 return rc;
93 rc = socket->GetLocalAddress(&server_address_);
94 if (rc < 0) {
95 LOG(ERROR) << "GetLocalAddress() failed: " << ErrorToString(rc);
96 return rc;
99 DVLOG(1) << "Listening on " << server_address_.ToString();
101 socket_.swap(socket);
103 dispatcher_.reset(
104 new QuicDispatcher(config_,
105 crypto_config_,
106 supported_versions_,
107 new QuicDispatcher::DefaultPacketWriterFactory(),
108 &helper_));
109 QuicServerPacketWriter* writer = new QuicServerPacketWriter(
110 socket_.get(),
111 dispatcher_.get());
112 dispatcher_->Initialize(writer);
114 StartReading();
116 return OK;
119 void QuicServer::Shutdown() {
120 // Before we shut down the epoll server, give all active sessions a chance to
121 // notify clients that they're closing.
122 dispatcher_->Shutdown();
124 socket_->Close();
125 socket_.reset();
128 void QuicServer::StartReading() {
129 if (read_pending_) {
130 return;
132 read_pending_ = true;
134 int result = socket_->RecvFrom(
135 read_buffer_.get(),
136 read_buffer_->size(),
137 &client_address_,
138 base::Bind(&QuicServer::OnReadComplete, base::Unretained(this)));
140 if (result == ERR_IO_PENDING) {
141 synchronous_read_count_ = 0;
142 return;
145 if (++synchronous_read_count_ > 32) {
146 synchronous_read_count_ = 0;
147 // Schedule the processing through the message loop to 1) prevent infinite
148 // recursion and 2) avoid blocking the thread for too long.
149 base::MessageLoop::current()->PostTask(
150 FROM_HERE,
151 base::Bind(&QuicServer::OnReadComplete,
152 weak_factory_.GetWeakPtr(),
153 result));
154 } else {
155 OnReadComplete(result);
159 void QuicServer::OnReadComplete(int result) {
160 read_pending_ = false;
161 if (result == 0)
162 result = ERR_CONNECTION_CLOSED;
164 if (result < 0) {
165 LOG(ERROR) << "QuicServer read failed: " << ErrorToString(result);
166 Shutdown();
167 return;
170 QuicEncryptedPacket packet(read_buffer_->data(), result, false);
171 dispatcher_->ProcessPacket(server_address_, client_address_, packet);
173 StartReading();
176 } // namespace net