Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(114)

Side by Side Diff: net/quic/quic_server.cc

Issue 1036023002: Move remaining QUIC server files from net/quic/ to net/tools/quic/. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: correctly fix cronet Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/quic/quic_server.h ('k') | net/quic/quic_server_bin.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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/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_per_connection_packet_writer.h"
16 #include "net/quic/quic_protocol.h"
17 #include "net/quic/quic_server_packet_writer.h"
18 #include "net/tools/quic/quic_dispatcher.h"
19 #include "net/udp/udp_server_socket.h"
20
21 namespace net {
22
23 using tools::QuicDispatcher;
24
25 namespace {
26
27 const char kSourceAddressTokenSecret[] = "secret";
28
29 // Allocate some extra space so we can send an error if the client goes over
30 // the limit.
31 const int kReadBufferSize = 2 * kMaxPacketSize;
32
33 // A packet writer factory which wraps a shared QuicServerPacketWriter
34 // inside of a QuicPerConnectionPacketWriter. Instead of checking that
35 // the shared_writer is the expected writer, this could instead cast
36 // from QuicPacketWriter to QuicServerPacketWriter.
37 class CustomPacketWriterFactory : public QuicDispatcher::PacketWriterFactory {
38 public:
39 ~CustomPacketWriterFactory() override {}
40
41 QuicPacketWriter* Create(QuicPacketWriter* writer,
42 QuicConnection* connection) override {
43 if (writer == nullptr) {
44 LOG(DFATAL) << "shared_writer not initialized";
45 return nullptr;
46 }
47 if (writer != shared_writer_) {
48 LOG(DFATAL) << "writer mismatch";
49 return nullptr;
50 }
51 return new QuicPerConnectionPacketWriter(shared_writer_, connection);
52 }
53
54 void set_shared_writer(QuicServerPacketWriter* shared_writer) {
55 shared_writer_ = shared_writer;
56 }
57
58 private:
59 QuicServerPacketWriter* shared_writer_; // Not owned.
60 };
61
62 } // namespace
63
64 QuicServer::QuicServer(const QuicConfig& config,
65 const QuicVersionVector& supported_versions)
66 : helper_(base::MessageLoop::current()->message_loop_proxy().get(),
67 &clock_,
68 QuicRandom::GetInstance()),
69 config_(config),
70 crypto_config_(kSourceAddressTokenSecret, QuicRandom::GetInstance()),
71 supported_versions_(supported_versions),
72 read_pending_(false),
73 synchronous_read_count_(0),
74 read_buffer_(new IOBufferWithSize(kReadBufferSize)),
75 weak_factory_(this) {
76 Initialize();
77 }
78
79 void QuicServer::Initialize() {
80 #if MMSG_MORE
81 use_recvmmsg_ = true;
82 #endif
83
84 // If an initial flow control window has not explicitly been set, then use a
85 // sensible value for a server: 1 MB for session, 64 KB for each stream.
86 const uint32 kInitialSessionFlowControlWindow = 1 * 1024 * 1024; // 1 MB
87 const uint32 kInitialStreamFlowControlWindow = 64 * 1024; // 64 KB
88 if (config_.GetInitialStreamFlowControlWindowToSend() ==
89 kMinimumFlowControlSendWindow) {
90 config_.SetInitialStreamFlowControlWindowToSend(
91 kInitialStreamFlowControlWindow);
92 }
93 if (config_.GetInitialSessionFlowControlWindowToSend() ==
94 kMinimumFlowControlSendWindow) {
95 config_.SetInitialSessionFlowControlWindowToSend(
96 kInitialSessionFlowControlWindow);
97 }
98
99 scoped_ptr<CryptoHandshakeMessage> scfg(
100 crypto_config_.AddDefaultConfig(
101 helper_.GetRandomGenerator(), helper_.GetClock(),
102 QuicCryptoServerConfig::ConfigOptions()));
103 }
104
105 QuicServer::~QuicServer() {
106 }
107
108 int QuicServer::Listen(const IPEndPoint& address) {
109 scoped_ptr<UDPServerSocket> socket(
110 new UDPServerSocket(&net_log_, NetLog::Source()));
111
112 socket->AllowAddressReuse();
113
114 int rc = socket->Listen(address);
115 if (rc < 0) {
116 LOG(ERROR) << "Listen() failed: " << ErrorToString(rc);
117 return rc;
118 }
119
120 // These send and receive buffer sizes are sized for a single connection,
121 // because the default usage of QuicServer is as a test server with one or
122 // two clients. Adjust higher for use with many clients.
123 rc = socket->SetReceiveBufferSize(
124 static_cast<int32>(kDefaultSocketReceiveBuffer));
125 if (rc < 0) {
126 LOG(ERROR) << "SetReceiveBufferSize() failed: " << ErrorToString(rc);
127 return rc;
128 }
129
130 rc = socket->SetSendBufferSize(20 * kMaxPacketSize);
131 if (rc < 0) {
132 LOG(ERROR) << "SetSendBufferSize() failed: " << ErrorToString(rc);
133 return rc;
134 }
135
136 rc = socket->GetLocalAddress(&server_address_);
137 if (rc < 0) {
138 LOG(ERROR) << "GetLocalAddress() failed: " << ErrorToString(rc);
139 return rc;
140 }
141
142 DVLOG(1) << "Listening on " << server_address_.ToString();
143
144 socket_.swap(socket);
145
146 CustomPacketWriterFactory* factory = new CustomPacketWriterFactory();
147 dispatcher_.reset(
148 new QuicDispatcher(config_,
149 crypto_config_,
150 supported_versions_,
151 factory,
152 &helper_));
153 QuicServerPacketWriter* writer = new QuicServerPacketWriter(
154 socket_.get(),
155 dispatcher_.get());
156 factory->set_shared_writer(writer);
157 dispatcher_->InitializeWithWriter(writer);
158
159 StartReading();
160
161 return OK;
162 }
163
164 void QuicServer::Shutdown() {
165 // Before we shut down the epoll server, give all active sessions a chance to
166 // notify clients that they're closing.
167 dispatcher_->Shutdown();
168
169 socket_->Close();
170 socket_.reset();
171 }
172
173 void QuicServer::StartReading() {
174 if (read_pending_) {
175 return;
176 }
177 read_pending_ = true;
178
179 int result = socket_->RecvFrom(
180 read_buffer_.get(),
181 read_buffer_->size(),
182 &client_address_,
183 base::Bind(&QuicServer::OnReadComplete, base::Unretained(this)));
184
185 if (result == ERR_IO_PENDING) {
186 synchronous_read_count_ = 0;
187 return;
188 }
189
190 if (++synchronous_read_count_ > 32) {
191 synchronous_read_count_ = 0;
192 // Schedule the processing through the message loop to 1) prevent infinite
193 // recursion and 2) avoid blocking the thread for too long.
194 base::MessageLoop::current()->PostTask(
195 FROM_HERE,
196 base::Bind(&QuicServer::OnReadComplete,
197 weak_factory_.GetWeakPtr(),
198 result));
199 } else {
200 OnReadComplete(result);
201 }
202 }
203
204 void QuicServer::OnReadComplete(int result) {
205 read_pending_ = false;
206 if (result == 0)
207 result = ERR_CONNECTION_CLOSED;
208
209 if (result < 0) {
210 LOG(ERROR) << "QuicServer read failed: " << ErrorToString(result);
211 Shutdown();
212 return;
213 }
214
215 QuicEncryptedPacket packet(read_buffer_->data(), result, false);
216 dispatcher_->ProcessPacket(server_address_, client_address_, packet);
217
218 StartReading();
219 }
220
221 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_server.h ('k') | net/quic/quic_server_bin.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698