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/chromium/quic_stream_factory.h" | 5 #include "net/quic/chromium/quic_stream_factory.h" |
6 | 6 |
7 #include <openssl/aead.h> | 7 #include <openssl/aead.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <tuple> | 10 #include <tuple> |
(...skipping 22 matching lines...) Expand all Loading... |
33 #include "net/dns/single_request_host_resolver.h" | 33 #include "net/dns/single_request_host_resolver.h" |
34 #include "net/http/bidirectional_stream_impl.h" | 34 #include "net/http/bidirectional_stream_impl.h" |
35 #include "net/quic/chromium/bidirectional_stream_quic_impl.h" | 35 #include "net/quic/chromium/bidirectional_stream_quic_impl.h" |
36 #include "net/quic/chromium/crypto/channel_id_chromium.h" | 36 #include "net/quic/chromium/crypto/channel_id_chromium.h" |
37 #include "net/quic/chromium/crypto/proof_verifier_chromium.h" | 37 #include "net/quic/chromium/crypto/proof_verifier_chromium.h" |
38 #include "net/quic/chromium/port_suggester.h" | 38 #include "net/quic/chromium/port_suggester.h" |
39 #include "net/quic/chromium/quic_chromium_alarm_factory.h" | 39 #include "net/quic/chromium/quic_chromium_alarm_factory.h" |
40 #include "net/quic/chromium/quic_chromium_connection_helper.h" | 40 #include "net/quic/chromium/quic_chromium_connection_helper.h" |
41 #include "net/quic/chromium/quic_chromium_packet_reader.h" | 41 #include "net/quic/chromium/quic_chromium_packet_reader.h" |
42 #include "net/quic/chromium/quic_chromium_packet_writer.h" | 42 #include "net/quic/chromium/quic_chromium_packet_writer.h" |
| 43 #include "net/quic/core/crypto/proof_verifier.h" |
43 #include "net/quic/core/crypto/properties_based_quic_server_info.h" | 44 #include "net/quic/core/crypto/properties_based_quic_server_info.h" |
44 #include "net/quic/core/crypto/quic_random.h" | 45 #include "net/quic/core/crypto/quic_random.h" |
45 #include "net/quic/core/crypto/quic_server_info.h" | 46 #include "net/quic/core/crypto/quic_server_info.h" |
46 #include "net/quic/core/quic_client_promised_info.h" | 47 #include "net/quic/core/quic_client_promised_info.h" |
47 #include "net/quic/core/quic_clock.h" | 48 #include "net/quic/core/quic_clock.h" |
48 #include "net/quic/core/quic_connection.h" | 49 #include "net/quic/core/quic_connection.h" |
49 #include "net/quic/core/quic_crypto_client_stream_factory.h" | 50 #include "net/quic/core/quic_crypto_client_stream_factory.h" |
50 #include "net/quic/core/quic_flags.h" | 51 #include "net/quic/core/quic_flags.h" |
51 #include "net/socket/client_socket_factory.h" | 52 #include "net/socket/client_socket_factory.h" |
52 #include "net/socket/socket_performance_watcher.h" | 53 #include "net/socket/socket_performance_watcher.h" |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 QuicConfig config; | 161 QuicConfig config; |
161 config.SetIdleConnectionStateLifetime( | 162 config.SetIdleConnectionStateLifetime( |
162 QuicTime::Delta::FromSeconds(idle_connection_timeout_seconds), | 163 QuicTime::Delta::FromSeconds(idle_connection_timeout_seconds), |
163 QuicTime::Delta::FromSeconds(idle_connection_timeout_seconds)); | 164 QuicTime::Delta::FromSeconds(idle_connection_timeout_seconds)); |
164 config.SetConnectionOptionsToSend(connection_options); | 165 config.SetConnectionOptionsToSend(connection_options); |
165 return config; | 166 return config; |
166 } | 167 } |
167 | 168 |
168 } // namespace | 169 } // namespace |
169 | 170 |
| 171 // Responsible for verifying the certificates saved in |
| 172 // QuicCryptoClientConfig, and for notifying any associated requests when |
| 173 // complete. Results from cert verification are ignored. |
| 174 class QuicStreamFactory::CertVerifierJob { |
| 175 public: |
| 176 // ProofVerifierCallbackImpl is passed as the callback method to |
| 177 // VerifyCertChain. The ProofVerifier calls this class with the result of cert |
| 178 // verification when verification is performed asynchronously. |
| 179 class ProofVerifierCallbackImpl : public ProofVerifierCallback { |
| 180 public: |
| 181 explicit ProofVerifierCallbackImpl(CertVerifierJob* job) : job_(job) {} |
| 182 |
| 183 ~ProofVerifierCallbackImpl() override {} |
| 184 |
| 185 void Run(bool ok, |
| 186 const std::string& error_details, |
| 187 std::unique_ptr<ProofVerifyDetails>* details) override { |
| 188 if (job_ == nullptr) |
| 189 return; |
| 190 job_->verify_callback_ = nullptr; |
| 191 job_->OnComplete(); |
| 192 } |
| 193 |
| 194 void Cancel() { job_ = nullptr; } |
| 195 |
| 196 private: |
| 197 CertVerifierJob* job_; |
| 198 }; |
| 199 |
| 200 CertVerifierJob(const QuicServerId& server_id, |
| 201 int cert_verify_flags, |
| 202 const BoundNetLog& net_log) |
| 203 : server_id_(server_id), |
| 204 verify_callback_(nullptr), |
| 205 verify_context_(base::WrapUnique( |
| 206 new ProofVerifyContextChromium(cert_verify_flags, net_log))), |
| 207 net_log_(net_log), |
| 208 weak_factory_(this) {} |
| 209 |
| 210 ~CertVerifierJob() { |
| 211 if (verify_callback_) |
| 212 verify_callback_->Cancel(); |
| 213 } |
| 214 |
| 215 // Starts verification of certs cached in the |crypto_config|. |
| 216 QuicAsyncStatus Run(QuicCryptoClientConfig* crypto_config, |
| 217 const CompletionCallback& callback) { |
| 218 QuicCryptoClientConfig::CachedState* cached = |
| 219 crypto_config->LookupOrCreate(server_id_); |
| 220 ProofVerifierCallbackImpl* verify_callback = |
| 221 new ProofVerifierCallbackImpl(this); |
| 222 QuicAsyncStatus status = crypto_config->proof_verifier()->VerifyCertChain( |
| 223 server_id_.host(), cached->certs(), verify_context_.get(), |
| 224 &verify_error_details_, &verify_details_, |
| 225 std::unique_ptr<ProofVerifierCallback>(verify_callback)); |
| 226 if (status == QUIC_PENDING) { |
| 227 verify_callback_ = verify_callback; |
| 228 callback_ = callback; |
| 229 } |
| 230 return status; |
| 231 } |
| 232 |
| 233 void OnComplete() { |
| 234 if (!callback_.is_null()) |
| 235 callback_.Run(OK); |
| 236 } |
| 237 |
| 238 const QuicServerId& server_id() const { return server_id_; } |
| 239 |
| 240 private: |
| 241 QuicServerId server_id_; |
| 242 ProofVerifierCallbackImpl* verify_callback_; |
| 243 std::unique_ptr<ProofVerifyContext> verify_context_; |
| 244 std::unique_ptr<ProofVerifyDetails> verify_details_; |
| 245 std::string verify_error_details_; |
| 246 const BoundNetLog net_log_; |
| 247 CompletionCallback callback_; |
| 248 base::WeakPtrFactory<CertVerifierJob> weak_factory_; |
| 249 |
| 250 DISALLOW_COPY_AND_ASSIGN(CertVerifierJob); |
| 251 }; |
| 252 |
170 // Responsible for creating a new QUIC session to the specified server, and | 253 // Responsible for creating a new QUIC session to the specified server, and |
171 // for notifying any associated requests when complete. | 254 // for notifying any associated requests when complete. |
172 class QuicStreamFactory::Job { | 255 class QuicStreamFactory::Job { |
173 public: | 256 public: |
174 Job(QuicStreamFactory* factory, | 257 Job(QuicStreamFactory* factory, |
175 HostResolver* host_resolver, | 258 HostResolver* host_resolver, |
176 const QuicSessionKey& key, | 259 const QuicSessionKey& key, |
177 bool was_alternative_service_recently_broken, | 260 bool was_alternative_service_recently_broken, |
178 int cert_verify_flags, | 261 int cert_verify_flags, |
179 QuicServerInfo* server_info, | 262 QuicServerInfo* server_info, |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 void QuicStreamFactory::Job::CancelWaitForDataReadyCallback() { | 440 void QuicStreamFactory::Job::CancelWaitForDataReadyCallback() { |
358 // If we are waiting for WaitForDataReadyCallback, then cancel the callback. | 441 // If we are waiting for WaitForDataReadyCallback, then cancel the callback. |
359 if (io_state_ != STATE_LOAD_SERVER_INFO_COMPLETE) | 442 if (io_state_ != STATE_LOAD_SERVER_INFO_COMPLETE) |
360 return; | 443 return; |
361 server_info_->CancelWaitForDataReadyCallback(); | 444 server_info_->CancelWaitForDataReadyCallback(); |
362 OnIOComplete(OK); | 445 OnIOComplete(OK); |
363 } | 446 } |
364 | 447 |
365 int QuicStreamFactory::Job::DoResolveHost() { | 448 int QuicStreamFactory::Job::DoResolveHost() { |
366 // Start loading the data now, and wait for it after we resolve the host. | 449 // Start loading the data now, and wait for it after we resolve the host. |
367 if (server_info_) { | 450 if (server_info_) |
368 server_info_->Start(); | 451 server_info_->Start(); |
369 } | |
370 | 452 |
371 io_state_ = STATE_RESOLVE_HOST_COMPLETE; | 453 io_state_ = STATE_RESOLVE_HOST_COMPLETE; |
372 dns_resolution_start_time_ = base::TimeTicks::Now(); | 454 dns_resolution_start_time_ = base::TimeTicks::Now(); |
373 return host_resolver_.Resolve( | 455 return host_resolver_.Resolve( |
374 HostResolver::RequestInfo(key_.destination()), DEFAULT_PRIORITY, | 456 HostResolver::RequestInfo(key_.destination()), DEFAULT_PRIORITY, |
375 &address_list_, | 457 &address_list_, |
376 base::Bind(&QuicStreamFactory::Job::OnIOComplete, GetWeakPtr()), | 458 base::Bind(&QuicStreamFactory::Job::OnIOComplete, GetWeakPtr()), |
377 net_log_); | 459 net_log_); |
378 } | 460 } |
379 | 461 |
380 int QuicStreamFactory::Job::DoResolveHostComplete(int rv) { | 462 int QuicStreamFactory::Job::DoResolveHostComplete(int rv) { |
381 dns_resolution_end_time_ = base::TimeTicks::Now(); | 463 dns_resolution_end_time_ = base::TimeTicks::Now(); |
382 UMA_HISTOGRAM_TIMES("Net.QuicSession.HostResolutionTime", | 464 UMA_HISTOGRAM_TIMES("Net.QuicSession.HostResolutionTime", |
383 dns_resolution_end_time_ - dns_resolution_start_time_); | 465 dns_resolution_end_time_ - dns_resolution_start_time_); |
384 if (rv != OK) | 466 if (rv != OK) |
385 return rv; | 467 return rv; |
386 | 468 |
387 DCHECK(!factory_->HasActiveSession(key_.server_id())); | 469 DCHECK(!factory_->HasActiveSession(key_.server_id())); |
388 | 470 |
389 // Inform the factory of this resolution, which will set up | 471 // Inform the factory of this resolution, which will set up |
390 // a session alias, if possible. | 472 // a session alias, if possible. |
391 if (factory_->OnResolution(key_, address_list_)) { | 473 if (factory_->OnResolution(key_, address_list_)) |
392 return OK; | 474 return OK; |
393 } | |
394 | 475 |
395 if (server_info_) | 476 if (server_info_) |
396 io_state_ = STATE_LOAD_SERVER_INFO; | 477 io_state_ = STATE_LOAD_SERVER_INFO; |
397 else | 478 else |
398 io_state_ = STATE_CONNECT; | 479 io_state_ = STATE_CONNECT; |
399 return OK; | 480 return OK; |
400 } | 481 } |
401 | 482 |
402 int QuicStreamFactory::Job::DoLoadServerInfo() { | 483 int QuicStreamFactory::Job::DoLoadServerInfo() { |
403 io_state_ = STATE_LOAD_SERVER_INFO_COMPLETE; | 484 io_state_ = STATE_LOAD_SERVER_INFO_COMPLETE; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
462 | 543 |
463 int rv = factory_->CreateSession( | 544 int rv = factory_->CreateSession( |
464 key_, cert_verify_flags_, std::move(server_info_), address_list_, | 545 key_, cert_verify_flags_, std::move(server_info_), address_list_, |
465 dns_resolution_end_time_, net_log_, &session_); | 546 dns_resolution_end_time_, net_log_, &session_); |
466 if (rv != OK) { | 547 if (rv != OK) { |
467 DCHECK(rv != ERR_IO_PENDING); | 548 DCHECK(rv != ERR_IO_PENDING); |
468 DCHECK(!session_); | 549 DCHECK(!session_); |
469 return rv; | 550 return rv; |
470 } | 551 } |
471 | 552 |
472 if (!session_->connection()->connected()) { | 553 if (!session_->connection()->connected()) |
473 return ERR_CONNECTION_CLOSED; | 554 return ERR_CONNECTION_CLOSED; |
474 } | |
475 | 555 |
476 session_->StartReading(); | 556 session_->StartReading(); |
477 if (!session_->connection()->connected()) { | 557 if (!session_->connection()->connected()) |
478 return ERR_QUIC_PROTOCOL_ERROR; | 558 return ERR_QUIC_PROTOCOL_ERROR; |
479 } | |
480 bool require_confirmation = factory_->require_confirmation() || | 559 bool require_confirmation = factory_->require_confirmation() || |
481 was_alternative_service_recently_broken_; | 560 was_alternative_service_recently_broken_; |
482 | 561 |
483 rv = session_->CryptoConnect( | 562 rv = session_->CryptoConnect( |
484 require_confirmation, | 563 require_confirmation, |
485 base::Bind(&QuicStreamFactory::Job::OnIOComplete, GetWeakPtr())); | 564 base::Bind(&QuicStreamFactory::Job::OnIOComplete, GetWeakPtr())); |
486 | 565 |
487 if (!session_->connection()->connected() && | 566 if (!session_->connection()->connected() && |
488 session_->error() == QUIC_PROOF_INVALID) | 567 session_->error() == QUIC_PROOF_INVALID) { |
489 return ERR_QUIC_HANDSHAKE_FAILED; | 568 return ERR_QUIC_HANDSHAKE_FAILED; |
| 569 } |
490 | 570 |
491 return rv; | 571 return rv; |
492 } | 572 } |
493 | 573 |
494 int QuicStreamFactory::Job::DoResumeConnect() { | 574 int QuicStreamFactory::Job::DoResumeConnect() { |
495 io_state_ = STATE_CONNECT_COMPLETE; | 575 io_state_ = STATE_CONNECT_COMPLETE; |
496 | 576 |
497 int rv = session_->ResumeCryptoConnect( | 577 int rv = session_->ResumeCryptoConnect( |
498 base::Bind(&QuicStreamFactory::Job::OnIOComplete, GetWeakPtr())); | 578 base::Bind(&QuicStreamFactory::Job::OnIOComplete, GetWeakPtr())); |
499 | 579 |
500 return rv; | 580 return rv; |
501 } | 581 } |
502 | 582 |
503 int QuicStreamFactory::Job::DoConnectComplete(int rv) { | 583 int QuicStreamFactory::Job::DoConnectComplete(int rv) { |
504 if (session_ && session_->error() == QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) { | 584 if (session_ && session_->error() == QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) { |
505 num_sent_client_hellos_ += session_->GetNumSentClientHellos(); | 585 num_sent_client_hellos_ += session_->GetNumSentClientHellos(); |
506 if (num_sent_client_hellos_ >= QuicCryptoClientStream::kMaxClientHellos) { | 586 if (num_sent_client_hellos_ >= QuicCryptoClientStream::kMaxClientHellos) |
507 return ERR_QUIC_HANDSHAKE_FAILED; | 587 return ERR_QUIC_HANDSHAKE_FAILED; |
508 } | |
509 // The handshake was rejected statelessly, so create another connection | 588 // The handshake was rejected statelessly, so create another connection |
510 // to resume the handshake. | 589 // to resume the handshake. |
511 io_state_ = STATE_CONNECT; | 590 io_state_ = STATE_CONNECT; |
512 return OK; | 591 return OK; |
513 } | 592 } |
514 | 593 |
515 if (rv != OK) | 594 if (rv != OK) |
516 return rv; | 595 return rv; |
517 | 596 |
518 DCHECK(!factory_->HasActiveSession(key_.server_id())); | 597 DCHECK(!factory_->HasActiveSession(key_.server_id())); |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
627 int socket_receive_buffer_size, | 706 int socket_receive_buffer_size, |
628 bool delay_tcp_race, | 707 bool delay_tcp_race, |
629 int max_server_configs_stored_in_properties, | 708 int max_server_configs_stored_in_properties, |
630 bool close_sessions_on_ip_change, | 709 bool close_sessions_on_ip_change, |
631 bool disable_quic_on_timeout_with_open_streams, | 710 bool disable_quic_on_timeout_with_open_streams, |
632 int idle_connection_timeout_seconds, | 711 int idle_connection_timeout_seconds, |
633 bool migrate_sessions_on_network_change, | 712 bool migrate_sessions_on_network_change, |
634 bool migrate_sessions_early, | 713 bool migrate_sessions_early, |
635 bool allow_server_migration, | 714 bool allow_server_migration, |
636 bool force_hol_blocking, | 715 bool force_hol_blocking, |
| 716 bool race_cert_verification, |
637 const QuicTagVector& connection_options, | 717 const QuicTagVector& connection_options, |
638 bool enable_token_binding) | 718 bool enable_token_binding) |
639 : require_confirmation_(true), | 719 : require_confirmation_(true), |
640 net_log_(net_log), | 720 net_log_(net_log), |
641 host_resolver_(host_resolver), | 721 host_resolver_(host_resolver), |
642 client_socket_factory_(client_socket_factory), | 722 client_socket_factory_(client_socket_factory), |
643 http_server_properties_(http_server_properties), | 723 http_server_properties_(http_server_properties), |
644 transport_security_state_(transport_security_state), | 724 transport_security_state_(transport_security_state), |
645 cert_transparency_verifier_(cert_transparency_verifier), | 725 cert_transparency_verifier_(cert_transparency_verifier), |
646 quic_crypto_client_stream_factory_(quic_crypto_client_stream_factory), | 726 quic_crypto_client_stream_factory_(quic_crypto_client_stream_factory), |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
683 yield_after_duration_(QuicTime::Delta::FromMilliseconds( | 763 yield_after_duration_(QuicTime::Delta::FromMilliseconds( |
684 kQuicYieldAfterDurationMilliseconds)), | 764 kQuicYieldAfterDurationMilliseconds)), |
685 close_sessions_on_ip_change_(close_sessions_on_ip_change), | 765 close_sessions_on_ip_change_(close_sessions_on_ip_change), |
686 migrate_sessions_on_network_change_( | 766 migrate_sessions_on_network_change_( |
687 migrate_sessions_on_network_change && | 767 migrate_sessions_on_network_change && |
688 NetworkChangeNotifier::AreNetworkHandlesSupported()), | 768 NetworkChangeNotifier::AreNetworkHandlesSupported()), |
689 migrate_sessions_early_(migrate_sessions_early && | 769 migrate_sessions_early_(migrate_sessions_early && |
690 migrate_sessions_on_network_change_), | 770 migrate_sessions_on_network_change_), |
691 allow_server_migration_(allow_server_migration), | 771 allow_server_migration_(allow_server_migration), |
692 force_hol_blocking_(force_hol_blocking), | 772 force_hol_blocking_(force_hol_blocking), |
| 773 race_cert_verification_(race_cert_verification), |
693 port_seed_(random_generator_->RandUint64()), | 774 port_seed_(random_generator_->RandUint64()), |
694 check_persisted_supports_quic_(true), | 775 check_persisted_supports_quic_(true), |
695 has_initialized_data_(false), | 776 has_initialized_data_(false), |
696 num_push_streams_created_(0), | 777 num_push_streams_created_(0), |
697 status_(OPEN), | 778 status_(OPEN), |
698 task_runner_(nullptr), | 779 task_runner_(nullptr), |
699 ssl_config_service_(ssl_config_service), | 780 ssl_config_service_(ssl_config_service), |
700 weak_factory_(this) { | 781 weak_factory_(this) { |
701 if (ssl_config_service_.get()) | 782 if (ssl_config_service_.get()) |
702 ssl_config_service_->AddObserver(this); | 783 ssl_config_service_->AddObserver(this); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
750 CloseAllSessions(ERR_ABORTED, QUIC_CONNECTION_CANCELLED); | 831 CloseAllSessions(ERR_ABORTED, QUIC_CONNECTION_CANCELLED); |
751 while (!all_sessions_.empty()) { | 832 while (!all_sessions_.empty()) { |
752 delete all_sessions_.begin()->first; | 833 delete all_sessions_.begin()->first; |
753 all_sessions_.erase(all_sessions_.begin()); | 834 all_sessions_.erase(all_sessions_.begin()); |
754 } | 835 } |
755 while (!active_jobs_.empty()) { | 836 while (!active_jobs_.empty()) { |
756 const QuicServerId server_id = active_jobs_.begin()->first; | 837 const QuicServerId server_id = active_jobs_.begin()->first; |
757 STLDeleteElements(&(active_jobs_[server_id])); | 838 STLDeleteElements(&(active_jobs_[server_id])); |
758 active_jobs_.erase(server_id); | 839 active_jobs_.erase(server_id); |
759 } | 840 } |
| 841 while (!active_cert_verifier_jobs_.empty()) |
| 842 active_cert_verifier_jobs_.erase(active_cert_verifier_jobs_.begin()); |
760 if (ssl_config_service_.get()) | 843 if (ssl_config_service_.get()) |
761 ssl_config_service_->RemoveObserver(this); | 844 ssl_config_service_->RemoveObserver(this); |
762 if (migrate_sessions_on_network_change_) { | 845 if (migrate_sessions_on_network_change_) { |
763 NetworkChangeNotifier::RemoveNetworkObserver(this); | 846 NetworkChangeNotifier::RemoveNetworkObserver(this); |
764 } else if (close_sessions_on_ip_change_) { | 847 } else if (close_sessions_on_ip_change_) { |
765 NetworkChangeNotifier::RemoveIPAddressObserver(this); | 848 NetworkChangeNotifier::RemoveIPAddressObserver(this); |
766 } | 849 } |
767 } | 850 } |
768 | 851 |
769 void QuicStreamFactory::set_require_confirmation(bool require_confirmation) { | 852 void QuicStreamFactory::set_require_confirmation(bool require_confirmation) { |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
881 | 964 |
882 QuicServerInfo* quic_server_info = nullptr; | 965 QuicServerInfo* quic_server_info = nullptr; |
883 if (quic_server_info_factory_.get()) { | 966 if (quic_server_info_factory_.get()) { |
884 bool load_from_disk_cache = !disable_disk_cache_; | 967 bool load_from_disk_cache = !disable_disk_cache_; |
885 MaybeInitialize(); | 968 MaybeInitialize(); |
886 if (!ContainsKey(quic_supported_servers_at_startup_, destination)) { | 969 if (!ContainsKey(quic_supported_servers_at_startup_, destination)) { |
887 // If there is no entry for QUIC, consider that as a new server and | 970 // If there is no entry for QUIC, consider that as a new server and |
888 // don't wait for Cache thread to load the data for that server. | 971 // don't wait for Cache thread to load the data for that server. |
889 load_from_disk_cache = false; | 972 load_from_disk_cache = false; |
890 } | 973 } |
891 if (load_from_disk_cache && CryptoConfigCacheIsEmpty(server_id)) { | 974 if (load_from_disk_cache && CryptoConfigCacheIsEmpty(server_id)) |
892 quic_server_info = quic_server_info_factory_->GetForServer(server_id); | 975 quic_server_info = quic_server_info_factory_->GetForServer(server_id); |
893 } | |
894 } | 976 } |
895 | 977 |
| 978 ignore_result(StartCertVerifyJob(server_id, cert_verify_flags, net_log)); |
| 979 |
896 QuicSessionKey key(destination, server_id); | 980 QuicSessionKey key(destination, server_id); |
897 std::unique_ptr<Job> job( | 981 std::unique_ptr<Job> job( |
898 new Job(this, host_resolver_, key, WasQuicRecentlyBroken(server_id), | 982 new Job(this, host_resolver_, key, WasQuicRecentlyBroken(server_id), |
899 cert_verify_flags, quic_server_info, net_log)); | 983 cert_verify_flags, quic_server_info, net_log)); |
900 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, | 984 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, |
901 base::Unretained(this), job.get())); | 985 base::Unretained(this), job.get())); |
902 if (rv == ERR_IO_PENDING) { | 986 if (rv == ERR_IO_PENDING) { |
903 active_requests_[request] = server_id; | 987 active_requests_[request] = server_id; |
904 job_requests_map_[server_id].insert(request); | 988 job_requests_map_[server_id].insert(request); |
905 active_jobs_[server_id].insert(job.release()); | 989 active_jobs_[server_id].insert(job.release()); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
946 active_jobs_[key.server_id()].insert(aux_job); | 1030 active_jobs_[key.server_id()].insert(aux_job); |
947 task_runner_->PostTask(FROM_HERE, | 1031 task_runner_->PostTask(FROM_HERE, |
948 base::Bind(&QuicStreamFactory::Job::RunAuxilaryJob, | 1032 base::Bind(&QuicStreamFactory::Job::RunAuxilaryJob, |
949 aux_job->GetWeakPtr())); | 1033 aux_job->GetWeakPtr())); |
950 } | 1034 } |
951 | 1035 |
952 bool QuicStreamFactory::OnResolution(const QuicSessionKey& key, | 1036 bool QuicStreamFactory::OnResolution(const QuicSessionKey& key, |
953 const AddressList& address_list) { | 1037 const AddressList& address_list) { |
954 const QuicServerId& server_id(key.server_id()); | 1038 const QuicServerId& server_id(key.server_id()); |
955 DCHECK(!HasActiveSession(server_id)); | 1039 DCHECK(!HasActiveSession(server_id)); |
956 if (disable_connection_pooling_) { | 1040 if (disable_connection_pooling_) |
957 return false; | 1041 return false; |
958 } | |
959 for (const IPEndPoint& address : address_list) { | 1042 for (const IPEndPoint& address : address_list) { |
960 if (!ContainsKey(ip_aliases_, address)) | 1043 if (!ContainsKey(ip_aliases_, address)) |
961 continue; | 1044 continue; |
962 | 1045 |
963 const SessionSet& sessions = ip_aliases_[address]; | 1046 const SessionSet& sessions = ip_aliases_[address]; |
964 for (QuicChromiumClientSession* session : sessions) { | 1047 for (QuicChromiumClientSession* session : sessions) { |
965 if (!session->CanPool(server_id.host(), server_id.privacy_mode())) | 1048 if (!session->CanPool(server_id.host(), server_id.privacy_mode())) |
966 continue; | 1049 continue; |
967 active_sessions_[server_id] = session; | 1050 active_sessions_[server_id] = session; |
968 session_aliases_[session].insert(key); | 1051 session_aliases_[session].insert(key); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1018 for (Job* other_job : active_jobs_[server_id]) { | 1101 for (Job* other_job : active_jobs_[server_id]) { |
1019 if (other_job != job) | 1102 if (other_job != job) |
1020 other_job->Cancel(); | 1103 other_job->Cancel(); |
1021 } | 1104 } |
1022 | 1105 |
1023 STLDeleteElements(&(active_jobs_[server_id])); | 1106 STLDeleteElements(&(active_jobs_[server_id])); |
1024 active_jobs_.erase(server_id); | 1107 active_jobs_.erase(server_id); |
1025 job_requests_map_.erase(server_id); | 1108 job_requests_map_.erase(server_id); |
1026 } | 1109 } |
1027 | 1110 |
| 1111 void QuicStreamFactory::OnCertVerifyJobComplete(CertVerifierJob* job, int rv) { |
| 1112 active_cert_verifier_jobs_.erase(job->server_id()); |
| 1113 } |
| 1114 |
1028 std::unique_ptr<QuicHttpStream> QuicStreamFactory::CreateFromSession( | 1115 std::unique_ptr<QuicHttpStream> QuicStreamFactory::CreateFromSession( |
1029 QuicChromiumClientSession* session) { | 1116 QuicChromiumClientSession* session) { |
1030 return std::unique_ptr<QuicHttpStream>( | 1117 return std::unique_ptr<QuicHttpStream>( |
1031 new QuicHttpStream(session->GetWeakPtr())); | 1118 new QuicHttpStream(session->GetWeakPtr())); |
1032 } | 1119 } |
1033 | 1120 |
1034 QuicChromiumClientSession::QuicDisabledReason | 1121 QuicChromiumClientSession::QuicDisabledReason |
1035 QuicStreamFactory::QuicDisabledReason(uint16_t port) const { | 1122 QuicStreamFactory::QuicDisabledReason(uint16_t port) const { |
1036 if (max_number_of_lossy_connections_ > 0 && | 1123 if (max_number_of_lossy_connections_ > 0 && |
1037 number_of_lossy_connections_.find(port) != | 1124 number_of_lossy_connections_.find(port) != |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1133 | 1220 |
1134 void QuicStreamFactory::OnSessionGoingAway(QuicChromiumClientSession* session) { | 1221 void QuicStreamFactory::OnSessionGoingAway(QuicChromiumClientSession* session) { |
1135 const AliasSet& aliases = session_aliases_[session]; | 1222 const AliasSet& aliases = session_aliases_[session]; |
1136 for (AliasSet::const_iterator it = aliases.begin(); it != aliases.end(); | 1223 for (AliasSet::const_iterator it = aliases.begin(); it != aliases.end(); |
1137 ++it) { | 1224 ++it) { |
1138 const QuicServerId& server_id = it->server_id(); | 1225 const QuicServerId& server_id = it->server_id(); |
1139 DCHECK(active_sessions_.count(server_id)); | 1226 DCHECK(active_sessions_.count(server_id)); |
1140 DCHECK_EQ(session, active_sessions_[server_id]); | 1227 DCHECK_EQ(session, active_sessions_[server_id]); |
1141 // Track sessions which have recently gone away so that we can disable | 1228 // Track sessions which have recently gone away so that we can disable |
1142 // port suggestions. | 1229 // port suggestions. |
1143 if (session->goaway_received()) { | 1230 if (session->goaway_received()) |
1144 gone_away_aliases_.insert(*it); | 1231 gone_away_aliases_.insert(*it); |
1145 } | |
1146 | 1232 |
1147 active_sessions_.erase(server_id); | 1233 active_sessions_.erase(server_id); |
1148 ProcessGoingAwaySession(session, server_id, true); | 1234 ProcessGoingAwaySession(session, server_id, true); |
1149 } | 1235 } |
1150 ProcessGoingAwaySession(session, all_sessions_[session].server_id(), false); | 1236 ProcessGoingAwaySession(session, all_sessions_[session].server_id(), false); |
1151 if (!aliases.empty()) { | 1237 if (!aliases.empty()) { |
1152 const IPEndPoint peer_address = session->connection()->peer_address(); | 1238 const IPEndPoint peer_address = session->connection()->peer_address(); |
1153 ip_aliases_[peer_address].erase(session); | 1239 ip_aliases_[peer_address].erase(session); |
1154 if (ip_aliases_[peer_address].empty()) { | 1240 if (ip_aliases_[peer_address].empty()) |
1155 ip_aliases_.erase(peer_address); | 1241 ip_aliases_.erase(peer_address); |
1156 } | |
1157 } | 1242 } |
1158 session_aliases_.erase(session); | 1243 session_aliases_.erase(session); |
1159 } | 1244 } |
1160 | 1245 |
1161 void QuicStreamFactory::MaybeDisableQuic(QuicChromiumClientSession* session) { | 1246 void QuicStreamFactory::MaybeDisableQuic(QuicChromiumClientSession* session) { |
1162 DCHECK(session); | 1247 DCHECK(session); |
1163 uint16_t port = session->server_id().port(); | 1248 uint16_t port = session->server_id().port(); |
1164 if (IsQuicDisabled(port)) | 1249 if (IsQuicDisabled(port)) |
1165 return; | 1250 return; |
1166 | 1251 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1251 MaybeDisableQuic(session); | 1336 MaybeDisableQuic(session); |
1252 OnSessionGoingAway(session); | 1337 OnSessionGoingAway(session); |
1253 delete session; | 1338 delete session; |
1254 all_sessions_.erase(session); | 1339 all_sessions_.erase(session); |
1255 } | 1340 } |
1256 | 1341 |
1257 void QuicStreamFactory::OnSessionConnectTimeout( | 1342 void QuicStreamFactory::OnSessionConnectTimeout( |
1258 QuicChromiumClientSession* session) { | 1343 QuicChromiumClientSession* session) { |
1259 const AliasSet& aliases = session_aliases_[session]; | 1344 const AliasSet& aliases = session_aliases_[session]; |
1260 | 1345 |
1261 if (aliases.empty()) { | 1346 if (aliases.empty()) |
1262 return; | 1347 return; |
1263 } | |
1264 | 1348 |
1265 for (const QuicSessionKey& key : aliases) { | 1349 for (const QuicSessionKey& key : aliases) { |
1266 const QuicServerId& server_id = key.server_id(); | 1350 const QuicServerId& server_id = key.server_id(); |
1267 SessionMap::iterator session_it = active_sessions_.find(server_id); | 1351 SessionMap::iterator session_it = active_sessions_.find(server_id); |
1268 DCHECK(session_it != active_sessions_.end()); | 1352 DCHECK(session_it != active_sessions_.end()); |
1269 DCHECK_EQ(session, session_it->second); | 1353 DCHECK_EQ(session, session_it->second); |
1270 active_sessions_.erase(session_it); | 1354 active_sessions_.erase(session_it); |
1271 } | 1355 } |
1272 | 1356 |
1273 const IPEndPoint peer_address = session->connection()->peer_address(); | 1357 const IPEndPoint peer_address = session->connection()->peer_address(); |
1274 ip_aliases_[peer_address].erase(session); | 1358 ip_aliases_[peer_address].erase(session); |
1275 if (ip_aliases_[peer_address].empty()) { | 1359 if (ip_aliases_[peer_address].empty()) |
1276 ip_aliases_.erase(peer_address); | 1360 ip_aliases_.erase(peer_address); |
1277 } | |
1278 QuicSessionKey key = *aliases.begin(); | 1361 QuicSessionKey key = *aliases.begin(); |
1279 session_aliases_.erase(session); | 1362 session_aliases_.erase(session); |
1280 Job* job = new Job(this, host_resolver_, session, key); | 1363 Job* job = new Job(this, host_resolver_, session, key); |
1281 active_jobs_[key.server_id()].insert(job); | 1364 active_jobs_[key.server_id()].insert(job); |
1282 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, | 1365 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, |
1283 base::Unretained(this), job)); | 1366 base::Unretained(this), job)); |
1284 DCHECK_EQ(ERR_IO_PENDING, rv); | 1367 DCHECK_EQ(ERR_IO_PENDING, rv); |
1285 } | 1368 } |
1286 | 1369 |
1287 void QuicStreamFactory::CancelRequest(QuicStreamRequest* request) { | 1370 void QuicStreamFactory::CancelRequest(QuicStreamRequest* request) { |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1363 MaybeMigrateOrCloseSessions(network, /*force_close=*/false, | 1446 MaybeMigrateOrCloseSessions(network, /*force_close=*/false, |
1364 scoped_event_log.net_log()); | 1447 scoped_event_log.net_log()); |
1365 } | 1448 } |
1366 | 1449 |
1367 NetworkHandle QuicStreamFactory::FindAlternateNetwork( | 1450 NetworkHandle QuicStreamFactory::FindAlternateNetwork( |
1368 NetworkHandle old_network) { | 1451 NetworkHandle old_network) { |
1369 // Find a new network that sessions bound to |old_network| can be migrated to. | 1452 // Find a new network that sessions bound to |old_network| can be migrated to. |
1370 NetworkChangeNotifier::NetworkList network_list; | 1453 NetworkChangeNotifier::NetworkList network_list; |
1371 NetworkChangeNotifier::GetConnectedNetworks(&network_list); | 1454 NetworkChangeNotifier::GetConnectedNetworks(&network_list); |
1372 for (NetworkHandle new_network : network_list) { | 1455 for (NetworkHandle new_network : network_list) { |
1373 if (new_network != old_network) { | 1456 if (new_network != old_network) |
1374 return new_network; | 1457 return new_network; |
1375 } | |
1376 } | 1458 } |
1377 return NetworkChangeNotifier::kInvalidNetworkHandle; | 1459 return NetworkChangeNotifier::kInvalidNetworkHandle; |
1378 } | 1460 } |
1379 | 1461 |
1380 void QuicStreamFactory::MaybeMigrateOrCloseSessions( | 1462 void QuicStreamFactory::MaybeMigrateOrCloseSessions( |
1381 NetworkHandle network, | 1463 NetworkHandle network, |
1382 bool force_close, | 1464 bool force_close, |
1383 const BoundNetLog& bound_net_log) { | 1465 const BoundNetLog& bound_net_log) { |
1384 DCHECK_NE(NetworkChangeNotifier::kInvalidNetworkHandle, network); | 1466 DCHECK_NE(NetworkChangeNotifier::kInvalidNetworkHandle, network); |
1385 NetworkHandle new_network = FindAlternateNetwork(network); | 1467 NetworkHandle new_network = FindAlternateNetwork(network); |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1573 // TODO(rtenneti): crbug.com/498823 - delete active_sessions_.empty() check. | 1655 // TODO(rtenneti): crbug.com/498823 - delete active_sessions_.empty() check. |
1574 if (active_sessions_.empty()) | 1656 if (active_sessions_.empty()) |
1575 return false; | 1657 return false; |
1576 return ContainsKey(active_sessions_, server_id); | 1658 return ContainsKey(active_sessions_, server_id); |
1577 } | 1659 } |
1578 | 1660 |
1579 bool QuicStreamFactory::HasActiveJob(const QuicServerId& server_id) const { | 1661 bool QuicStreamFactory::HasActiveJob(const QuicServerId& server_id) const { |
1580 return ContainsKey(active_jobs_, server_id); | 1662 return ContainsKey(active_jobs_, server_id); |
1581 } | 1663 } |
1582 | 1664 |
| 1665 bool QuicStreamFactory::HasActiveCertVerifierJob( |
| 1666 const QuicServerId& server_id) const { |
| 1667 return ContainsKey(active_cert_verifier_jobs_, server_id); |
| 1668 } |
| 1669 |
1583 int QuicStreamFactory::ConfigureSocket(DatagramClientSocket* socket, | 1670 int QuicStreamFactory::ConfigureSocket(DatagramClientSocket* socket, |
1584 IPEndPoint addr, | 1671 IPEndPoint addr, |
1585 NetworkHandle network) { | 1672 NetworkHandle network) { |
1586 if (enable_non_blocking_io_ && | 1673 if (enable_non_blocking_io_ && |
1587 client_socket_factory_ == ClientSocketFactory::GetDefaultFactory()) { | 1674 client_socket_factory_ == ClientSocketFactory::GetDefaultFactory()) { |
1588 #if defined(OS_WIN) | 1675 #if defined(OS_WIN) |
1589 static_cast<UDPClientSocket*>(socket)->UseNonBlockingIO(); | 1676 static_cast<UDPClientSocket*>(socket)->UseNonBlockingIO(); |
1590 #endif | 1677 #endif |
1591 } | 1678 } |
1592 | 1679 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1661 DatagramSocket::DEFAULT_BIND; // Use OS to randomize. | 1748 DatagramSocket::DEFAULT_BIND; // Use OS to randomize. |
1662 | 1749 |
1663 std::unique_ptr<DatagramClientSocket> socket( | 1750 std::unique_ptr<DatagramClientSocket> socket( |
1664 client_socket_factory_->CreateDatagramClientSocket( | 1751 client_socket_factory_->CreateDatagramClientSocket( |
1665 bind_type, base::Bind(&PortSuggester::SuggestPort, port_suggester), | 1752 bind_type, base::Bind(&PortSuggester::SuggestPort, port_suggester), |
1666 net_log.net_log(), net_log.source())); | 1753 net_log.net_log(), net_log.source())); |
1667 | 1754 |
1668 // Passing in kInvalidNetworkHandle binds socket to default network. | 1755 // Passing in kInvalidNetworkHandle binds socket to default network. |
1669 int rv = ConfigureSocket(socket.get(), addr, | 1756 int rv = ConfigureSocket(socket.get(), addr, |
1670 NetworkChangeNotifier::kInvalidNetworkHandle); | 1757 NetworkChangeNotifier::kInvalidNetworkHandle); |
1671 if (rv != OK) { | 1758 if (rv != OK) |
1672 return rv; | 1759 return rv; |
1673 } | |
1674 | 1760 |
1675 if (enable_port_selection) { | 1761 if (enable_port_selection) |
1676 DCHECK_LE(1u, port_suggester->call_count()); | 1762 DCHECK_LE(1u, port_suggester->call_count()); |
1677 } else { | 1763 else |
1678 DCHECK_EQ(0u, port_suggester->call_count()); | 1764 DCHECK_EQ(0u, port_suggester->call_count()); |
1679 } | |
1680 | 1765 |
1681 if (!helper_.get()) { | 1766 if (!helper_.get()) { |
1682 helper_.reset( | 1767 helper_.reset( |
1683 new QuicChromiumConnectionHelper(clock_.get(), random_generator_)); | 1768 new QuicChromiumConnectionHelper(clock_.get(), random_generator_)); |
1684 } | 1769 } |
1685 | 1770 |
1686 if (!alarm_factory_.get()) { | 1771 if (!alarm_factory_.get()) { |
1687 alarm_factory_.reset(new QuicChromiumAlarmFactory( | 1772 alarm_factory_.reset(new QuicChromiumAlarmFactory( |
1688 base::ThreadTaskRunnerHandle::Get().get(), clock_.get())); | 1773 base::ThreadTaskRunnerHandle::Get().get(), clock_.get())); |
1689 } | 1774 } |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1783 alternative_service); | 1868 alternative_service); |
1784 } | 1869 } |
1785 | 1870 |
1786 bool QuicStreamFactory::CryptoConfigCacheIsEmpty( | 1871 bool QuicStreamFactory::CryptoConfigCacheIsEmpty( |
1787 const QuicServerId& server_id) { | 1872 const QuicServerId& server_id) { |
1788 QuicCryptoClientConfig::CachedState* cached = | 1873 QuicCryptoClientConfig::CachedState* cached = |
1789 crypto_config_.LookupOrCreate(server_id); | 1874 crypto_config_.LookupOrCreate(server_id); |
1790 return cached->IsEmpty(); | 1875 return cached->IsEmpty(); |
1791 } | 1876 } |
1792 | 1877 |
| 1878 QuicAsyncStatus QuicStreamFactory::StartCertVerifyJob( |
| 1879 const QuicServerId& server_id, |
| 1880 int cert_verify_flags, |
| 1881 const BoundNetLog& net_log) { |
| 1882 if (!race_cert_verification_) |
| 1883 return QUIC_FAILURE; |
| 1884 QuicCryptoClientConfig::CachedState* cached = |
| 1885 crypto_config_.LookupOrCreate(server_id); |
| 1886 if (!cached || cached->certs().empty() || |
| 1887 HasActiveCertVerifierJob(server_id)) { |
| 1888 return QUIC_FAILURE; |
| 1889 } |
| 1890 std::unique_ptr<CertVerifierJob> cert_verifier_job( |
| 1891 new CertVerifierJob(server_id, cert_verify_flags, net_log)); |
| 1892 QuicAsyncStatus status = cert_verifier_job->Run( |
| 1893 &crypto_config_, |
| 1894 base::Bind(&QuicStreamFactory::OnCertVerifyJobComplete, |
| 1895 base::Unretained(this), cert_verifier_job.get())); |
| 1896 if (status == QUIC_PENDING) |
| 1897 active_cert_verifier_jobs_[server_id] = std::move(cert_verifier_job); |
| 1898 return status; |
| 1899 } |
| 1900 |
1793 void QuicStreamFactory::InitializeCachedStateInCryptoConfig( | 1901 void QuicStreamFactory::InitializeCachedStateInCryptoConfig( |
1794 const QuicServerId& server_id, | 1902 const QuicServerId& server_id, |
1795 const std::unique_ptr<QuicServerInfo>& server_info, | 1903 const std::unique_ptr<QuicServerInfo>& server_info, |
1796 QuicConnectionId* connection_id) { | 1904 QuicConnectionId* connection_id) { |
1797 QuicCryptoClientConfig::CachedState* cached = | 1905 QuicCryptoClientConfig::CachedState* cached = |
1798 crypto_config_.LookupOrCreate(server_id); | 1906 crypto_config_.LookupOrCreate(server_id); |
1799 if (cached->has_server_designated_connection_id()) | 1907 if (cached->has_server_designated_connection_id()) |
1800 *connection_id = cached->GetNextServerDesignatedConnectionId(); | 1908 *connection_id = cached->GetNextServerDesignatedConnectionId(); |
1801 | 1909 |
1802 if (!cached->IsEmpty()) | 1910 if (!cached->IsEmpty()) |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1904 // Since the session was active, there's no longer an | 2012 // Since the session was active, there's no longer an |
1905 // HttpStreamFactoryImpl::Job running which can mark it broken, unless the TCP | 2013 // HttpStreamFactoryImpl::Job running which can mark it broken, unless the TCP |
1906 // job also fails. So to avoid not using QUIC when we otherwise could, we mark | 2014 // job also fails. So to avoid not using QUIC when we otherwise could, we mark |
1907 // it as recently broken, which means that 0-RTT will be disabled but we'll | 2015 // it as recently broken, which means that 0-RTT will be disabled but we'll |
1908 // still race. | 2016 // still race. |
1909 http_server_properties_->MarkAlternativeServiceRecentlyBroken( | 2017 http_server_properties_->MarkAlternativeServiceRecentlyBroken( |
1910 alternative_service); | 2018 alternative_service); |
1911 } | 2019 } |
1912 | 2020 |
1913 } // namespace net | 2021 } // namespace net |
OLD | NEW |