Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / net / quic / quic_server.cc
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.
4
5 #include "net/quic/quic_server.h"
6
7 #include <string.h>
8
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"
21
22 namespace net {
23
24 namespace {
25
26 const char kSourceAddressTokenSecret[] = "secret";
27
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;
31
32 } // namespace
33
34 QuicServer::QuicServer(const QuicConfig& config,
35                        const QuicVersionVector& supported_versions)
36     : helper_(base::MessageLoop::current()->message_loop_proxy().get(),
37               &clock_,
38               QuicRandom::GetInstance()),
39       config_(config),
40       crypto_config_(kSourceAddressTokenSecret, QuicRandom::GetInstance()),
41       supported_versions_(supported_versions),
42       read_pending_(false),
43       synchronous_read_count_(0),
44       read_buffer_(new IOBufferWithSize(kReadBufferSize)),
45       weak_factory_(this) {
46   Initialize();
47 }
48
49 void QuicServer::Initialize() {
50   // Initialize the in memory cache now.
51   QuicInMemoryCache::GetInstance();
52
53   scoped_ptr<CryptoHandshakeMessage> scfg(
54       crypto_config_.AddDefaultConfig(
55           helper_.GetRandomGenerator(), helper_.GetClock(),
56           QuicCryptoServerConfig::ConfigOptions()));
57 }
58
59 QuicServer::~QuicServer() {
60 }
61
62 int QuicServer::Listen(const IPEndPoint& address) {
63   scoped_ptr<UDPServerSocket> socket(
64       new UDPServerSocket(&net_log_, NetLog::Source()));
65
66   socket->AllowAddressReuse();
67
68   int rc = socket->Listen(address);
69   if (rc < 0) {
70     LOG(ERROR) << "Listen() failed: " << ErrorToString(rc);
71     return rc;
72   }
73
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);
78   if (rc < 0) {
79     LOG(ERROR) << "SetReceiveBufferSize() failed: " << ErrorToString(rc);
80     return rc;
81   }
82
83   rc = socket->SetSendBufferSize(20 * kMaxPacketSize);
84   if (rc < 0) {
85     LOG(ERROR) << "SetSendBufferSize() failed: " << ErrorToString(rc);
86     return rc;
87   }
88
89   rc = socket->GetLocalAddress(&server_address_);
90   if (rc < 0) {
91     LOG(ERROR) << "GetLocalAddress() failed: " << ErrorToString(rc);
92     return rc;
93   }
94
95   DVLOG(1) << "Listening on " << server_address_.ToString();
96
97   socket_.swap(socket);
98
99   dispatcher_.reset(
100       new QuicDispatcher(config_,
101                          crypto_config_,
102                          supported_versions_,
103                          new QuicDispatcher::DefaultPacketWriterFactory(),
104                          &helper_));
105   QuicServerPacketWriter* writer = new QuicServerPacketWriter(
106       socket_.get(),
107       dispatcher_.get());
108   dispatcher_->Initialize(writer);
109
110   StartReading();
111
112   return OK;
113 }
114
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();
119
120   socket_->Close();
121   socket_.reset();
122 }
123
124 void QuicServer::StartReading() {
125   if (read_pending_) {
126     return;
127   }
128   read_pending_ = true;
129
130   int result = socket_->RecvFrom(
131       read_buffer_.get(),
132       read_buffer_->size(),
133       &client_address_,
134       base::Bind(&QuicServer::OnReadComplete, base::Unretained(this)));
135
136   if (result == ERR_IO_PENDING) {
137     synchronous_read_count_ = 0;
138     return;
139   }
140
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(
146         FROM_HERE,
147         base::Bind(&QuicServer::OnReadComplete,
148                    weak_factory_.GetWeakPtr(),
149                    result));
150   } else {
151     OnReadComplete(result);
152   }
153 }
154
155 void QuicServer::OnReadComplete(int result) {
156   read_pending_ = false;
157   if (result == 0)
158     result = ERR_CONNECTION_CLOSED;
159
160   if (result < 0) {
161     LOG(ERROR) << "QuicServer read failed: " << ErrorToString(result);
162     Shutdown();
163     return;
164   }
165
166   QuicEncryptedPacket packet(read_buffer_->data(), result, false);
167   dispatcher_->ProcessPacket(server_address_, client_address_, packet);
168
169   StartReading();
170 }
171
172 }  // namespace net