Chromium Code Reviews| 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, |
| 40 const QuicCryptoServerConfig::ConfigOptions& crypto_config_options, | 41 const QuicCryptoServerConfig::ConfigOptions& crypto_config_options, |
| 41 const QuicVersionVector& supported_versions) | 42 const QuicVersionVector& supported_versions) |
| 42 : version_manager_(supported_versions), | 43 : version_manager_(supported_versions), |
| 43 helper_( | 44 helper_( |
| 44 new QuicChromiumConnectionHelper(&clock_, QuicRandom::GetInstance())), | 45 new QuicChromiumConnectionHelper(&clock_, QuicRandom::GetInstance())), |
| 45 alarm_factory_(new QuicChromiumAlarmFactory( | 46 alarm_factory_(new QuicChromiumAlarmFactory( |
| 46 base::ThreadTaskRunnerHandle::Get().get(), | 47 base::ThreadTaskRunnerHandle::Get().get(), |
| 47 &clock_)), | 48 &clock_)), |
| 48 config_(config), | 49 config_(config), |
| 49 crypto_config_options_(crypto_config_options), | 50 crypto_config_options_(crypto_config_options), |
| 50 crypto_config_(kSourceAddressTokenSecret, | 51 crypto_config_(kSourceAddressTokenSecret, |
| 51 QuicRandom::GetInstance(), | 52 QuicRandom::GetInstance(), |
| 52 std::move(proof_source)), | 53 std::move(proof_source)), |
| 53 read_pending_(false), | 54 read_pending_(false), |
| 54 synchronous_read_count_(0), | 55 synchronous_read_count_(0), |
| 55 read_buffer_(new IOBufferWithSize(kReadBufferSize)), | 56 read_buffer_(new IOBufferWithSize(kReadBufferSize)), |
| 57 check_packet_buffer_(true), | |
| 56 weak_factory_(this) { | 58 weak_factory_(this) { |
| 57 Initialize(); | 59 Initialize(); |
| 58 } | 60 } |
| 59 | 61 |
| 60 void QuicSimpleServer::Initialize() { | 62 void QuicSimpleServer::Initialize() { |
| 61 #if MMSG_MORE | 63 #if MMSG_MORE |
| 62 use_recvmmsg_ = true; | 64 use_recvmmsg_ = true; |
| 63 #endif | 65 #endif |
| 64 | 66 |
| 65 // If an initial flow control window has not explicitly been set, then use a | 67 // If an initial flow control window has not explicitly been set, then use a |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 145 socket_->Close(); | 147 socket_->Close(); |
| 146 socket_.reset(); | 148 socket_.reset(); |
| 147 } | 149 } |
| 148 | 150 |
| 149 void QuicSimpleServer::StartReading() { | 151 void QuicSimpleServer::StartReading() { |
| 150 if (read_pending_) { | 152 if (read_pending_) { |
| 151 return; | 153 return; |
| 152 } | 154 } |
| 153 read_pending_ = true; | 155 read_pending_ = true; |
| 154 | 156 |
| 157 if (check_packet_buffer_) { | |
| 158 dispatcher_->ProcessBufferedChlos(kNumSessionsToCreatePerSocketEvent); | |
| 159 } | |
| 160 | |
| 161 check_packet_buffer_ = false; | |
| 155 int result = socket_->RecvFrom( | 162 int result = socket_->RecvFrom( |
| 156 read_buffer_.get(), read_buffer_->size(), &client_address_, | 163 read_buffer_.get(), read_buffer_->size(), &client_address_, |
| 157 base::Bind(&QuicSimpleServer::OnReadComplete, base::Unretained(this))); | 164 base::Bind(&QuicSimpleServer::OnReadComplete, base::Unretained(this))); |
| 158 | 165 |
| 159 if (result == ERR_IO_PENDING) { | 166 if (result == ERR_IO_PENDING) { |
| 160 synchronous_read_count_ = 0; | 167 synchronous_read_count_ = 0; |
| 168 if (dispatcher_->HasChlosBuffered()) { | |
| 169 // No more packets to read, but still keep processing buffered packets if | |
| 170 // there is any. | |
| 171 read_pending_ = false; | |
|
Ryan Hamilton
2016/09/06 21:18:33
This looks like a bug. read_pending_ should be tru
| |
| 172 check_packet_buffer_ = true; | |
| 173 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 174 FROM_HERE, base::Bind(&QuicSimpleServer::StartReading, | |
| 175 weak_factory_.GetWeakPtr())); | |
|
Ryan Hamilton
2016/09/06 21:18:33
I don't think this is the right method to call. Th
| |
| 176 } | |
| 161 return; | 177 return; |
| 162 } | 178 } |
| 163 | 179 |
| 164 if (++synchronous_read_count_ > 32) { | 180 if (++synchronous_read_count_ > 32) { |
| 165 synchronous_read_count_ = 0; | 181 synchronous_read_count_ = 0; |
| 166 // Schedule the processing through the message loop to 1) prevent infinite | 182 // Schedule the processing through the message loop to 1) prevent infinite |
| 167 // recursion and 2) avoid blocking the thread for too long. | 183 // recursion and 2) avoid blocking the thread for too long. |
| 184 check_packet_buffer_ = true; | |
| 168 base::ThreadTaskRunnerHandle::Get()->PostTask( | 185 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 169 FROM_HERE, base::Bind(&QuicSimpleServer::OnReadComplete, | 186 FROM_HERE, base::Bind(&QuicSimpleServer::OnReadComplete, |
| 170 weak_factory_.GetWeakPtr(), result)); | 187 weak_factory_.GetWeakPtr(), result)); |
| 171 } else { | 188 } else { |
| 189 // No need to check buffer befor following read. | |
|
Ryan Hamilton
2016/09/06 21:18:33
nit: "before" not "befor"
That being said, I'm su
| |
| 172 OnReadComplete(result); | 190 OnReadComplete(result); |
| 173 } | 191 } |
| 174 } | 192 } |
| 175 | 193 |
| 176 void QuicSimpleServer::OnReadComplete(int result) { | 194 void QuicSimpleServer::OnReadComplete(int result) { |
| 177 read_pending_ = false; | 195 read_pending_ = false; |
| 178 if (result == 0) | 196 if (result == 0) |
| 179 result = ERR_CONNECTION_CLOSED; | 197 result = ERR_CONNECTION_CLOSED; |
| 180 | 198 |
| 181 if (result < 0) { | 199 if (result < 0) { |
| 182 LOG(ERROR) << "QuicSimpleServer read failed: " << ErrorToString(result); | 200 LOG(ERROR) << "QuicSimpleServer read failed: " << ErrorToString(result); |
| 183 Shutdown(); | 201 Shutdown(); |
| 184 return; | 202 return; |
| 185 } | 203 } |
| 186 | 204 |
| 187 QuicReceivedPacket packet(read_buffer_->data(), result, | 205 QuicReceivedPacket packet(read_buffer_->data(), result, |
| 188 helper_->GetClock()->Now(), false); | 206 helper_->GetClock()->Now(), false); |
| 189 dispatcher_->ProcessPacket(server_address_, client_address_, packet); | 207 dispatcher_->ProcessPacket(server_address_, client_address_, packet); |
| 190 | 208 |
| 191 StartReading(); | 209 StartReading(); |
| 192 } | 210 } |
| 193 | 211 |
| 194 } // namespace net | 212 } // namespace net |
| OLD | NEW |