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"
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"
26 const char kSourceAddressTokenSecret[] = "secret";
28 // Allocate some extra space so we can send an error if the client goes over
30 const int kReadBufferSize = 2 * kMaxPacketSize;
34 QuicServer::QuicServer(const QuicConfig& config,
35 const QuicVersionVector& supported_versions)
36 : helper_(base::MessageLoop::current()->message_loop_proxy().get(),
38 QuicRandom::GetInstance()),
40 crypto_config_(kSourceAddressTokenSecret, QuicRandom::GetInstance()),
41 supported_versions_(supported_versions),
43 synchronous_read_count_(0),
44 read_buffer_(new IOBufferWithSize(kReadBufferSize)),
49 void QuicServer::Initialize() {
50 // Initialize the in memory cache now.
51 QuicInMemoryCache::GetInstance();
53 scoped_ptr<CryptoHandshakeMessage> scfg(
54 crypto_config_.AddDefaultConfig(
55 helper_.GetRandomGenerator(), helper_.GetClock(),
56 QuicCryptoServerConfig::ConfigOptions()));
59 QuicServer::~QuicServer() {
62 int QuicServer::Listen(const IPEndPoint& address) {
63 scoped_ptr<UDPServerSocket> socket(
64 new UDPServerSocket(&net_log_, NetLog::Source()));
66 socket->AllowAddressReuse();
68 int rc = socket->Listen(address);
70 LOG(ERROR) << "Listen() failed: " << ErrorToString(rc);
74 // These send and receive buffer sizes are sized for a single connection,
75 // because the default usage of QuicServer is as a test server with one or
76 // two clients. Adjust higher for use with many clients.
77 rc = socket->SetReceiveBufferSize(TcpReceiver::kReceiveWindowTCP);
79 LOG(ERROR) << "SetReceiveBufferSize() failed: " << ErrorToString(rc);
83 rc = socket->SetSendBufferSize(20 * kMaxPacketSize);
85 LOG(ERROR) << "SetSendBufferSize() failed: " << ErrorToString(rc);
89 rc = socket->GetLocalAddress(&server_address_);
91 LOG(ERROR) << "GetLocalAddress() failed: " << ErrorToString(rc);
95 DVLOG(1) << "Listening on " << server_address_.ToString();
100 new QuicDispatcher(config_,
103 new QuicDispatcher::DefaultPacketWriterFactory(),
105 QuicServerPacketWriter* writer = new QuicServerPacketWriter(
108 dispatcher_->Initialize(writer);
115 void QuicServer::Shutdown() {
116 // Before we shut down the epoll server, give all active sessions a chance to
117 // notify clients that they're closing.
118 dispatcher_->Shutdown();
124 void QuicServer::StartReading() {
128 read_pending_ = true;
130 int result = socket_->RecvFrom(
132 read_buffer_->size(),
134 base::Bind(&QuicServer::OnReadComplete, base::Unretained(this)));
136 if (result == ERR_IO_PENDING) {
137 synchronous_read_count_ = 0;
141 if (++synchronous_read_count_ > 32) {
142 synchronous_read_count_ = 0;
143 // Schedule the processing through the message loop to 1) prevent infinite
144 // recursion and 2) avoid blocking the thread for too long.
145 base::MessageLoop::current()->PostTask(
147 base::Bind(&QuicServer::OnReadComplete,
148 weak_factory_.GetWeakPtr(),
151 OnReadComplete(result);
155 void QuicServer::OnReadComplete(int result) {
156 read_pending_ = false;
158 result = ERR_CONNECTION_CLOSED;
161 LOG(ERROR) << "QuicServer read failed: " << ErrorToString(result);
166 QuicEncryptedPacket packet(read_buffer_->data(), result, false);
167 dispatcher_->ProcessPacket(server_address_, client_address_, packet);