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/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"
25 const char kSourceAddressTokenSecret
[] = "secret";
27 // Allocate some extra space so we can send an error if the client goes over
29 const int kReadBufferSize
= 2 * kMaxPacketSize
;
33 QuicServer::QuicServer(const QuicConfig
& config
,
34 const QuicVersionVector
& supported_versions
)
35 : helper_(base::MessageLoop::current()->message_loop_proxy().get(),
37 QuicRandom::GetInstance()),
39 crypto_config_(kSourceAddressTokenSecret
, QuicRandom::GetInstance()),
40 supported_versions_(supported_versions
),
42 synchronous_read_count_(0),
43 read_buffer_(new IOBufferWithSize(kReadBufferSize
)),
48 void QuicServer::Initialize() {
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
);
88 LOG(ERROR
) << "Listen() failed: " << ErrorToString(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
));
98 LOG(ERROR
) << "SetReceiveBufferSize() failed: " << ErrorToString(rc
);
102 rc
= socket
->SetSendBufferSize(20 * kMaxPacketSize
);
104 LOG(ERROR
) << "SetSendBufferSize() failed: " << ErrorToString(rc
);
108 rc
= socket
->GetLocalAddress(&server_address_
);
110 LOG(ERROR
) << "GetLocalAddress() failed: " << ErrorToString(rc
);
114 DVLOG(1) << "Listening on " << server_address_
.ToString();
116 socket_
.swap(socket
);
119 new QuicDispatcher(config_
,
122 new QuicDispatcher::DefaultPacketWriterFactory(),
124 QuicServerPacketWriter
* writer
= new QuicServerPacketWriter(
127 dispatcher_
->Initialize(writer
);
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();
143 void QuicServer::StartReading() {
147 read_pending_
= true;
149 int result
= socket_
->RecvFrom(
151 read_buffer_
->size(),
153 base::Bind(&QuicServer::OnReadComplete
, base::Unretained(this)));
155 if (result
== ERR_IO_PENDING
) {
156 synchronous_read_count_
= 0;
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(
166 base::Bind(&QuicServer::OnReadComplete
,
167 weak_factory_
.GetWeakPtr(),
170 OnReadComplete(result
);
174 void QuicServer::OnReadComplete(int result
) {
175 read_pending_
= false;
177 result
= ERR_CONNECTION_CLOSED
;
180 LOG(ERROR
) << "QuicServer read failed: " << ErrorToString(result
);
185 QuicEncryptedPacket
packet(read_buffer_
->data(), result
, false);
186 dispatcher_
->ProcessPacket(server_address_
, client_address_
, packet
);