| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_stream_factory.h" | 5 #include "net/quic/quic_stream_factory.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/cpu.h" | 9 #include "base/cpu.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| 11 #include "base/message_loop/message_loop_proxy.h" | 11 #include "base/message_loop/message_loop_proxy.h" |
| 12 #include "base/metrics/field_trial.h" | 12 #include "base/metrics/field_trial.h" |
| 13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
| 14 #include "base/profiler/scoped_tracker.h" | 14 #include "base/profiler/scoped_tracker.h" |
| 15 #include "base/rand_util.h" | 15 #include "base/rand_util.h" |
| 16 #include "base/stl_util.h" | 16 #include "base/stl_util.h" |
| 17 #include "base/strings/string_util.h" | 17 #include "base/strings/string_util.h" |
| 18 #include "base/values.h" | 18 #include "base/values.h" |
| 19 #include "net/base/net_errors.h" | 19 #include "net/base/net_errors.h" |
| 20 #include "net/cert/cert_verifier.h" | 20 #include "net/cert/cert_verifier.h" |
| 21 #include "net/dns/host_resolver.h" | 21 #include "net/dns/host_resolver.h" |
| 22 #include "net/dns/single_request_host_resolver.h" | 22 #include "net/dns/single_request_host_resolver.h" |
| 23 #include "net/http/http_server_properties.h" | 23 #include "net/http/http_server_properties.h" |
| 24 #include "net/quic/congestion_control/tcp_receiver.h" | |
| 25 #include "net/quic/crypto/channel_id_chromium.h" | 24 #include "net/quic/crypto/channel_id_chromium.h" |
| 26 #include "net/quic/crypto/proof_verifier_chromium.h" | 25 #include "net/quic/crypto/proof_verifier_chromium.h" |
| 27 #include "net/quic/crypto/quic_random.h" | 26 #include "net/quic/crypto/quic_random.h" |
| 28 #include "net/quic/crypto/quic_server_info.h" | 27 #include "net/quic/crypto/quic_server_info.h" |
| 29 #include "net/quic/port_suggester.h" | 28 #include "net/quic/port_suggester.h" |
| 30 #include "net/quic/quic_client_session.h" | 29 #include "net/quic/quic_client_session.h" |
| 31 #include "net/quic/quic_clock.h" | 30 #include "net/quic/quic_clock.h" |
| 32 #include "net/quic/quic_connection.h" | 31 #include "net/quic/quic_connection.h" |
| 33 #include "net/quic/quic_connection_helper.h" | 32 #include "net/quic/quic_connection_helper.h" |
| 34 #include "net/quic/quic_crypto_client_stream_factory.h" | 33 #include "net/quic/quic_crypto_client_stream_factory.h" |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 // Responsible for creating a new QUIC session to the specified server, and | 133 // Responsible for creating a new QUIC session to the specified server, and |
| 135 // for notifying any associated requests when complete. | 134 // for notifying any associated requests when complete. |
| 136 class QuicStreamFactory::Job { | 135 class QuicStreamFactory::Job { |
| 137 public: | 136 public: |
| 138 Job(QuicStreamFactory* factory, | 137 Job(QuicStreamFactory* factory, |
| 139 HostResolver* host_resolver, | 138 HostResolver* host_resolver, |
| 140 const HostPortPair& host_port_pair, | 139 const HostPortPair& host_port_pair, |
| 141 bool is_https, | 140 bool is_https, |
| 142 bool was_alternate_protocol_recently_broken, | 141 bool was_alternate_protocol_recently_broken, |
| 143 PrivacyMode privacy_mode, | 142 PrivacyMode privacy_mode, |
| 144 base::StringPiece method, | 143 bool is_post, |
| 145 QuicServerInfo* server_info, | 144 QuicServerInfo* server_info, |
| 146 const BoundNetLog& net_log); | 145 const BoundNetLog& net_log); |
| 147 | 146 |
| 148 // Creates a new job to handle the resumption of for connecting an | 147 // Creates a new job to handle the resumption of for connecting an |
| 149 // existing session. | 148 // existing session. |
| 150 Job(QuicStreamFactory* factory, | 149 Job(QuicStreamFactory* factory, |
| 151 HostResolver* host_resolver, | 150 HostResolver* host_resolver, |
| 152 QuicClientSession* session, | 151 QuicClientSession* session, |
| 153 QuicServerId server_id); | 152 QuicServerId server_id); |
| 154 | 153 |
| 155 ~Job(); | 154 ~Job(); |
| 156 | 155 |
| 157 int Run(const CompletionCallback& callback); | 156 int Run(const CompletionCallback& callback); |
| 158 | 157 |
| 159 int DoLoop(int rv); | 158 int DoLoop(int rv); |
| 160 int DoResolveHost(); | 159 int DoResolveHost(); |
| 161 int DoResolveHostComplete(int rv); | 160 int DoResolveHostComplete(int rv); |
| 162 int DoLoadServerInfo(); | 161 int DoLoadServerInfo(); |
| 163 int DoLoadServerInfoComplete(int rv); | 162 int DoLoadServerInfoComplete(int rv); |
| 164 int DoConnect(); | 163 int DoConnect(); |
| 165 int DoResumeConnect(); | 164 int DoResumeConnect(); |
| 166 int DoConnectComplete(int rv); | 165 int DoConnectComplete(int rv); |
| 167 | 166 |
| 168 void OnIOComplete(int rv); | 167 void OnIOComplete(int rv); |
| 169 | 168 |
| 169 void RunAuxilaryJob(); |
| 170 |
| 171 void Cancel(); |
| 172 |
| 170 void CancelWaitForDataReadyCallback(); | 173 void CancelWaitForDataReadyCallback(); |
| 171 | 174 |
| 172 CompletionCallback callback() { | 175 const QuicServerId server_id() const { return server_id_; } |
| 173 return callback_; | |
| 174 } | |
| 175 | 176 |
| 176 const QuicServerId server_id() const { | 177 base::WeakPtr<Job> GetWeakPtr() { return weak_factory_.GetWeakPtr(); } |
| 177 return server_id_; | |
| 178 } | |
| 179 | 178 |
| 180 private: | 179 private: |
| 181 enum IoState { | 180 enum IoState { |
| 182 STATE_NONE, | 181 STATE_NONE, |
| 183 STATE_RESOLVE_HOST, | 182 STATE_RESOLVE_HOST, |
| 184 STATE_RESOLVE_HOST_COMPLETE, | 183 STATE_RESOLVE_HOST_COMPLETE, |
| 185 STATE_LOAD_SERVER_INFO, | 184 STATE_LOAD_SERVER_INFO, |
| 186 STATE_LOAD_SERVER_INFO_COMPLETE, | 185 STATE_LOAD_SERVER_INFO_COMPLETE, |
| 187 STATE_CONNECT, | 186 STATE_CONNECT, |
| 188 STATE_RESUME_CONNECT, | 187 STATE_RESUME_CONNECT, |
| 189 STATE_CONNECT_COMPLETE, | 188 STATE_CONNECT_COMPLETE, |
| 190 }; | 189 }; |
| 191 IoState io_state_; | 190 IoState io_state_; |
| 192 | 191 |
| 193 QuicStreamFactory* factory_; | 192 QuicStreamFactory* factory_; |
| 194 SingleRequestHostResolver host_resolver_; | 193 SingleRequestHostResolver host_resolver_; |
| 195 QuicServerId server_id_; | 194 QuicServerId server_id_; |
| 196 bool is_post_; | 195 bool is_post_; |
| 197 bool was_alternate_protocol_recently_broken_; | 196 bool was_alternate_protocol_recently_broken_; |
| 198 scoped_ptr<QuicServerInfo> server_info_; | 197 scoped_ptr<QuicServerInfo> server_info_; |
| 198 bool started_another_job_; |
| 199 const BoundNetLog net_log_; | 199 const BoundNetLog net_log_; |
| 200 QuicClientSession* session_; | 200 QuicClientSession* session_; |
| 201 CompletionCallback callback_; | 201 CompletionCallback callback_; |
| 202 AddressList address_list_; | 202 AddressList address_list_; |
| 203 base::TimeTicks disk_cache_load_start_time_; | 203 base::TimeTicks disk_cache_load_start_time_; |
| 204 base::TimeTicks dns_resolution_start_time_; | 204 base::TimeTicks dns_resolution_start_time_; |
| 205 base::WeakPtrFactory<Job> weak_factory_; | 205 base::WeakPtrFactory<Job> weak_factory_; |
| 206 DISALLOW_COPY_AND_ASSIGN(Job); | 206 DISALLOW_COPY_AND_ASSIGN(Job); |
| 207 }; | 207 }; |
| 208 | 208 |
| 209 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, | 209 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, |
| 210 HostResolver* host_resolver, | 210 HostResolver* host_resolver, |
| 211 const HostPortPair& host_port_pair, | 211 const HostPortPair& host_port_pair, |
| 212 bool is_https, | 212 bool is_https, |
| 213 bool was_alternate_protocol_recently_broken, | 213 bool was_alternate_protocol_recently_broken, |
| 214 PrivacyMode privacy_mode, | 214 PrivacyMode privacy_mode, |
| 215 base::StringPiece method, | 215 bool is_post, |
| 216 QuicServerInfo* server_info, | 216 QuicServerInfo* server_info, |
| 217 const BoundNetLog& net_log) | 217 const BoundNetLog& net_log) |
| 218 : io_state_(STATE_RESOLVE_HOST), | 218 : io_state_(STATE_RESOLVE_HOST), |
| 219 factory_(factory), | 219 factory_(factory), |
| 220 host_resolver_(host_resolver), | 220 host_resolver_(host_resolver), |
| 221 server_id_(host_port_pair, is_https, privacy_mode), | 221 server_id_(host_port_pair, is_https, privacy_mode), |
| 222 is_post_(method == "POST"), | 222 is_post_(is_post), |
| 223 was_alternate_protocol_recently_broken_( | 223 was_alternate_protocol_recently_broken_( |
| 224 was_alternate_protocol_recently_broken), | 224 was_alternate_protocol_recently_broken), |
| 225 server_info_(server_info), | 225 server_info_(server_info), |
| 226 started_another_job_(false), |
| 226 net_log_(net_log), | 227 net_log_(net_log), |
| 227 session_(nullptr), | 228 session_(nullptr), |
| 228 weak_factory_(this) {} | 229 weak_factory_(this) { |
| 230 } |
| 229 | 231 |
| 230 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, | 232 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, |
| 231 HostResolver* host_resolver, | 233 HostResolver* host_resolver, |
| 232 QuicClientSession* session, | 234 QuicClientSession* session, |
| 233 QuicServerId server_id) | 235 QuicServerId server_id) |
| 234 : io_state_(STATE_RESUME_CONNECT), | 236 : io_state_(STATE_RESUME_CONNECT), |
| 235 factory_(factory), | 237 factory_(factory), |
| 236 host_resolver_(host_resolver), // unused | 238 host_resolver_(host_resolver), // unused |
| 237 server_id_(server_id), | 239 server_id_(server_id), |
| 238 is_post_(false), // unused | 240 is_post_(false), // unused |
| 239 was_alternate_protocol_recently_broken_(false), // unused | 241 was_alternate_protocol_recently_broken_(false), // unused |
| 240 net_log_(session->net_log()), // unused | 242 started_another_job_(false), // unused |
| 243 net_log_(session->net_log()), // unused |
| 241 session_(session), | 244 session_(session), |
| 242 weak_factory_(this) {} | 245 weak_factory_(this) { |
| 246 } |
| 243 | 247 |
| 244 QuicStreamFactory::Job::~Job() { | 248 QuicStreamFactory::Job::~Job() { |
| 249 // If disk cache has a pending WaitForDataReadyCallback, cancel that callback. |
| 250 if (server_info_) |
| 251 server_info_->ResetWaitForDataReadyCallback(); |
| 245 } | 252 } |
| 246 | 253 |
| 247 int QuicStreamFactory::Job::Run(const CompletionCallback& callback) { | 254 int QuicStreamFactory::Job::Run(const CompletionCallback& callback) { |
| 248 int rv = DoLoop(OK); | 255 int rv = DoLoop(OK); |
| 249 if (rv == ERR_IO_PENDING) | 256 if (rv == ERR_IO_PENDING) |
| 250 callback_ = callback; | 257 callback_ = callback; |
| 251 | 258 |
| 252 return rv > 0 ? OK : rv; | 259 return rv > 0 ? OK : rv; |
| 253 } | 260 } |
| 254 | 261 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 300 | 307 |
| 301 tracked_objects::ScopedTracker tracking_profile2( | 308 tracked_objects::ScopedTracker tracking_profile2( |
| 302 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 309 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 303 "422516 QuicStreamFactory::Job::OnIOComplete2")); | 310 "422516 QuicStreamFactory::Job::OnIOComplete2")); |
| 304 | 311 |
| 305 if (rv != ERR_IO_PENDING && !callback_.is_null()) { | 312 if (rv != ERR_IO_PENDING && !callback_.is_null()) { |
| 306 callback_.Run(rv); | 313 callback_.Run(rv); |
| 307 } | 314 } |
| 308 } | 315 } |
| 309 | 316 |
| 317 void QuicStreamFactory::Job::RunAuxilaryJob() { |
| 318 int rv = Run(base::Bind(&QuicStreamFactory::OnJobComplete, |
| 319 base::Unretained(factory_), this)); |
| 320 if (rv != ERR_IO_PENDING) |
| 321 factory_->OnJobComplete(this, rv); |
| 322 } |
| 323 |
| 324 void QuicStreamFactory::Job::Cancel() { |
| 325 callback_.Reset(); |
| 326 if (session_) |
| 327 session_->connection()->SendConnectionClose(QUIC_CONNECTION_CANCELLED); |
| 328 } |
| 329 |
| 310 void QuicStreamFactory::Job::CancelWaitForDataReadyCallback() { | 330 void QuicStreamFactory::Job::CancelWaitForDataReadyCallback() { |
| 311 // If we are waiting for WaitForDataReadyCallback, then cancel the callback. | 331 // If we are waiting for WaitForDataReadyCallback, then cancel the callback. |
| 312 if (io_state_ != STATE_LOAD_SERVER_INFO_COMPLETE) | 332 if (io_state_ != STATE_LOAD_SERVER_INFO_COMPLETE) |
| 313 return; | 333 return; |
| 314 server_info_->CancelWaitForDataReadyCallback(); | 334 server_info_->CancelWaitForDataReadyCallback(); |
| 315 OnIOComplete(OK); | 335 OnIOComplete(OK); |
| 316 } | 336 } |
| 317 | 337 |
| 318 int QuicStreamFactory::Job::DoResolveHost() { | 338 int QuicStreamFactory::Job::DoResolveHost() { |
| 319 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 339 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
| 320 tracked_objects::ScopedTracker tracking_profile( | 340 tracked_objects::ScopedTracker tracking_profile( |
| 321 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 341 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 322 "422516 QuicStreamFactory::Job::DoResolveHost")); | 342 "422516 QuicStreamFactory::Job::DoResolveHost")); |
| 323 | 343 |
| 324 // Start loading the data now, and wait for it after we resolve the host. | 344 // Start loading the data now, and wait for it after we resolve the host. |
| 325 if (server_info_) { | 345 if (server_info_) { |
| 326 server_info_->Start(); | 346 server_info_->Start(); |
| 327 } | 347 } |
| 328 | 348 |
| 329 io_state_ = STATE_RESOLVE_HOST_COMPLETE; | 349 io_state_ = STATE_RESOLVE_HOST_COMPLETE; |
| 330 dns_resolution_start_time_ = base::TimeTicks::Now(); | 350 dns_resolution_start_time_ = base::TimeTicks::Now(); |
| 331 return host_resolver_.Resolve( | 351 return host_resolver_.Resolve( |
| 332 HostResolver::RequestInfo(server_id_.host_port_pair()), | 352 HostResolver::RequestInfo(server_id_.host_port_pair()), DEFAULT_PRIORITY, |
| 333 DEFAULT_PRIORITY, | |
| 334 &address_list_, | 353 &address_list_, |
| 335 base::Bind(&QuicStreamFactory::Job::OnIOComplete, | 354 base::Bind(&QuicStreamFactory::Job::OnIOComplete, GetWeakPtr()), |
| 336 weak_factory_.GetWeakPtr()), | |
| 337 net_log_); | 355 net_log_); |
| 338 } | 356 } |
| 339 | 357 |
| 340 int QuicStreamFactory::Job::DoResolveHostComplete(int rv) { | 358 int QuicStreamFactory::Job::DoResolveHostComplete(int rv) { |
| 341 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 359 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
| 342 tracked_objects::ScopedTracker tracking_profile( | 360 tracked_objects::ScopedTracker tracking_profile( |
| 343 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 361 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 344 "422516 QuicStreamFactory::Job::DoResolveHostComplete")); | 362 "422516 QuicStreamFactory::Job::DoResolveHostComplete")); |
| 345 | 363 |
| 346 UMA_HISTOGRAM_TIMES("Net.QuicSession.HostResolutionTime", | 364 UMA_HISTOGRAM_TIMES("Net.QuicSession.HostResolutionTime", |
| 347 base::TimeTicks::Now() - dns_resolution_start_time_); | 365 base::TimeTicks::Now() - dns_resolution_start_time_); |
| 348 if (rv != OK) | 366 if (rv != OK) |
| 349 return rv; | 367 return rv; |
| 350 | 368 |
| 351 DCHECK(!factory_->HasActiveSession(server_id_)); | 369 DCHECK(!factory_->HasActiveSession(server_id_)); |
| 352 | 370 |
| 353 // Inform the factory of this resolution, which will set up | 371 // Inform the factory of this resolution, which will set up |
| 354 // a session alias, if possible. | 372 // a session alias, if possible. |
| 355 if (factory_->OnResolution(server_id_, address_list_)) { | 373 if (factory_->OnResolution(server_id_, address_list_)) { |
| 356 return OK; | 374 return OK; |
| 357 } | 375 } |
| 358 | 376 |
| 359 io_state_ = STATE_LOAD_SERVER_INFO; | 377 if (server_info_) |
| 378 io_state_ = STATE_LOAD_SERVER_INFO; |
| 379 else |
| 380 io_state_ = STATE_CONNECT; |
| 360 return OK; | 381 return OK; |
| 361 } | 382 } |
| 362 | 383 |
| 363 int QuicStreamFactory::Job::DoLoadServerInfo() { | 384 int QuicStreamFactory::Job::DoLoadServerInfo() { |
| 364 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 385 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
| 365 tracked_objects::ScopedTracker tracking_profile( | 386 tracked_objects::ScopedTracker tracking_profile( |
| 366 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 387 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 367 "422516 QuicStreamFactory::Job::DoLoadServerInfo")); | 388 "422516 QuicStreamFactory::Job::DoLoadServerInfo")); |
| 368 | 389 |
| 369 io_state_ = STATE_LOAD_SERVER_INFO_COMPLETE; | 390 io_state_ = STATE_LOAD_SERVER_INFO_COMPLETE; |
| 370 | 391 |
| 371 if (!server_info_) | 392 DCHECK(server_info_); |
| 372 return OK; | |
| 373 | 393 |
| 374 // To mitigate the effects of disk cache taking too long to load QUIC server | 394 // To mitigate the effects of disk cache taking too long to load QUIC server |
| 375 // information, set up a timer to cancel WaitForDataReady's callback. | 395 // information, set up a timer to cancel WaitForDataReady's callback. |
| 376 int64 load_server_info_timeout_ms = factory_->load_server_info_timeout_ms_; | 396 int64 load_server_info_timeout_ms = factory_->load_server_info_timeout_ms_; |
| 377 if (factory_->load_server_info_timeout_srtt_multiplier_ > 0) { | 397 if (factory_->load_server_info_timeout_srtt_multiplier_ > 0) { |
| 378 DCHECK_EQ(0, load_server_info_timeout_ms); | 398 DCHECK_EQ(0, load_server_info_timeout_ms); |
| 379 load_server_info_timeout_ms = | 399 load_server_info_timeout_ms = |
| 380 (factory_->load_server_info_timeout_srtt_multiplier_ * | 400 (factory_->load_server_info_timeout_srtt_multiplier_ * |
| 381 factory_->GetServerNetworkStatsSmoothedRttInMicroseconds(server_id_)) / | 401 factory_->GetServerNetworkStatsSmoothedRttInMicroseconds(server_id_)) / |
| 382 1000; | 402 1000; |
| 383 } | 403 } |
| 384 if (load_server_info_timeout_ms > 0) { | 404 if (load_server_info_timeout_ms > 0) { |
| 385 factory_->task_runner_->PostDelayedTask( | 405 factory_->task_runner_->PostDelayedTask( |
| 386 FROM_HERE, | 406 FROM_HERE, |
| 387 base::Bind(&QuicStreamFactory::Job::CancelWaitForDataReadyCallback, | 407 base::Bind(&QuicStreamFactory::Job::CancelWaitForDataReadyCallback, |
| 388 weak_factory_.GetWeakPtr()), | 408 GetWeakPtr()), |
| 389 base::TimeDelta::FromMilliseconds(load_server_info_timeout_ms)); | 409 base::TimeDelta::FromMilliseconds(load_server_info_timeout_ms)); |
| 390 } | 410 } |
| 391 | 411 |
| 392 disk_cache_load_start_time_ = base::TimeTicks::Now(); | 412 disk_cache_load_start_time_ = base::TimeTicks::Now(); |
| 393 return server_info_->WaitForDataReady( | 413 int rv = server_info_->WaitForDataReady( |
| 394 base::Bind(&QuicStreamFactory::Job::OnIOComplete, | 414 base::Bind(&QuicStreamFactory::Job::OnIOComplete, GetWeakPtr())); |
| 395 weak_factory_.GetWeakPtr())); | 415 if (rv == ERR_IO_PENDING && factory_->enable_connection_racing()) { |
| 416 // If we are waiting to load server config from the disk cache, then start |
| 417 // another job. |
| 418 started_another_job_ = true; |
| 419 factory_->CreateAuxilaryJob(server_id_, is_post_, net_log_); |
| 420 } |
| 421 return rv; |
| 396 } | 422 } |
| 397 | 423 |
| 398 int QuicStreamFactory::Job::DoLoadServerInfoComplete(int rv) { | 424 int QuicStreamFactory::Job::DoLoadServerInfoComplete(int rv) { |
| 399 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 425 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
| 400 tracked_objects::ScopedTracker tracking_profile( | 426 tracked_objects::ScopedTracker tracking_profile( |
| 401 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 427 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 402 "422516 QuicStreamFactory::Job::DoLoadServerInfoComplete")); | 428 "422516 QuicStreamFactory::Job::DoLoadServerInfoComplete")); |
| 403 | 429 |
| 404 if (server_info_) { | 430 UMA_HISTOGRAM_TIMES("Net.QuicServerInfo.DiskCacheWaitForDataReadyTime", |
| 405 UMA_HISTOGRAM_TIMES("Net.QuicServerInfo.DiskCacheWaitForDataReadyTime", | 431 base::TimeTicks::Now() - disk_cache_load_start_time_); |
| 406 base::TimeTicks::Now() - disk_cache_load_start_time_); | |
| 407 } | |
| 408 | 432 |
| 409 if (rv != OK) { | 433 if (rv != OK) |
| 410 server_info_.reset(); | 434 server_info_.reset(); |
| 435 |
| 436 if (started_another_job_ && |
| 437 (!server_info_ || server_info_->state().server_config.empty() || |
| 438 !factory_->CryptoConfigCacheIsEmpty(server_id_))) { |
| 439 // If we have started another job and if we didn't load the server config |
| 440 // from the disk cache or if we have received a new server config from the |
| 441 // server, then cancel the current job. |
| 442 io_state_ = STATE_NONE; |
| 443 return ERR_CONNECTION_CLOSED; |
| 411 } | 444 } |
| 412 | 445 |
| 413 io_state_ = STATE_CONNECT; | 446 io_state_ = STATE_CONNECT; |
| 414 return OK; | 447 return OK; |
| 415 } | 448 } |
| 416 | 449 |
| 417 int QuicStreamFactory::Job::DoConnect() { | 450 int QuicStreamFactory::Job::DoConnect() { |
| 418 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 451 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
| 419 tracked_objects::ScopedTracker tracking_profile( | 452 tracked_objects::ScopedTracker tracking_profile( |
| 420 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 453 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| (...skipping 26 matching lines...) Expand all Loading... |
| 447 factory_->require_confirmation() || is_post_ || | 480 factory_->require_confirmation() || is_post_ || |
| 448 was_alternate_protocol_recently_broken_; | 481 was_alternate_protocol_recently_broken_; |
| 449 | 482 |
| 450 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 483 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
| 451 tracked_objects::ScopedTracker tracking_profile2( | 484 tracked_objects::ScopedTracker tracking_profile2( |
| 452 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 485 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 453 "422516 QuicStreamFactory::Job::DoConnect2")); | 486 "422516 QuicStreamFactory::Job::DoConnect2")); |
| 454 | 487 |
| 455 rv = session_->CryptoConnect( | 488 rv = session_->CryptoConnect( |
| 456 require_confirmation, | 489 require_confirmation, |
| 457 base::Bind(&QuicStreamFactory::Job::OnIOComplete, | 490 base::Bind(&QuicStreamFactory::Job::OnIOComplete, GetWeakPtr())); |
| 458 base::Unretained(this))); | |
| 459 return rv; | 491 return rv; |
| 460 } | 492 } |
| 461 | 493 |
| 462 int QuicStreamFactory::Job::DoResumeConnect() { | 494 int QuicStreamFactory::Job::DoResumeConnect() { |
| 463 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 495 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
| 464 tracked_objects::ScopedTracker tracking_profile( | 496 tracked_objects::ScopedTracker tracking_profile( |
| 465 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 497 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 466 "422516 QuicStreamFactory::Job::DoResumeConnect")); | 498 "422516 QuicStreamFactory::Job::DoResumeConnect")); |
| 467 | 499 |
| 468 io_state_ = STATE_CONNECT_COMPLETE; | 500 io_state_ = STATE_CONNECT_COMPLETE; |
| 469 | 501 |
| 470 int rv = session_->ResumeCryptoConnect( | 502 int rv = session_->ResumeCryptoConnect( |
| 471 base::Bind(&QuicStreamFactory::Job::OnIOComplete, | 503 base::Bind(&QuicStreamFactory::Job::OnIOComplete, GetWeakPtr())); |
| 472 base::Unretained(this))); | |
| 473 | 504 |
| 474 return rv; | 505 return rv; |
| 475 } | 506 } |
| 476 | 507 |
| 477 int QuicStreamFactory::Job::DoConnectComplete(int rv) { | 508 int QuicStreamFactory::Job::DoConnectComplete(int rv) { |
| 478 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 509 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
| 479 tracked_objects::ScopedTracker tracking_profile( | 510 tracked_objects::ScopedTracker tracking_profile( |
| 480 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 511 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 481 "422516 QuicStreamFactory::Job::DoConnectComplete")); | 512 "422516 QuicStreamFactory::Job::DoConnectComplete")); |
| 482 | 513 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 557 QuicClock* clock, | 588 QuicClock* clock, |
| 558 size_t max_packet_length, | 589 size_t max_packet_length, |
| 559 const std::string& user_agent_id, | 590 const std::string& user_agent_id, |
| 560 const QuicVersionVector& supported_versions, | 591 const QuicVersionVector& supported_versions, |
| 561 bool enable_port_selection, | 592 bool enable_port_selection, |
| 562 bool always_require_handshake_confirmation, | 593 bool always_require_handshake_confirmation, |
| 563 bool disable_connection_pooling, | 594 bool disable_connection_pooling, |
| 564 int load_server_info_timeout, | 595 int load_server_info_timeout, |
| 565 float load_server_info_timeout_srtt_multiplier, | 596 float load_server_info_timeout_srtt_multiplier, |
| 566 bool enable_truncated_connection_ids, | 597 bool enable_truncated_connection_ids, |
| 598 bool enable_connection_racing, |
| 567 const QuicTagVector& connection_options) | 599 const QuicTagVector& connection_options) |
| 568 : require_confirmation_(true), | 600 : require_confirmation_(true), |
| 569 host_resolver_(host_resolver), | 601 host_resolver_(host_resolver), |
| 570 client_socket_factory_(client_socket_factory), | 602 client_socket_factory_(client_socket_factory), |
| 571 http_server_properties_(http_server_properties), | 603 http_server_properties_(http_server_properties), |
| 572 transport_security_state_(transport_security_state), | 604 transport_security_state_(transport_security_state), |
| 573 quic_server_info_factory_(nullptr), | 605 quic_server_info_factory_(nullptr), |
| 574 quic_crypto_client_stream_factory_(quic_crypto_client_stream_factory), | 606 quic_crypto_client_stream_factory_(quic_crypto_client_stream_factory), |
| 575 random_generator_(random_generator), | 607 random_generator_(random_generator), |
| 576 clock_(clock), | 608 clock_(clock), |
| 577 max_packet_length_(max_packet_length), | 609 max_packet_length_(max_packet_length), |
| 578 config_(InitializeQuicConfig(connection_options)), | 610 config_(InitializeQuicConfig(connection_options)), |
| 579 supported_versions_(supported_versions), | 611 supported_versions_(supported_versions), |
| 580 enable_port_selection_(enable_port_selection), | 612 enable_port_selection_(enable_port_selection), |
| 581 always_require_handshake_confirmation_( | 613 always_require_handshake_confirmation_( |
| 582 always_require_handshake_confirmation), | 614 always_require_handshake_confirmation), |
| 583 disable_connection_pooling_(disable_connection_pooling), | 615 disable_connection_pooling_(disable_connection_pooling), |
| 584 load_server_info_timeout_ms_(load_server_info_timeout), | 616 load_server_info_timeout_ms_(load_server_info_timeout), |
| 585 load_server_info_timeout_srtt_multiplier_( | 617 load_server_info_timeout_srtt_multiplier_( |
| 586 load_server_info_timeout_srtt_multiplier), | 618 load_server_info_timeout_srtt_multiplier), |
| 587 enable_truncated_connection_ids_(enable_truncated_connection_ids), | 619 enable_truncated_connection_ids_(enable_truncated_connection_ids), |
| 620 enable_connection_racing_(enable_connection_racing), |
| 588 port_seed_(random_generator_->RandUint64()), | 621 port_seed_(random_generator_->RandUint64()), |
| 589 check_persisted_supports_quic_(true), | 622 check_persisted_supports_quic_(true), |
| 590 task_runner_(nullptr), | 623 task_runner_(nullptr), |
| 591 weak_factory_(this) { | 624 weak_factory_(this) { |
| 592 DCHECK(transport_security_state_); | 625 DCHECK(transport_security_state_); |
| 626 // TODO(michaeln): Remove ScopedTracker below once crbug.com/454983 is fixed |
| 627 tracked_objects::ScopedTracker tracking_profile( |
| 628 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 629 "454983 QuicStreamFactory::QuicStreamFactory")); |
| 593 crypto_config_.set_user_agent_id(user_agent_id); | 630 crypto_config_.set_user_agent_id(user_agent_id); |
| 594 crypto_config_.AddCanonicalSuffix(".c.youtube.com"); | 631 crypto_config_.AddCanonicalSuffix(".c.youtube.com"); |
| 595 crypto_config_.AddCanonicalSuffix(".googlevideo.com"); | 632 crypto_config_.AddCanonicalSuffix(".googlevideo.com"); |
| 596 crypto_config_.SetProofVerifier( | 633 crypto_config_.SetProofVerifier( |
| 597 new ProofVerifierChromium(cert_verifier, transport_security_state)); | 634 new ProofVerifierChromium(cert_verifier, transport_security_state)); |
| 598 crypto_config_.SetChannelIDSource( | 635 crypto_config_.SetChannelIDSource( |
| 599 new ChannelIDSourceChromium(channel_id_service)); | 636 new ChannelIDSourceChromium(channel_id_service)); |
| 600 base::CPU cpu; | 637 base::CPU cpu; |
| 601 if (cpu.has_aesni() && cpu.has_avx()) | 638 if (cpu.has_aesni() && cpu.has_avx()) |
| 602 crypto_config_.PreferAesGcm(); | 639 crypto_config_.PreferAesGcm(); |
| 603 if (!IsEcdsaSupported()) | 640 if (!IsEcdsaSupported()) |
| 604 crypto_config_.DisableEcdsa(); | 641 crypto_config_.DisableEcdsa(); |
| 605 } | 642 } |
| 606 | 643 |
| 607 QuicStreamFactory::~QuicStreamFactory() { | 644 QuicStreamFactory::~QuicStreamFactory() { |
| 608 CloseAllSessions(ERR_ABORTED); | 645 CloseAllSessions(ERR_ABORTED); |
| 609 while (!all_sessions_.empty()) { | 646 while (!all_sessions_.empty()) { |
| 610 delete all_sessions_.begin()->first; | 647 delete all_sessions_.begin()->first; |
| 611 all_sessions_.erase(all_sessions_.begin()); | 648 all_sessions_.erase(all_sessions_.begin()); |
| 612 } | 649 } |
| 613 STLDeleteValues(&active_jobs_); | 650 while (!active_jobs_.empty()) { |
| 651 const QuicServerId server_id = active_jobs_.begin()->first; |
| 652 STLDeleteElements(&(active_jobs_[server_id])); |
| 653 active_jobs_.erase(server_id); |
| 654 } |
| 614 } | 655 } |
| 615 | 656 |
| 616 void QuicStreamFactory::set_require_confirmation(bool require_confirmation) { | 657 void QuicStreamFactory::set_require_confirmation(bool require_confirmation) { |
| 617 require_confirmation_ = require_confirmation; | 658 require_confirmation_ = require_confirmation; |
| 618 if (http_server_properties_ && (!(local_address_ == IPEndPoint()))) { | 659 if (http_server_properties_ && (!(local_address_ == IPEndPoint()))) { |
| 619 http_server_properties_->SetSupportsQuic(!require_confirmation, | 660 http_server_properties_->SetSupportsQuic(!require_confirmation, |
| 620 local_address_.address()); | 661 local_address_.address()); |
| 621 } | 662 } |
| 622 } | 663 } |
| 623 | 664 |
| 624 int QuicStreamFactory::Create(const HostPortPair& host_port_pair, | 665 int QuicStreamFactory::Create(const HostPortPair& host_port_pair, |
| 625 bool is_https, | 666 bool is_https, |
| 626 PrivacyMode privacy_mode, | 667 PrivacyMode privacy_mode, |
| 627 base::StringPiece method, | 668 base::StringPiece method, |
| 628 const BoundNetLog& net_log, | 669 const BoundNetLog& net_log, |
| 629 QuicStreamRequest* request) { | 670 QuicStreamRequest* request) { |
| 630 QuicServerId server_id(host_port_pair, is_https, privacy_mode); | 671 QuicServerId server_id(host_port_pair, is_https, privacy_mode); |
| 631 if (HasActiveSession(server_id)) { | 672 if (HasActiveSession(server_id)) { |
| 632 request->set_stream(CreateIfSessionExists(server_id, net_log)); | 673 request->set_stream(CreateIfSessionExists(server_id, net_log)); |
| 633 return OK; | 674 return OK; |
| 634 } | 675 } |
| 635 | 676 |
| 636 if (HasActiveJob(server_id)) { | 677 if (HasActiveJob(server_id)) { |
| 637 Job* job = active_jobs_[server_id]; | 678 active_requests_[request] = server_id; |
| 638 active_requests_[request] = job; | 679 job_requests_map_[server_id].insert(request); |
| 639 job_requests_map_[job].insert(request); | |
| 640 return ERR_IO_PENDING; | 680 return ERR_IO_PENDING; |
| 641 } | 681 } |
| 642 | 682 |
| 683 // TODO(rtenneti): |task_runner_| is used by the Job. Initialize task_runner_ |
| 684 // in the constructor after WebRequestActionWithThreadsTest.* tests are fixed. |
| 685 if (!task_runner_) |
| 686 task_runner_ = base::MessageLoop::current()->message_loop_proxy().get(); |
| 687 |
| 643 QuicServerInfo* quic_server_info = nullptr; | 688 QuicServerInfo* quic_server_info = nullptr; |
| 644 if (quic_server_info_factory_) { | 689 if (quic_server_info_factory_) { |
| 645 bool load_from_disk_cache = true; | 690 bool load_from_disk_cache = true; |
| 646 if (http_server_properties_) { | 691 if (http_server_properties_) { |
| 647 const AlternateProtocolMap& alternate_protocol_map = | 692 const AlternateProtocolMap& alternate_protocol_map = |
| 648 http_server_properties_->alternate_protocol_map(); | 693 http_server_properties_->alternate_protocol_map(); |
| 649 AlternateProtocolMap::const_iterator it = | 694 AlternateProtocolMap::const_iterator it = |
| 650 alternate_protocol_map.Peek(server_id.host_port_pair()); | 695 alternate_protocol_map.Peek(server_id.host_port_pair()); |
| 651 if (it == alternate_protocol_map.end() || it->second.protocol != QUIC) { | 696 if (it == alternate_protocol_map.end() || it->second.protocol != QUIC) { |
| 652 // If there is no entry for QUIC, consider that as a new server and | 697 // If there is no entry for QUIC, consider that as a new server and |
| 653 // don't wait for Cache thread to load the data for that server. | 698 // don't wait for Cache thread to load the data for that server. |
| 654 load_from_disk_cache = false; | 699 load_from_disk_cache = false; |
| 655 } | 700 } |
| 656 } | 701 } |
| 657 if (load_from_disk_cache) { | 702 if (load_from_disk_cache && CryptoConfigCacheIsEmpty(server_id)) { |
| 658 QuicCryptoClientConfig::CachedState* cached = | 703 quic_server_info = quic_server_info_factory_->GetForServer(server_id); |
| 659 crypto_config_.LookupOrCreate(server_id); | |
| 660 DCHECK(cached); | |
| 661 if (cached->IsEmpty()) { | |
| 662 quic_server_info = quic_server_info_factory_->GetForServer(server_id); | |
| 663 } | |
| 664 } | 704 } |
| 665 } | 705 } |
| 666 // TODO(rtenneti): Initialize task_runner_ in the constructor after | |
| 667 // WebRequestActionWithThreadsTest.* tests are fixed. | |
| 668 if (!task_runner_) | |
| 669 task_runner_ = base::MessageLoop::current()->message_loop_proxy().get(); | |
| 670 | 706 |
| 671 bool was_alternate_protocol_recently_broken = | |
| 672 http_server_properties_ && | |
| 673 http_server_properties_->WasAlternateProtocolRecentlyBroken( | |
| 674 server_id.host_port_pair()); | |
| 675 scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_pair, is_https, | 707 scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_pair, is_https, |
| 676 was_alternate_protocol_recently_broken, | 708 WasAlternateProtocolRecentlyBroken(server_id), |
| 677 privacy_mode, method, quic_server_info, net_log)); | 709 privacy_mode, method == "POST" /* is_post */, |
| 710 quic_server_info, net_log)); |
| 678 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, | 711 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, |
| 679 base::Unretained(this), job.get())); | 712 base::Unretained(this), job.get())); |
| 680 | |
| 681 if (rv == ERR_IO_PENDING) { | 713 if (rv == ERR_IO_PENDING) { |
| 682 active_requests_[request] = job.get(); | 714 active_requests_[request] = server_id; |
| 683 job_requests_map_[job.get()].insert(request); | 715 job_requests_map_[server_id].insert(request); |
| 684 active_jobs_[server_id] = job.release(); | 716 active_jobs_[server_id].insert(job.release()); |
| 717 return rv; |
| 685 } | 718 } |
| 686 if (rv == OK) { | 719 if (rv == OK) { |
| 687 DCHECK(HasActiveSession(server_id)); | 720 DCHECK(HasActiveSession(server_id)); |
| 688 request->set_stream(CreateIfSessionExists(server_id, net_log)); | 721 request->set_stream(CreateIfSessionExists(server_id, net_log)); |
| 689 } | 722 } |
| 690 return rv; | 723 return rv; |
| 691 } | 724 } |
| 692 | 725 |
| 726 void QuicStreamFactory::CreateAuxilaryJob(const QuicServerId server_id, |
| 727 bool is_post, |
| 728 const BoundNetLog& net_log) { |
| 729 Job* aux_job = new Job(this, host_resolver_, server_id.host_port_pair(), |
| 730 server_id.is_https(), |
| 731 WasAlternateProtocolRecentlyBroken(server_id), |
| 732 server_id.privacy_mode(), is_post, nullptr, net_log); |
| 733 active_jobs_[server_id].insert(aux_job); |
| 734 task_runner_->PostTask(FROM_HERE, |
| 735 base::Bind(&QuicStreamFactory::Job::RunAuxilaryJob, |
| 736 aux_job->GetWeakPtr())); |
| 737 } |
| 738 |
| 693 bool QuicStreamFactory::OnResolution( | 739 bool QuicStreamFactory::OnResolution( |
| 694 const QuicServerId& server_id, | 740 const QuicServerId& server_id, |
| 695 const AddressList& address_list) { | 741 const AddressList& address_list) { |
| 696 DCHECK(!HasActiveSession(server_id)); | 742 DCHECK(!HasActiveSession(server_id)); |
| 697 if (disable_connection_pooling_) { | 743 if (disable_connection_pooling_) { |
| 698 return false; | 744 return false; |
| 699 } | 745 } |
| 700 for (const IPEndPoint& address : address_list) { | 746 for (const IPEndPoint& address : address_list) { |
| 701 const IpAliasKey ip_alias_key(address, server_id.is_https()); | 747 const IpAliasKey ip_alias_key(address, server_id.is_https()); |
| 702 if (!ContainsKey(ip_aliases_, ip_alias_key)) | 748 if (!ContainsKey(ip_aliases_, ip_alias_key)) |
| 703 continue; | 749 continue; |
| 704 | 750 |
| 705 const SessionSet& sessions = ip_aliases_[ip_alias_key]; | 751 const SessionSet& sessions = ip_aliases_[ip_alias_key]; |
| 706 for (QuicClientSession* session : sessions) { | 752 for (QuicClientSession* session : sessions) { |
| 707 if (!session->CanPool(server_id.host(), server_id.privacy_mode())) | 753 if (!session->CanPool(server_id.host(), server_id.privacy_mode())) |
| 708 continue; | 754 continue; |
| 709 active_sessions_[server_id] = session; | 755 active_sessions_[server_id] = session; |
| 710 session_aliases_[session].insert(server_id); | 756 session_aliases_[session].insert(server_id); |
| 711 return true; | 757 return true; |
| 712 } | 758 } |
| 713 } | 759 } |
| 714 return false; | 760 return false; |
| 715 } | 761 } |
| 716 | 762 |
| 717 void QuicStreamFactory::OnJobComplete(Job* job, int rv) { | 763 void QuicStreamFactory::OnJobComplete(Job* job, int rv) { |
| 764 QuicServerId server_id = job->server_id(); |
| 765 if (rv != OK) { |
| 766 JobSet* jobs = &(active_jobs_[server_id]); |
| 767 if (jobs->size() > 1) { |
| 768 // If there is another pending job, then we can delete this job and let |
| 769 // the other job handle the request. |
| 770 job->Cancel(); |
| 771 jobs->erase(job); |
| 772 delete job; |
| 773 return; |
| 774 } |
| 775 } |
| 776 |
| 718 if (rv == OK) { | 777 if (rv == OK) { |
| 719 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 778 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
| 720 tracked_objects::ScopedTracker tracking_profile1( | 779 tracked_objects::ScopedTracker tracking_profile1( |
| 721 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 780 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 722 "422516 QuicStreamFactory::OnJobComplete1")); | 781 "422516 QuicStreamFactory::OnJobComplete1")); |
| 723 | 782 |
| 724 if (!always_require_handshake_confirmation_) | 783 if (!always_require_handshake_confirmation_) |
| 725 set_require_confirmation(false); | 784 set_require_confirmation(false); |
| 726 | 785 |
| 727 // Create all the streams, but do not notify them yet. | 786 // Create all the streams, but do not notify them yet. |
| 728 for (RequestSet::iterator it = job_requests_map_[job].begin(); | 787 for (QuicStreamRequest* request : job_requests_map_[server_id]) { |
| 729 it != job_requests_map_[job].end() ; ++it) { | 788 DCHECK(HasActiveSession(server_id)); |
| 730 DCHECK(HasActiveSession(job->server_id())); | 789 request->set_stream(CreateIfSessionExists(server_id, request->net_log())); |
| 731 (*it)->set_stream(CreateIfSessionExists(job->server_id(), | |
| 732 (*it)->net_log())); | |
| 733 } | 790 } |
| 734 } | 791 } |
| 735 | 792 |
| 736 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 793 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
| 737 tracked_objects::ScopedTracker tracking_profile2( | 794 tracked_objects::ScopedTracker tracking_profile2( |
| 738 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 795 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 739 "422516 QuicStreamFactory::OnJobComplete2")); | 796 "422516 QuicStreamFactory::OnJobComplete2")); |
| 740 | 797 |
| 741 while (!job_requests_map_[job].empty()) { | 798 while (!job_requests_map_[server_id].empty()) { |
| 742 RequestSet::iterator it = job_requests_map_[job].begin(); | 799 RequestSet::iterator it = job_requests_map_[server_id].begin(); |
| 743 QuicStreamRequest* request = *it; | 800 QuicStreamRequest* request = *it; |
| 744 job_requests_map_[job].erase(it); | 801 job_requests_map_[server_id].erase(it); |
| 745 active_requests_.erase(request); | 802 active_requests_.erase(request); |
| 746 // Even though we're invoking callbacks here, we don't need to worry | 803 // Even though we're invoking callbacks here, we don't need to worry |
| 747 // about |this| being deleted, because the factory is owned by the | 804 // about |this| being deleted, because the factory is owned by the |
| 748 // profile which can not be deleted via callbacks. | 805 // profile which can not be deleted via callbacks. |
| 749 request->OnRequestComplete(rv); | 806 request->OnRequestComplete(rv); |
| 750 } | 807 } |
| 751 | 808 |
| 752 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 809 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
| 753 tracked_objects::ScopedTracker tracking_profile3( | 810 tracked_objects::ScopedTracker tracking_profile3( |
| 754 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 811 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 755 "422516 QuicStreamFactory::OnJobComplete3")); | 812 "422516 QuicStreamFactory::OnJobComplete3")); |
| 756 | 813 |
| 757 active_jobs_.erase(job->server_id()); | 814 for (Job* other_job : active_jobs_[server_id]) { |
| 758 job_requests_map_.erase(job); | 815 if (other_job != job) |
| 759 delete job; | 816 other_job->Cancel(); |
| 760 return; | 817 } |
| 818 |
| 819 STLDeleteElements(&(active_jobs_[server_id])); |
| 820 active_jobs_.erase(server_id); |
| 821 job_requests_map_.erase(server_id); |
| 761 } | 822 } |
| 762 | 823 |
| 763 // Returns a newly created QuicHttpStream owned by the caller, if a | 824 // Returns a newly created QuicHttpStream owned by the caller, if a |
| 764 // matching session already exists. Returns nullptr otherwise. | 825 // matching session already exists. Returns nullptr otherwise. |
| 765 scoped_ptr<QuicHttpStream> QuicStreamFactory::CreateIfSessionExists( | 826 scoped_ptr<QuicHttpStream> QuicStreamFactory::CreateIfSessionExists( |
| 766 const QuicServerId& server_id, | 827 const QuicServerId& server_id, |
| 767 const BoundNetLog& net_log) { | 828 const BoundNetLog& net_log) { |
| 768 if (!HasActiveSession(server_id)) { | 829 if (!HasActiveSession(server_id)) { |
| 769 DVLOG(1) << "No active session"; | 830 DVLOG(1) << "No active session"; |
| 770 return scoped_ptr<QuicHttpStream>(); | 831 return scoped_ptr<QuicHttpStream>(); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 829 | 890 |
| 830 const IpAliasKey ip_alias_key(session->connection()->peer_address(), | 891 const IpAliasKey ip_alias_key(session->connection()->peer_address(), |
| 831 aliases.begin()->is_https()); | 892 aliases.begin()->is_https()); |
| 832 ip_aliases_[ip_alias_key].erase(session); | 893 ip_aliases_[ip_alias_key].erase(session); |
| 833 if (ip_aliases_[ip_alias_key].empty()) { | 894 if (ip_aliases_[ip_alias_key].empty()) { |
| 834 ip_aliases_.erase(ip_alias_key); | 895 ip_aliases_.erase(ip_alias_key); |
| 835 } | 896 } |
| 836 QuicServerId server_id = *aliases.begin(); | 897 QuicServerId server_id = *aliases.begin(); |
| 837 session_aliases_.erase(session); | 898 session_aliases_.erase(session); |
| 838 Job* job = new Job(this, host_resolver_, session, server_id); | 899 Job* job = new Job(this, host_resolver_, session, server_id); |
| 839 active_jobs_[server_id] = job; | 900 active_jobs_[server_id].insert(job); |
| 840 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, | 901 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, |
| 841 base::Unretained(this), job)); | 902 base::Unretained(this), job)); |
| 842 DCHECK_EQ(ERR_IO_PENDING, rv); | 903 DCHECK_EQ(ERR_IO_PENDING, rv); |
| 843 } | 904 } |
| 844 | 905 |
| 845 void QuicStreamFactory::CancelRequest(QuicStreamRequest* request) { | 906 void QuicStreamFactory::CancelRequest(QuicStreamRequest* request) { |
| 846 DCHECK(ContainsKey(active_requests_, request)); | 907 DCHECK(ContainsKey(active_requests_, request)); |
| 847 Job* job = active_requests_[request]; | 908 QuicServerId server_id = active_requests_[request]; |
| 848 job_requests_map_[job].erase(request); | 909 job_requests_map_[server_id].erase(request); |
| 849 active_requests_.erase(request); | 910 active_requests_.erase(request); |
| 850 } | 911 } |
| 851 | 912 |
| 852 void QuicStreamFactory::CloseAllSessions(int error) { | 913 void QuicStreamFactory::CloseAllSessions(int error) { |
| 853 while (!active_sessions_.empty()) { | 914 while (!active_sessions_.empty()) { |
| 854 size_t initial_size = active_sessions_.size(); | 915 size_t initial_size = active_sessions_.size(); |
| 855 active_sessions_.begin()->second->CloseSessionOnError(error); | 916 active_sessions_.begin()->second->CloseSessionOnError(error); |
| 856 DCHECK_NE(initial_size, active_sessions_.size()); | 917 DCHECK_NE(initial_size, active_sessions_.size()); |
| 857 } | 918 } |
| 858 while (!all_sessions_.empty()) { | 919 while (!all_sessions_.empty()) { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 908 // kind of change it is, we have to flush the socket | 969 // kind of change it is, we have to flush the socket |
| 909 // pools to be safe. | 970 // pools to be safe. |
| 910 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); | 971 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); |
| 911 } | 972 } |
| 912 | 973 |
| 913 bool QuicStreamFactory::HasActiveSession( | 974 bool QuicStreamFactory::HasActiveSession( |
| 914 const QuicServerId& server_id) const { | 975 const QuicServerId& server_id) const { |
| 915 return ContainsKey(active_sessions_, server_id); | 976 return ContainsKey(active_sessions_, server_id); |
| 916 } | 977 } |
| 917 | 978 |
| 979 bool QuicStreamFactory::HasActiveJob(const QuicServerId& key) const { |
| 980 return ContainsKey(active_jobs_, key); |
| 981 } |
| 982 |
| 918 int QuicStreamFactory::CreateSession( | 983 int QuicStreamFactory::CreateSession( |
| 919 const QuicServerId& server_id, | 984 const QuicServerId& server_id, |
| 920 scoped_ptr<QuicServerInfo> server_info, | 985 scoped_ptr<QuicServerInfo> server_info, |
| 921 const AddressList& address_list, | 986 const AddressList& address_list, |
| 922 const BoundNetLog& net_log, | 987 const BoundNetLog& net_log, |
| 923 QuicClientSession** session) { | 988 QuicClientSession** session) { |
| 924 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 989 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
| 925 tracked_objects::ScopedTracker tracking_profile1( | 990 tracked_objects::ScopedTracker tracking_profile1( |
| 926 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 991 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 927 "422516 QuicStreamFactory::CreateSession1")); | 992 "422516 QuicStreamFactory::CreateSession1")); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 971 DCHECK_LE(1u, port_suggester->call_count()); | 1036 DCHECK_LE(1u, port_suggester->call_count()); |
| 972 } else { | 1037 } else { |
| 973 DCHECK_EQ(0u, port_suggester->call_count()); | 1038 DCHECK_EQ(0u, port_suggester->call_count()); |
| 974 } | 1039 } |
| 975 | 1040 |
| 976 // We should adaptively set this buffer size, but for now, we'll use a size | 1041 // We should adaptively set this buffer size, but for now, we'll use a size |
| 977 // that is more than large enough for a full receive window, and yet | 1042 // that is more than large enough for a full receive window, and yet |
| 978 // does not consume "too much" memory. If we see bursty packet loss, we may | 1043 // does not consume "too much" memory. If we see bursty packet loss, we may |
| 979 // revisit this setting and test for its impact. | 1044 // revisit this setting and test for its impact. |
| 980 const int32 kSocketBufferSize = | 1045 const int32 kSocketBufferSize = |
| 981 static_cast<int32>(TcpReceiver::kReceiveWindowTCP); | 1046 static_cast<int32>(kDefaultSocketReceiveBuffer); |
| 982 rv = socket->SetReceiveBufferSize(kSocketBufferSize); | 1047 rv = socket->SetReceiveBufferSize(kSocketBufferSize); |
| 983 if (rv != OK) { | 1048 if (rv != OK) { |
| 984 HistogramCreateSessionFailure(CREATION_ERROR_SETTING_RECEIVE_BUFFER); | 1049 HistogramCreateSessionFailure(CREATION_ERROR_SETTING_RECEIVE_BUFFER); |
| 985 return rv; | 1050 return rv; |
| 986 } | 1051 } |
| 987 // Set a buffer large enough to contain the initial CWND's worth of packet | 1052 // Set a buffer large enough to contain the initial CWND's worth of packet |
| 988 // to work around the problem with CHLO packets being sent out with the | 1053 // to work around the problem with CHLO packets being sent out with the |
| 989 // wrong encryption level, when the send buffer is full. | 1054 // wrong encryption level, when the send buffer is full. |
| 990 rv = socket->SetSendBufferSize(kMaxPacketSize * 20); | 1055 rv = socket->SetSendBufferSize(kMaxPacketSize * 20); |
| 991 if (rv != OK) { | 1056 if (rv != OK) { |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1091 "422516 QuicStreamFactory::CreateSession6")); | 1156 "422516 QuicStreamFactory::CreateSession6")); |
| 1092 | 1157 |
| 1093 // Start the disk cache loading so that we can persist the newer QUIC server | 1158 // Start the disk cache loading so that we can persist the newer QUIC server |
| 1094 // information and/or inform the disk cache that we have reused | 1159 // information and/or inform the disk cache that we have reused |
| 1095 // |server_info|. | 1160 // |server_info|. |
| 1096 server_info.reset(quic_server_info_factory_->GetForServer(server_id)); | 1161 server_info.reset(quic_server_info_factory_->GetForServer(server_id)); |
| 1097 server_info->Start(); | 1162 server_info->Start(); |
| 1098 } | 1163 } |
| 1099 | 1164 |
| 1100 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 1165 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
| 1101 tracked_objects::ScopedTracker tracking_profile6( | 1166 tracked_objects::ScopedTracker tracking_profile61( |
| 1102 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1167 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 1103 "422516 QuicStreamFactory::CreateSession61")); | 1168 "422516 QuicStreamFactory::CreateSession61")); |
| 1104 | 1169 |
| 1105 *session = new QuicClientSession( | 1170 *session = new QuicClientSession( |
| 1106 connection, socket.Pass(), this, transport_security_state_, | 1171 connection, socket.Pass(), this, transport_security_state_, |
| 1107 server_info.Pass(), config, | 1172 server_info.Pass(), config, |
| 1108 base::MessageLoop::current()->message_loop_proxy().get(), | 1173 base::MessageLoop::current()->message_loop_proxy().get(), |
| 1109 net_log.net_log()); | 1174 net_log.net_log()); |
| 1175 |
| 1176 // TODO(rtenneti): Remove ScopedTracker below once crbug.com/422516 is fixed. |
| 1177 tracked_objects::ScopedTracker tracking_profile62( |
| 1178 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 1179 "422516 QuicStreamFactory::CreateSession62")); |
| 1180 |
| 1110 all_sessions_[*session] = server_id; // owning pointer | 1181 all_sessions_[*session] = server_id; // owning pointer |
| 1111 | 1182 |
| 1112 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 1183 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
| 1113 tracked_objects::ScopedTracker tracking_profile7( | 1184 tracked_objects::ScopedTracker tracking_profile7( |
| 1114 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1185 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 1115 "422516 QuicStreamFactory::CreateSession7")); | 1186 "422516 QuicStreamFactory::CreateSession7")); |
| 1116 | 1187 |
| 1117 (*session)->InitializeSession(server_id, &crypto_config_, | 1188 (*session)->InitializeSession(server_id, &crypto_config_, |
| 1118 quic_crypto_client_stream_factory_); | 1189 quic_crypto_client_stream_factory_); |
| 1119 bool closed_during_initialize = | 1190 bool closed_during_initialize = |
| 1120 !ContainsKey(all_sessions_, *session) || | 1191 !ContainsKey(all_sessions_, *session) || |
| 1121 !(*session)->connection()->connected(); | 1192 !(*session)->connection()->connected(); |
| 1122 UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.ClosedDuringInitializeSession", | 1193 UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.ClosedDuringInitializeSession", |
| 1123 closed_during_initialize); | 1194 closed_during_initialize); |
| 1124 if (closed_during_initialize) { | 1195 if (closed_during_initialize) { |
| 1125 DLOG(DFATAL) << "Session closed during initialize"; | 1196 DLOG(DFATAL) << "Session closed during initialize"; |
| 1126 *session = nullptr; | 1197 *session = nullptr; |
| 1127 return ERR_CONNECTION_CLOSED; | 1198 return ERR_CONNECTION_CLOSED; |
| 1128 } | 1199 } |
| 1129 return OK; | 1200 return OK; |
| 1130 } | 1201 } |
| 1131 | 1202 |
| 1132 bool QuicStreamFactory::HasActiveJob(const QuicServerId& key) const { | |
| 1133 return ContainsKey(active_jobs_, key); | |
| 1134 } | |
| 1135 | |
| 1136 void QuicStreamFactory::ActivateSession( | 1203 void QuicStreamFactory::ActivateSession( |
| 1137 const QuicServerId& server_id, | 1204 const QuicServerId& server_id, |
| 1138 QuicClientSession* session) { | 1205 QuicClientSession* session) { |
| 1139 DCHECK(!HasActiveSession(server_id)); | 1206 DCHECK(!HasActiveSession(server_id)); |
| 1140 UMA_HISTOGRAM_COUNTS("Net.QuicActiveSessions", active_sessions_.size()); | 1207 UMA_HISTOGRAM_COUNTS("Net.QuicActiveSessions", active_sessions_.size()); |
| 1141 active_sessions_[server_id] = session; | 1208 active_sessions_[server_id] = session; |
| 1142 session_aliases_[session].insert(server_id); | 1209 session_aliases_[session].insert(server_id); |
| 1143 const IpAliasKey ip_alias_key(session->connection()->peer_address(), | 1210 const IpAliasKey ip_alias_key(session->connection()->peer_address(), |
| 1144 server_id.is_https()); | 1211 server_id.is_https()); |
| 1145 DCHECK(!ContainsKey(ip_aliases_[ip_alias_key], session)); | 1212 DCHECK(!ContainsKey(ip_aliases_[ip_alias_key], session)); |
| 1146 ip_aliases_[ip_alias_key].insert(session); | 1213 ip_aliases_[ip_alias_key].insert(session); |
| 1147 } | 1214 } |
| 1148 | 1215 |
| 1149 int64 QuicStreamFactory::GetServerNetworkStatsSmoothedRttInMicroseconds( | 1216 int64 QuicStreamFactory::GetServerNetworkStatsSmoothedRttInMicroseconds( |
| 1150 const QuicServerId& server_id) const { | 1217 const QuicServerId& server_id) const { |
| 1151 if (!http_server_properties_) | 1218 if (!http_server_properties_) |
| 1152 return 0; | 1219 return 0; |
| 1153 const ServerNetworkStats* stats = | 1220 const ServerNetworkStats* stats = |
| 1154 http_server_properties_->GetServerNetworkStats( | 1221 http_server_properties_->GetServerNetworkStats( |
| 1155 server_id.host_port_pair()); | 1222 server_id.host_port_pair()); |
| 1156 if (stats == nullptr) | 1223 if (stats == nullptr) |
| 1157 return 0; | 1224 return 0; |
| 1158 return stats->srtt.InMicroseconds(); | 1225 return stats->srtt.InMicroseconds(); |
| 1159 } | 1226 } |
| 1160 | 1227 |
| 1228 bool QuicStreamFactory::WasAlternateProtocolRecentlyBroken( |
| 1229 const QuicServerId& server_id) const { |
| 1230 return http_server_properties_ && |
| 1231 http_server_properties_->WasAlternateProtocolRecentlyBroken( |
| 1232 server_id.host_port_pair()); |
| 1233 } |
| 1234 |
| 1235 bool QuicStreamFactory::CryptoConfigCacheIsEmpty( |
| 1236 const QuicServerId& server_id) { |
| 1237 QuicCryptoClientConfig::CachedState* cached = |
| 1238 crypto_config_.LookupOrCreate(server_id); |
| 1239 return cached->IsEmpty(); |
| 1240 } |
| 1241 |
| 1161 void QuicStreamFactory::InitializeCachedStateInCryptoConfig( | 1242 void QuicStreamFactory::InitializeCachedStateInCryptoConfig( |
| 1162 const QuicServerId& server_id, | 1243 const QuicServerId& server_id, |
| 1163 const scoped_ptr<QuicServerInfo>& server_info) { | 1244 const scoped_ptr<QuicServerInfo>& server_info) { |
| 1164 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 1245 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
| 1165 tracked_objects::ScopedTracker tracking_profile1( | 1246 tracked_objects::ScopedTracker tracking_profile1( |
| 1166 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1247 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 1167 "422516 QuicStreamFactory::InitializeCachedStateInCryptoConfig1")); | 1248 "422516 QuicStreamFactory::InitializeCachedStateInCryptoConfig1")); |
| 1168 | 1249 |
| 1169 // |server_info| will be NULL, if a non-empty server config already exists in | 1250 // |server_info| will be NULL, if a non-empty server config already exists in |
| 1170 // the memory cache. This is a minor optimization to avoid LookupOrCreate. | 1251 // the memory cache. This is a minor optimization to avoid LookupOrCreate. |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1264 http_server_properties_->ClearAlternateProtocol(server); | 1345 http_server_properties_->ClearAlternateProtocol(server); |
| 1265 http_server_properties_->SetAlternateProtocol( | 1346 http_server_properties_->SetAlternateProtocol( |
| 1266 server, alternate.port, alternate.protocol, 1); | 1347 server, alternate.port, alternate.protocol, 1); |
| 1267 DCHECK_EQ(QUIC, | 1348 DCHECK_EQ(QUIC, |
| 1268 http_server_properties_->GetAlternateProtocol(server).protocol); | 1349 http_server_properties_->GetAlternateProtocol(server).protocol); |
| 1269 DCHECK(http_server_properties_->WasAlternateProtocolRecentlyBroken( | 1350 DCHECK(http_server_properties_->WasAlternateProtocolRecentlyBroken( |
| 1270 server)); | 1351 server)); |
| 1271 } | 1352 } |
| 1272 | 1353 |
| 1273 } // namespace net | 1354 } // namespace net |
| OLD | NEW |