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 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 }; | 81 }; |
82 | 82 |
83 // Responsible for creating a new QUIC session to the specified server, and | 83 // Responsible for creating a new QUIC session to the specified server, and |
84 // for notifying any associated requests when complete. | 84 // for notifying any associated requests when complete. |
85 class QuicStreamFactory::Job { | 85 class QuicStreamFactory::Job { |
86 public: | 86 public: |
87 Job(QuicStreamFactory* factory, | 87 Job(QuicStreamFactory* factory, |
88 HostResolver* host_resolver, | 88 HostResolver* host_resolver, |
89 const HostPortPair& host_port_pair, | 89 const HostPortPair& host_port_pair, |
90 bool is_https, | 90 bool is_https, |
| 91 PrivacyMode privacy_mode, |
91 base::StringPiece method, | 92 base::StringPiece method, |
92 QuicServerInfo* server_info, | 93 QuicServerInfo* server_info, |
93 const BoundNetLog& net_log); | 94 const BoundNetLog& net_log); |
94 | 95 |
95 ~Job(); | 96 ~Job(); |
96 | 97 |
97 int Run(const CompletionCallback& callback); | 98 int Run(const CompletionCallback& callback); |
98 | 99 |
99 int DoLoop(int rv); | 100 int DoLoop(int rv); |
100 int DoResolveHost(); | 101 int DoResolveHost(); |
(...skipping 20 matching lines...) Expand all Loading... |
121 STATE_RESOLVE_HOST_COMPLETE, | 122 STATE_RESOLVE_HOST_COMPLETE, |
122 STATE_LOAD_SERVER_INFO, | 123 STATE_LOAD_SERVER_INFO, |
123 STATE_LOAD_SERVER_INFO_COMPLETE, | 124 STATE_LOAD_SERVER_INFO_COMPLETE, |
124 STATE_CONNECT, | 125 STATE_CONNECT, |
125 STATE_CONNECT_COMPLETE, | 126 STATE_CONNECT_COMPLETE, |
126 }; | 127 }; |
127 IoState io_state_; | 128 IoState io_state_; |
128 | 129 |
129 QuicStreamFactory* factory_; | 130 QuicStreamFactory* factory_; |
130 SingleRequestHostResolver host_resolver_; | 131 SingleRequestHostResolver host_resolver_; |
131 bool is_https_; | |
132 QuicSessionKey session_key_; | 132 QuicSessionKey session_key_; |
133 bool is_post_; | 133 bool is_post_; |
134 scoped_ptr<QuicServerInfo> server_info_; | 134 scoped_ptr<QuicServerInfo> server_info_; |
135 const BoundNetLog net_log_; | 135 const BoundNetLog net_log_; |
136 QuicClientSession* session_; | 136 QuicClientSession* session_; |
137 CompletionCallback callback_; | 137 CompletionCallback callback_; |
138 AddressList address_list_; | 138 AddressList address_list_; |
139 base::TimeTicks disk_cache_load_start_time_; | 139 base::TimeTicks disk_cache_load_start_time_; |
140 base::WeakPtrFactory<Job> weak_factory_; | 140 base::WeakPtrFactory<Job> weak_factory_; |
141 DISALLOW_COPY_AND_ASSIGN(Job); | 141 DISALLOW_COPY_AND_ASSIGN(Job); |
142 }; | 142 }; |
143 | 143 |
144 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, | 144 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, |
145 HostResolver* host_resolver, | 145 HostResolver* host_resolver, |
146 const HostPortPair& host_port_pair, | 146 const HostPortPair& host_port_pair, |
147 bool is_https, | 147 bool is_https, |
| 148 PrivacyMode privacy_mode, |
148 base::StringPiece method, | 149 base::StringPiece method, |
149 QuicServerInfo* server_info, | 150 QuicServerInfo* server_info, |
150 const BoundNetLog& net_log) | 151 const BoundNetLog& net_log) |
151 : factory_(factory), | 152 : factory_(factory), |
152 host_resolver_(host_resolver), | 153 host_resolver_(host_resolver), |
153 is_https_(is_https), | 154 session_key_(host_port_pair, is_https, privacy_mode), |
154 session_key_(host_port_pair, is_https), | |
155 is_post_(method == "POST"), | 155 is_post_(method == "POST"), |
156 server_info_(server_info), | 156 server_info_(server_info), |
157 net_log_(net_log), | 157 net_log_(net_log), |
158 session_(NULL), | 158 session_(NULL), |
159 weak_factory_(this) {} | 159 weak_factory_(this) {} |
160 | 160 |
161 QuicStreamFactory::Job::~Job() { | 161 QuicStreamFactory::Job::~Job() { |
162 } | 162 } |
163 | 163 |
164 int QuicStreamFactory::Job::Run(const CompletionCallback& callback) { | 164 int QuicStreamFactory::Job::Run(const CompletionCallback& callback) { |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 server_info_.reset(); | 266 server_info_.reset(); |
267 } | 267 } |
268 | 268 |
269 io_state_ = STATE_CONNECT; | 269 io_state_ = STATE_CONNECT; |
270 return OK; | 270 return OK; |
271 } | 271 } |
272 | 272 |
273 int QuicStreamFactory::Job::DoConnect() { | 273 int QuicStreamFactory::Job::DoConnect() { |
274 io_state_ = STATE_CONNECT_COMPLETE; | 274 io_state_ = STATE_CONNECT_COMPLETE; |
275 | 275 |
276 int rv = factory_->CreateSession(session_key_.host_port_pair(), is_https_, | 276 int rv = factory_->CreateSession(session_key_, server_info_.Pass(), |
277 server_info_.Pass(), address_list_, | 277 address_list_, net_log_, &session_); |
278 net_log_, &session_); | |
279 if (rv != OK) { | 278 if (rv != OK) { |
280 DCHECK(rv != ERR_IO_PENDING); | 279 DCHECK(rv != ERR_IO_PENDING); |
281 DCHECK(!session_); | 280 DCHECK(!session_); |
282 return rv; | 281 return rv; |
283 } | 282 } |
284 | 283 |
285 session_->StartReading(); | 284 session_->StartReading(); |
286 if (!session_->connection()->connected()) { | 285 if (!session_->connection()->connected()) { |
287 return ERR_QUIC_PROTOCOL_ERROR; | 286 return ERR_QUIC_PROTOCOL_ERROR; |
288 } | 287 } |
289 rv = session_->CryptoConnect( | 288 rv = session_->CryptoConnect( |
290 factory_->require_confirmation() || is_https_ || is_post_, | 289 factory_->require_confirmation() || session_key_.is_https() || is_post_, |
291 base::Bind(&QuicStreamFactory::Job::OnIOComplete, | 290 base::Bind(&QuicStreamFactory::Job::OnIOComplete, |
292 base::Unretained(this))); | 291 base::Unretained(this))); |
293 return rv; | 292 return rv; |
294 } | 293 } |
295 | 294 |
296 int QuicStreamFactory::Job::DoConnectComplete(int rv) { | 295 int QuicStreamFactory::Job::DoConnectComplete(int rv) { |
297 if (rv != OK) | 296 if (rv != OK) |
298 return rv; | 297 return rv; |
299 | 298 |
300 DCHECK(!factory_->HasActiveSession(session_key_)); | 299 DCHECK(!factory_->HasActiveSession(session_key_)); |
(...skipping 14 matching lines...) Expand all Loading... |
315 QuicStreamRequest::QuicStreamRequest(QuicStreamFactory* factory) | 314 QuicStreamRequest::QuicStreamRequest(QuicStreamFactory* factory) |
316 : factory_(factory) {} | 315 : factory_(factory) {} |
317 | 316 |
318 QuicStreamRequest::~QuicStreamRequest() { | 317 QuicStreamRequest::~QuicStreamRequest() { |
319 if (factory_ && !callback_.is_null()) | 318 if (factory_ && !callback_.is_null()) |
320 factory_->CancelRequest(this); | 319 factory_->CancelRequest(this); |
321 } | 320 } |
322 | 321 |
323 int QuicStreamRequest::Request(const HostPortPair& host_port_pair, | 322 int QuicStreamRequest::Request(const HostPortPair& host_port_pair, |
324 bool is_https, | 323 bool is_https, |
| 324 PrivacyMode privacy_mode, |
325 base::StringPiece method, | 325 base::StringPiece method, |
326 const BoundNetLog& net_log, | 326 const BoundNetLog& net_log, |
327 const CompletionCallback& callback) { | 327 const CompletionCallback& callback) { |
328 DCHECK(!stream_); | 328 DCHECK(!stream_); |
329 DCHECK(callback_.is_null()); | 329 DCHECK(callback_.is_null()); |
330 DCHECK(factory_); | 330 DCHECK(factory_); |
331 int rv = factory_->Create(host_port_pair, is_https, method, net_log, this); | 331 int rv = factory_->Create(host_port_pair, is_https, privacy_mode, method, |
| 332 net_log, this); |
332 if (rv == ERR_IO_PENDING) { | 333 if (rv == ERR_IO_PENDING) { |
333 host_port_pair_ = host_port_pair; | 334 host_port_pair_ = host_port_pair; |
334 is_https_ = is_https; | 335 is_https_ = is_https; |
335 net_log_ = net_log; | 336 net_log_ = net_log; |
336 callback_ = callback; | 337 callback_ = callback; |
337 } else { | 338 } else { |
338 factory_ = NULL; | 339 factory_ = NULL; |
339 } | 340 } |
340 if (rv == OK) | 341 if (rv == OK) |
341 DCHECK(stream_); | 342 DCHECK(stream_); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
397 } | 398 } |
398 | 399 |
399 QuicStreamFactory::~QuicStreamFactory() { | 400 QuicStreamFactory::~QuicStreamFactory() { |
400 CloseAllSessions(ERR_ABORTED); | 401 CloseAllSessions(ERR_ABORTED); |
401 STLDeleteElements(&all_sessions_); | 402 STLDeleteElements(&all_sessions_); |
402 STLDeleteValues(&active_jobs_); | 403 STLDeleteValues(&active_jobs_); |
403 } | 404 } |
404 | 405 |
405 int QuicStreamFactory::Create(const HostPortPair& host_port_pair, | 406 int QuicStreamFactory::Create(const HostPortPair& host_port_pair, |
406 bool is_https, | 407 bool is_https, |
| 408 PrivacyMode privacy_mode, |
407 base::StringPiece method, | 409 base::StringPiece method, |
408 const BoundNetLog& net_log, | 410 const BoundNetLog& net_log, |
409 QuicStreamRequest* request) { | 411 QuicStreamRequest* request) { |
410 QuicSessionKey session_key(host_port_pair, is_https); | 412 QuicSessionKey session_key(host_port_pair, is_https, privacy_mode); |
411 if (HasActiveSession(session_key)) { | 413 if (HasActiveSession(session_key)) { |
412 request->set_stream(CreateIfSessionExists(session_key, net_log)); | 414 request->set_stream(CreateIfSessionExists(session_key, net_log)); |
413 return OK; | 415 return OK; |
414 } | 416 } |
415 | 417 |
416 if (HasActiveJob(session_key)) { | 418 if (HasActiveJob(session_key)) { |
417 Job* job = active_jobs_[session_key]; | 419 Job* job = active_jobs_[session_key]; |
418 active_requests_[request] = job; | 420 active_requests_[request] = job; |
419 job_requests_map_[job].insert(request); | 421 job_requests_map_[job].insert(request); |
420 return ERR_IO_PENDING; | 422 return ERR_IO_PENDING; |
421 } | 423 } |
422 | 424 |
423 QuicServerInfo* quic_server_info = NULL; | 425 QuicServerInfo* quic_server_info = NULL; |
424 if (quic_server_info_factory_) { | 426 if (quic_server_info_factory_) { |
425 QuicCryptoClientConfig::CachedState* cached = | 427 QuicCryptoClientConfig::CachedState* cached = |
426 crypto_config_.LookupOrCreate(session_key); | 428 crypto_config_.LookupOrCreate(session_key); |
427 DCHECK(cached); | 429 DCHECK(cached); |
428 if (cached->IsEmpty()) { | 430 if (cached->IsEmpty()) { |
429 quic_server_info = quic_server_info_factory_->GetForServer(session_key); | 431 quic_server_info = quic_server_info_factory_->GetForServer(session_key); |
430 } | 432 } |
431 } | 433 } |
432 scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_pair, | 434 scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_pair, is_https, |
433 is_https, method, quic_server_info, net_log)); | 435 privacy_mode, method, quic_server_info, net_log)); |
434 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, | 436 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, |
435 base::Unretained(this), job.get())); | 437 base::Unretained(this), job.get())); |
436 | 438 |
437 if (rv == ERR_IO_PENDING) { | 439 if (rv == ERR_IO_PENDING) { |
438 active_requests_[request] = job.get(); | 440 active_requests_[request] = job.get(); |
439 job_requests_map_[job.get()].insert(request); | 441 job_requests_map_[job.get()].insert(request); |
440 active_jobs_[session_key] = job.release(); | 442 active_jobs_[session_key] = job.release(); |
441 } | 443 } |
442 if (rv == OK) { | 444 if (rv == OK) { |
443 DCHECK(HasActiveSession(session_key)); | 445 DCHECK(HasActiveSession(session_key)); |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
646 // pools to be safe. | 648 // pools to be safe. |
647 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); | 649 CloseAllSessions(ERR_CERT_DATABASE_CHANGED); |
648 } | 650 } |
649 | 651 |
650 bool QuicStreamFactory::HasActiveSession( | 652 bool QuicStreamFactory::HasActiveSession( |
651 const QuicSessionKey& session_key) const { | 653 const QuicSessionKey& session_key) const { |
652 return ContainsKey(active_sessions_, session_key); | 654 return ContainsKey(active_sessions_, session_key); |
653 } | 655 } |
654 | 656 |
655 int QuicStreamFactory::CreateSession( | 657 int QuicStreamFactory::CreateSession( |
656 const HostPortPair& host_port_pair, | 658 const QuicSessionKey& session_key, |
657 bool is_https, | |
658 scoped_ptr<QuicServerInfo> server_info, | 659 scoped_ptr<QuicServerInfo> server_info, |
659 const AddressList& address_list, | 660 const AddressList& address_list, |
660 const BoundNetLog& net_log, | 661 const BoundNetLog& net_log, |
661 QuicClientSession** session) { | 662 QuicClientSession** session) { |
662 bool enable_port_selection = enable_port_selection_; | 663 bool enable_port_selection = enable_port_selection_; |
663 QuicSessionKey session_key(host_port_pair, is_https); | |
664 if (enable_port_selection && | 664 if (enable_port_selection && |
665 ContainsKey(gone_away_aliases_, session_key)) { | 665 ContainsKey(gone_away_aliases_, session_key)) { |
666 // Disable port selection when the server is going away. | 666 // Disable port selection when the server is going away. |
667 // There is no point in trying to return to the same server, if | 667 // There is no point in trying to return to the same server, if |
668 // that server is no longer handling requests. | 668 // that server is no longer handling requests. |
669 enable_port_selection = false; | 669 enable_port_selection = false; |
670 gone_away_aliases_.erase(session_key); | 670 gone_away_aliases_.erase(session_key); |
671 } | 671 } |
672 | 672 |
673 QuicConnectionId connection_id = random_generator_->RandUint64(); | 673 QuicConnectionId connection_id = random_generator_->RandUint64(); |
674 IPEndPoint addr = *address_list.begin(); | 674 IPEndPoint addr = *address_list.begin(); |
675 scoped_refptr<PortSuggester> port_suggester = | 675 scoped_refptr<PortSuggester> port_suggester = |
676 new PortSuggester(host_port_pair, port_seed_); | 676 new PortSuggester(session_key.host_port_pair(), port_seed_); |
677 DatagramSocket::BindType bind_type = enable_port_selection ? | 677 DatagramSocket::BindType bind_type = enable_port_selection ? |
678 DatagramSocket::RANDOM_BIND : // Use our callback. | 678 DatagramSocket::RANDOM_BIND : // Use our callback. |
679 DatagramSocket::DEFAULT_BIND; // Use OS to randomize. | 679 DatagramSocket::DEFAULT_BIND; // Use OS to randomize. |
680 scoped_ptr<DatagramClientSocket> socket( | 680 scoped_ptr<DatagramClientSocket> socket( |
681 client_socket_factory_->CreateDatagramClientSocket( | 681 client_socket_factory_->CreateDatagramClientSocket( |
682 bind_type, | 682 bind_type, |
683 base::Bind(&PortSuggester::SuggestPort, port_suggester), | 683 base::Bind(&PortSuggester::SuggestPort, port_suggester), |
684 net_log.net_log(), net_log.source())); | 684 net_log.net_log(), net_log.source())); |
685 int rv = socket->Connect(addr); | 685 int rv = socket->Connect(addr); |
686 if (rv != OK) { | 686 if (rv != OK) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
726 writer.get(), false, | 726 writer.get(), false, |
727 supported_versions_); | 727 supported_versions_); |
728 writer->SetConnection(connection); | 728 writer->SetConnection(connection); |
729 connection->options()->max_packet_length = max_packet_length_; | 729 connection->options()->max_packet_length = max_packet_length_; |
730 | 730 |
731 InitializeCachedState(session_key, server_info); | 731 InitializeCachedState(session_key, server_info); |
732 | 732 |
733 QuicConfig config = config_; | 733 QuicConfig config = config_; |
734 if (http_server_properties_) { | 734 if (http_server_properties_) { |
735 const HttpServerProperties::NetworkStats* stats = | 735 const HttpServerProperties::NetworkStats* stats = |
736 http_server_properties_->GetServerNetworkStats(host_port_pair); | 736 http_server_properties_->GetServerNetworkStats( |
| 737 session_key.host_port_pair()); |
737 if (stats != NULL) { | 738 if (stats != NULL) { |
738 config.set_initial_round_trip_time_us(stats->rtt.InMicroseconds(), | 739 config.set_initial_round_trip_time_us(stats->rtt.InMicroseconds(), |
739 stats->rtt.InMicroseconds()); | 740 stats->rtt.InMicroseconds()); |
740 } | 741 } |
741 } | 742 } |
742 | 743 |
743 *session = new QuicClientSession( | 744 *session = new QuicClientSession( |
744 connection, socket.Pass(), writer.Pass(), this, | 745 connection, socket.Pass(), writer.Pass(), this, |
745 quic_crypto_client_stream_factory_, server_info.Pass(), session_key, | 746 quic_crypto_client_stream_factory_, server_info.Pass(), session_key, |
746 config, &crypto_config_, net_log.net_log()); | 747 config, &crypto_config_, net_log.net_log()); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
811 base::TimeTicks when = broken_alternate_protocol_list_.front().when; | 812 base::TimeTicks when = broken_alternate_protocol_list_.front().when; |
812 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); | 813 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); |
813 base::MessageLoop::current()->PostDelayedTask( | 814 base::MessageLoop::current()->PostDelayedTask( |
814 FROM_HERE, | 815 FROM_HERE, |
815 base::Bind(&QuicStreamFactory::ExpireBrokenAlternateProtocolMappings, | 816 base::Bind(&QuicStreamFactory::ExpireBrokenAlternateProtocolMappings, |
816 weak_factory_.GetWeakPtr()), | 817 weak_factory_.GetWeakPtr()), |
817 delay); | 818 delay); |
818 } | 819 } |
819 | 820 |
820 } // namespace net | 821 } // namespace net |
OLD | NEW |