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 |