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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 // Responsible for creating a new QUIC session to the specified server, and | 64 // Responsible for creating a new QUIC session to the specified server, and |
65 // for notifying any associated requests when complete. | 65 // for notifying any associated requests when complete. |
66 class QuicStreamFactory::Job { | 66 class QuicStreamFactory::Job { |
67 public: | 67 public: |
68 Job(QuicStreamFactory* factory, | 68 Job(QuicStreamFactory* factory, |
69 HostResolver* host_resolver, | 69 HostResolver* host_resolver, |
70 const HostPortPair& host_port_pair, | 70 const HostPortPair& host_port_pair, |
71 bool is_https, | 71 bool is_https, |
72 base::StringPiece method, | 72 base::StringPiece method, |
73 CertVerifier* cert_verifier, | 73 CertVerifier* cert_verifier, |
| 74 QuicServerInfo* server_info, |
74 const BoundNetLog& net_log); | 75 const BoundNetLog& net_log); |
75 | 76 |
76 ~Job(); | 77 ~Job(); |
77 | 78 |
78 int Run(const CompletionCallback& callback); | 79 int Run(const CompletionCallback& callback); |
79 | 80 |
80 int DoLoop(int rv); | 81 int DoLoop(int rv); |
| 82 int DoLoadServerInfo(); |
| 83 int DoLoadServerInfoComplete(int rv); |
81 int DoResolveHost(); | 84 int DoResolveHost(); |
82 int DoResolveHostComplete(int rv); | 85 int DoResolveHostComplete(int rv); |
83 int DoConnect(); | 86 int DoConnect(); |
84 int DoConnectComplete(int rv); | 87 int DoConnectComplete(int rv); |
85 | 88 |
86 void OnIOComplete(int rv); | 89 void OnIOComplete(int rv); |
87 | 90 |
88 CompletionCallback callback() { | 91 CompletionCallback callback() { |
89 return callback_; | 92 return callback_; |
90 } | 93 } |
91 | 94 |
92 const QuicSessionKey session_key() const { | 95 const QuicSessionKey session_key() const { |
93 return session_key_; | 96 return session_key_; |
94 } | 97 } |
95 | 98 |
96 private: | 99 private: |
97 enum IoState { | 100 enum IoState { |
98 STATE_NONE, | 101 STATE_NONE, |
| 102 STATE_LOAD_SERVER_INFO, |
| 103 STATE_LOAD_SERVER_INFO_COMPLETE, |
99 STATE_RESOLVE_HOST, | 104 STATE_RESOLVE_HOST, |
100 STATE_RESOLVE_HOST_COMPLETE, | 105 STATE_RESOLVE_HOST_COMPLETE, |
101 STATE_CONNECT, | 106 STATE_CONNECT, |
102 STATE_CONNECT_COMPLETE, | 107 STATE_CONNECT_COMPLETE, |
103 }; | 108 }; |
104 IoState io_state_; | 109 IoState io_state_; |
105 | 110 |
106 QuicStreamFactory* factory_; | 111 QuicStreamFactory* factory_; |
107 SingleRequestHostResolver host_resolver_; | 112 SingleRequestHostResolver host_resolver_; |
108 bool is_https_; | 113 bool is_https_; |
109 QuicSessionKey session_key_; | 114 QuicSessionKey session_key_; |
110 bool is_post_; | 115 bool is_post_; |
111 CertVerifier* cert_verifier_; | 116 CertVerifier* cert_verifier_; |
| 117 scoped_ptr<QuicServerInfo> server_info_; |
112 const BoundNetLog net_log_; | 118 const BoundNetLog net_log_; |
113 QuicClientSession* session_; | 119 QuicClientSession* session_; |
114 CompletionCallback callback_; | 120 CompletionCallback callback_; |
115 AddressList address_list_; | 121 AddressList address_list_; |
116 DISALLOW_COPY_AND_ASSIGN(Job); | 122 DISALLOW_COPY_AND_ASSIGN(Job); |
117 }; | 123 }; |
118 | 124 |
119 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, | 125 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, |
120 HostResolver* host_resolver, | 126 HostResolver* host_resolver, |
121 const HostPortPair& host_port_pair, | 127 const HostPortPair& host_port_pair, |
122 bool is_https, | 128 bool is_https, |
123 base::StringPiece method, | 129 base::StringPiece method, |
124 CertVerifier* cert_verifier, | 130 CertVerifier* cert_verifier, |
| 131 QuicServerInfo* server_info, |
125 const BoundNetLog& net_log) | 132 const BoundNetLog& net_log) |
126 : factory_(factory), | 133 : factory_(factory), |
127 host_resolver_(host_resolver), | 134 host_resolver_(host_resolver), |
128 is_https_(is_https), | 135 is_https_(is_https), |
129 session_key_(host_port_pair, is_https), | 136 session_key_(host_port_pair, is_https), |
130 is_post_(method == "POST"), | 137 is_post_(method == "POST"), |
131 cert_verifier_(cert_verifier), | 138 cert_verifier_(cert_verifier), |
| 139 server_info_(server_info), |
132 net_log_(net_log), | 140 net_log_(net_log), |
133 session_(NULL) {} | 141 session_(NULL) {} |
134 | 142 |
135 QuicStreamFactory::Job::~Job() { | 143 QuicStreamFactory::Job::~Job() { |
136 } | 144 } |
137 | 145 |
138 int QuicStreamFactory::Job::Run(const CompletionCallback& callback) { | 146 int QuicStreamFactory::Job::Run(const CompletionCallback& callback) { |
139 io_state_ = STATE_RESOLVE_HOST; | 147 io_state_ = STATE_LOAD_SERVER_INFO; |
140 int rv = DoLoop(OK); | 148 int rv = DoLoop(OK); |
141 if (rv == ERR_IO_PENDING) | 149 if (rv == ERR_IO_PENDING) |
142 callback_ = callback; | 150 callback_ = callback; |
143 | 151 |
144 return rv > 0 ? OK : rv; | 152 return rv > 0 ? OK : rv; |
145 } | 153 } |
146 | 154 |
147 int QuicStreamFactory::Job::DoLoop(int rv) { | 155 int QuicStreamFactory::Job::DoLoop(int rv) { |
148 do { | 156 do { |
149 IoState state = io_state_; | 157 IoState state = io_state_; |
150 io_state_ = STATE_NONE; | 158 io_state_ = STATE_NONE; |
151 switch (state) { | 159 switch (state) { |
| 160 case STATE_LOAD_SERVER_INFO: |
| 161 CHECK_EQ(OK, rv); |
| 162 rv = DoLoadServerInfo(); |
| 163 break; |
| 164 case STATE_LOAD_SERVER_INFO_COMPLETE: |
| 165 rv = DoLoadServerInfoComplete(rv); |
| 166 break; |
152 case STATE_RESOLVE_HOST: | 167 case STATE_RESOLVE_HOST: |
153 CHECK_EQ(OK, rv); | 168 CHECK_EQ(OK, rv); |
154 rv = DoResolveHost(); | 169 rv = DoResolveHost(); |
155 break; | 170 break; |
156 case STATE_RESOLVE_HOST_COMPLETE: | 171 case STATE_RESOLVE_HOST_COMPLETE: |
157 rv = DoResolveHostComplete(rv); | 172 rv = DoResolveHostComplete(rv); |
158 break; | 173 break; |
159 case STATE_CONNECT: | 174 case STATE_CONNECT: |
160 CHECK_EQ(OK, rv); | 175 CHECK_EQ(OK, rv); |
161 rv = DoConnect(); | 176 rv = DoConnect(); |
(...skipping 10 matching lines...) Expand all Loading... |
172 } | 187 } |
173 | 188 |
174 void QuicStreamFactory::Job::OnIOComplete(int rv) { | 189 void QuicStreamFactory::Job::OnIOComplete(int rv) { |
175 rv = DoLoop(rv); | 190 rv = DoLoop(rv); |
176 | 191 |
177 if (rv != ERR_IO_PENDING && !callback_.is_null()) { | 192 if (rv != ERR_IO_PENDING && !callback_.is_null()) { |
178 callback_.Run(rv); | 193 callback_.Run(rv); |
179 } | 194 } |
180 } | 195 } |
181 | 196 |
| 197 int QuicStreamFactory::Job::DoLoadServerInfo() { |
| 198 io_state_ = STATE_LOAD_SERVER_INFO_COMPLETE; |
| 199 |
| 200 if (server_info_) |
| 201 server_info_->Start(); |
| 202 |
| 203 return OK; |
| 204 } |
| 205 |
| 206 int QuicStreamFactory::Job::DoLoadServerInfoComplete(int rv) { |
| 207 if (rv != OK) |
| 208 return rv; |
| 209 |
| 210 io_state_ = STATE_RESOLVE_HOST; |
| 211 return OK; |
| 212 } |
| 213 |
182 int QuicStreamFactory::Job::DoResolveHost() { | 214 int QuicStreamFactory::Job::DoResolveHost() { |
183 io_state_ = STATE_RESOLVE_HOST_COMPLETE; | 215 io_state_ = STATE_RESOLVE_HOST_COMPLETE; |
184 return host_resolver_.Resolve( | 216 return host_resolver_.Resolve( |
185 HostResolver::RequestInfo(session_key_.host_port_pair()), | 217 HostResolver::RequestInfo(session_key_.host_port_pair()), |
186 DEFAULT_PRIORITY, | 218 DEFAULT_PRIORITY, |
187 &address_list_, | 219 &address_list_, |
188 base::Bind(&QuicStreamFactory::Job::OnIOComplete, base::Unretained(this)), | 220 base::Bind(&QuicStreamFactory::Job::OnIOComplete, base::Unretained(this)), |
189 net_log_); | 221 net_log_); |
190 } | 222 } |
191 | 223 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
250 | 282 |
251 scoped_ptr<QuicHttpStream> QuicStreamRequest::ReleaseStream() { | 283 scoped_ptr<QuicHttpStream> QuicStreamRequest::ReleaseStream() { |
252 DCHECK(stream_); | 284 DCHECK(stream_); |
253 return stream_.Pass(); | 285 return stream_.Pass(); |
254 } | 286 } |
255 | 287 |
256 int QuicStreamFactory::Job::DoConnect() { | 288 int QuicStreamFactory::Job::DoConnect() { |
257 io_state_ = STATE_CONNECT_COMPLETE; | 289 io_state_ = STATE_CONNECT_COMPLETE; |
258 | 290 |
259 int rv = factory_->CreateSession(session_key_.host_port_pair(), is_https_, | 291 int rv = factory_->CreateSession(session_key_.host_port_pair(), is_https_, |
260 cert_verifier_, address_list_, net_log_, &session_); | 292 cert_verifier_, server_info_.Pass(), |
| 293 address_list_, net_log_, &session_); |
261 if (rv != OK) { | 294 if (rv != OK) { |
262 DCHECK(rv != ERR_IO_PENDING); | 295 DCHECK(rv != ERR_IO_PENDING); |
263 DCHECK(!session_); | 296 DCHECK(!session_); |
264 return rv; | 297 return rv; |
265 } | 298 } |
266 | 299 |
267 session_->StartReading(); | 300 session_->StartReading(); |
268 if (!session_->connection()->connected()) { | 301 if (!session_->connection()->connected()) { |
269 return ERR_QUIC_PROTOCOL_ERROR; | 302 return ERR_QUIC_PROTOCOL_ERROR; |
270 } | 303 } |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 return OK; | 381 return OK; |
349 } | 382 } |
350 | 383 |
351 if (HasActiveJob(session_key)) { | 384 if (HasActiveJob(session_key)) { |
352 Job* job = active_jobs_[session_key]; | 385 Job* job = active_jobs_[session_key]; |
353 active_requests_[request] = job; | 386 active_requests_[request] = job; |
354 job_requests_map_[job].insert(request); | 387 job_requests_map_[job].insert(request); |
355 return ERR_IO_PENDING; | 388 return ERR_IO_PENDING; |
356 } | 389 } |
357 | 390 |
358 // Create crypto config and start the process of loading QUIC server | 391 QuicServerInfo* quic_server_info = NULL; |
359 // information from disk cache. | 392 if (quic_server_info_factory_) { |
360 QuicCryptoClientConfig* crypto_config = GetOrCreateCryptoConfig(session_key); | 393 QuicCryptoClientConfig* crypto_config = |
361 DCHECK(crypto_config); | 394 GetOrCreateCryptoConfig(session_key); |
362 | 395 QuicCryptoClientConfig::CachedState* cached = |
| 396 crypto_config->LookupOrCreate(session_key.host_port_pair().host()); |
| 397 DCHECK(cached); |
| 398 if (cached->IsEmpty()) { |
| 399 quic_server_info = |
| 400 quic_server_info_factory_->GetForHost(host_port_pair.host()); |
| 401 } |
| 402 } |
363 scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_pair, | 403 scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_pair, |
364 is_https, method, cert_verifier, net_log)); | 404 is_https, method, cert_verifier, |
| 405 quic_server_info, net_log)); |
365 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, | 406 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, |
366 base::Unretained(this), job.get())); | 407 base::Unretained(this), job.get())); |
367 | 408 |
368 if (rv == ERR_IO_PENDING) { | 409 if (rv == ERR_IO_PENDING) { |
369 active_requests_[request] = job.get(); | 410 active_requests_[request] = job.get(); |
370 job_requests_map_[job.get()].insert(request); | 411 job_requests_map_[job.get()].insert(request); |
371 active_jobs_[session_key] = job.release(); | 412 active_jobs_[session_key] = job.release(); |
372 } | 413 } |
373 if (rv == OK) { | 414 if (rv == OK) { |
374 DCHECK(HasActiveSession(session_key)); | 415 DCHECK(HasActiveSession(session_key)); |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
566 | 607 |
567 bool QuicStreamFactory::HasActiveSession( | 608 bool QuicStreamFactory::HasActiveSession( |
568 const QuicSessionKey& session_key) const { | 609 const QuicSessionKey& session_key) const { |
569 return ContainsKey(active_sessions_, session_key); | 610 return ContainsKey(active_sessions_, session_key); |
570 } | 611 } |
571 | 612 |
572 int QuicStreamFactory::CreateSession( | 613 int QuicStreamFactory::CreateSession( |
573 const HostPortPair& host_port_pair, | 614 const HostPortPair& host_port_pair, |
574 bool is_https, | 615 bool is_https, |
575 CertVerifier* cert_verifier, | 616 CertVerifier* cert_verifier, |
| 617 scoped_ptr<QuicServerInfo> server_info, |
576 const AddressList& address_list, | 618 const AddressList& address_list, |
577 const BoundNetLog& net_log, | 619 const BoundNetLog& net_log, |
578 QuicClientSession** session) { | 620 QuicClientSession** session) { |
579 bool enable_port_selection = enable_port_selection_; | 621 bool enable_port_selection = enable_port_selection_; |
580 QuicSessionKey session_key(host_port_pair, is_https); | 622 QuicSessionKey session_key(host_port_pair, is_https); |
581 if (enable_port_selection && | 623 if (enable_port_selection && |
582 ContainsKey(gone_away_aliases_, session_key)) { | 624 ContainsKey(gone_away_aliases_, session_key)) { |
583 // Disable port selection when the server is going away. | 625 // Disable port selection when the server is going away. |
584 // There is no point in trying to return to the same server, if | 626 // There is no point in trying to return to the same server, if |
585 // that server is no longer handling requests. | 627 // that server is no longer handling requests. |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
645 if (http_server_properties_) { | 687 if (http_server_properties_) { |
646 const HttpServerProperties::NetworkStats* stats = | 688 const HttpServerProperties::NetworkStats* stats = |
647 http_server_properties_->GetServerNetworkStats(host_port_pair); | 689 http_server_properties_->GetServerNetworkStats(host_port_pair); |
648 if (stats != NULL) { | 690 if (stats != NULL) { |
649 config.set_initial_round_trip_time_us(stats->rtt.InMicroseconds(), | 691 config.set_initial_round_trip_time_us(stats->rtt.InMicroseconds(), |
650 stats->rtt.InMicroseconds()); | 692 stats->rtt.InMicroseconds()); |
651 } | 693 } |
652 } | 694 } |
653 | 695 |
654 *session = new QuicClientSession( | 696 *session = new QuicClientSession( |
655 connection, socket.Pass(), writer.Pass(), this, | 697 connection, socket.Pass(), writer.Pass(), this, server_info.Pass(), |
656 quic_crypto_client_stream_factory_, host_port_pair.host(), | 698 quic_crypto_client_stream_factory_, host_port_pair.host(), |
657 config, crypto_config, net_log.net_log()); | 699 config, crypto_config, net_log.net_log()); |
658 all_sessions_.insert(*session); // owning pointer | 700 all_sessions_.insert(*session); // owning pointer |
659 if (is_https) { | 701 if (is_https) { |
660 crypto_config->SetProofVerifier( | 702 crypto_config->SetProofVerifier( |
661 new ProofVerifierChromium(cert_verifier, net_log)); | 703 new ProofVerifierChromium(cert_verifier, net_log)); |
662 } | 704 } |
663 return OK; | 705 return OK; |
664 } | 706 } |
665 | 707 |
(...skipping 17 matching lines...) Expand all Loading... |
683 const QuicSessionKey& session_key) { | 725 const QuicSessionKey& session_key) { |
684 QuicCryptoClientConfig* crypto_config; | 726 QuicCryptoClientConfig* crypto_config; |
685 | 727 |
686 if (ContainsKey(all_crypto_configs_, session_key)) { | 728 if (ContainsKey(all_crypto_configs_, session_key)) { |
687 crypto_config = all_crypto_configs_[session_key]; | 729 crypto_config = all_crypto_configs_[session_key]; |
688 DCHECK(crypto_config); | 730 DCHECK(crypto_config); |
689 } else { | 731 } else { |
690 // TODO(rtenneti): if two quic_sessions for the same host_port_pair | 732 // TODO(rtenneti): if two quic_sessions for the same host_port_pair |
691 // share the same crypto_config, will it cause issues? | 733 // share the same crypto_config, will it cause issues? |
692 crypto_config = new QuicCryptoClientConfig(); | 734 crypto_config = new QuicCryptoClientConfig(); |
693 if (quic_server_info_factory_) { | |
694 QuicCryptoClientConfig::CachedState* cached = | |
695 crypto_config->Create(session_key.host_port_pair().host(), | |
696 quic_server_info_factory_); | |
697 DCHECK(cached); | |
698 } | |
699 crypto_config->SetDefaults(); | 735 crypto_config->SetDefaults(); |
700 all_crypto_configs_[session_key] = crypto_config; | 736 all_crypto_configs_[session_key] = crypto_config; |
701 PopulateFromCanonicalConfig(session_key, crypto_config); | 737 PopulateFromCanonicalConfig(session_key, crypto_config); |
702 } | 738 } |
703 return crypto_config; | 739 return crypto_config; |
704 } | 740 } |
705 | 741 |
706 void QuicStreamFactory::PopulateFromCanonicalConfig( | 742 void QuicStreamFactory::PopulateFromCanonicalConfig( |
707 const QuicSessionKey& session_key, | 743 const QuicSessionKey& session_key, |
708 QuicCryptoClientConfig* crypto_config) { | 744 QuicCryptoClientConfig* crypto_config) { |
(...skipping 30 matching lines...) Expand all Loading... |
739 // as the initial CachedState for the server_hostname in crypto_config. | 775 // as the initial CachedState for the server_hostname in crypto_config. |
740 crypto_config->InitializeFrom(server_hostname, | 776 crypto_config->InitializeFrom(server_hostname, |
741 canonical_host_port_pair.host(), | 777 canonical_host_port_pair.host(), |
742 canonical_crypto_config); | 778 canonical_crypto_config); |
743 // Update canonical version to point at the "most recent" crypto_config. | 779 // Update canonical version to point at the "most recent" crypto_config. |
744 canonical_hostname_to_origin_map_[suffix_session_key] = | 780 canonical_hostname_to_origin_map_[suffix_session_key] = |
745 canonical_session_key; | 781 canonical_session_key; |
746 } | 782 } |
747 | 783 |
748 } // namespace net | 784 } // namespace net |
OLD | NEW |