OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/quic/quic_server.h" | 5 #include "net/tools/quic/quic_simple_server.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include "net/base/ip_endpoint.h" | 9 #include "net/base/ip_endpoint.h" |
10 #include "net/base/net_errors.h" | 10 #include "net/base/net_errors.h" |
11 #include "net/quic/crypto/crypto_handshake.h" | 11 #include "net/quic/crypto/crypto_handshake.h" |
12 #include "net/quic/crypto/quic_random.h" | 12 #include "net/quic/crypto/quic_random.h" |
13 #include "net/quic/quic_crypto_stream.h" | 13 #include "net/quic/quic_crypto_stream.h" |
14 #include "net/quic/quic_data_reader.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" | 15 #include "net/quic/quic_protocol.h" |
17 #include "net/quic/quic_server_packet_writer.h" | |
18 #include "net/tools/quic/quic_dispatcher.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" | 19 #include "net/udp/udp_server_socket.h" |
20 | 20 |
21 namespace net { | 21 namespace net { |
22 | 22 namespace tools { |
23 using tools::QuicDispatcher; | |
24 | 23 |
25 namespace { | 24 namespace { |
26 | 25 |
27 const char kSourceAddressTokenSecret[] = "secret"; | 26 const char kSourceAddressTokenSecret[] = "secret"; |
28 | 27 |
29 // Allocate some extra space so we can send an error if the client goes over | 28 // Allocate some extra space so we can send an error if the client goes over |
30 // the limit. | 29 // the limit. |
31 const int kReadBufferSize = 2 * kMaxPacketSize; | 30 const int kReadBufferSize = 2 * kMaxPacketSize; |
32 | 31 |
33 // A packet writer factory which wraps a shared QuicServerPacketWriter | 32 // A packet writer factory which wraps a shared QuicSimpleServerPacketWriter |
34 // inside of a QuicPerConnectionPacketWriter. Instead of checking that | 33 // inside of a QuicPerConnectionPacketWriter. Instead of checking that |
35 // the shared_writer is the expected writer, this could instead cast | 34 // the shared_writer is the expected writer, this could instead cast |
36 // from QuicPacketWriter to QuicServerPacketWriter. | 35 // from QuicPacketWriter to QuicSimpleServerPacketWriter. |
37 class CustomPacketWriterFactory : public QuicDispatcher::PacketWriterFactory { | 36 class CustomPacketWriterFactory : public QuicDispatcher::PacketWriterFactory { |
38 public: | 37 public: |
39 ~CustomPacketWriterFactory() override {} | 38 ~CustomPacketWriterFactory() override {} |
40 | 39 |
41 QuicPacketWriter* Create(QuicPacketWriter* writer, | 40 QuicPacketWriter* Create(QuicPacketWriter* writer, |
42 QuicConnection* connection) override { | 41 QuicConnection* connection) override { |
43 if (writer == nullptr) { | 42 if (writer == nullptr) { |
44 LOG(DFATAL) << "shared_writer not initialized"; | 43 LOG(DFATAL) << "shared_writer not initialized"; |
45 return nullptr; | 44 return nullptr; |
46 } | 45 } |
47 if (writer != shared_writer_) { | 46 if (writer != shared_writer_) { |
48 LOG(DFATAL) << "writer mismatch"; | 47 LOG(DFATAL) << "writer mismatch"; |
49 return nullptr; | 48 return nullptr; |
50 } | 49 } |
51 return new QuicPerConnectionPacketWriter(shared_writer_, connection); | 50 return new QuicSimplePerConnectionPacketWriter(shared_writer_, connection); |
52 } | 51 } |
53 | 52 |
54 void set_shared_writer(QuicServerPacketWriter* shared_writer) { | 53 void set_shared_writer(QuicSimpleServerPacketWriter* shared_writer) { |
55 shared_writer_ = shared_writer; | 54 shared_writer_ = shared_writer; |
56 } | 55 } |
57 | 56 |
58 private: | 57 private: |
59 QuicServerPacketWriter* shared_writer_; // Not owned. | 58 QuicSimpleServerPacketWriter* shared_writer_; // Not owned. |
60 }; | 59 }; |
61 | 60 |
62 } // namespace | 61 } // namespace |
63 | 62 |
64 QuicServer::QuicServer(const QuicConfig& config, | 63 QuicSimpleServer::QuicSimpleServer(const QuicConfig& config, |
65 const QuicVersionVector& supported_versions) | 64 const QuicVersionVector& supported_versions) |
66 : helper_(base::MessageLoop::current()->message_loop_proxy().get(), | 65 : helper_(base::MessageLoop::current()->message_loop_proxy().get(), |
67 &clock_, | 66 &clock_, |
68 QuicRandom::GetInstance()), | 67 QuicRandom::GetInstance()), |
69 config_(config), | 68 config_(config), |
70 crypto_config_(kSourceAddressTokenSecret, QuicRandom::GetInstance()), | 69 crypto_config_(kSourceAddressTokenSecret, QuicRandom::GetInstance()), |
71 supported_versions_(supported_versions), | 70 supported_versions_(supported_versions), |
72 read_pending_(false), | 71 read_pending_(false), |
73 synchronous_read_count_(0), | 72 synchronous_read_count_(0), |
74 read_buffer_(new IOBufferWithSize(kReadBufferSize)), | 73 read_buffer_(new IOBufferWithSize(kReadBufferSize)), |
75 weak_factory_(this) { | 74 weak_factory_(this) { |
76 Initialize(); | 75 Initialize(); |
77 } | 76 } |
78 | 77 |
79 void QuicServer::Initialize() { | 78 void QuicSimpleServer::Initialize() { |
80 #if MMSG_MORE | 79 #if MMSG_MORE |
81 use_recvmmsg_ = true; | 80 use_recvmmsg_ = true; |
82 #endif | 81 #endif |
83 | 82 |
84 // If an initial flow control window has not explicitly been set, then use a | 83 // 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. | 84 // sensible value for a server: 1 MB for session, 64 KB for each stream. |
86 const uint32 kInitialSessionFlowControlWindow = 1 * 1024 * 1024; // 1 MB | 85 const uint32 kInitialSessionFlowControlWindow = 1 * 1024 * 1024; // 1 MB |
87 const uint32 kInitialStreamFlowControlWindow = 64 * 1024; // 64 KB | 86 const uint32 kInitialStreamFlowControlWindow = 64 * 1024; // 64 KB |
88 if (config_.GetInitialStreamFlowControlWindowToSend() == | 87 if (config_.GetInitialStreamFlowControlWindowToSend() == |
89 kMinimumFlowControlSendWindow) { | 88 kMinimumFlowControlSendWindow) { |
90 config_.SetInitialStreamFlowControlWindowToSend( | 89 config_.SetInitialStreamFlowControlWindowToSend( |
91 kInitialStreamFlowControlWindow); | 90 kInitialStreamFlowControlWindow); |
92 } | 91 } |
93 if (config_.GetInitialSessionFlowControlWindowToSend() == | 92 if (config_.GetInitialSessionFlowControlWindowToSend() == |
94 kMinimumFlowControlSendWindow) { | 93 kMinimumFlowControlSendWindow) { |
95 config_.SetInitialSessionFlowControlWindowToSend( | 94 config_.SetInitialSessionFlowControlWindowToSend( |
96 kInitialSessionFlowControlWindow); | 95 kInitialSessionFlowControlWindow); |
97 } | 96 } |
98 | 97 |
99 scoped_ptr<CryptoHandshakeMessage> scfg( | 98 scoped_ptr<CryptoHandshakeMessage> scfg( |
100 crypto_config_.AddDefaultConfig( | 99 crypto_config_.AddDefaultConfig( |
101 helper_.GetRandomGenerator(), helper_.GetClock(), | 100 helper_.GetRandomGenerator(), helper_.GetClock(), |
102 QuicCryptoServerConfig::ConfigOptions())); | 101 QuicCryptoServerConfig::ConfigOptions())); |
103 } | 102 } |
104 | 103 |
105 QuicServer::~QuicServer() { | 104 QuicSimpleServer::~QuicSimpleServer() { |
106 } | 105 } |
107 | 106 |
108 int QuicServer::Listen(const IPEndPoint& address) { | 107 int QuicSimpleServer::Listen(const IPEndPoint& address) { |
109 scoped_ptr<UDPServerSocket> socket( | 108 scoped_ptr<UDPServerSocket> socket( |
110 new UDPServerSocket(&net_log_, NetLog::Source())); | 109 new UDPServerSocket(&net_log_, NetLog::Source())); |
111 | 110 |
112 socket->AllowAddressReuse(); | 111 socket->AllowAddressReuse(); |
113 | 112 |
114 int rc = socket->Listen(address); | 113 int rc = socket->Listen(address); |
115 if (rc < 0) { | 114 if (rc < 0) { |
116 LOG(ERROR) << "Listen() failed: " << ErrorToString(rc); | 115 LOG(ERROR) << "Listen() failed: " << ErrorToString(rc); |
117 return rc; | 116 return rc; |
118 } | 117 } |
119 | 118 |
120 // These send and receive buffer sizes are sized for a single connection, | 119 // 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 | 120 // because the default usage of QuicSimpleServer is as a test server with |
122 // two clients. Adjust higher for use with many clients. | 121 // one or two clients. Adjust higher for use with many clients. |
123 rc = socket->SetReceiveBufferSize( | 122 rc = socket->SetReceiveBufferSize( |
124 static_cast<int32>(kDefaultSocketReceiveBuffer)); | 123 static_cast<int32>(kDefaultSocketReceiveBuffer)); |
125 if (rc < 0) { | 124 if (rc < 0) { |
126 LOG(ERROR) << "SetReceiveBufferSize() failed: " << ErrorToString(rc); | 125 LOG(ERROR) << "SetReceiveBufferSize() failed: " << ErrorToString(rc); |
127 return rc; | 126 return rc; |
128 } | 127 } |
129 | 128 |
130 rc = socket->SetSendBufferSize(20 * kMaxPacketSize); | 129 rc = socket->SetSendBufferSize(20 * kMaxPacketSize); |
131 if (rc < 0) { | 130 if (rc < 0) { |
132 LOG(ERROR) << "SetSendBufferSize() failed: " << ErrorToString(rc); | 131 LOG(ERROR) << "SetSendBufferSize() failed: " << ErrorToString(rc); |
(...skipping 10 matching lines...) Expand all Loading... |
143 | 142 |
144 socket_.swap(socket); | 143 socket_.swap(socket); |
145 | 144 |
146 CustomPacketWriterFactory* factory = new CustomPacketWriterFactory(); | 145 CustomPacketWriterFactory* factory = new CustomPacketWriterFactory(); |
147 dispatcher_.reset( | 146 dispatcher_.reset( |
148 new QuicDispatcher(config_, | 147 new QuicDispatcher(config_, |
149 crypto_config_, | 148 crypto_config_, |
150 supported_versions_, | 149 supported_versions_, |
151 factory, | 150 factory, |
152 &helper_)); | 151 &helper_)); |
153 QuicServerPacketWriter* writer = new QuicServerPacketWriter( | 152 QuicSimpleServerPacketWriter* writer = new QuicSimpleServerPacketWriter( |
154 socket_.get(), | 153 socket_.get(), |
155 dispatcher_.get()); | 154 dispatcher_.get()); |
156 factory->set_shared_writer(writer); | 155 factory->set_shared_writer(writer); |
157 dispatcher_->InitializeWithWriter(writer); | 156 dispatcher_->InitializeWithWriter(writer); |
158 | 157 |
159 StartReading(); | 158 StartReading(); |
160 | 159 |
161 return OK; | 160 return OK; |
162 } | 161 } |
163 | 162 |
164 void QuicServer::Shutdown() { | 163 void QuicSimpleServer::Shutdown() { |
165 // Before we shut down the epoll server, give all active sessions a chance to | 164 // Before we shut down the epoll server, give all active sessions a chance to |
166 // notify clients that they're closing. | 165 // notify clients that they're closing. |
167 dispatcher_->Shutdown(); | 166 dispatcher_->Shutdown(); |
168 | 167 |
169 socket_->Close(); | 168 socket_->Close(); |
170 socket_.reset(); | 169 socket_.reset(); |
171 } | 170 } |
172 | 171 |
173 void QuicServer::StartReading() { | 172 void QuicSimpleServer::StartReading() { |
174 if (read_pending_) { | 173 if (read_pending_) { |
175 return; | 174 return; |
176 } | 175 } |
177 read_pending_ = true; | 176 read_pending_ = true; |
178 | 177 |
179 int result = socket_->RecvFrom( | 178 int result = socket_->RecvFrom( |
180 read_buffer_.get(), | 179 read_buffer_.get(), |
181 read_buffer_->size(), | 180 read_buffer_->size(), |
182 &client_address_, | 181 &client_address_, |
183 base::Bind(&QuicServer::OnReadComplete, base::Unretained(this))); | 182 base::Bind(&QuicSimpleServer::OnReadComplete, base::Unretained(this))); |
184 | 183 |
185 if (result == ERR_IO_PENDING) { | 184 if (result == ERR_IO_PENDING) { |
186 synchronous_read_count_ = 0; | 185 synchronous_read_count_ = 0; |
187 return; | 186 return; |
188 } | 187 } |
189 | 188 |
190 if (++synchronous_read_count_ > 32) { | 189 if (++synchronous_read_count_ > 32) { |
191 synchronous_read_count_ = 0; | 190 synchronous_read_count_ = 0; |
192 // Schedule the processing through the message loop to 1) prevent infinite | 191 // Schedule the processing through the message loop to 1) prevent infinite |
193 // recursion and 2) avoid blocking the thread for too long. | 192 // recursion and 2) avoid blocking the thread for too long. |
194 base::MessageLoop::current()->PostTask( | 193 base::MessageLoop::current()->PostTask( |
195 FROM_HERE, | 194 FROM_HERE, |
196 base::Bind(&QuicServer::OnReadComplete, | 195 base::Bind(&QuicSimpleServer::OnReadComplete, |
197 weak_factory_.GetWeakPtr(), | 196 weak_factory_.GetWeakPtr(), |
198 result)); | 197 result)); |
199 } else { | 198 } else { |
200 OnReadComplete(result); | 199 OnReadComplete(result); |
201 } | 200 } |
202 } | 201 } |
203 | 202 |
204 void QuicServer::OnReadComplete(int result) { | 203 void QuicSimpleServer::OnReadComplete(int result) { |
205 read_pending_ = false; | 204 read_pending_ = false; |
206 if (result == 0) | 205 if (result == 0) |
207 result = ERR_CONNECTION_CLOSED; | 206 result = ERR_CONNECTION_CLOSED; |
208 | 207 |
209 if (result < 0) { | 208 if (result < 0) { |
210 LOG(ERROR) << "QuicServer read failed: " << ErrorToString(result); | 209 LOG(ERROR) << "QuicSimpleServer read failed: " << ErrorToString(result); |
211 Shutdown(); | 210 Shutdown(); |
212 return; | 211 return; |
213 } | 212 } |
214 | 213 |
215 QuicEncryptedPacket packet(read_buffer_->data(), result, false); | 214 QuicEncryptedPacket packet(read_buffer_->data(), result, false); |
216 dispatcher_->ProcessPacket(server_address_, client_address_, packet); | 215 dispatcher_->ProcessPacket(server_address_, client_address_, packet); |
217 | 216 |
218 StartReading(); | 217 StartReading(); |
219 } | 218 } |
220 | 219 |
| 220 } // namespace tools |
221 } // namespace net | 221 } // namespace net |
OLD | NEW |