Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(623)

Side by Side Diff: net/quic/quic_stream_factory.cc

Issue 881133004: QUIC - Race two connections. One connection which loads data from disk (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 class QuicStreamFactory::Job { 139 class QuicStreamFactory::Job {
140 public: 140 public:
141 Job(QuicStreamFactory* factory, 141 Job(QuicStreamFactory* factory,
142 HostResolver* host_resolver, 142 HostResolver* host_resolver,
143 const HostPortPair& host_port_pair, 143 const HostPortPair& host_port_pair,
144 bool is_https, 144 bool is_https,
145 bool was_alternate_protocol_recently_broken, 145 bool was_alternate_protocol_recently_broken,
146 PrivacyMode privacy_mode, 146 PrivacyMode privacy_mode,
147 base::StringPiece method, 147 base::StringPiece method,
148 QuicServerInfo* server_info, 148 QuicServerInfo* server_info,
149 bool is_main_job,
149 const BoundNetLog& net_log); 150 const BoundNetLog& net_log);
150 151
151 // Creates a new job to handle the resumption of for connecting an 152 // Creates a new job to handle the resumption of for connecting an
152 // existing session. 153 // existing session.
153 Job(QuicStreamFactory* factory, 154 Job(QuicStreamFactory* factory,
154 HostResolver* host_resolver, 155 HostResolver* host_resolver,
155 QuicClientSession* session, 156 QuicClientSession* session,
156 QuicServerId server_id); 157 QuicServerId server_id);
157 158
158 ~Job(); 159 ~Job();
159 160
160 int Run(const CompletionCallback& callback); 161 int Run(const CompletionCallback& callback);
161 162
162 int DoLoop(int rv); 163 int DoLoop(int rv);
163 int DoResolveHost(); 164 int DoResolveHost();
164 int DoResolveHostComplete(int rv); 165 int DoResolveHostComplete(int rv);
165 int DoLoadServerInfo(); 166 int DoLoadServerInfo();
166 int DoLoadServerInfoComplete(int rv); 167 int DoLoadServerInfoComplete(int rv);
167 int DoConnect(); 168 int DoConnect();
168 int DoResumeConnect(); 169 int DoResumeConnect();
169 int DoConnectComplete(int rv); 170 int DoConnectComplete(int rv);
170 171
171 void OnIOComplete(int rv); 172 void OnIOComplete(int rv);
172 173
173 void CancelWaitForDataReadyCallback(); 174 void CancelWaitForDataReadyCallback();
174 175
175 CompletionCallback callback() { 176 CompletionCallback callback() { return callback_; }
176 return callback_;
177 }
178 177
179 const QuicServerId server_id() const { 178 const QuicServerId server_id() const { return server_id_; }
180 return server_id_; 179
180 QuicSession* session() { return session_; }
181
182 bool is_main_job() const { return is_main_job_; }
183
184 bool is_cancelled() const { return is_cancelled_; }
Ryan Hamilton 2015/02/03 18:54:36 nit: newline after
ramant (doing other things) 2015/02/04 17:40:46 Done.
185 void CancelJob() {
186 DCHECK(!is_cancelled_);
187 is_cancelled_ = true;
181 } 188 }
182 189
183 private: 190 private:
184 enum IoState { 191 enum IoState {
185 STATE_NONE, 192 STATE_NONE,
186 STATE_RESOLVE_HOST, 193 STATE_RESOLVE_HOST,
187 STATE_RESOLVE_HOST_COMPLETE, 194 STATE_RESOLVE_HOST_COMPLETE,
188 STATE_LOAD_SERVER_INFO, 195 STATE_LOAD_SERVER_INFO,
189 STATE_LOAD_SERVER_INFO_COMPLETE, 196 STATE_LOAD_SERVER_INFO_COMPLETE,
190 STATE_CONNECT, 197 STATE_CONNECT,
191 STATE_RESUME_CONNECT, 198 STATE_RESUME_CONNECT,
192 STATE_CONNECT_COMPLETE, 199 STATE_CONNECT_COMPLETE,
193 }; 200 };
194 IoState io_state_; 201 IoState io_state_;
195 202
196 QuicStreamFactory* factory_; 203 QuicStreamFactory* factory_;
197 SingleRequestHostResolver host_resolver_; 204 SingleRequestHostResolver host_resolver_;
198 QuicServerId server_id_; 205 QuicServerId server_id_;
199 bool is_post_; 206 bool is_post_;
200 bool was_alternate_protocol_recently_broken_; 207 bool was_alternate_protocol_recently_broken_;
201 scoped_ptr<QuicServerInfo> server_info_; 208 scoped_ptr<QuicServerInfo> server_info_;
209 bool is_main_job_;
210 bool is_cancelled_;
202 const BoundNetLog net_log_; 211 const BoundNetLog net_log_;
203 QuicClientSession* session_; 212 QuicClientSession* session_;
204 CompletionCallback callback_; 213 CompletionCallback callback_;
205 AddressList address_list_; 214 AddressList address_list_;
206 base::TimeTicks disk_cache_load_start_time_; 215 base::TimeTicks disk_cache_load_start_time_;
207 base::TimeTicks dns_resolution_start_time_; 216 base::TimeTicks dns_resolution_start_time_;
208 base::WeakPtrFactory<Job> weak_factory_; 217 base::WeakPtrFactory<Job> weak_factory_;
209 DISALLOW_COPY_AND_ASSIGN(Job); 218 DISALLOW_COPY_AND_ASSIGN(Job);
210 }; 219 };
211 220
212 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, 221 QuicStreamFactory::Job::Job(QuicStreamFactory* factory,
213 HostResolver* host_resolver, 222 HostResolver* host_resolver,
214 const HostPortPair& host_port_pair, 223 const HostPortPair& host_port_pair,
215 bool is_https, 224 bool is_https,
216 bool was_alternate_protocol_recently_broken, 225 bool was_alternate_protocol_recently_broken,
217 PrivacyMode privacy_mode, 226 PrivacyMode privacy_mode,
218 base::StringPiece method, 227 base::StringPiece method,
219 QuicServerInfo* server_info, 228 QuicServerInfo* server_info,
229 bool is_main_job,
220 const BoundNetLog& net_log) 230 const BoundNetLog& net_log)
221 : io_state_(STATE_RESOLVE_HOST), 231 : io_state_(STATE_RESOLVE_HOST),
222 factory_(factory), 232 factory_(factory),
223 host_resolver_(host_resolver), 233 host_resolver_(host_resolver),
224 server_id_(host_port_pair, is_https, privacy_mode), 234 server_id_(host_port_pair, is_https, privacy_mode),
225 is_post_(method == "POST"), 235 is_post_(method == "POST"),
226 was_alternate_protocol_recently_broken_( 236 was_alternate_protocol_recently_broken_(
227 was_alternate_protocol_recently_broken), 237 was_alternate_protocol_recently_broken),
228 server_info_(server_info), 238 server_info_(server_info),
239 is_main_job_(is_main_job),
240 is_cancelled_(false),
229 net_log_(net_log), 241 net_log_(net_log),
230 session_(nullptr), 242 session_(nullptr),
231 weak_factory_(this) {} 243 weak_factory_(this) {
244 }
232 245
233 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, 246 QuicStreamFactory::Job::Job(QuicStreamFactory* factory,
234 HostResolver* host_resolver, 247 HostResolver* host_resolver,
235 QuicClientSession* session, 248 QuicClientSession* session,
236 QuicServerId server_id) 249 QuicServerId server_id)
237 : io_state_(STATE_RESUME_CONNECT), 250 : io_state_(STATE_RESUME_CONNECT),
238 factory_(factory), 251 factory_(factory),
239 host_resolver_(host_resolver), // unused 252 host_resolver_(host_resolver), // unused
240 server_id_(server_id), 253 server_id_(server_id),
241 is_post_(false), // unused 254 is_post_(false), // unused
242 was_alternate_protocol_recently_broken_(false), // unused 255 was_alternate_protocol_recently_broken_(false), // unused
243 net_log_(session->net_log()), // unused 256 net_log_(session->net_log()), // unused
244 session_(session), 257 session_(session),
245 weak_factory_(this) {} 258 weak_factory_(this) {}
246 259
247 QuicStreamFactory::Job::~Job() { 260 QuicStreamFactory::Job::~Job() {
261 if (server_info_) {
262 // Cancel any pending callbacks.
263 server_info_->CancelWaitForDataReadyCallback();
Ryan Hamilton 2015/02/03 18:54:36 Out of curiosity, did we need this code before?
ramant (doing other things) 2015/02/04 17:40:46 If we had closed the job when it is in the WaitFor
264 }
248 } 265 }
249 266
250 int QuicStreamFactory::Job::Run(const CompletionCallback& callback) { 267 int QuicStreamFactory::Job::Run(const CompletionCallback& callback) {
251 int rv = DoLoop(OK); 268 int rv = DoLoop(OK);
252 if (rv == ERR_IO_PENDING) 269 if (rv == ERR_IO_PENDING)
253 callback_ = callback; 270 callback_ = callback;
254 271
255 return rv > 0 ? OK : rv; 272 return rv > 0 ? OK : rv;
256 } 273 }
257 274
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 } 435 }
419 436
420 int QuicStreamFactory::Job::DoConnect() { 437 int QuicStreamFactory::Job::DoConnect() {
421 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. 438 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed.
422 tracked_objects::ScopedTracker tracking_profile( 439 tracked_objects::ScopedTracker tracking_profile(
423 FROM_HERE_WITH_EXPLICIT_FUNCTION( 440 FROM_HERE_WITH_EXPLICIT_FUNCTION(
424 "422516 QuicStreamFactory::Job::DoConnect")); 441 "422516 QuicStreamFactory::Job::DoConnect"));
425 442
426 io_state_ = STATE_CONNECT_COMPLETE; 443 io_state_ = STATE_CONNECT_COMPLETE;
427 444
445 // If this is the main job, check if the auxilary job got the server config
446 // from the server, if so discontinue this job. If not, discontinue the
447 // auxilary job.
448 if (factory_->enable_connection_racing()) {
449 if (is_main_job_) {
450 if (!factory_->CryptoConfigCacheIsEmpty(server_id_)) {
451 is_cancelled_ = true;
452 return ERR_CONNECTION_CLOSED;
453 }
454 factory_->CancelAuxilaryJob(this, server_id_);
455 } else if (is_cancelled_) {
456 // This is the auxilary job and it is cancelled.
457 return ERR_CONNECTION_CLOSED;
458 }
459 }
Ryan Hamilton 2015/02/03 18:54:36 This seems to be the only place where a job is can
ramant (doing other things) 2015/02/04 17:40:46 Cancelled the job that loads server config from di
460
428 int rv = factory_->CreateSession(server_id_, server_info_.Pass(), 461 int rv = factory_->CreateSession(server_id_, server_info_.Pass(),
429 address_list_, net_log_, &session_); 462 address_list_, net_log_, &session_);
430 if (rv != OK) { 463 if (rv != OK) {
431 DCHECK(rv != ERR_IO_PENDING); 464 DCHECK(rv != ERR_IO_PENDING);
432 DCHECK(!session_); 465 DCHECK(!session_);
433 return rv; 466 return rv;
434 } 467 }
435 468
436 if (!session_->connection()->connected()) { 469 if (!session_->connection()->connected()) {
437 return ERR_CONNECTION_CLOSED; 470 return ERR_CONNECTION_CLOSED;
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
581 config_(InitializeQuicConfig(connection_options)), 614 config_(InitializeQuicConfig(connection_options)),
582 supported_versions_(supported_versions), 615 supported_versions_(supported_versions),
583 enable_port_selection_(enable_port_selection), 616 enable_port_selection_(enable_port_selection),
584 always_require_handshake_confirmation_( 617 always_require_handshake_confirmation_(
585 always_require_handshake_confirmation), 618 always_require_handshake_confirmation),
586 disable_connection_pooling_(disable_connection_pooling), 619 disable_connection_pooling_(disable_connection_pooling),
587 load_server_info_timeout_ms_(load_server_info_timeout), 620 load_server_info_timeout_ms_(load_server_info_timeout),
588 load_server_info_timeout_srtt_multiplier_( 621 load_server_info_timeout_srtt_multiplier_(
589 load_server_info_timeout_srtt_multiplier), 622 load_server_info_timeout_srtt_multiplier),
590 enable_truncated_connection_ids_(enable_truncated_connection_ids), 623 enable_truncated_connection_ids_(enable_truncated_connection_ids),
624 enable_connection_racing_(false),
591 port_seed_(random_generator_->RandUint64()), 625 port_seed_(random_generator_->RandUint64()),
592 check_persisted_supports_quic_(true), 626 check_persisted_supports_quic_(true),
593 task_runner_(nullptr), 627 task_runner_(nullptr),
594 weak_factory_(this) { 628 weak_factory_(this) {
595 DCHECK(transport_security_state_); 629 DCHECK(transport_security_state_);
596 crypto_config_.set_user_agent_id(user_agent_id); 630 crypto_config_.set_user_agent_id(user_agent_id);
597 crypto_config_.AddCanonicalSuffix(".c.youtube.com"); 631 crypto_config_.AddCanonicalSuffix(".c.youtube.com");
598 crypto_config_.AddCanonicalSuffix(".googlevideo.com"); 632 crypto_config_.AddCanonicalSuffix(".googlevideo.com");
599 crypto_config_.SetProofVerifier( 633 crypto_config_.SetProofVerifier(
600 new ProofVerifierChromium(cert_verifier, transport_security_state)); 634 new ProofVerifierChromium(cert_verifier, transport_security_state));
601 crypto_config_.SetChannelIDSource( 635 crypto_config_.SetChannelIDSource(
602 new ChannelIDSourceChromium(channel_id_service)); 636 new ChannelIDSourceChromium(channel_id_service));
603 base::CPU cpu; 637 base::CPU cpu;
604 if (cpu.has_aesni() && cpu.has_avx()) 638 if (cpu.has_aesni() && cpu.has_avx())
605 crypto_config_.PreferAesGcm(); 639 crypto_config_.PreferAesGcm();
606 if (!IsEcdsaSupported()) 640 if (!IsEcdsaSupported())
607 crypto_config_.DisableEcdsa(); 641 crypto_config_.DisableEcdsa();
608 } 642 }
609 643
610 QuicStreamFactory::~QuicStreamFactory() { 644 QuicStreamFactory::~QuicStreamFactory() {
611 CloseAllSessions(ERR_ABORTED); 645 CloseAllSessions(ERR_ABORTED);
612 while (!all_sessions_.empty()) { 646 while (!all_sessions_.empty()) {
613 delete all_sessions_.begin()->first; 647 delete all_sessions_.begin()->first;
614 all_sessions_.erase(all_sessions_.begin()); 648 all_sessions_.erase(all_sessions_.begin());
615 } 649 }
616 STLDeleteValues(&active_jobs_); 650 while (!active_jobs_.empty()) {
651 const QuicServerId server_id = active_jobs_.begin()->first;
652 STLDeleteElements(&(active_jobs_[server_id]));
653 active_jobs_.erase(server_id);
654 }
617 } 655 }
618 656
619 void QuicStreamFactory::set_require_confirmation(bool require_confirmation) { 657 void QuicStreamFactory::set_require_confirmation(bool require_confirmation) {
620 require_confirmation_ = require_confirmation; 658 require_confirmation_ = require_confirmation;
621 if (http_server_properties_ && (!(local_address_ == IPEndPoint()))) { 659 if (http_server_properties_ && (!(local_address_ == IPEndPoint()))) {
622 // TODO(rtenneti): Delete host_port_pair and persist data in globals. 660 // TODO(rtenneti): Delete host_port_pair and persist data in globals.
623 HostPortPair host_port_pair(kDummyHostname, kDummyPort); 661 HostPortPair host_port_pair(kDummyHostname, kDummyPort);
624 http_server_properties_->SetSupportsQuic( 662 http_server_properties_->SetSupportsQuic(
625 host_port_pair, !require_confirmation, 663 host_port_pair, !require_confirmation,
626 local_address_.ToStringWithoutPort()); 664 local_address_.ToStringWithoutPort());
627 } 665 }
628 } 666 }
629 667
630 int QuicStreamFactory::Create(const HostPortPair& host_port_pair, 668 int QuicStreamFactory::Create(const HostPortPair& host_port_pair,
631 bool is_https, 669 bool is_https,
632 PrivacyMode privacy_mode, 670 PrivacyMode privacy_mode,
633 base::StringPiece method, 671 base::StringPiece method,
634 const BoundNetLog& net_log, 672 const BoundNetLog& net_log,
635 QuicStreamRequest* request) { 673 QuicStreamRequest* request) {
636 QuicServerId server_id(host_port_pair, is_https, privacy_mode); 674 QuicServerId server_id(host_port_pair, is_https, privacy_mode);
637 if (HasActiveSession(server_id)) { 675 if (HasActiveSession(server_id)) {
638 request->set_stream(CreateIfSessionExists(server_id, net_log)); 676 request->set_stream(CreateIfSessionExists(server_id, net_log));
639 return OK; 677 return OK;
640 } 678 }
641 679
642 if (HasActiveJob(server_id)) { 680 if (HasActiveJob(server_id)) {
643 Job* job = active_jobs_[server_id]; 681 active_requests_[request] = server_id;
644 active_requests_[request] = job; 682 job_requests_map_[server_id].insert(request);
645 job_requests_map_[job].insert(request);
646 return ERR_IO_PENDING; 683 return ERR_IO_PENDING;
647 } 684 }
648 685
686 // TODO(rtenneti): |task_runner_| is used by the Job. Initialize task_runner_
687 // in the constructor after WebRequestActionWithThreadsTest.* tests are fixed.
688 if (!task_runner_)
689 task_runner_ = base::MessageLoop::current()->message_loop_proxy().get();
690
649 QuicServerInfo* quic_server_info = nullptr; 691 QuicServerInfo* quic_server_info = nullptr;
650 if (quic_server_info_factory_) { 692 if (quic_server_info_factory_) {
651 bool load_from_disk_cache = true; 693 bool load_from_disk_cache = true;
652 if (http_server_properties_) { 694 if (http_server_properties_) {
653 const AlternateProtocolMap& alternate_protocol_map = 695 const AlternateProtocolMap& alternate_protocol_map =
654 http_server_properties_->alternate_protocol_map(); 696 http_server_properties_->alternate_protocol_map();
655 AlternateProtocolMap::const_iterator it = 697 AlternateProtocolMap::const_iterator it =
656 alternate_protocol_map.Peek(server_id.host_port_pair()); 698 alternate_protocol_map.Peek(server_id.host_port_pair());
657 if (it == alternate_protocol_map.end() || it->second.protocol != QUIC) { 699 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 700 // 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. 701 // don't wait for Cache thread to load the data for that server.
660 load_from_disk_cache = false; 702 load_from_disk_cache = false;
661 } 703 }
662 } 704 }
663 if (load_from_disk_cache) { 705 if (load_from_disk_cache && CryptoConfigCacheIsEmpty(server_id)) {
664 QuicCryptoClientConfig::CachedState* cached = 706 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 } 707 }
671 } 708 }
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 709
677 bool was_alternate_protocol_recently_broken =
678 http_server_properties_ &&
679 http_server_properties_->WasAlternateProtocolRecentlyBroken(
680 server_id.host_port_pair());
681 scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_pair, is_https, 710 scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_pair, is_https,
682 was_alternate_protocol_recently_broken, 711 WasAlternateProtocolRecentlyBroken(server_id),
683 privacy_mode, method, quic_server_info, net_log)); 712 privacy_mode, method, quic_server_info,
713 true /*is_main_job*/, net_log));
684 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, 714 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete,
685 base::Unretained(this), job.get())); 715 base::Unretained(this), job.get()));
686 716
687 if (rv == ERR_IO_PENDING) { 717 if (rv == ERR_IO_PENDING) {
688 active_requests_[request] = job.get(); 718 // Start an auxilary job that doesn't require loading of server config
689 job_requests_map_[job.get()].insert(request); 719 // from the disk cache.
690 active_jobs_[server_id] = job.release(); 720 if (enable_connection_racing_ && quic_server_info &&
721 (CreateAuxilaryJob(server_id, method, net_log, request) == OK)) {
722 return OK;
Ryan Hamilton 2015/02/03 18:54:36 If this returns OK, it looks like we skip the code
ramant (doing other things) 2015/02/04 17:40:46 Removed the duplicated code from lines 750-753. D
723 }
724 active_requests_[request] = server_id;
725 job_requests_map_[server_id].insert(request);
726 active_jobs_[server_id].insert(job.release());
727 return rv;
691 } 728 }
692 if (rv == OK) { 729 if (rv == OK) {
693 DCHECK(HasActiveSession(server_id)); 730 DCHECK(HasActiveSession(server_id));
731 request->set_stream(CreateIfSessionExists(server_id, net_log));
732 }
733 return rv;
734 }
735
736 int QuicStreamFactory::CreateAuxilaryJob(const QuicServerId server_id,
737 base::StringPiece method,
738 const BoundNetLog& net_log,
739 QuicStreamRequest* request) {
740 scoped_ptr<Job> aux_job(new Job(
741 this, host_resolver_, server_id.host_port_pair(), server_id.is_https(),
742 WasAlternateProtocolRecentlyBroken(server_id), server_id.privacy_mode(),
743 method, nullptr, false /*is_main_job*/, net_log));
744 int rv = aux_job->Run(base::Bind(&QuicStreamFactory::OnJobComplete,
745 base::Unretained(this), aux_job.get()));
746 if (rv == ERR_IO_PENDING) {
747 active_jobs_[server_id].insert(aux_job.release());
748 return rv;
749 }
750 if (rv == OK) {
751 DCHECK(HasActiveSession(server_id));
694 request->set_stream(CreateIfSessionExists(server_id, net_log)); 752 request->set_stream(CreateIfSessionExists(server_id, net_log));
695 } 753 }
696 return rv; 754 return rv;
697 } 755 }
698 756
699 bool QuicStreamFactory::OnResolution( 757 bool QuicStreamFactory::OnResolution(
700 const QuicServerId& server_id, 758 const QuicServerId& server_id,
701 const AddressList& address_list) { 759 const AddressList& address_list) {
702 DCHECK(!HasActiveSession(server_id)); 760 DCHECK(!HasActiveSession(server_id));
703 if (disable_connection_pooling_) { 761 if (disable_connection_pooling_) {
(...skipping 10 matching lines...) Expand all
714 continue; 772 continue;
715 active_sessions_[server_id] = session; 773 active_sessions_[server_id] = session;
716 session_aliases_[session].insert(server_id); 774 session_aliases_[session].insert(server_id);
717 return true; 775 return true;
718 } 776 }
719 } 777 }
720 return false; 778 return false;
721 } 779 }
722 780
723 void QuicStreamFactory::OnJobComplete(Job* job, int rv) { 781 void QuicStreamFactory::OnJobComplete(Job* job, int rv) {
782 QuicServerId server_id = job->server_id();
724 if (rv == OK) { 783 if (rv == OK) {
725 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. 784 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed.
726 tracked_objects::ScopedTracker tracking_profile1( 785 tracked_objects::ScopedTracker tracking_profile1(
727 FROM_HERE_WITH_EXPLICIT_FUNCTION( 786 FROM_HERE_WITH_EXPLICIT_FUNCTION(
728 "422516 QuicStreamFactory::OnJobComplete1")); 787 "422516 QuicStreamFactory::OnJobComplete1"));
729 788
730 if (!always_require_handshake_confirmation_) 789 if (!always_require_handshake_confirmation_)
731 set_require_confirmation(false); 790 set_require_confirmation(false);
732 791
733 // Create all the streams, but do not notify them yet. 792 // Create all the streams, but do not notify them yet.
734 for (RequestSet::iterator it = job_requests_map_[job].begin(); 793 for (RequestSet::iterator it = job_requests_map_[server_id].begin();
735 it != job_requests_map_[job].end() ; ++it) { 794 it != job_requests_map_[server_id].end(); ++it) {
736 DCHECK(HasActiveSession(job->server_id())); 795 DCHECK(HasActiveSession(server_id));
737 (*it)->set_stream(CreateIfSessionExists(job->server_id(), 796 (*it)->set_stream(CreateIfSessionExists(server_id, (*it)->net_log()));
738 (*it)->net_log()));
739 } 797 }
798 } else if (job->is_cancelled() && (!active_jobs_[server_id].empty())) {
Ryan Hamilton 2015/02/03 18:54:36 Can rv == OK if the job was cancelled? In this cas
ramant (doing other things) 2015/02/04 17:40:46 Previously STLDeleteElements was deleting all the
799 return;
740 } 800 }
741 801
742 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. 802 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed.
743 tracked_objects::ScopedTracker tracking_profile2( 803 tracked_objects::ScopedTracker tracking_profile2(
744 FROM_HERE_WITH_EXPLICIT_FUNCTION( 804 FROM_HERE_WITH_EXPLICIT_FUNCTION(
745 "422516 QuicStreamFactory::OnJobComplete2")); 805 "422516 QuicStreamFactory::OnJobComplete2"));
746 806
747 while (!job_requests_map_[job].empty()) { 807 while (!job_requests_map_[server_id].empty()) {
748 RequestSet::iterator it = job_requests_map_[job].begin(); 808 RequestSet::iterator it = job_requests_map_[server_id].begin();
749 QuicStreamRequest* request = *it; 809 QuicStreamRequest* request = *it;
750 job_requests_map_[job].erase(it); 810 job_requests_map_[server_id].erase(it);
751 active_requests_.erase(request); 811 active_requests_.erase(request);
752 // Even though we're invoking callbacks here, we don't need to worry 812 // 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 813 // about |this| being deleted, because the factory is owned by the
754 // profile which can not be deleted via callbacks. 814 // profile which can not be deleted via callbacks.
755 request->OnRequestComplete(rv); 815 request->OnRequestComplete(rv);
756 } 816 }
757 817
758 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. 818 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed.
759 tracked_objects::ScopedTracker tracking_profile3( 819 tracked_objects::ScopedTracker tracking_profile3(
760 FROM_HERE_WITH_EXPLICIT_FUNCTION( 820 FROM_HERE_WITH_EXPLICIT_FUNCTION(
761 "422516 QuicStreamFactory::OnJobComplete3")); 821 "422516 QuicStreamFactory::OnJobComplete3"));
762 822
763 active_jobs_.erase(job->server_id()); 823 STLDeleteElements(&(active_jobs_[server_id]));
764 job_requests_map_.erase(job); 824 active_jobs_.erase(server_id);
765 delete job; 825 job_requests_map_.erase(server_id);
766 return;
767 } 826 }
768 827
769 // Returns a newly created QuicHttpStream owned by the caller, if a 828 // Returns a newly created QuicHttpStream owned by the caller, if a
770 // matching session already exists. Returns nullptr otherwise. 829 // matching session already exists. Returns nullptr otherwise.
771 scoped_ptr<QuicHttpStream> QuicStreamFactory::CreateIfSessionExists( 830 scoped_ptr<QuicHttpStream> QuicStreamFactory::CreateIfSessionExists(
772 const QuicServerId& server_id, 831 const QuicServerId& server_id,
773 const BoundNetLog& net_log) { 832 const BoundNetLog& net_log) {
774 if (!HasActiveSession(server_id)) { 833 if (!HasActiveSession(server_id)) {
775 DVLOG(1) << "No active session"; 834 DVLOG(1) << "No active session";
776 return scoped_ptr<QuicHttpStream>(); 835 return scoped_ptr<QuicHttpStream>();
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
835 894
836 const IpAliasKey ip_alias_key(session->connection()->peer_address(), 895 const IpAliasKey ip_alias_key(session->connection()->peer_address(),
837 aliases.begin()->is_https()); 896 aliases.begin()->is_https());
838 ip_aliases_[ip_alias_key].erase(session); 897 ip_aliases_[ip_alias_key].erase(session);
839 if (ip_aliases_[ip_alias_key].empty()) { 898 if (ip_aliases_[ip_alias_key].empty()) {
840 ip_aliases_.erase(ip_alias_key); 899 ip_aliases_.erase(ip_alias_key);
841 } 900 }
842 QuicServerId server_id = *aliases.begin(); 901 QuicServerId server_id = *aliases.begin();
843 session_aliases_.erase(session); 902 session_aliases_.erase(session);
844 Job* job = new Job(this, host_resolver_, session, server_id); 903 Job* job = new Job(this, host_resolver_, session, server_id);
845 active_jobs_[server_id] = job; 904 active_jobs_[server_id].insert(job);
846 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, 905 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete,
847 base::Unretained(this), job)); 906 base::Unretained(this), job));
848 DCHECK_EQ(ERR_IO_PENDING, rv); 907 DCHECK_EQ(ERR_IO_PENDING, rv);
849 } 908 }
850 909
851 void QuicStreamFactory::CancelRequest(QuicStreamRequest* request) { 910 void QuicStreamFactory::CancelRequest(QuicStreamRequest* request) {
852 DCHECK(ContainsKey(active_requests_, request)); 911 DCHECK(ContainsKey(active_requests_, request));
853 Job* job = active_requests_[request]; 912 QuicServerId server_id = active_requests_[request];
854 job_requests_map_[job].erase(request); 913 job_requests_map_[server_id].erase(request);
855 active_requests_.erase(request); 914 active_requests_.erase(request);
856 } 915 }
857 916
858 void QuicStreamFactory::CloseAllSessions(int error) { 917 void QuicStreamFactory::CloseAllSessions(int error) {
859 while (!active_sessions_.empty()) { 918 while (!active_sessions_.empty()) {
860 size_t initial_size = active_sessions_.size(); 919 size_t initial_size = active_sessions_.size();
861 active_sessions_.begin()->second->CloseSessionOnError(error); 920 active_sessions_.begin()->second->CloseSessionOnError(error);
862 DCHECK_NE(initial_size, active_sessions_.size()); 921 DCHECK_NE(initial_size, active_sessions_.size());
863 } 922 }
864 while (!all_sessions_.empty()) { 923 while (!all_sessions_.empty()) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
914 // kind of change it is, we have to flush the socket 973 // kind of change it is, we have to flush the socket
915 // pools to be safe. 974 // pools to be safe.
916 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); 975 CloseAllSessions(ERR_CERT_DATABASE_CHANGED);
917 } 976 }
918 977
919 bool QuicStreamFactory::HasActiveSession( 978 bool QuicStreamFactory::HasActiveSession(
920 const QuicServerId& server_id) const { 979 const QuicServerId& server_id) const {
921 return ContainsKey(active_sessions_, server_id); 980 return ContainsKey(active_sessions_, server_id);
922 } 981 }
923 982
983 bool QuicStreamFactory::HasActiveJob(const QuicServerId& key) const {
984 return ContainsKey(active_jobs_, key);
985 }
986
987 void QuicStreamFactory::CancelAuxilaryJob(Job* job,
988 const QuicServerId& server_id) {
989 Job* aux_job = nullptr;
990 for (JobSet::iterator it = active_jobs_[server_id].begin();
991 it != active_jobs_[server_id].end(); ++it) {
992 if (*it != job) {
993 aux_job = *it;
994 break;
995 }
996 }
997 if (!aux_job) {
998 return;
999 }
1000 DCHECK(!aux_job->is_main_job());
1001 aux_job->CancelJob();
1002 if (aux_job->session()) {
1003 aux_job->session()->connection()->SendConnectionClose(
1004 QUIC_CONNECTION_IP_POOLED);
1005 }
1006 }
1007
924 int QuicStreamFactory::CreateSession( 1008 int QuicStreamFactory::CreateSession(
925 const QuicServerId& server_id, 1009 const QuicServerId& server_id,
926 scoped_ptr<QuicServerInfo> server_info, 1010 scoped_ptr<QuicServerInfo> server_info,
927 const AddressList& address_list, 1011 const AddressList& address_list,
928 const BoundNetLog& net_log, 1012 const BoundNetLog& net_log,
929 QuicClientSession** session) { 1013 QuicClientSession** session) {
930 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. 1014 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed.
931 tracked_objects::ScopedTracker tracking_profile1( 1015 tracked_objects::ScopedTracker tracking_profile1(
932 FROM_HERE_WITH_EXPLICIT_FUNCTION( 1016 FROM_HERE_WITH_EXPLICIT_FUNCTION(
933 "422516 QuicStreamFactory::CreateSession1")); 1017 "422516 QuicStreamFactory::CreateSession1"));
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
1130 UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.ClosedDuringInitializeSession", 1214 UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.ClosedDuringInitializeSession",
1131 closed_during_initialize); 1215 closed_during_initialize);
1132 if (closed_during_initialize) { 1216 if (closed_during_initialize) {
1133 DLOG(DFATAL) << "Session closed during initialize"; 1217 DLOG(DFATAL) << "Session closed during initialize";
1134 *session = nullptr; 1218 *session = nullptr;
1135 return ERR_CONNECTION_CLOSED; 1219 return ERR_CONNECTION_CLOSED;
1136 } 1220 }
1137 return OK; 1221 return OK;
1138 } 1222 }
1139 1223
1140 bool QuicStreamFactory::HasActiveJob(const QuicServerId& key) const {
1141 return ContainsKey(active_jobs_, key);
1142 }
1143
1144 void QuicStreamFactory::ActivateSession( 1224 void QuicStreamFactory::ActivateSession(
1145 const QuicServerId& server_id, 1225 const QuicServerId& server_id,
1146 QuicClientSession* session) { 1226 QuicClientSession* session) {
1147 DCHECK(!HasActiveSession(server_id)); 1227 DCHECK(!HasActiveSession(server_id));
1148 UMA_HISTOGRAM_COUNTS("Net.QuicActiveSessions", active_sessions_.size()); 1228 UMA_HISTOGRAM_COUNTS("Net.QuicActiveSessions", active_sessions_.size());
1149 active_sessions_[server_id] = session; 1229 active_sessions_[server_id] = session;
1150 session_aliases_[session].insert(server_id); 1230 session_aliases_[session].insert(server_id);
1151 const IpAliasKey ip_alias_key(session->connection()->peer_address(), 1231 const IpAliasKey ip_alias_key(session->connection()->peer_address(),
1152 server_id.is_https()); 1232 server_id.is_https());
1153 DCHECK(!ContainsKey(ip_aliases_[ip_alias_key], session)); 1233 DCHECK(!ContainsKey(ip_aliases_[ip_alias_key], session));
1154 ip_aliases_[ip_alias_key].insert(session); 1234 ip_aliases_[ip_alias_key].insert(session);
1155 } 1235 }
1156 1236
1157 int64 QuicStreamFactory::GetServerNetworkStatsSmoothedRttInMicroseconds( 1237 int64 QuicStreamFactory::GetServerNetworkStatsSmoothedRttInMicroseconds(
1158 const QuicServerId& server_id) const { 1238 const QuicServerId& server_id) const {
1159 if (!http_server_properties_) 1239 if (!http_server_properties_)
1160 return 0; 1240 return 0;
1161 const ServerNetworkStats* stats = 1241 const ServerNetworkStats* stats =
1162 http_server_properties_->GetServerNetworkStats( 1242 http_server_properties_->GetServerNetworkStats(
1163 server_id.host_port_pair()); 1243 server_id.host_port_pair());
1164 if (stats == nullptr) 1244 if (stats == nullptr)
1165 return 0; 1245 return 0;
1166 return stats->srtt.InMicroseconds(); 1246 return stats->srtt.InMicroseconds();
1167 } 1247 }
1168 1248
1249 bool QuicStreamFactory::WasAlternateProtocolRecentlyBroken(
1250 const QuicServerId& server_id) const {
1251 return http_server_properties_ &&
1252 http_server_properties_->WasAlternateProtocolRecentlyBroken(
1253 server_id.host_port_pair());
1254 }
1255
1256 bool QuicStreamFactory::CryptoConfigCacheIsEmpty(
1257 const QuicServerId& server_id) {
1258 QuicCryptoClientConfig::CachedState* cached =
1259 crypto_config_.LookupOrCreate(server_id);
1260 return cached->IsEmpty();
1261 }
1262
1169 void QuicStreamFactory::InitializeCachedStateInCryptoConfig( 1263 void QuicStreamFactory::InitializeCachedStateInCryptoConfig(
1170 const QuicServerId& server_id, 1264 const QuicServerId& server_id,
1171 const scoped_ptr<QuicServerInfo>& server_info) { 1265 const scoped_ptr<QuicServerInfo>& server_info) {
1172 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed. 1266 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422516 is fixed.
1173 tracked_objects::ScopedTracker tracking_profile1( 1267 tracked_objects::ScopedTracker tracking_profile1(
1174 FROM_HERE_WITH_EXPLICIT_FUNCTION( 1268 FROM_HERE_WITH_EXPLICIT_FUNCTION(
1175 "422516 QuicStreamFactory::InitializeCachedStateInCryptoConfig1")); 1269 "422516 QuicStreamFactory::InitializeCachedStateInCryptoConfig1"));
1176 1270
1177 // |server_info| will be NULL, if a non-empty server config already exists in 1271 // |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. 1272 // the memory cache. This is a minor optimization to avoid LookupOrCreate.
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1272 http_server_properties_->ClearAlternateProtocol(server); 1366 http_server_properties_->ClearAlternateProtocol(server);
1273 http_server_properties_->SetAlternateProtocol( 1367 http_server_properties_->SetAlternateProtocol(
1274 server, alternate.port, alternate.protocol, 1); 1368 server, alternate.port, alternate.protocol, 1);
1275 DCHECK_EQ(QUIC, 1369 DCHECK_EQ(QUIC,
1276 http_server_properties_->GetAlternateProtocol(server).protocol); 1370 http_server_properties_->GetAlternateProtocol(server).protocol);
1277 DCHECK(http_server_properties_->WasAlternateProtocolRecentlyBroken( 1371 DCHECK(http_server_properties_->WasAlternateProtocolRecentlyBroken(
1278 server)); 1372 server));
1279 } 1373 }
1280 1374
1281 } // namespace net 1375 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698