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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 }; | 69 }; |
70 | 70 |
71 // Responsible for creating a new QUIC session to the specified server, and | 71 // Responsible for creating a new QUIC session to the specified server, and |
72 // for notifying any associated requests when complete. | 72 // for notifying any associated requests when complete. |
73 class QuicStreamFactory::Job { | 73 class QuicStreamFactory::Job { |
74 public: | 74 public: |
75 Job(QuicStreamFactory* factory, | 75 Job(QuicStreamFactory* factory, |
76 HostResolver* host_resolver, | 76 HostResolver* host_resolver, |
77 const HostPortPair& host_port_pair, | 77 const HostPortPair& host_port_pair, |
78 bool is_https, | 78 bool is_https, |
79 PrivacyMode privacy_mode, | |
80 base::StringPiece method, | 79 base::StringPiece method, |
81 QuicServerInfo* server_info, | 80 QuicServerInfo* server_info, |
82 const BoundNetLog& net_log); | 81 const BoundNetLog& net_log); |
83 | 82 |
84 ~Job(); | 83 ~Job(); |
85 | 84 |
86 int Run(const CompletionCallback& callback); | 85 int Run(const CompletionCallback& callback); |
87 | 86 |
88 int DoLoop(int rv); | 87 int DoLoop(int rv); |
89 int DoResolveHost(); | 88 int DoResolveHost(); |
(...skipping 20 matching lines...) Expand all Loading... |
110 STATE_RESOLVE_HOST_COMPLETE, | 109 STATE_RESOLVE_HOST_COMPLETE, |
111 STATE_LOAD_SERVER_INFO, | 110 STATE_LOAD_SERVER_INFO, |
112 STATE_LOAD_SERVER_INFO_COMPLETE, | 111 STATE_LOAD_SERVER_INFO_COMPLETE, |
113 STATE_CONNECT, | 112 STATE_CONNECT, |
114 STATE_CONNECT_COMPLETE, | 113 STATE_CONNECT_COMPLETE, |
115 }; | 114 }; |
116 IoState io_state_; | 115 IoState io_state_; |
117 | 116 |
118 QuicStreamFactory* factory_; | 117 QuicStreamFactory* factory_; |
119 SingleRequestHostResolver host_resolver_; | 118 SingleRequestHostResolver host_resolver_; |
| 119 bool is_https_; |
120 QuicSessionKey session_key_; | 120 QuicSessionKey session_key_; |
121 bool is_post_; | 121 bool is_post_; |
122 scoped_ptr<QuicServerInfo> server_info_; | 122 scoped_ptr<QuicServerInfo> server_info_; |
123 const BoundNetLog net_log_; | 123 const BoundNetLog net_log_; |
124 QuicClientSession* session_; | 124 QuicClientSession* session_; |
125 CompletionCallback callback_; | 125 CompletionCallback callback_; |
126 AddressList address_list_; | 126 AddressList address_list_; |
127 base::TimeTicks disk_cache_load_start_time_; | 127 base::TimeTicks disk_cache_load_start_time_; |
128 base::WeakPtrFactory<Job> weak_factory_; | 128 base::WeakPtrFactory<Job> weak_factory_; |
129 DISALLOW_COPY_AND_ASSIGN(Job); | 129 DISALLOW_COPY_AND_ASSIGN(Job); |
130 }; | 130 }; |
131 | 131 |
132 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, | 132 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, |
133 HostResolver* host_resolver, | 133 HostResolver* host_resolver, |
134 const HostPortPair& host_port_pair, | 134 const HostPortPair& host_port_pair, |
135 bool is_https, | 135 bool is_https, |
136 PrivacyMode privacy_mode, | |
137 base::StringPiece method, | 136 base::StringPiece method, |
138 QuicServerInfo* server_info, | 137 QuicServerInfo* server_info, |
139 const BoundNetLog& net_log) | 138 const BoundNetLog& net_log) |
140 : factory_(factory), | 139 : factory_(factory), |
141 host_resolver_(host_resolver), | 140 host_resolver_(host_resolver), |
142 session_key_(host_port_pair, is_https, privacy_mode), | 141 is_https_(is_https), |
| 142 session_key_(host_port_pair, is_https), |
143 is_post_(method == "POST"), | 143 is_post_(method == "POST"), |
144 server_info_(server_info), | 144 server_info_(server_info), |
145 net_log_(net_log), | 145 net_log_(net_log), |
146 session_(NULL), | 146 session_(NULL), |
147 weak_factory_(this) {} | 147 weak_factory_(this) {} |
148 | 148 |
149 QuicStreamFactory::Job::~Job() { | 149 QuicStreamFactory::Job::~Job() { |
150 } | 150 } |
151 | 151 |
152 int QuicStreamFactory::Job::Run(const CompletionCallback& callback) { | 152 int QuicStreamFactory::Job::Run(const CompletionCallback& callback) { |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 server_info_.reset(); | 254 server_info_.reset(); |
255 } | 255 } |
256 | 256 |
257 io_state_ = STATE_CONNECT; | 257 io_state_ = STATE_CONNECT; |
258 return OK; | 258 return OK; |
259 } | 259 } |
260 | 260 |
261 int QuicStreamFactory::Job::DoConnect() { | 261 int QuicStreamFactory::Job::DoConnect() { |
262 io_state_ = STATE_CONNECT_COMPLETE; | 262 io_state_ = STATE_CONNECT_COMPLETE; |
263 | 263 |
264 int rv = factory_->CreateSession(session_key_, server_info_.Pass(), | 264 int rv = factory_->CreateSession(session_key_.host_port_pair(), is_https_, |
265 address_list_, net_log_, &session_); | 265 server_info_.Pass(), address_list_, |
| 266 net_log_, &session_); |
266 if (rv != OK) { | 267 if (rv != OK) { |
267 DCHECK(rv != ERR_IO_PENDING); | 268 DCHECK(rv != ERR_IO_PENDING); |
268 DCHECK(!session_); | 269 DCHECK(!session_); |
269 return rv; | 270 return rv; |
270 } | 271 } |
271 | 272 |
272 session_->StartReading(); | 273 session_->StartReading(); |
273 if (!session_->connection()->connected()) { | 274 if (!session_->connection()->connected()) { |
274 return ERR_QUIC_PROTOCOL_ERROR; | 275 return ERR_QUIC_PROTOCOL_ERROR; |
275 } | 276 } |
276 rv = session_->CryptoConnect( | 277 rv = session_->CryptoConnect( |
277 factory_->require_confirmation() || session_key_.is_https(), | 278 factory_->require_confirmation() || is_https_, |
278 base::Bind(&QuicStreamFactory::Job::OnIOComplete, | 279 base::Bind(&QuicStreamFactory::Job::OnIOComplete, |
279 base::Unretained(this))); | 280 base::Unretained(this))); |
280 return rv; | 281 return rv; |
281 } | 282 } |
282 | 283 |
283 int QuicStreamFactory::Job::DoConnectComplete(int rv) { | 284 int QuicStreamFactory::Job::DoConnectComplete(int rv) { |
284 if (rv != OK) | 285 if (rv != OK) |
285 return rv; | 286 return rv; |
286 | 287 |
287 DCHECK(!factory_->HasActiveSession(session_key_)); | 288 DCHECK(!factory_->HasActiveSession(session_key_)); |
(...skipping 14 matching lines...) Expand all Loading... |
302 QuicStreamRequest::QuicStreamRequest(QuicStreamFactory* factory) | 303 QuicStreamRequest::QuicStreamRequest(QuicStreamFactory* factory) |
303 : factory_(factory) {} | 304 : factory_(factory) {} |
304 | 305 |
305 QuicStreamRequest::~QuicStreamRequest() { | 306 QuicStreamRequest::~QuicStreamRequest() { |
306 if (factory_ && !callback_.is_null()) | 307 if (factory_ && !callback_.is_null()) |
307 factory_->CancelRequest(this); | 308 factory_->CancelRequest(this); |
308 } | 309 } |
309 | 310 |
310 int QuicStreamRequest::Request(const HostPortPair& host_port_pair, | 311 int QuicStreamRequest::Request(const HostPortPair& host_port_pair, |
311 bool is_https, | 312 bool is_https, |
312 PrivacyMode privacy_mode, | |
313 base::StringPiece method, | 313 base::StringPiece method, |
314 const BoundNetLog& net_log, | 314 const BoundNetLog& net_log, |
315 const CompletionCallback& callback) { | 315 const CompletionCallback& callback) { |
316 DCHECK(!stream_); | 316 DCHECK(!stream_); |
317 DCHECK(callback_.is_null()); | 317 DCHECK(callback_.is_null()); |
318 DCHECK(factory_); | 318 DCHECK(factory_); |
319 int rv = factory_->Create(host_port_pair, is_https, privacy_mode, method, | 319 int rv = factory_->Create(host_port_pair, is_https, method, net_log, this); |
320 net_log, this); | |
321 if (rv == ERR_IO_PENDING) { | 320 if (rv == ERR_IO_PENDING) { |
322 host_port_pair_ = host_port_pair; | 321 host_port_pair_ = host_port_pair; |
323 is_https_ = is_https; | 322 is_https_ = is_https; |
324 net_log_ = net_log; | 323 net_log_ = net_log; |
325 callback_ = callback; | 324 callback_ = callback; |
326 } else { | 325 } else { |
327 factory_ = NULL; | 326 factory_ = NULL; |
328 } | 327 } |
329 if (rv == OK) | 328 if (rv == OK) |
330 DCHECK(stream_); | 329 DCHECK(stream_); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 } | 385 } |
387 | 386 |
388 QuicStreamFactory::~QuicStreamFactory() { | 387 QuicStreamFactory::~QuicStreamFactory() { |
389 CloseAllSessions(ERR_ABORTED); | 388 CloseAllSessions(ERR_ABORTED); |
390 STLDeleteElements(&all_sessions_); | 389 STLDeleteElements(&all_sessions_); |
391 STLDeleteValues(&active_jobs_); | 390 STLDeleteValues(&active_jobs_); |
392 } | 391 } |
393 | 392 |
394 int QuicStreamFactory::Create(const HostPortPair& host_port_pair, | 393 int QuicStreamFactory::Create(const HostPortPair& host_port_pair, |
395 bool is_https, | 394 bool is_https, |
396 PrivacyMode privacy_mode, | |
397 base::StringPiece method, | 395 base::StringPiece method, |
398 const BoundNetLog& net_log, | 396 const BoundNetLog& net_log, |
399 QuicStreamRequest* request) { | 397 QuicStreamRequest* request) { |
400 QuicSessionKey session_key(host_port_pair, is_https, privacy_mode); | 398 QuicSessionKey session_key(host_port_pair, is_https); |
401 if (HasActiveSession(session_key)) { | 399 if (HasActiveSession(session_key)) { |
402 request->set_stream(CreateIfSessionExists(session_key, net_log)); | 400 request->set_stream(CreateIfSessionExists(session_key, net_log)); |
403 return OK; | 401 return OK; |
404 } | 402 } |
405 | 403 |
406 if (HasActiveJob(session_key)) { | 404 if (HasActiveJob(session_key)) { |
407 Job* job = active_jobs_[session_key]; | 405 Job* job = active_jobs_[session_key]; |
408 active_requests_[request] = job; | 406 active_requests_[request] = job; |
409 job_requests_map_[job].insert(request); | 407 job_requests_map_[job].insert(request); |
410 return ERR_IO_PENDING; | 408 return ERR_IO_PENDING; |
411 } | 409 } |
412 | 410 |
413 QuicServerInfo* quic_server_info = NULL; | 411 QuicServerInfo* quic_server_info = NULL; |
414 if (quic_server_info_factory_) { | 412 if (quic_server_info_factory_) { |
415 QuicCryptoClientConfig::CachedState* cached = | 413 QuicCryptoClientConfig::CachedState* cached = |
416 crypto_config_.LookupOrCreate(session_key); | 414 crypto_config_.LookupOrCreate(session_key); |
417 DCHECK(cached); | 415 DCHECK(cached); |
418 if (cached->IsEmpty()) { | 416 if (cached->IsEmpty()) { |
419 quic_server_info = quic_server_info_factory_->GetForServer(session_key); | 417 quic_server_info = quic_server_info_factory_->GetForServer(session_key); |
420 } | 418 } |
421 } | 419 } |
422 scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_pair, is_https, | 420 scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_pair, |
423 privacy_mode, method, quic_server_info, net_log)); | 421 is_https, method, quic_server_info, net_log)); |
424 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, | 422 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, |
425 base::Unretained(this), job.get())); | 423 base::Unretained(this), job.get())); |
426 | 424 |
427 if (rv == ERR_IO_PENDING) { | 425 if (rv == ERR_IO_PENDING) { |
428 active_requests_[request] = job.get(); | 426 active_requests_[request] = job.get(); |
429 job_requests_map_[job.get()].insert(request); | 427 job_requests_map_[job.get()].insert(request); |
430 active_jobs_[session_key] = job.release(); | 428 active_jobs_[session_key] = job.release(); |
431 } | 429 } |
432 if (rv == OK) { | 430 if (rv == OK) { |
433 DCHECK(HasActiveSession(session_key)); | 431 DCHECK(HasActiveSession(session_key)); |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
636 // pools to be safe. | 634 // pools to be safe. |
637 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); | 635 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); |
638 } | 636 } |
639 | 637 |
640 bool QuicStreamFactory::HasActiveSession( | 638 bool QuicStreamFactory::HasActiveSession( |
641 const QuicSessionKey& session_key) const { | 639 const QuicSessionKey& session_key) const { |
642 return ContainsKey(active_sessions_, session_key); | 640 return ContainsKey(active_sessions_, session_key); |
643 } | 641 } |
644 | 642 |
645 int QuicStreamFactory::CreateSession( | 643 int QuicStreamFactory::CreateSession( |
646 const QuicSessionKey& session_key, | 644 const HostPortPair& host_port_pair, |
| 645 bool is_https, |
647 scoped_ptr<QuicServerInfo> server_info, | 646 scoped_ptr<QuicServerInfo> server_info, |
648 const AddressList& address_list, | 647 const AddressList& address_list, |
649 const BoundNetLog& net_log, | 648 const BoundNetLog& net_log, |
650 QuicClientSession** session) { | 649 QuicClientSession** session) { |
651 bool enable_port_selection = enable_port_selection_; | 650 bool enable_port_selection = enable_port_selection_; |
| 651 QuicSessionKey session_key(host_port_pair, is_https); |
652 if (enable_port_selection && | 652 if (enable_port_selection && |
653 ContainsKey(gone_away_aliases_, session_key)) { | 653 ContainsKey(gone_away_aliases_, session_key)) { |
654 // Disable port selection when the server is going away. | 654 // Disable port selection when the server is going away. |
655 // There is no point in trying to return to the same server, if | 655 // There is no point in trying to return to the same server, if |
656 // that server is no longer handling requests. | 656 // that server is no longer handling requests. |
657 enable_port_selection = false; | 657 enable_port_selection = false; |
658 gone_away_aliases_.erase(session_key); | 658 gone_away_aliases_.erase(session_key); |
659 } | 659 } |
660 | 660 |
661 QuicConnectionId connection_id = random_generator_->RandUint64(); | 661 QuicConnectionId connection_id = random_generator_->RandUint64(); |
662 IPEndPoint addr = *address_list.begin(); | 662 IPEndPoint addr = *address_list.begin(); |
663 scoped_refptr<PortSuggester> port_suggester = | 663 scoped_refptr<PortSuggester> port_suggester = |
664 new PortSuggester(session_key.host_port_pair(), port_seed_); | 664 new PortSuggester(host_port_pair, port_seed_); |
665 DatagramSocket::BindType bind_type = enable_port_selection ? | 665 DatagramSocket::BindType bind_type = enable_port_selection ? |
666 DatagramSocket::RANDOM_BIND : // Use our callback. | 666 DatagramSocket::RANDOM_BIND : // Use our callback. |
667 DatagramSocket::DEFAULT_BIND; // Use OS to randomize. | 667 DatagramSocket::DEFAULT_BIND; // Use OS to randomize. |
668 scoped_ptr<DatagramClientSocket> socket( | 668 scoped_ptr<DatagramClientSocket> socket( |
669 client_socket_factory_->CreateDatagramClientSocket( | 669 client_socket_factory_->CreateDatagramClientSocket( |
670 bind_type, | 670 bind_type, |
671 base::Bind(&PortSuggester::SuggestPort, port_suggester), | 671 base::Bind(&PortSuggester::SuggestPort, port_suggester), |
672 net_log.net_log(), net_log.source())); | 672 net_log.net_log(), net_log.source())); |
673 int rv = socket->Connect(addr); | 673 int rv = socket->Connect(addr); |
674 if (rv != OK) | 674 if (rv != OK) |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
706 writer.get(), false, | 706 writer.get(), false, |
707 supported_versions_); | 707 supported_versions_); |
708 writer->SetConnection(connection); | 708 writer->SetConnection(connection); |
709 connection->options()->max_packet_length = max_packet_length_; | 709 connection->options()->max_packet_length = max_packet_length_; |
710 | 710 |
711 InitializeCachedState(session_key, server_info); | 711 InitializeCachedState(session_key, server_info); |
712 | 712 |
713 QuicConfig config = config_; | 713 QuicConfig config = config_; |
714 if (http_server_properties_) { | 714 if (http_server_properties_) { |
715 const HttpServerProperties::NetworkStats* stats = | 715 const HttpServerProperties::NetworkStats* stats = |
716 http_server_properties_->GetServerNetworkStats( | 716 http_server_properties_->GetServerNetworkStats(host_port_pair); |
717 session_key.host_port_pair()); | |
718 if (stats != NULL) { | 717 if (stats != NULL) { |
719 config.set_initial_round_trip_time_us(stats->rtt.InMicroseconds(), | 718 config.set_initial_round_trip_time_us(stats->rtt.InMicroseconds(), |
720 stats->rtt.InMicroseconds()); | 719 stats->rtt.InMicroseconds()); |
721 } | 720 } |
722 } | 721 } |
723 | 722 |
724 *session = new QuicClientSession( | 723 *session = new QuicClientSession( |
725 connection, socket.Pass(), writer.Pass(), this, | 724 connection, socket.Pass(), writer.Pass(), this, |
726 quic_crypto_client_stream_factory_, server_info.Pass(), session_key, | 725 quic_crypto_client_stream_factory_, server_info.Pass(), session_key, |
727 config, &crypto_config_, net_log.net_log()); | 726 config, &crypto_config_, net_log.net_log()); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
792 base::TimeTicks when = broken_alternate_protocol_list_.front().when; | 791 base::TimeTicks when = broken_alternate_protocol_list_.front().when; |
793 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); | 792 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); |
794 base::MessageLoop::current()->PostDelayedTask( | 793 base::MessageLoop::current()->PostDelayedTask( |
795 FROM_HERE, | 794 FROM_HERE, |
796 base::Bind(&QuicStreamFactory::ExpireBrokenAlternateProtocolMappings, | 795 base::Bind(&QuicStreamFactory::ExpireBrokenAlternateProtocolMappings, |
797 weak_factory_.GetWeakPtr()), | 796 weak_factory_.GetWeakPtr()), |
798 delay); | 797 delay); |
799 } | 798 } |
800 | 799 |
801 } // namespace net | 800 } // namespace net |
OLD | NEW |