| 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 |