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/tools/quic/quic_simple_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 "base/location.h" | 9 #include "base/location.h" |
10 #include "base/single_thread_task_runner.h" | 10 #include "base/single_thread_task_runner.h" |
11 #include "base/threading/thread_task_runner_handle.h" | 11 #include "base/threading/thread_task_runner_handle.h" |
12 #include "net/base/ip_endpoint.h" | 12 #include "net/base/ip_endpoint.h" |
13 #include "net/base/net_errors.h" | 13 #include "net/base/net_errors.h" |
14 #include "net/quic/core/crypto/crypto_handshake.h" | 14 #include "net/quic/core/crypto/crypto_handshake.h" |
15 #include "net/quic/core/crypto/quic_random.h" | 15 #include "net/quic/core/crypto/quic_random.h" |
16 #include "net/quic/core/quic_crypto_stream.h" | 16 #include "net/quic/core/quic_crypto_stream.h" |
17 #include "net/quic/core/quic_data_reader.h" | 17 #include "net/quic/core/quic_data_reader.h" |
18 #include "net/quic/core/quic_protocol.h" | 18 #include "net/quic/core/quic_protocol.h" |
19 #include "net/tools/quic/quic_simple_dispatcher.h" | 19 #include "net/tools/quic/quic_simple_dispatcher.h" |
20 #include "net/tools/quic/quic_simple_per_connection_packet_writer.h" | 20 #include "net/tools/quic/quic_simple_per_connection_packet_writer.h" |
21 #include "net/tools/quic/quic_simple_server_packet_writer.h" | 21 #include "net/tools/quic/quic_simple_server_packet_writer.h" |
22 #include "net/tools/quic/quic_simple_server_session_helper.h" | 22 #include "net/tools/quic/quic_simple_server_session_helper.h" |
23 #include "net/udp/udp_server_socket.h" | 23 #include "net/udp/udp_server_socket.h" |
24 | 24 |
25 namespace net { | 25 namespace net { |
26 | 26 |
27 namespace { | 27 namespace { |
28 | 28 |
29 const char kSourceAddressTokenSecret[] = "secret"; | 29 const char kSourceAddressTokenSecret[] = "secret"; |
30 const size_t kNumSessionsToCreatePerSocketEvent = 16; | |
30 | 31 |
31 // Allocate some extra space so we can send an error if the client goes over | 32 // Allocate some extra space so we can send an error if the client goes over |
32 // the limit. | 33 // the limit. |
33 const int kReadBufferSize = 2 * kMaxPacketSize; | 34 const int kReadBufferSize = 2 * kMaxPacketSize; |
34 | 35 |
35 } // namespace | 36 } // namespace |
36 | 37 |
37 QuicSimpleServer::QuicSimpleServer( | 38 QuicSimpleServer::QuicSimpleServer( |
38 std::unique_ptr<ProofSource> proof_source, | 39 std::unique_ptr<ProofSource> proof_source, |
39 const QuicConfig& config, | 40 const QuicConfig& config, |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
125 dispatcher_.reset(new QuicSimpleDispatcher( | 126 dispatcher_.reset(new QuicSimpleDispatcher( |
126 config_, &crypto_config_, &version_manager_, | 127 config_, &crypto_config_, &version_manager_, |
127 std::unique_ptr<QuicConnectionHelperInterface>(helper_), | 128 std::unique_ptr<QuicConnectionHelperInterface>(helper_), |
128 std::unique_ptr<QuicServerSessionBase::Helper>( | 129 std::unique_ptr<QuicServerSessionBase::Helper>( |
129 new QuicSimpleServerSessionHelper(QuicRandom::GetInstance())), | 130 new QuicSimpleServerSessionHelper(QuicRandom::GetInstance())), |
130 std::unique_ptr<QuicAlarmFactory>(alarm_factory_))); | 131 std::unique_ptr<QuicAlarmFactory>(alarm_factory_))); |
131 QuicSimpleServerPacketWriter* writer = | 132 QuicSimpleServerPacketWriter* writer = |
132 new QuicSimpleServerPacketWriter(socket_.get(), dispatcher_.get()); | 133 new QuicSimpleServerPacketWriter(socket_.get(), dispatcher_.get()); |
133 dispatcher_->InitializeWithWriter(writer); | 134 dispatcher_->InitializeWithWriter(writer); |
134 | 135 |
135 StartReading(); | 136 StartReading(true); |
136 | 137 |
137 return OK; | 138 return OK; |
138 } | 139 } |
139 | 140 |
140 void QuicSimpleServer::Shutdown() { | 141 void QuicSimpleServer::Shutdown() { |
141 // Before we shut down the epoll server, give all active sessions a chance to | 142 // Before we shut down the epoll server, give all active sessions a chance to |
142 // notify clients that they're closing. | 143 // notify clients that they're closing. |
143 dispatcher_->Shutdown(); | 144 dispatcher_->Shutdown(); |
144 | 145 |
145 socket_->Close(); | 146 socket_->Close(); |
146 socket_.reset(); | 147 socket_.reset(); |
147 } | 148 } |
148 | 149 |
149 void QuicSimpleServer::StartReading() { | 150 void QuicSimpleServer::StartReading(bool check_packet_buffer) { |
151 if (check_packet_buffer) { | |
Ryan Hamilton
2016/09/06 23:21:46
I wonder if you could simply check synchronous_rea
| |
152 dispatcher_->ProcessBufferedChlos(kNumSessionsToCreatePerSocketEvent); | |
153 } | |
154 | |
150 if (read_pending_) { | 155 if (read_pending_) { |
151 return; | 156 return; |
152 } | 157 } |
153 read_pending_ = true; | 158 read_pending_ = true; |
154 | 159 |
155 int result = socket_->RecvFrom( | 160 int result = socket_->RecvFrom( |
156 read_buffer_.get(), read_buffer_->size(), &client_address_, | 161 read_buffer_.get(), read_buffer_->size(), &client_address_, |
157 base::Bind(&QuicSimpleServer::OnReadComplete, base::Unretained(this))); | 162 base::Bind(&QuicSimpleServer::OnAsyncReadComplete, |
163 base::Unretained(this))); | |
158 | 164 |
159 if (result == ERR_IO_PENDING) { | 165 if (result == ERR_IO_PENDING) { |
160 synchronous_read_count_ = 0; | 166 synchronous_read_count_ = 0; |
167 if (dispatcher_->HasChlosBuffered()) { | |
168 // No more packets to read, but still keep processing buffered packets in | |
169 // next socket event if there is any. | |
170 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
171 FROM_HERE, base::Bind(&QuicSimpleServer::StartReading, | |
172 weak_factory_.GetWeakPtr(), true)); | |
173 } | |
161 return; | 174 return; |
162 } | 175 } |
163 | 176 |
177 // For synchronous read, if server has read enough for current socket event, | |
178 // yeild and continue processing in next event. | |
164 if (++synchronous_read_count_ > 32) { | 179 if (++synchronous_read_count_ > 32) { |
165 synchronous_read_count_ = 0; | 180 synchronous_read_count_ = 0; |
166 // Schedule the processing through the message loop to 1) prevent infinite | 181 // Schedule the processing through the message loop to 1) prevent infinite |
167 // recursion and 2) avoid blocking the thread for too long. | 182 // recursion and 2) avoid blocking the thread for too long. |
183 // Check buffer in next event. | |
168 base::ThreadTaskRunnerHandle::Get()->PostTask( | 184 base::ThreadTaskRunnerHandle::Get()->PostTask( |
169 FROM_HERE, base::Bind(&QuicSimpleServer::OnReadComplete, | 185 FROM_HERE, base::Bind(&QuicSimpleServer::OnReadComplete, |
170 weak_factory_.GetWeakPtr(), result)); | 186 weak_factory_.GetWeakPtr(), result, true)); |
171 } else { | 187 } else { |
172 OnReadComplete(result); | 188 // No need to check buffer for following reads. |
189 OnReadComplete(result, false); | |
173 } | 190 } |
174 } | 191 } |
175 | 192 |
176 void QuicSimpleServer::OnReadComplete(int result) { | 193 void QuicSimpleServer::OnAsyncReadComplete( |
194 int result) { // For asynchronous read, check the buffer again. | |
195 OnReadComplete(result, true); | |
196 } | |
197 | |
198 void QuicSimpleServer::OnReadComplete(int result, bool check_packet_buffer) { | |
177 read_pending_ = false; | 199 read_pending_ = false; |
178 if (result == 0) | 200 if (result == 0) |
179 result = ERR_CONNECTION_CLOSED; | 201 result = ERR_CONNECTION_CLOSED; |
180 | 202 |
181 if (result < 0) { | 203 if (result < 0) { |
182 LOG(ERROR) << "QuicSimpleServer read failed: " << ErrorToString(result); | 204 LOG(ERROR) << "QuicSimpleServer read failed: " << ErrorToString(result); |
183 Shutdown(); | 205 Shutdown(); |
184 return; | 206 return; |
185 } | 207 } |
186 | 208 |
187 QuicReceivedPacket packet(read_buffer_->data(), result, | 209 QuicReceivedPacket packet(read_buffer_->data(), result, |
188 helper_->GetClock()->Now(), false); | 210 helper_->GetClock()->Now(), false); |
189 dispatcher_->ProcessPacket(server_address_, client_address_, packet); | 211 dispatcher_->ProcessPacket(server_address_, client_address_, packet); |
190 | 212 |
191 StartReading(); | 213 StartReading(check_packet_buffer); |
192 } | 214 } |
193 | 215 |
194 } // namespace net | 216 } // namespace net |
OLD | NEW |