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/tools/quic/quic_simple_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_protocol.h"
16 #include "net/tools/quic/quic_dispatcher.h"
17 #include "net/tools/quic/quic_simple_per_connection_packet_writer.h"
18 #include "net/tools/quic/quic_simple_server_packet_writer.h"
19 #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
;
32 // A packet writer factory which wraps a shared QuicSimpleServerPacketWriter
33 // inside of a QuicPerConnectionPacketWriter. Instead of checking that
34 // the shared_writer is the expected writer, this could instead cast
35 // from QuicPacketWriter to QuicSimpleServerPacketWriter.
36 class CustomPacketWriterFactory
: public QuicDispatcher::PacketWriterFactory
{
38 ~CustomPacketWriterFactory() override
{}
40 QuicPacketWriter
* Create(QuicPacketWriter
* writer
,
41 QuicConnection
* connection
) override
{
42 if (writer
== nullptr) {
43 LOG(DFATAL
) << "shared_writer not initialized";
46 if (writer
!= shared_writer_
) {
47 LOG(DFATAL
) << "writer mismatch";
50 return new QuicSimplePerConnectionPacketWriter(shared_writer_
, connection
);
53 void set_shared_writer(QuicSimpleServerPacketWriter
* shared_writer
) {
54 shared_writer_
= shared_writer
;
58 QuicSimpleServerPacketWriter
* shared_writer_
; // Not owned.
63 QuicSimpleServer::QuicSimpleServer(const QuicConfig
& config
,
64 const QuicVersionVector
& supported_versions
)
65 : helper_(base::MessageLoop::current()->message_loop_proxy().get(),
67 QuicRandom::GetInstance()),
69 crypto_config_(kSourceAddressTokenSecret
, QuicRandom::GetInstance()),
70 supported_versions_(supported_versions
),
72 synchronous_read_count_(0),
73 read_buffer_(new IOBufferWithSize(kReadBufferSize
)),
78 void QuicSimpleServer::Initialize() {
83 // If an initial flow control window has not explicitly been set, then use a
84 // sensible value for a server: 1 MB for session, 64 KB for each stream.
85 const uint32 kInitialSessionFlowControlWindow
= 1 * 1024 * 1024; // 1 MB
86 const uint32 kInitialStreamFlowControlWindow
= 64 * 1024; // 64 KB
87 if (config_
.GetInitialStreamFlowControlWindowToSend() ==
88 kMinimumFlowControlSendWindow
) {
89 config_
.SetInitialStreamFlowControlWindowToSend(
90 kInitialStreamFlowControlWindow
);
92 if (config_
.GetInitialSessionFlowControlWindowToSend() ==
93 kMinimumFlowControlSendWindow
) {
94 config_
.SetInitialSessionFlowControlWindowToSend(
95 kInitialSessionFlowControlWindow
);
98 scoped_ptr
<CryptoHandshakeMessage
> scfg(
99 crypto_config_
.AddDefaultConfig(
100 helper_
.GetRandomGenerator(), helper_
.GetClock(),
101 QuicCryptoServerConfig::ConfigOptions()));
104 QuicSimpleServer::~QuicSimpleServer() {
107 int QuicSimpleServer::Listen(const IPEndPoint
& address
) {
108 scoped_ptr
<UDPServerSocket
> socket(
109 new UDPServerSocket(&net_log_
, NetLog::Source()));
111 socket
->AllowAddressReuse();
113 int rc
= socket
->Listen(address
);
115 LOG(ERROR
) << "Listen() failed: " << ErrorToString(rc
);
119 // These send and receive buffer sizes are sized for a single connection,
120 // because the default usage of QuicSimpleServer is as a test server with
121 // one or two clients. Adjust higher for use with many clients.
122 rc
= socket
->SetReceiveBufferSize(
123 static_cast<int32
>(kDefaultSocketReceiveBuffer
));
125 LOG(ERROR
) << "SetReceiveBufferSize() failed: " << ErrorToString(rc
);
129 rc
= socket
->SetSendBufferSize(20 * kMaxPacketSize
);
131 LOG(ERROR
) << "SetSendBufferSize() failed: " << ErrorToString(rc
);
135 rc
= socket
->GetLocalAddress(&server_address_
);
137 LOG(ERROR
) << "GetLocalAddress() failed: " << ErrorToString(rc
);
141 DVLOG(1) << "Listening on " << server_address_
.ToString();
143 socket_
.swap(socket
);
145 CustomPacketWriterFactory
* factory
= new CustomPacketWriterFactory();
147 new QuicDispatcher(config_
,
152 QuicSimpleServerPacketWriter
* writer
= new QuicSimpleServerPacketWriter(
155 factory
->set_shared_writer(writer
);
156 dispatcher_
->InitializeWithWriter(writer
);
163 void QuicSimpleServer::Shutdown() {
164 // Before we shut down the epoll server, give all active sessions a chance to
165 // notify clients that they're closing.
166 dispatcher_
->Shutdown();
172 void QuicSimpleServer::StartReading() {
176 read_pending_
= true;
178 int result
= socket_
->RecvFrom(
180 read_buffer_
->size(),
182 base::Bind(&QuicSimpleServer::OnReadComplete
, base::Unretained(this)));
184 if (result
== ERR_IO_PENDING
) {
185 synchronous_read_count_
= 0;
189 if (++synchronous_read_count_
> 32) {
190 synchronous_read_count_
= 0;
191 // Schedule the processing through the message loop to 1) prevent infinite
192 // recursion and 2) avoid blocking the thread for too long.
193 base::MessageLoop::current()->PostTask(
195 base::Bind(&QuicSimpleServer::OnReadComplete
,
196 weak_factory_
.GetWeakPtr(),
199 OnReadComplete(result
);
203 void QuicSimpleServer::OnReadComplete(int result
) {
204 read_pending_
= false;
206 result
= ERR_CONNECTION_CLOSED
;
209 LOG(ERROR
) << "QuicSimpleServer read failed: " << ErrorToString(result
);
214 QuicEncryptedPacket
packet(read_buffer_
->data(), result
, false);
215 dispatcher_
->ProcessPacket(server_address_
, client_address_
, packet
);