OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/quic/quic_stream_factory.h" | 5 #include "net/quic/quic_stream_factory.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 | 8 |
9 #include "base/cpu.h" | 9 #include "base/cpu.h" |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
163 int DoResolveHost(); | 163 int DoResolveHost(); |
164 int DoResolveHostComplete(int rv); | 164 int DoResolveHostComplete(int rv); |
165 int DoLoadServerInfo(); | 165 int DoLoadServerInfo(); |
166 int DoLoadServerInfoComplete(int rv); | 166 int DoLoadServerInfoComplete(int rv); |
167 int DoConnect(); | 167 int DoConnect(); |
168 int DoResumeConnect(); | 168 int DoResumeConnect(); |
169 int DoConnectComplete(int rv); | 169 int DoConnectComplete(int rv); |
170 | 170 |
171 void OnIOComplete(int rv); | 171 void OnIOComplete(int rv); |
172 | 172 |
173 void CancelWaitForDataReadyPendingCallback(); | |
174 | |
175 void CancelJob(); | |
176 | |
173 void CancelWaitForDataReadyCallback(); | 177 void CancelWaitForDataReadyCallback(); |
174 | 178 |
175 CompletionCallback callback() { | 179 CompletionCallback callback() { return callback_; } |
176 return callback_; | |
177 } | |
178 | 180 |
179 const QuicServerId server_id() const { | 181 const QuicServerId server_id() const { return server_id_; } |
180 return server_id_; | 182 |
181 } | 183 QuicSession* session() { return session_; } |
184 | |
185 bool is_cancelled() const { return is_cancelled_; } | |
182 | 186 |
183 private: | 187 private: |
184 enum IoState { | 188 enum IoState { |
185 STATE_NONE, | 189 STATE_NONE, |
186 STATE_RESOLVE_HOST, | 190 STATE_RESOLVE_HOST, |
187 STATE_RESOLVE_HOST_COMPLETE, | 191 STATE_RESOLVE_HOST_COMPLETE, |
188 STATE_LOAD_SERVER_INFO, | 192 STATE_LOAD_SERVER_INFO, |
189 STATE_LOAD_SERVER_INFO_COMPLETE, | 193 STATE_LOAD_SERVER_INFO_COMPLETE, |
190 STATE_CONNECT, | 194 STATE_CONNECT, |
191 STATE_RESUME_CONNECT, | 195 STATE_RESUME_CONNECT, |
192 STATE_CONNECT_COMPLETE, | 196 STATE_CONNECT_COMPLETE, |
193 }; | 197 }; |
194 IoState io_state_; | 198 IoState io_state_; |
195 | 199 |
196 QuicStreamFactory* factory_; | 200 QuicStreamFactory* factory_; |
197 SingleRequestHostResolver host_resolver_; | 201 SingleRequestHostResolver host_resolver_; |
198 QuicServerId server_id_; | 202 QuicServerId server_id_; |
199 bool is_post_; | 203 bool is_post_; |
200 bool was_alternate_protocol_recently_broken_; | 204 bool was_alternate_protocol_recently_broken_; |
201 scoped_ptr<QuicServerInfo> server_info_; | 205 scoped_ptr<QuicServerInfo> server_info_; |
206 bool waiting_to_load_server_config_; | |
207 bool is_cancelled_; | |
202 const BoundNetLog net_log_; | 208 const BoundNetLog net_log_; |
203 QuicClientSession* session_; | 209 QuicClientSession* session_; |
204 CompletionCallback callback_; | 210 CompletionCallback callback_; |
205 AddressList address_list_; | 211 AddressList address_list_; |
206 base::TimeTicks disk_cache_load_start_time_; | 212 base::TimeTicks disk_cache_load_start_time_; |
207 base::TimeTicks dns_resolution_start_time_; | 213 base::TimeTicks dns_resolution_start_time_; |
208 base::WeakPtrFactory<Job> weak_factory_; | 214 base::WeakPtrFactory<Job> weak_factory_; |
209 DISALLOW_COPY_AND_ASSIGN(Job); | 215 DISALLOW_COPY_AND_ASSIGN(Job); |
210 }; | 216 }; |
211 | 217 |
212 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, | 218 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, |
213 HostResolver* host_resolver, | 219 HostResolver* host_resolver, |
214 const HostPortPair& host_port_pair, | 220 const HostPortPair& host_port_pair, |
215 bool is_https, | 221 bool is_https, |
216 bool was_alternate_protocol_recently_broken, | 222 bool was_alternate_protocol_recently_broken, |
217 PrivacyMode privacy_mode, | 223 PrivacyMode privacy_mode, |
218 base::StringPiece method, | 224 base::StringPiece method, |
219 QuicServerInfo* server_info, | 225 QuicServerInfo* server_info, |
220 const BoundNetLog& net_log) | 226 const BoundNetLog& net_log) |
221 : io_state_(STATE_RESOLVE_HOST), | 227 : io_state_(STATE_RESOLVE_HOST), |
222 factory_(factory), | 228 factory_(factory), |
223 host_resolver_(host_resolver), | 229 host_resolver_(host_resolver), |
224 server_id_(host_port_pair, is_https, privacy_mode), | 230 server_id_(host_port_pair, is_https, privacy_mode), |
225 is_post_(method == "POST"), | 231 is_post_(method == "POST"), |
226 was_alternate_protocol_recently_broken_( | 232 was_alternate_protocol_recently_broken_( |
227 was_alternate_protocol_recently_broken), | 233 was_alternate_protocol_recently_broken), |
228 server_info_(server_info), | 234 server_info_(server_info), |
235 waiting_to_load_server_config_(false), | |
236 is_cancelled_(false), | |
229 net_log_(net_log), | 237 net_log_(net_log), |
230 session_(nullptr), | 238 session_(nullptr), |
231 weak_factory_(this) {} | 239 weak_factory_(this) { |
240 } | |
232 | 241 |
233 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, | 242 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, |
234 HostResolver* host_resolver, | 243 HostResolver* host_resolver, |
235 QuicClientSession* session, | 244 QuicClientSession* session, |
236 QuicServerId server_id) | 245 QuicServerId server_id) |
237 : io_state_(STATE_RESUME_CONNECT), | 246 : io_state_(STATE_RESUME_CONNECT), |
238 factory_(factory), | 247 factory_(factory), |
239 host_resolver_(host_resolver), // unused | 248 host_resolver_(host_resolver), // unused |
240 server_id_(server_id), | 249 server_id_(server_id), |
241 is_post_(false), // unused | 250 is_post_(false), // unused |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
303 | 312 |
304 tracked_objects::ScopedTracker tracking_profile2( | 313 tracked_objects::ScopedTracker tracking_profile2( |
305 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 314 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
306 "422516 QuicStreamFactory::Job::OnIOComplete2")); | 315 "422516 QuicStreamFactory::Job::OnIOComplete2")); |
307 | 316 |
308 if (rv != ERR_IO_PENDING && !callback_.is_null()) { | 317 if (rv != ERR_IO_PENDING && !callback_.is_null()) { |
309 callback_.Run(rv); | 318 callback_.Run(rv); |
310 } | 319 } |
311 } | 320 } |
312 | 321 |
322 void QuicStreamFactory::Job::CancelWaitForDataReadyPendingCallback() { | |
323 if (!server_info_ || io_state_ != STATE_LOAD_SERVER_INFO_COMPLETE) | |
324 return; | |
325 // If we are waiting for WaitForDataReadyCallback, then cancel the pending | |
326 // callback. | |
Ryan Hamilton
2015/02/04 20:10:29
nit: I think I'd reverse the order here:
// If
ramant (doing other things)
2015/02/05 03:39:41
Done.
| |
327 server_info_->CancelWaitForDataReadyCallback(); | |
328 } | |
329 | |
330 void QuicStreamFactory::Job::CancelJob() { | |
331 DCHECK(!is_cancelled_); | |
332 CancelWaitForDataReadyPendingCallback(); | |
333 is_cancelled_ = true; | |
334 } | |
335 | |
313 void QuicStreamFactory::Job::CancelWaitForDataReadyCallback() { | 336 void QuicStreamFactory::Job::CancelWaitForDataReadyCallback() { |
314 // If we are waiting for WaitForDataReadyCallback, then cancel the callback. | 337 CancelWaitForDataReadyPendingCallback(); |
315 if (io_state_ != STATE_LOAD_SERVER_INFO_COMPLETE) | |
316 return; | |
317 server_info_->CancelWaitForDataReadyCallback(); | |
318 OnIOComplete(OK); | 338 OnIOComplete(OK); |
319 } | 339 } |
320 | 340 |
321 int QuicStreamFactory::Job::DoResolveHost() { | 341 int QuicStreamFactory::Job::DoResolveHost() { |
322 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 342 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
323 tracked_objects::ScopedTracker tracking_profile( | 343 tracked_objects::ScopedTracker tracking_profile( |
324 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 344 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
325 "422516 QuicStreamFactory::Job::DoResolveHost")); | 345 "422516 QuicStreamFactory::Job::DoResolveHost")); |
326 | 346 |
327 // Start loading the data now, and wait for it after we resolve the host. | 347 // Start loading the data now, and wait for it after we resolve the host. |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
386 } | 406 } |
387 if (load_server_info_timeout_ms > 0) { | 407 if (load_server_info_timeout_ms > 0) { |
388 factory_->task_runner_->PostDelayedTask( | 408 factory_->task_runner_->PostDelayedTask( |
389 FROM_HERE, | 409 FROM_HERE, |
390 base::Bind(&QuicStreamFactory::Job::CancelWaitForDataReadyCallback, | 410 base::Bind(&QuicStreamFactory::Job::CancelWaitForDataReadyCallback, |
391 weak_factory_.GetWeakPtr()), | 411 weak_factory_.GetWeakPtr()), |
392 base::TimeDelta::FromMilliseconds(load_server_info_timeout_ms)); | 412 base::TimeDelta::FromMilliseconds(load_server_info_timeout_ms)); |
393 } | 413 } |
394 | 414 |
395 disk_cache_load_start_time_ = base::TimeTicks::Now(); | 415 disk_cache_load_start_time_ = base::TimeTicks::Now(); |
416 waiting_to_load_server_config_ = true; | |
396 return server_info_->WaitForDataReady( | 417 return server_info_->WaitForDataReady( |
397 base::Bind(&QuicStreamFactory::Job::OnIOComplete, | 418 base::Bind(&QuicStreamFactory::Job::OnIOComplete, |
398 weak_factory_.GetWeakPtr())); | 419 weak_factory_.GetWeakPtr())); |
399 } | 420 } |
400 | 421 |
401 int QuicStreamFactory::Job::DoLoadServerInfoComplete(int rv) { | 422 int QuicStreamFactory::Job::DoLoadServerInfoComplete(int rv) { |
402 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 423 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
403 tracked_objects::ScopedTracker tracking_profile( | 424 tracked_objects::ScopedTracker tracking_profile( |
404 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 425 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
405 "422516 QuicStreamFactory::Job::DoLoadServerInfoComplete")); | 426 "422516 QuicStreamFactory::Job::DoLoadServerInfoComplete")); |
(...skipping 12 matching lines...) Expand all Loading... | |
418 } | 439 } |
419 | 440 |
420 int QuicStreamFactory::Job::DoConnect() { | 441 int QuicStreamFactory::Job::DoConnect() { |
421 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 442 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
422 tracked_objects::ScopedTracker tracking_profile( | 443 tracked_objects::ScopedTracker tracking_profile( |
423 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 444 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
424 "422516 QuicStreamFactory::Job::DoConnect")); | 445 "422516 QuicStreamFactory::Job::DoConnect")); |
425 | 446 |
426 io_state_ = STATE_CONNECT_COMPLETE; | 447 io_state_ = STATE_CONNECT_COMPLETE; |
427 | 448 |
449 if (factory_->enable_connection_racing()) { | |
450 if (is_cancelled_) { | |
451 return ERR_CONNECTION_CLOSED; | |
452 } | |
Ryan Hamilton
2015/02/04 20:10:29
If this is the right place to check this value, I'
ramant (doing other things)
2015/02/05 03:39:41
The only time, we cancel the job is when we wait (
| |
453 if (waiting_to_load_server_config_ && | |
454 (server_info_->state().server_config.empty() || | |
455 !factory_->CryptoConfigCacheIsEmpty(server_id_))) { | |
456 // If we didn't load the server config from the disk cache or if we have | |
457 // received a new server config from the server, then cancel the current | |
458 // job. | |
459 CancelJob(); | |
460 return ERR_CONNECTION_CLOSED; | |
461 } | |
462 } | |
463 | |
428 int rv = factory_->CreateSession(server_id_, server_info_.Pass(), | 464 int rv = factory_->CreateSession(server_id_, server_info_.Pass(), |
429 address_list_, net_log_, &session_); | 465 address_list_, net_log_, &session_); |
430 if (rv != OK) { | 466 if (rv != OK) { |
431 DCHECK(rv != ERR_IO_PENDING); | 467 DCHECK(rv != ERR_IO_PENDING); |
432 DCHECK(!session_); | 468 DCHECK(!session_); |
433 return rv; | 469 return rv; |
434 } | 470 } |
435 | 471 |
436 if (!session_->connection()->connected()) { | 472 if (!session_->connection()->connected()) { |
437 return ERR_CONNECTION_CLOSED; | 473 return ERR_CONNECTION_CLOSED; |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
581 config_(InitializeQuicConfig(connection_options)), | 617 config_(InitializeQuicConfig(connection_options)), |
582 supported_versions_(supported_versions), | 618 supported_versions_(supported_versions), |
583 enable_port_selection_(enable_port_selection), | 619 enable_port_selection_(enable_port_selection), |
584 always_require_handshake_confirmation_( | 620 always_require_handshake_confirmation_( |
585 always_require_handshake_confirmation), | 621 always_require_handshake_confirmation), |
586 disable_connection_pooling_(disable_connection_pooling), | 622 disable_connection_pooling_(disable_connection_pooling), |
587 load_server_info_timeout_ms_(load_server_info_timeout), | 623 load_server_info_timeout_ms_(load_server_info_timeout), |
588 load_server_info_timeout_srtt_multiplier_( | 624 load_server_info_timeout_srtt_multiplier_( |
589 load_server_info_timeout_srtt_multiplier), | 625 load_server_info_timeout_srtt_multiplier), |
590 enable_truncated_connection_ids_(enable_truncated_connection_ids), | 626 enable_truncated_connection_ids_(enable_truncated_connection_ids), |
627 enable_connection_racing_(false), | |
591 port_seed_(random_generator_->RandUint64()), | 628 port_seed_(random_generator_->RandUint64()), |
592 check_persisted_supports_quic_(true), | 629 check_persisted_supports_quic_(true), |
593 task_runner_(nullptr), | 630 task_runner_(nullptr), |
594 weak_factory_(this) { | 631 weak_factory_(this) { |
595 DCHECK(transport_security_state_); | 632 DCHECK(transport_security_state_); |
596 crypto_config_.set_user_agent_id(user_agent_id); | 633 crypto_config_.set_user_agent_id(user_agent_id); |
597 crypto_config_.AddCanonicalSuffix(".c.youtube.com"); | 634 crypto_config_.AddCanonicalSuffix(".c.youtube.com"); |
598 crypto_config_.AddCanonicalSuffix(".googlevideo.com"); | 635 crypto_config_.AddCanonicalSuffix(".googlevideo.com"); |
599 crypto_config_.SetProofVerifier( | 636 crypto_config_.SetProofVerifier( |
600 new ProofVerifierChromium(cert_verifier, transport_security_state)); | 637 new ProofVerifierChromium(cert_verifier, transport_security_state)); |
601 crypto_config_.SetChannelIDSource( | 638 crypto_config_.SetChannelIDSource( |
602 new ChannelIDSourceChromium(channel_id_service)); | 639 new ChannelIDSourceChromium(channel_id_service)); |
603 base::CPU cpu; | 640 base::CPU cpu; |
604 if (cpu.has_aesni() && cpu.has_avx()) | 641 if (cpu.has_aesni() && cpu.has_avx()) |
605 crypto_config_.PreferAesGcm(); | 642 crypto_config_.PreferAesGcm(); |
606 if (!IsEcdsaSupported()) | 643 if (!IsEcdsaSupported()) |
607 crypto_config_.DisableEcdsa(); | 644 crypto_config_.DisableEcdsa(); |
608 } | 645 } |
609 | 646 |
610 QuicStreamFactory::~QuicStreamFactory() { | 647 QuicStreamFactory::~QuicStreamFactory() { |
611 CloseAllSessions(ERR_ABORTED); | 648 CloseAllSessions(ERR_ABORTED); |
612 while (!all_sessions_.empty()) { | 649 while (!all_sessions_.empty()) { |
613 delete all_sessions_.begin()->first; | 650 delete all_sessions_.begin()->first; |
614 all_sessions_.erase(all_sessions_.begin()); | 651 all_sessions_.erase(all_sessions_.begin()); |
615 } | 652 } |
616 STLDeleteValues(&active_jobs_); | 653 while (!active_jobs_.empty()) { |
654 const QuicServerId server_id = active_jobs_.begin()->first; | |
655 STLDeleteElements(&(active_jobs_[server_id])); | |
656 active_jobs_.erase(server_id); | |
657 } | |
617 } | 658 } |
618 | 659 |
619 void QuicStreamFactory::set_require_confirmation(bool require_confirmation) { | 660 void QuicStreamFactory::set_require_confirmation(bool require_confirmation) { |
620 require_confirmation_ = require_confirmation; | 661 require_confirmation_ = require_confirmation; |
621 if (http_server_properties_ && (!(local_address_ == IPEndPoint()))) { | 662 if (http_server_properties_ && (!(local_address_ == IPEndPoint()))) { |
622 // TODO(rtenneti): Delete host_port_pair and persist data in globals. | 663 // TODO(rtenneti): Delete host_port_pair and persist data in globals. |
623 HostPortPair host_port_pair(kDummyHostname, kDummyPort); | 664 HostPortPair host_port_pair(kDummyHostname, kDummyPort); |
624 http_server_properties_->SetSupportsQuic( | 665 http_server_properties_->SetSupportsQuic( |
625 host_port_pair, !require_confirmation, | 666 host_port_pair, !require_confirmation, |
626 local_address_.ToStringWithoutPort()); | 667 local_address_.ToStringWithoutPort()); |
627 } | 668 } |
628 } | 669 } |
629 | 670 |
630 int QuicStreamFactory::Create(const HostPortPair& host_port_pair, | 671 int QuicStreamFactory::Create(const HostPortPair& host_port_pair, |
631 bool is_https, | 672 bool is_https, |
632 PrivacyMode privacy_mode, | 673 PrivacyMode privacy_mode, |
633 base::StringPiece method, | 674 base::StringPiece method, |
634 const BoundNetLog& net_log, | 675 const BoundNetLog& net_log, |
635 QuicStreamRequest* request) { | 676 QuicStreamRequest* request) { |
636 QuicServerId server_id(host_port_pair, is_https, privacy_mode); | 677 QuicServerId server_id(host_port_pair, is_https, privacy_mode); |
637 if (HasActiveSession(server_id)) { | 678 if (HasActiveSession(server_id)) { |
638 request->set_stream(CreateIfSessionExists(server_id, net_log)); | 679 request->set_stream(CreateIfSessionExists(server_id, net_log)); |
639 return OK; | 680 return OK; |
640 } | 681 } |
641 | 682 |
642 if (HasActiveJob(server_id)) { | 683 if (HasActiveJob(server_id)) { |
643 Job* job = active_jobs_[server_id]; | 684 active_requests_[request] = server_id; |
644 active_requests_[request] = job; | 685 job_requests_map_[server_id].insert(request); |
645 job_requests_map_[job].insert(request); | |
646 return ERR_IO_PENDING; | 686 return ERR_IO_PENDING; |
647 } | 687 } |
648 | 688 |
689 // TODO(rtenneti): |task_runner_| is used by the Job. Initialize task_runner_ | |
690 // in the constructor after WebRequestActionWithThreadsTest.* tests are fixed. | |
691 if (!task_runner_) | |
692 task_runner_ = base::MessageLoop::current()->message_loop_proxy().get(); | |
693 | |
649 QuicServerInfo* quic_server_info = nullptr; | 694 QuicServerInfo* quic_server_info = nullptr; |
650 if (quic_server_info_factory_) { | 695 if (quic_server_info_factory_) { |
651 bool load_from_disk_cache = true; | 696 bool load_from_disk_cache = true; |
652 if (http_server_properties_) { | 697 if (http_server_properties_) { |
653 const AlternateProtocolMap& alternate_protocol_map = | 698 const AlternateProtocolMap& alternate_protocol_map = |
654 http_server_properties_->alternate_protocol_map(); | 699 http_server_properties_->alternate_protocol_map(); |
655 AlternateProtocolMap::const_iterator it = | 700 AlternateProtocolMap::const_iterator it = |
656 alternate_protocol_map.Peek(server_id.host_port_pair()); | 701 alternate_protocol_map.Peek(server_id.host_port_pair()); |
657 if (it == alternate_protocol_map.end() || it->second.protocol != QUIC) { | 702 if (it == alternate_protocol_map.end() || it->second.protocol != QUIC) { |
658 // If there is no entry for QUIC, consider that as a new server and | 703 // If there is no entry for QUIC, consider that as a new server and |
659 // don't wait for Cache thread to load the data for that server. | 704 // don't wait for Cache thread to load the data for that server. |
660 load_from_disk_cache = false; | 705 load_from_disk_cache = false; |
661 } | 706 } |
662 } | 707 } |
663 if (load_from_disk_cache) { | 708 if (load_from_disk_cache && CryptoConfigCacheIsEmpty(server_id)) { |
664 QuicCryptoClientConfig::CachedState* cached = | 709 quic_server_info = quic_server_info_factory_->GetForServer(server_id); |
665 crypto_config_.LookupOrCreate(server_id); | |
666 DCHECK(cached); | |
667 if (cached->IsEmpty()) { | |
668 quic_server_info = quic_server_info_factory_->GetForServer(server_id); | |
669 } | |
670 } | 710 } |
671 } | 711 } |
672 // TODO(rtenneti): Initialize task_runner_ in the constructor after | |
673 // WebRequestActionWithThreadsTest.* tests are fixed. | |
674 if (!task_runner_) | |
675 task_runner_ = base::MessageLoop::current()->message_loop_proxy().get(); | |
676 | 712 |
677 bool was_alternate_protocol_recently_broken = | 713 // Start an auxilary job that loads server config from the disk cache. |
678 http_server_properties_ && | 714 if (enable_connection_racing_ && quic_server_info && |
679 http_server_properties_->WasAlternateProtocolRecentlyBroken( | 715 (CreateAuxilaryJob(quic_server_info, server_id, method, net_log, |
680 server_id.host_port_pair()); | 716 request) == OK)) { |
681 scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_pair, is_https, | 717 DCHECK(HasActiveSession(server_id)); |
682 was_alternate_protocol_recently_broken, | 718 request->set_stream(CreateIfSessionExists(server_id, net_log)); |
683 privacy_mode, method, quic_server_info, net_log)); | 719 return OK; |
720 } | |
Ryan Hamilton
2015/02/04 20:10:29
Do you think it would make sense to delay starting
ramant (doing other things)
2015/02/05 03:39:41
Done.
| |
721 | |
722 scoped_ptr<Job> job(new Job( | |
723 this, host_resolver_, host_port_pair, is_https, | |
724 WasAlternateProtocolRecentlyBroken(server_id), privacy_mode, method, | |
725 enable_connection_racing_ ? nullptr : quic_server_info, net_log)); | |
684 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, | 726 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, |
685 base::Unretained(this), job.get())); | 727 base::Unretained(this), job.get())); |
686 | 728 |
687 if (rv == ERR_IO_PENDING) { | 729 if (rv == ERR_IO_PENDING) { |
688 active_requests_[request] = job.get(); | 730 active_requests_[request] = server_id; |
689 job_requests_map_[job.get()].insert(request); | 731 job_requests_map_[server_id].insert(request); |
690 active_jobs_[server_id] = job.release(); | 732 active_jobs_[server_id].insert(job.release()); |
733 return rv; | |
691 } | 734 } |
692 if (rv == OK) { | 735 if (rv == OK) { |
693 DCHECK(HasActiveSession(server_id)); | 736 DCHECK(HasActiveSession(server_id)); |
694 request->set_stream(CreateIfSessionExists(server_id, net_log)); | 737 request->set_stream(CreateIfSessionExists(server_id, net_log)); |
695 } | 738 } |
696 return rv; | 739 return rv; |
697 } | 740 } |
698 | 741 |
742 int QuicStreamFactory::CreateAuxilaryJob(QuicServerInfo* quic_server_info, | |
743 const QuicServerId server_id, | |
744 base::StringPiece method, | |
745 const BoundNetLog& net_log, | |
746 QuicStreamRequest* request) { | |
747 scoped_ptr<Job> aux_job(new Job( | |
748 this, host_resolver_, server_id.host_port_pair(), server_id.is_https(), | |
749 WasAlternateProtocolRecentlyBroken(server_id), server_id.privacy_mode(), | |
750 method, quic_server_info, net_log)); | |
751 int rv = aux_job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, | |
752 base::Unretained(this), aux_job.get())); | |
753 if (rv == ERR_IO_PENDING) | |
754 active_jobs_[server_id].insert(aux_job.release()); | |
755 return rv; | |
756 } | |
757 | |
699 bool QuicStreamFactory::OnResolution( | 758 bool QuicStreamFactory::OnResolution( |
700 const QuicServerId& server_id, | 759 const QuicServerId& server_id, |
701 const AddressList& address_list) { | 760 const AddressList& address_list) { |
702 DCHECK(!HasActiveSession(server_id)); | 761 DCHECK(!HasActiveSession(server_id)); |
703 if (disable_connection_pooling_) { | 762 if (disable_connection_pooling_) { |
704 return false; | 763 return false; |
705 } | 764 } |
706 for (const IPEndPoint& address : address_list) { | 765 for (const IPEndPoint& address : address_list) { |
707 const IpAliasKey ip_alias_key(address, server_id.is_https()); | 766 const IpAliasKey ip_alias_key(address, server_id.is_https()); |
708 if (!ContainsKey(ip_aliases_, ip_alias_key)) | 767 if (!ContainsKey(ip_aliases_, ip_alias_key)) |
709 continue; | 768 continue; |
710 | 769 |
711 const SessionSet& sessions = ip_aliases_[ip_alias_key]; | 770 const SessionSet& sessions = ip_aliases_[ip_alias_key]; |
712 for (QuicClientSession* session : sessions) { | 771 for (QuicClientSession* session : sessions) { |
713 if (!session->CanPool(server_id.host(), server_id.privacy_mode())) | 772 if (!session->CanPool(server_id.host(), server_id.privacy_mode())) |
714 continue; | 773 continue; |
715 active_sessions_[server_id] = session; | 774 active_sessions_[server_id] = session; |
716 session_aliases_[session].insert(server_id); | 775 session_aliases_[session].insert(server_id); |
717 return true; | 776 return true; |
718 } | 777 } |
719 } | 778 } |
720 return false; | 779 return false; |
721 } | 780 } |
722 | 781 |
723 void QuicStreamFactory::OnJobComplete(Job* job, int rv) { | 782 void QuicStreamFactory::OnJobComplete(Job* job, int rv) { |
783 QuicServerId server_id = job->server_id(); | |
784 if (job->is_cancelled()) { | |
785 JobSet* jobs = &(active_jobs_[server_id]); | |
786 if (jobs && (jobs->erase(job) == 1)) | |
787 delete job; | |
788 DCHECK_LT(0u, jobs->size()); // Verify there is atleast one job. | |
Ryan Hamilton
2015/02/04 20:10:29
It looks like jobs might be null. in that case, th
ramant (doing other things)
2015/02/05 03:39:41
In the previous implementation, removed the jobs a
ramant (doing other things)
2015/02/05 20:06:28
Checked that there is at least one other job to co
| |
789 return; | |
790 } | |
724 if (rv == OK) { | 791 if (rv == OK) { |
725 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 792 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
726 tracked_objects::ScopedTracker tracking_profile1( | 793 tracked_objects::ScopedTracker tracking_profile1( |
727 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 794 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
728 "422516 QuicStreamFactory::OnJobComplete1")); | 795 "422516 QuicStreamFactory::OnJobComplete1")); |
729 | 796 |
730 if (!always_require_handshake_confirmation_) | 797 if (!always_require_handshake_confirmation_) |
731 set_require_confirmation(false); | 798 set_require_confirmation(false); |
732 | 799 |
733 // Create all the streams, but do not notify them yet. | 800 // Create all the streams, but do not notify them yet. |
734 for (RequestSet::iterator it = job_requests_map_[job].begin(); | 801 for (RequestSet::iterator it = job_requests_map_[server_id].begin(); |
735 it != job_requests_map_[job].end() ; ++it) { | 802 it != job_requests_map_[server_id].end(); ++it) { |
736 DCHECK(HasActiveSession(job->server_id())); | 803 DCHECK(HasActiveSession(server_id)); |
737 (*it)->set_stream(CreateIfSessionExists(job->server_id(), | 804 (*it)->set_stream(CreateIfSessionExists(server_id, (*it)->net_log())); |
738 (*it)->net_log())); | |
739 } | 805 } |
740 } | 806 } |
741 | 807 |
742 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 808 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
743 tracked_objects::ScopedTracker tracking_profile2( | 809 tracked_objects::ScopedTracker tracking_profile2( |
744 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 810 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
745 "422516 QuicStreamFactory::OnJobComplete2")); | 811 "422516 QuicStreamFactory::OnJobComplete2")); |
746 | 812 |
747 while (!job_requests_map_[job].empty()) { | 813 while (!job_requests_map_[server_id].empty()) { |
748 RequestSet::iterator it = job_requests_map_[job].begin(); | 814 RequestSet::iterator it = job_requests_map_[server_id].begin(); |
749 QuicStreamRequest* request = *it; | 815 QuicStreamRequest* request = *it; |
750 job_requests_map_[job].erase(it); | 816 job_requests_map_[server_id].erase(it); |
751 active_requests_.erase(request); | 817 active_requests_.erase(request); |
752 // Even though we're invoking callbacks here, we don't need to worry | 818 // Even though we're invoking callbacks here, we don't need to worry |
753 // about |this| being deleted, because the factory is owned by the | 819 // about |this| being deleted, because the factory is owned by the |
754 // profile which can not be deleted via callbacks. | 820 // profile which can not be deleted via callbacks. |
755 request->OnRequestComplete(rv); | 821 request->OnRequestComplete(rv); |
756 } | 822 } |
757 | 823 |
758 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 824 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
759 tracked_objects::ScopedTracker tracking_profile3( | 825 tracked_objects::ScopedTracker tracking_profile3( |
760 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 826 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
761 "422516 QuicStreamFactory::OnJobComplete3")); | 827 "422516 QuicStreamFactory::OnJobComplete3")); |
762 | 828 |
763 active_jobs_.erase(job->server_id()); | 829 CancelOtherJob(job, server_id); // Cancel any pending job. |
764 job_requests_map_.erase(job); | 830 STLDeleteElements(&(active_jobs_[server_id])); // Delete all jobs. |
Ryan Hamilton
2015/02/04 20:10:29
nit: I think this two comments are pretty redundan
ramant (doing other things)
2015/02/05 03:39:41
Done.
| |
765 delete job; | 831 active_jobs_.erase(server_id); |
766 return; | 832 job_requests_map_.erase(server_id); |
767 } | 833 } |
768 | 834 |
769 // Returns a newly created QuicHttpStream owned by the caller, if a | 835 // Returns a newly created QuicHttpStream owned by the caller, if a |
770 // matching session already exists. Returns nullptr otherwise. | 836 // matching session already exists. Returns nullptr otherwise. |
771 scoped_ptr<QuicHttpStream> QuicStreamFactory::CreateIfSessionExists( | 837 scoped_ptr<QuicHttpStream> QuicStreamFactory::CreateIfSessionExists( |
772 const QuicServerId& server_id, | 838 const QuicServerId& server_id, |
773 const BoundNetLog& net_log) { | 839 const BoundNetLog& net_log) { |
774 if (!HasActiveSession(server_id)) { | 840 if (!HasActiveSession(server_id)) { |
775 DVLOG(1) << "No active session"; | 841 DVLOG(1) << "No active session"; |
776 return scoped_ptr<QuicHttpStream>(); | 842 return scoped_ptr<QuicHttpStream>(); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
835 | 901 |
836 const IpAliasKey ip_alias_key(session->connection()->peer_address(), | 902 const IpAliasKey ip_alias_key(session->connection()->peer_address(), |
837 aliases.begin()->is_https()); | 903 aliases.begin()->is_https()); |
838 ip_aliases_[ip_alias_key].erase(session); | 904 ip_aliases_[ip_alias_key].erase(session); |
839 if (ip_aliases_[ip_alias_key].empty()) { | 905 if (ip_aliases_[ip_alias_key].empty()) { |
840 ip_aliases_.erase(ip_alias_key); | 906 ip_aliases_.erase(ip_alias_key); |
841 } | 907 } |
842 QuicServerId server_id = *aliases.begin(); | 908 QuicServerId server_id = *aliases.begin(); |
843 session_aliases_.erase(session); | 909 session_aliases_.erase(session); |
844 Job* job = new Job(this, host_resolver_, session, server_id); | 910 Job* job = new Job(this, host_resolver_, session, server_id); |
845 active_jobs_[server_id] = job; | 911 active_jobs_[server_id].insert(job); |
846 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, | 912 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, |
847 base::Unretained(this), job)); | 913 base::Unretained(this), job)); |
848 DCHECK_EQ(ERR_IO_PENDING, rv); | 914 DCHECK_EQ(ERR_IO_PENDING, rv); |
849 } | 915 } |
850 | 916 |
851 void QuicStreamFactory::CancelRequest(QuicStreamRequest* request) { | 917 void QuicStreamFactory::CancelRequest(QuicStreamRequest* request) { |
852 DCHECK(ContainsKey(active_requests_, request)); | 918 DCHECK(ContainsKey(active_requests_, request)); |
853 Job* job = active_requests_[request]; | 919 QuicServerId server_id = active_requests_[request]; |
854 job_requests_map_[job].erase(request); | 920 job_requests_map_[server_id].erase(request); |
855 active_requests_.erase(request); | 921 active_requests_.erase(request); |
856 } | 922 } |
857 | 923 |
858 void QuicStreamFactory::CloseAllSessions(int error) { | 924 void QuicStreamFactory::CloseAllSessions(int error) { |
859 while (!active_sessions_.empty()) { | 925 while (!active_sessions_.empty()) { |
860 size_t initial_size = active_sessions_.size(); | 926 size_t initial_size = active_sessions_.size(); |
861 active_sessions_.begin()->second->CloseSessionOnError(error); | 927 active_sessions_.begin()->second->CloseSessionOnError(error); |
862 DCHECK_NE(initial_size, active_sessions_.size()); | 928 DCHECK_NE(initial_size, active_sessions_.size()); |
863 } | 929 } |
864 while (!all_sessions_.empty()) { | 930 while (!all_sessions_.empty()) { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
914 // kind of change it is, we have to flush the socket | 980 // kind of change it is, we have to flush the socket |
915 // pools to be safe. | 981 // pools to be safe. |
916 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); | 982 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); |
917 } | 983 } |
918 | 984 |
919 bool QuicStreamFactory::HasActiveSession( | 985 bool QuicStreamFactory::HasActiveSession( |
920 const QuicServerId& server_id) const { | 986 const QuicServerId& server_id) const { |
921 return ContainsKey(active_sessions_, server_id); | 987 return ContainsKey(active_sessions_, server_id); |
922 } | 988 } |
923 | 989 |
990 bool QuicStreamFactory::HasActiveJob(const QuicServerId& key) const { | |
991 return ContainsKey(active_jobs_, key); | |
992 } | |
993 | |
994 void QuicStreamFactory::CancelOtherJob(Job* job, | |
995 const QuicServerId& server_id) { | |
996 Job* other_job = nullptr; | |
997 for (JobSet::iterator it = active_jobs_[server_id].begin(); | |
Ryan Hamilton
2015/02/04 20:10:29
nit: for (Job* job : active_jobs_[server_id]) {
..
ramant (doing other things)
2015/02/05 03:39:41
Done.
| |
998 it != active_jobs_[server_id].end(); ++it) { | |
999 if (*it != job) { | |
1000 other_job = *it; | |
Ryan Hamilton
2015/02/04 20:10:29
I think I'd be inclined to do this:
CancelOtherJo
ramant (doing other things)
2015/02/05 03:39:41
Done.
| |
1001 break; | |
1002 } | |
1003 } | |
1004 if (!other_job) | |
1005 return; | |
1006 if (other_job->is_cancelled()) | |
1007 return; | |
1008 other_job->CancelJob(); | |
Ryan Hamilton
2015/02/04 20:10:29
It looks like CancelJob does not invoke the callba
ramant (doing other things)
2015/02/05 03:39:41
Deleted this method. Factory is cancelling the job
| |
1009 if (other_job->session()) { | |
1010 other_job->session()->connection()->SendConnectionClose( | |
1011 QUIC_CONNECTION_IP_POOLED); | |
1012 } | |
1013 } | |
1014 | |
924 int QuicStreamFactory::CreateSession( | 1015 int QuicStreamFactory::CreateSession( |
925 const QuicServerId& server_id, | 1016 const QuicServerId& server_id, |
926 scoped_ptr<QuicServerInfo> server_info, | 1017 scoped_ptr<QuicServerInfo> server_info, |
927 const AddressList& address_list, | 1018 const AddressList& address_list, |
928 const BoundNetLog& net_log, | 1019 const BoundNetLog& net_log, |
929 QuicClientSession** session) { | 1020 QuicClientSession** session) { |
930 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 1021 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
931 tracked_objects::ScopedTracker tracking_profile1( | 1022 tracked_objects::ScopedTracker tracking_profile1( |
932 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1023 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
933 "422516 QuicStreamFactory::CreateSession1")); | 1024 "422516 QuicStreamFactory::CreateSession1")); |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1130 UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.ClosedDuringInitializeSession", | 1221 UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.ClosedDuringInitializeSession", |
1131 closed_during_initialize); | 1222 closed_during_initialize); |
1132 if (closed_during_initialize) { | 1223 if (closed_during_initialize) { |
1133 DLOG(DFATAL) << "Session closed during initialize"; | 1224 DLOG(DFATAL) << "Session closed during initialize"; |
1134 *session = nullptr; | 1225 *session = nullptr; |
1135 return ERR_CONNECTION_CLOSED; | 1226 return ERR_CONNECTION_CLOSED; |
1136 } | 1227 } |
1137 return OK; | 1228 return OK; |
1138 } | 1229 } |
1139 | 1230 |
1140 bool QuicStreamFactory::HasActiveJob(const QuicServerId& key) const { | |
1141 return ContainsKey(active_jobs_, key); | |
1142 } | |
1143 | |
1144 void QuicStreamFactory::ActivateSession( | 1231 void QuicStreamFactory::ActivateSession( |
1145 const QuicServerId& server_id, | 1232 const QuicServerId& server_id, |
1146 QuicClientSession* session) { | 1233 QuicClientSession* session) { |
1147 DCHECK(!HasActiveSession(server_id)); | 1234 DCHECK(!HasActiveSession(server_id)); |
1148 UMA_HISTOGRAM_COUNTS("Net.QuicActiveSessions", active_sessions_.size()); | 1235 UMA_HISTOGRAM_COUNTS("Net.QuicActiveSessions", active_sessions_.size()); |
1149 active_sessions_[server_id] = session; | 1236 active_sessions_[server_id] = session; |
1150 session_aliases_[session].insert(server_id); | 1237 session_aliases_[session].insert(server_id); |
1151 const IpAliasKey ip_alias_key(session->connection()->peer_address(), | 1238 const IpAliasKey ip_alias_key(session->connection()->peer_address(), |
1152 server_id.is_https()); | 1239 server_id.is_https()); |
1153 DCHECK(!ContainsKey(ip_aliases_[ip_alias_key], session)); | 1240 DCHECK(!ContainsKey(ip_aliases_[ip_alias_key], session)); |
1154 ip_aliases_[ip_alias_key].insert(session); | 1241 ip_aliases_[ip_alias_key].insert(session); |
1155 } | 1242 } |
1156 | 1243 |
1157 int64 QuicStreamFactory::GetServerNetworkStatsSmoothedRttInMicroseconds( | 1244 int64 QuicStreamFactory::GetServerNetworkStatsSmoothedRttInMicroseconds( |
1158 const QuicServerId& server_id) const { | 1245 const QuicServerId& server_id) const { |
1159 if (!http_server_properties_) | 1246 if (!http_server_properties_) |
1160 return 0; | 1247 return 0; |
1161 const ServerNetworkStats* stats = | 1248 const ServerNetworkStats* stats = |
1162 http_server_properties_->GetServerNetworkStats( | 1249 http_server_properties_->GetServerNetworkStats( |
1163 server_id.host_port_pair()); | 1250 server_id.host_port_pair()); |
1164 if (stats == nullptr) | 1251 if (stats == nullptr) |
1165 return 0; | 1252 return 0; |
1166 return stats->srtt.InMicroseconds(); | 1253 return stats->srtt.InMicroseconds(); |
1167 } | 1254 } |
1168 | 1255 |
1256 bool QuicStreamFactory::WasAlternateProtocolRecentlyBroken( | |
1257 const QuicServerId& server_id) const { | |
1258 return http_server_properties_ && | |
1259 http_server_properties_->WasAlternateProtocolRecentlyBroken( | |
1260 server_id.host_port_pair()); | |
1261 } | |
1262 | |
1263 bool QuicStreamFactory::CryptoConfigCacheIsEmpty( | |
1264 const QuicServerId& server_id) { | |
1265 QuicCryptoClientConfig::CachedState* cached = | |
1266 crypto_config_.LookupOrCreate(server_id); | |
1267 return cached->IsEmpty(); | |
1268 } | |
1269 | |
1169 void QuicStreamFactory::InitializeCachedStateInCryptoConfig( | 1270 void QuicStreamFactory::InitializeCachedStateInCryptoConfig( |
1170 const QuicServerId& server_id, | 1271 const QuicServerId& server_id, |
1171 const scoped_ptr<QuicServerInfo>& server_info) { | 1272 const scoped_ptr<QuicServerInfo>& server_info) { |
1172 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. | 1273 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. |
1173 tracked_objects::ScopedTracker tracking_profile1( | 1274 tracked_objects::ScopedTracker tracking_profile1( |
1174 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1275 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
1175 "422516 QuicStreamFactory::InitializeCachedStateInCryptoConfig1")); | 1276 "422516 QuicStreamFactory::InitializeCachedStateInCryptoConfig1")); |
1176 | 1277 |
1177 // |server_info| will be NULL, if a non-empty server config already exists in | 1278 // |server_info| will be NULL, if a non-empty server config already exists in |
1178 // the memory cache. This is a minor optimization to avoid LookupOrCreate. | 1279 // the memory cache. This is a minor optimization to avoid LookupOrCreate. |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1272 http_server_properties_->ClearAlternateProtocol(server); | 1373 http_server_properties_->ClearAlternateProtocol(server); |
1273 http_server_properties_->SetAlternateProtocol( | 1374 http_server_properties_->SetAlternateProtocol( |
1274 server, alternate.port, alternate.protocol, 1); | 1375 server, alternate.port, alternate.protocol, 1); |
1275 DCHECK_EQ(QUIC, | 1376 DCHECK_EQ(QUIC, |
1276 http_server_properties_->GetAlternateProtocol(server).protocol); | 1377 http_server_properties_->GetAlternateProtocol(server).protocol); |
1277 DCHECK(http_server_properties_->WasAlternateProtocolRecentlyBroken( | 1378 DCHECK(http_server_properties_->WasAlternateProtocolRecentlyBroken( |
1278 server)); | 1379 server)); |
1279 } | 1380 } |
1280 | 1381 |
1281 } // namespace net | 1382 } // namespace net |
OLD | NEW |