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 "base/location.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "net/base/ip_endpoint.h"
13 #include "net/base/net_errors.h"
14 #include "net/quic/crypto/crypto_handshake.h"
15 #include "net/quic/crypto/quic_random.h"
16 #include "net/quic/quic_crypto_stream.h"
17 #include "net/quic/quic_data_reader.h"
18 #include "net/quic/quic_protocol.h"
19 #include "net/tools/quic/quic_dispatcher.h"
20 #include "net/tools/quic/quic_simple_per_connection_packet_writer.h"
21 #include "net/tools/quic/quic_simple_server_packet_writer.h"
22 #include "net/udp/udp_server_socket.h"
29 const char kSourceAddressTokenSecret
[] = "secret";
31 // Allocate some extra space so we can send an error if the client goes over
33 const int kReadBufferSize
= 2 * kMaxPacketSize
;
35 // A packet writer factory which wraps a shared QuicSimpleServerPacketWriter
36 // inside of a QuicPerConnectionPacketWriter. Instead of checking that
37 // the shared_writer is the expected writer, this could instead cast
38 // from QuicPacketWriter to QuicSimpleServerPacketWriter.
39 class CustomPacketWriterFactory
: public QuicDispatcher::PacketWriterFactory
{
41 ~CustomPacketWriterFactory() override
{}
43 QuicPacketWriter
* Create(QuicPacketWriter
* writer
,
44 QuicConnection
* connection
) override
{
45 if (writer
== nullptr) {
46 LOG(DFATAL
) << "shared_writer not initialized";
49 if (writer
!= shared_writer_
) {
50 LOG(DFATAL
) << "writer mismatch";
53 return new QuicSimplePerConnectionPacketWriter(shared_writer_
, connection
);
56 void set_shared_writer(QuicSimpleServerPacketWriter
* shared_writer
) {
57 shared_writer_
= shared_writer
;
61 QuicSimpleServerPacketWriter
* shared_writer_
; // Not owned.
66 QuicSimpleServer::QuicSimpleServer(const QuicConfig
& config
,
67 const QuicVersionVector
& supported_versions
)
68 : helper_(base::ThreadTaskRunnerHandle::Get().get(),
70 QuicRandom::GetInstance()),
72 crypto_config_(kSourceAddressTokenSecret
, QuicRandom::GetInstance()),
73 supported_versions_(supported_versions
),
75 synchronous_read_count_(0),
76 read_buffer_(new IOBufferWithSize(kReadBufferSize
)),
81 void QuicSimpleServer::Initialize() {
86 // If an initial flow control window has not explicitly been set, then use a
87 // sensible value for a server: 1 MB for session, 64 KB for each stream.
88 const uint32 kInitialSessionFlowControlWindow
= 1 * 1024 * 1024; // 1 MB
89 const uint32 kInitialStreamFlowControlWindow
= 64 * 1024; // 64 KB
90 if (config_
.GetInitialStreamFlowControlWindowToSend() ==
91 kMinimumFlowControlSendWindow
) {
92 config_
.SetInitialStreamFlowControlWindowToSend(
93 kInitialStreamFlowControlWindow
);
95 if (config_
.GetInitialSessionFlowControlWindowToSend() ==
96 kMinimumFlowControlSendWindow
) {
97 config_
.SetInitialSessionFlowControlWindowToSend(
98 kInitialSessionFlowControlWindow
);
101 scoped_ptr
<CryptoHandshakeMessage
> scfg(
102 crypto_config_
.AddDefaultConfig(
103 helper_
.GetRandomGenerator(), helper_
.GetClock(),
104 QuicCryptoServerConfig::ConfigOptions()));
107 QuicSimpleServer::~QuicSimpleServer() {
110 int QuicSimpleServer::Listen(const IPEndPoint
& address
) {
111 scoped_ptr
<UDPServerSocket
> socket(
112 new UDPServerSocket(&net_log_
, NetLog::Source()));
114 socket
->AllowAddressReuse();
116 int rc
= socket
->Listen(address
);
118 LOG(ERROR
) << "Listen() failed: " << ErrorToString(rc
);
122 // These send and receive buffer sizes are sized for a single connection,
123 // because the default usage of QuicSimpleServer is as a test server with
124 // one or two clients. Adjust higher for use with many clients.
125 rc
= socket
->SetReceiveBufferSize(
126 static_cast<int32
>(kDefaultSocketReceiveBuffer
));
128 LOG(ERROR
) << "SetReceiveBufferSize() failed: " << ErrorToString(rc
);
132 rc
= socket
->SetSendBufferSize(20 * kMaxPacketSize
);
134 LOG(ERROR
) << "SetSendBufferSize() failed: " << ErrorToString(rc
);
138 rc
= socket
->GetLocalAddress(&server_address_
);
140 LOG(ERROR
) << "GetLocalAddress() failed: " << ErrorToString(rc
);
144 DVLOG(1) << "Listening on " << server_address_
.ToString();
146 socket_
.swap(socket
);
148 CustomPacketWriterFactory
* factory
= new CustomPacketWriterFactory();
150 new QuicDispatcher(config_
,
155 QuicSimpleServerPacketWriter
* writer
= new QuicSimpleServerPacketWriter(
158 factory
->set_shared_writer(writer
);
159 dispatcher_
->InitializeWithWriter(writer
);
166 void QuicSimpleServer::Shutdown() {
167 // Before we shut down the epoll server, give all active sessions a chance to
168 // notify clients that they're closing.
169 dispatcher_
->Shutdown();
175 void QuicSimpleServer::StartReading() {
179 read_pending_
= true;
181 int result
= socket_
->RecvFrom(
183 read_buffer_
->size(),
185 base::Bind(&QuicSimpleServer::OnReadComplete
, base::Unretained(this)));
187 if (result
== ERR_IO_PENDING
) {
188 synchronous_read_count_
= 0;
192 if (++synchronous_read_count_
> 32) {
193 synchronous_read_count_
= 0;
194 // Schedule the processing through the message loop to 1) prevent infinite
195 // recursion and 2) avoid blocking the thread for too long.
196 base::ThreadTaskRunnerHandle::Get()->PostTask(
197 FROM_HERE
, base::Bind(&QuicSimpleServer::OnReadComplete
,
198 weak_factory_
.GetWeakPtr(), result
));
200 OnReadComplete(result
);
204 void QuicSimpleServer::OnReadComplete(int result
) {
205 read_pending_
= false;
207 result
= ERR_CONNECTION_CLOSED
;
210 LOG(ERROR
) << "QuicSimpleServer read failed: " << ErrorToString(result
);
215 QuicEncryptedPacket
packet(read_buffer_
->data(), result
, false);
216 dispatcher_
->ProcessPacket(server_address_
, client_address_
, packet
);