Chromium Code Reviews| 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/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/message_loop/message_loop_proxy.h" | 10 #include "base/message_loop/message_loop_proxy.h" |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 92 // Responsible for creating a new QUIC session to the specified server, and | 92 // Responsible for creating a new QUIC session to the specified server, and |
| 93 // for notifying any associated requests when complete. | 93 // for notifying any associated requests when complete. |
| 94 class QuicStreamFactory::Job { | 94 class QuicStreamFactory::Job { |
| 95 public: | 95 public: |
| 96 Job(QuicStreamFactory* factory, | 96 Job(QuicStreamFactory* factory, |
| 97 HostResolver* host_resolver, | 97 HostResolver* host_resolver, |
| 98 const HostPortProxyPair& host_port_proxy_pair, | 98 const HostPortProxyPair& host_port_proxy_pair, |
| 99 bool is_https, | 99 bool is_https, |
| 100 base::StringPiece method, | 100 base::StringPiece method, |
| 101 CertVerifier* cert_verifier, | 101 CertVerifier* cert_verifier, |
| 102 QuicServerInfo* server_info, | |
| 102 const BoundNetLog& net_log); | 103 const BoundNetLog& net_log); |
| 103 | 104 |
| 104 ~Job(); | 105 ~Job(); |
| 105 | 106 |
| 106 int Run(const CompletionCallback& callback); | 107 int Run(const CompletionCallback& callback); |
| 107 | 108 |
| 108 int DoLoop(int rv); | 109 int DoLoop(int rv); |
| 110 int DoLoadServerInfo(); | |
| 111 int DoLoadServerInfoComplete(int rv); | |
| 109 int DoResolveHost(); | 112 int DoResolveHost(); |
| 110 int DoResolveHostComplete(int rv); | 113 int DoResolveHostComplete(int rv); |
| 111 int DoConnect(); | 114 int DoConnect(); |
| 112 int DoConnectComplete(int rv); | 115 int DoConnectComplete(int rv); |
| 113 | 116 |
| 114 void OnIOComplete(int rv); | 117 void OnIOComplete(int rv); |
| 115 | 118 |
| 116 CompletionCallback callback() { | 119 CompletionCallback callback() { |
| 117 return callback_; | 120 return callback_; |
| 118 } | 121 } |
| 119 | 122 |
| 120 const SessionKey session_key() const { | 123 const SessionKey session_key() const { |
| 121 return session_key_; | 124 return session_key_; |
| 122 } | 125 } |
| 123 | 126 |
| 124 private: | 127 private: |
| 125 enum IoState { | 128 enum IoState { |
| 126 STATE_NONE, | 129 STATE_NONE, |
| 130 STATE_LOAD_SERVER_INFO, | |
| 131 STATE_LOAD_SERVER_INFO_COMPLETE, | |
| 127 STATE_RESOLVE_HOST, | 132 STATE_RESOLVE_HOST, |
| 128 STATE_RESOLVE_HOST_COMPLETE, | 133 STATE_RESOLVE_HOST_COMPLETE, |
| 129 STATE_CONNECT, | 134 STATE_CONNECT, |
| 130 STATE_CONNECT_COMPLETE, | 135 STATE_CONNECT_COMPLETE, |
| 131 }; | 136 }; |
| 132 IoState io_state_; | 137 IoState io_state_; |
| 133 | 138 |
| 134 QuicStreamFactory* factory_; | 139 QuicStreamFactory* factory_; |
| 135 SingleRequestHostResolver host_resolver_; | 140 SingleRequestHostResolver host_resolver_; |
| 136 bool is_https_; | 141 bool is_https_; |
| 137 SessionKey session_key_; | 142 SessionKey session_key_; |
| 138 bool is_post_; | 143 bool is_post_; |
| 139 CertVerifier* cert_verifier_; | 144 CertVerifier* cert_verifier_; |
| 145 scoped_ptr<QuicServerInfo> server_info_; | |
| 140 const BoundNetLog net_log_; | 146 const BoundNetLog net_log_; |
| 141 QuicClientSession* session_; | 147 QuicClientSession* session_; |
| 142 CompletionCallback callback_; | 148 CompletionCallback callback_; |
| 143 AddressList address_list_; | 149 AddressList address_list_; |
| 144 DISALLOW_COPY_AND_ASSIGN(Job); | 150 DISALLOW_COPY_AND_ASSIGN(Job); |
| 145 }; | 151 }; |
| 146 | 152 |
| 147 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, | 153 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, |
| 148 HostResolver* host_resolver, | 154 HostResolver* host_resolver, |
| 149 const HostPortProxyPair& host_port_proxy_pair, | 155 const HostPortProxyPair& host_port_proxy_pair, |
| 150 bool is_https, | 156 bool is_https, |
| 151 base::StringPiece method, | 157 base::StringPiece method, |
| 152 CertVerifier* cert_verifier, | 158 CertVerifier* cert_verifier, |
| 159 QuicServerInfo* server_info, | |
| 153 const BoundNetLog& net_log) | 160 const BoundNetLog& net_log) |
| 154 : factory_(factory), | 161 : factory_(factory), |
| 155 host_resolver_(host_resolver), | 162 host_resolver_(host_resolver), |
| 156 is_https_(is_https), | 163 is_https_(is_https), |
| 157 session_key_(host_port_proxy_pair, is_https), | 164 session_key_(host_port_proxy_pair, is_https), |
| 158 is_post_(method == "POST"), | 165 is_post_(method == "POST"), |
| 159 cert_verifier_(cert_verifier), | 166 cert_verifier_(cert_verifier), |
| 167 server_info_(server_info), | |
| 160 net_log_(net_log), | 168 net_log_(net_log), |
| 161 session_(NULL) {} | 169 session_(NULL) {} |
| 162 | 170 |
| 163 QuicStreamFactory::Job::~Job() { | 171 QuicStreamFactory::Job::~Job() { |
| 164 } | 172 } |
| 165 | 173 |
| 166 int QuicStreamFactory::Job::Run(const CompletionCallback& callback) { | 174 int QuicStreamFactory::Job::Run(const CompletionCallback& callback) { |
| 167 io_state_ = STATE_RESOLVE_HOST; | 175 io_state_ = STATE_RESOLVE_HOST; |
|
ramant (doing other things)
2014/03/12 00:50:56
nit: should we initialize the state to STATE_LOAD_
Ryan Hamilton
2014/03/12 04:00:45
Ugh! Yes, you're right. I need to write some tes
| |
| 168 int rv = DoLoop(OK); | 176 int rv = DoLoop(OK); |
| 169 if (rv == ERR_IO_PENDING) | 177 if (rv == ERR_IO_PENDING) |
| 170 callback_ = callback; | 178 callback_ = callback; |
| 171 | 179 |
| 172 return rv > 0 ? OK : rv; | 180 return rv > 0 ? OK : rv; |
| 173 } | 181 } |
| 174 | 182 |
| 175 int QuicStreamFactory::Job::DoLoop(int rv) { | 183 int QuicStreamFactory::Job::DoLoop(int rv) { |
| 176 do { | 184 do { |
| 177 IoState state = io_state_; | 185 IoState state = io_state_; |
| 178 io_state_ = STATE_NONE; | 186 io_state_ = STATE_NONE; |
| 179 switch (state) { | 187 switch (state) { |
| 188 case STATE_LOAD_SERVER_INFO: | |
| 189 CHECK_EQ(OK, rv); | |
| 190 rv = DoLoadServerInfo(); | |
| 191 break; | |
| 192 case STATE_LOAD_SERVER_INFO_COMPLETE: | |
| 193 rv = DoLoadServerInfoComplete(rv); | |
| 194 break; | |
| 180 case STATE_RESOLVE_HOST: | 195 case STATE_RESOLVE_HOST: |
| 181 CHECK_EQ(OK, rv); | 196 CHECK_EQ(OK, rv); |
| 182 rv = DoResolveHost(); | 197 rv = DoResolveHost(); |
| 183 break; | 198 break; |
| 184 case STATE_RESOLVE_HOST_COMPLETE: | 199 case STATE_RESOLVE_HOST_COMPLETE: |
| 185 rv = DoResolveHostComplete(rv); | 200 rv = DoResolveHostComplete(rv); |
| 186 break; | 201 break; |
| 187 case STATE_CONNECT: | 202 case STATE_CONNECT: |
| 188 CHECK_EQ(OK, rv); | 203 CHECK_EQ(OK, rv); |
| 189 rv = DoConnect(); | 204 rv = DoConnect(); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 200 } | 215 } |
| 201 | 216 |
| 202 void QuicStreamFactory::Job::OnIOComplete(int rv) { | 217 void QuicStreamFactory::Job::OnIOComplete(int rv) { |
| 203 rv = DoLoop(rv); | 218 rv = DoLoop(rv); |
| 204 | 219 |
| 205 if (rv != ERR_IO_PENDING && !callback_.is_null()) { | 220 if (rv != ERR_IO_PENDING && !callback_.is_null()) { |
| 206 callback_.Run(rv); | 221 callback_.Run(rv); |
| 207 } | 222 } |
| 208 } | 223 } |
| 209 | 224 |
| 225 int QuicStreamFactory::Job::DoLoadServerInfo() { | |
| 226 io_state_ = STATE_LOAD_SERVER_INFO_COMPLETE; | |
| 227 | |
| 228 if (server_info_) | |
| 229 server_info_->Start(); | |
| 230 | |
| 231 return OK; | |
| 232 } | |
| 233 | |
| 234 int QuicStreamFactory::Job::DoLoadServerInfoComplete(int rv) { | |
| 235 if (rv != OK) | |
| 236 return rv; | |
| 237 | |
| 238 io_state_ = STATE_RESOLVE_HOST; | |
| 239 return OK; | |
| 240 } | |
| 241 | |
| 210 int QuicStreamFactory::Job::DoResolveHost() { | 242 int QuicStreamFactory::Job::DoResolveHost() { |
| 211 io_state_ = STATE_RESOLVE_HOST_COMPLETE; | 243 io_state_ = STATE_RESOLVE_HOST_COMPLETE; |
| 212 return host_resolver_.Resolve( | 244 return host_resolver_.Resolve( |
| 213 HostResolver::RequestInfo(session_key_.host_port_proxy_pair.first), | 245 HostResolver::RequestInfo(session_key_.host_port_proxy_pair.first), |
| 214 DEFAULT_PRIORITY, | 246 DEFAULT_PRIORITY, |
| 215 &address_list_, | 247 &address_list_, |
| 216 base::Bind(&QuicStreamFactory::Job::OnIOComplete, base::Unretained(this)), | 248 base::Bind(&QuicStreamFactory::Job::OnIOComplete, base::Unretained(this)), |
| 217 net_log_); | 249 net_log_); |
| 218 } | 250 } |
| 219 | 251 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 278 | 310 |
| 279 scoped_ptr<QuicHttpStream> QuicStreamRequest::ReleaseStream() { | 311 scoped_ptr<QuicHttpStream> QuicStreamRequest::ReleaseStream() { |
| 280 DCHECK(stream_); | 312 DCHECK(stream_); |
| 281 return stream_.Pass(); | 313 return stream_.Pass(); |
| 282 } | 314 } |
| 283 | 315 |
| 284 int QuicStreamFactory::Job::DoConnect() { | 316 int QuicStreamFactory::Job::DoConnect() { |
| 285 io_state_ = STATE_CONNECT_COMPLETE; | 317 io_state_ = STATE_CONNECT_COMPLETE; |
| 286 | 318 |
| 287 int rv = factory_->CreateSession(session_key_.host_port_proxy_pair, is_https_, | 319 int rv = factory_->CreateSession(session_key_.host_port_proxy_pair, is_https_, |
| 288 cert_verifier_, address_list_, net_log_, &session_); | 320 cert_verifier_, server_info_.Pass(), |
| 321 address_list_, net_log_, &session_); | |
| 289 if (rv != OK) { | 322 if (rv != OK) { |
| 290 DCHECK(rv != ERR_IO_PENDING); | 323 DCHECK(rv != ERR_IO_PENDING); |
| 291 DCHECK(!session_); | 324 DCHECK(!session_); |
| 292 return rv; | 325 return rv; |
| 293 } | 326 } |
| 294 | 327 |
| 295 session_->StartReading(); | 328 session_->StartReading(); |
| 296 if (!session_->connection()->connected()) { | 329 if (!session_->connection()->connected()) { |
| 297 return ERR_QUIC_PROTOCOL_ERROR; | 330 return ERR_QUIC_PROTOCOL_ERROR; |
| 298 } | 331 } |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 376 return OK; | 409 return OK; |
| 377 } | 410 } |
| 378 | 411 |
| 379 if (HasActiveJob(session_key)) { | 412 if (HasActiveJob(session_key)) { |
| 380 Job* job = active_jobs_[session_key]; | 413 Job* job = active_jobs_[session_key]; |
| 381 active_requests_[request] = job; | 414 active_requests_[request] = job; |
| 382 job_requests_map_[job].insert(request); | 415 job_requests_map_[job].insert(request); |
| 383 return ERR_IO_PENDING; | 416 return ERR_IO_PENDING; |
| 384 } | 417 } |
| 385 | 418 |
| 386 // Create crypto config and start the process of loading QUIC server | 419 QuicServerInfo* quic_server_info = NULL; |
| 387 // information from disk cache. | 420 if (quic_server_info_factory_) { |
| 388 QuicCryptoClientConfig* crypto_config = GetOrCreateCryptoConfig(session_key); | 421 QuicCryptoClientConfig* crypto_config = |
| 389 DCHECK(crypto_config); | 422 GetOrCreateCryptoConfig(session_key); |
| 390 | 423 QuicCryptoClientConfig::CachedState* cached = |
| 424 crypto_config->LookupOrCreate( | |
| 425 session_key.host_port_proxy_pair.first.host()); | |
| 426 DCHECK(cached); | |
| 427 if (cached->IsEmpty()) { | |
| 428 quic_server_info = | |
| 429 quic_server_info_factory_->GetForHost( | |
| 430 host_port_proxy_pair.first.host()); | |
| 431 } | |
| 432 } | |
| 391 scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_proxy_pair, | 433 scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_proxy_pair, |
| 392 is_https, method, cert_verifier, net_log)); | 434 is_https, method, cert_verifier, |
| 435 quic_server_info, net_log)); | |
| 393 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, | 436 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, |
| 394 base::Unretained(this), job.get())); | 437 base::Unretained(this), job.get())); |
| 395 | 438 |
| 396 if (rv == ERR_IO_PENDING) { | 439 if (rv == ERR_IO_PENDING) { |
| 397 active_requests_[request] = job.get(); | 440 active_requests_[request] = job.get(); |
| 398 job_requests_map_[job.get()].insert(request); | 441 job_requests_map_[job.get()].insert(request); |
| 399 active_jobs_[session_key] = job.release(); | 442 active_jobs_[session_key] = job.release(); |
| 400 } | 443 } |
| 401 if (rv == OK) { | 444 if (rv == OK) { |
| 402 DCHECK(HasActiveSession(session_key)); | 445 DCHECK(HasActiveSession(session_key)); |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 594 } | 637 } |
| 595 | 638 |
| 596 bool QuicStreamFactory::HasActiveSession(const SessionKey& session_key) const { | 639 bool QuicStreamFactory::HasActiveSession(const SessionKey& session_key) const { |
| 597 return ContainsKey(active_sessions_, session_key); | 640 return ContainsKey(active_sessions_, session_key); |
| 598 } | 641 } |
| 599 | 642 |
| 600 int QuicStreamFactory::CreateSession( | 643 int QuicStreamFactory::CreateSession( |
| 601 const HostPortProxyPair& host_port_proxy_pair, | 644 const HostPortProxyPair& host_port_proxy_pair, |
| 602 bool is_https, | 645 bool is_https, |
| 603 CertVerifier* cert_verifier, | 646 CertVerifier* cert_verifier, |
| 647 scoped_ptr<QuicServerInfo> server_info, | |
| 604 const AddressList& address_list, | 648 const AddressList& address_list, |
| 605 const BoundNetLog& net_log, | 649 const BoundNetLog& net_log, |
| 606 QuicClientSession** session) { | 650 QuicClientSession** session) { |
| 607 bool enable_port_selection = enable_port_selection_; | 651 bool enable_port_selection = enable_port_selection_; |
| 608 SessionKey session_key(host_port_proxy_pair, is_https); | 652 SessionKey session_key(host_port_proxy_pair, is_https); |
| 609 if (enable_port_selection && | 653 if (enable_port_selection && |
| 610 ContainsKey(gone_away_aliases_, session_key)) { | 654 ContainsKey(gone_away_aliases_, session_key)) { |
| 611 // Disable port selection when the server is going away. | 655 // Disable port selection when the server is going away. |
| 612 // There is no point in trying to return to the same server, if | 656 // There is no point in trying to return to the same server, if |
| 613 // that server is no longer handling requests. | 657 // that server is no longer handling requests. |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 674 const HttpServerProperties::NetworkStats* stats = | 718 const HttpServerProperties::NetworkStats* stats = |
| 675 http_server_properties_->GetServerNetworkStats( | 719 http_server_properties_->GetServerNetworkStats( |
| 676 host_port_proxy_pair.first); | 720 host_port_proxy_pair.first); |
| 677 if (stats != NULL) { | 721 if (stats != NULL) { |
| 678 config.set_initial_round_trip_time_us(stats->rtt.InMicroseconds(), | 722 config.set_initial_round_trip_time_us(stats->rtt.InMicroseconds(), |
| 679 stats->rtt.InMicroseconds()); | 723 stats->rtt.InMicroseconds()); |
| 680 } | 724 } |
| 681 } | 725 } |
| 682 | 726 |
| 683 *session = new QuicClientSession( | 727 *session = new QuicClientSession( |
| 684 connection, socket.Pass(), writer.Pass(), this, | 728 connection, socket.Pass(), writer.Pass(), this, server_info.Pass(), |
| 685 quic_crypto_client_stream_factory_, host_port_proxy_pair.first.host(), | 729 quic_crypto_client_stream_factory_, host_port_proxy_pair.first.host(), |
| 686 config, crypto_config, net_log.net_log()); | 730 config, crypto_config, net_log.net_log()); |
| 687 all_sessions_.insert(*session); // owning pointer | 731 all_sessions_.insert(*session); // owning pointer |
| 688 if (is_https) { | 732 if (is_https) { |
| 689 crypto_config->SetProofVerifier( | 733 crypto_config->SetProofVerifier( |
| 690 new ProofVerifierChromium(cert_verifier, net_log)); | 734 new ProofVerifierChromium(cert_verifier, net_log)); |
| 691 } | 735 } |
| 692 return OK; | 736 return OK; |
| 693 } | 737 } |
| 694 | 738 |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 712 const SessionKey& session_key) { | 756 const SessionKey& session_key) { |
| 713 QuicCryptoClientConfig* crypto_config; | 757 QuicCryptoClientConfig* crypto_config; |
| 714 | 758 |
| 715 if (ContainsKey(all_crypto_configs_, session_key)) { | 759 if (ContainsKey(all_crypto_configs_, session_key)) { |
| 716 crypto_config = all_crypto_configs_[session_key]; | 760 crypto_config = all_crypto_configs_[session_key]; |
| 717 DCHECK(crypto_config); | 761 DCHECK(crypto_config); |
| 718 } else { | 762 } else { |
| 719 // TODO(rtenneti): if two quic_sessions for the same host_port_proxy_pair | 763 // TODO(rtenneti): if two quic_sessions for the same host_port_proxy_pair |
| 720 // share the same crypto_config, will it cause issues? | 764 // share the same crypto_config, will it cause issues? |
| 721 crypto_config = new QuicCryptoClientConfig(); | 765 crypto_config = new QuicCryptoClientConfig(); |
| 722 if (quic_server_info_factory_) { | |
| 723 QuicCryptoClientConfig::CachedState* cached = | |
| 724 crypto_config->Create(session_key.host_port_proxy_pair.first.host(), | |
| 725 quic_server_info_factory_); | |
| 726 DCHECK(cached); | |
| 727 } | |
| 728 crypto_config->SetDefaults(); | 766 crypto_config->SetDefaults(); |
| 729 all_crypto_configs_[session_key] = crypto_config; | 767 all_crypto_configs_[session_key] = crypto_config; |
| 730 PopulateFromCanonicalConfig(session_key, crypto_config); | 768 PopulateFromCanonicalConfig(session_key, crypto_config); |
| 731 } | 769 } |
| 732 return crypto_config; | 770 return crypto_config; |
| 733 } | 771 } |
| 734 | 772 |
| 735 void QuicStreamFactory::PopulateFromCanonicalConfig( | 773 void QuicStreamFactory::PopulateFromCanonicalConfig( |
| 736 const SessionKey& session_key, | 774 const SessionKey& session_key, |
| 737 QuicCryptoClientConfig* crypto_config) { | 775 QuicCryptoClientConfig* crypto_config) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 770 // as the initial CachedState for the server_hostname in crypto_config. | 808 // as the initial CachedState for the server_hostname in crypto_config. |
| 771 crypto_config->InitializeFrom(server_hostname, | 809 crypto_config->InitializeFrom(server_hostname, |
| 772 canonical_host_port_proxy_pair.first.host(), | 810 canonical_host_port_proxy_pair.first.host(), |
| 773 canonical_crypto_config); | 811 canonical_crypto_config); |
| 774 // Update canonical version to point at the "most recent" crypto_config. | 812 // Update canonical version to point at the "most recent" crypto_config. |
| 775 canonical_hostname_to_origin_map_[suffix_session_key] = | 813 canonical_hostname_to_origin_map_[suffix_session_key] = |
| 776 canonical_session_key; | 814 canonical_session_key; |
| 777 } | 815 } |
| 778 | 816 |
| 779 } // namespace net | 817 } // namespace net |
| OLD | NEW |