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