| 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/cpu.h" | 9 #include "base/cpu.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 ip_endpoint == other.ip_endpoint; | 131 ip_endpoint == other.ip_endpoint; |
| 132 }; | 132 }; |
| 133 | 133 |
| 134 // Responsible for creating a new QUIC session to the specified server, and | 134 // Responsible for creating a new QUIC session to the specified server, and |
| 135 // for notifying any associated requests when complete. | 135 // for notifying any associated requests when complete. |
| 136 class QuicStreamFactory::Job { | 136 class QuicStreamFactory::Job { |
| 137 public: | 137 public: |
| 138 Job(QuicStreamFactory* factory, | 138 Job(QuicStreamFactory* factory, |
| 139 HostResolver* host_resolver, | 139 HostResolver* host_resolver, |
| 140 const HostPortPair& host_port_pair, | 140 const HostPortPair& host_port_pair, |
| 141 bool server_and_origin_have_same_host, |
| 141 bool is_https, | 142 bool is_https, |
| 142 bool was_alternate_protocol_recently_broken, | 143 bool was_alternative_service_recently_broken, |
| 143 PrivacyMode privacy_mode, | 144 PrivacyMode privacy_mode, |
| 144 bool is_post, | 145 bool is_post, |
| 145 QuicServerInfo* server_info, | 146 QuicServerInfo* server_info, |
| 146 const BoundNetLog& net_log); | 147 const BoundNetLog& net_log); |
| 147 | 148 |
| 148 // Creates a new job to handle the resumption of for connecting an | 149 // Creates a new job to handle the resumption of for connecting an |
| 149 // existing session. | 150 // existing session. |
| 150 Job(QuicStreamFactory* factory, | 151 Job(QuicStreamFactory* factory, |
| 151 HostResolver* host_resolver, | 152 HostResolver* host_resolver, |
| 152 QuicClientSession* session, | 153 QuicClientSession* session, |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 STATE_LOAD_SERVER_INFO_COMPLETE, | 187 STATE_LOAD_SERVER_INFO_COMPLETE, |
| 187 STATE_CONNECT, | 188 STATE_CONNECT, |
| 188 STATE_RESUME_CONNECT, | 189 STATE_RESUME_CONNECT, |
| 189 STATE_CONNECT_COMPLETE, | 190 STATE_CONNECT_COMPLETE, |
| 190 }; | 191 }; |
| 191 IoState io_state_; | 192 IoState io_state_; |
| 192 | 193 |
| 193 QuicStreamFactory* factory_; | 194 QuicStreamFactory* factory_; |
| 194 SingleRequestHostResolver host_resolver_; | 195 SingleRequestHostResolver host_resolver_; |
| 195 QuicServerId server_id_; | 196 QuicServerId server_id_; |
| 197 // True if and only if server and origin have the same hostname. |
| 198 bool server_and_origin_have_same_host_; |
| 196 bool is_post_; | 199 bool is_post_; |
| 197 bool was_alternate_protocol_recently_broken_; | 200 bool was_alternative_service_recently_broken_; |
| 198 scoped_ptr<QuicServerInfo> server_info_; | 201 scoped_ptr<QuicServerInfo> server_info_; |
| 199 bool started_another_job_; | 202 bool started_another_job_; |
| 200 const BoundNetLog net_log_; | 203 const BoundNetLog net_log_; |
| 201 QuicClientSession* session_; | 204 QuicClientSession* session_; |
| 202 CompletionCallback callback_; | 205 CompletionCallback callback_; |
| 203 AddressList address_list_; | 206 AddressList address_list_; |
| 204 base::TimeTicks dns_resolution_start_time_; | 207 base::TimeTicks dns_resolution_start_time_; |
| 205 base::TimeTicks dns_resolution_end_time_; | 208 base::TimeTicks dns_resolution_end_time_; |
| 206 base::WeakPtrFactory<Job> weak_factory_; | 209 base::WeakPtrFactory<Job> weak_factory_; |
| 207 DISALLOW_COPY_AND_ASSIGN(Job); | 210 DISALLOW_COPY_AND_ASSIGN(Job); |
| 208 }; | 211 }; |
| 209 | 212 |
| 210 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, | 213 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, |
| 211 HostResolver* host_resolver, | 214 HostResolver* host_resolver, |
| 212 const HostPortPair& host_port_pair, | 215 const HostPortPair& host_port_pair, |
| 216 bool server_and_origin_have_same_host, |
| 213 bool is_https, | 217 bool is_https, |
| 214 bool was_alternate_protocol_recently_broken, | 218 bool was_alternative_service_recently_broken, |
| 215 PrivacyMode privacy_mode, | 219 PrivacyMode privacy_mode, |
| 216 bool is_post, | 220 bool is_post, |
| 217 QuicServerInfo* server_info, | 221 QuicServerInfo* server_info, |
| 218 const BoundNetLog& net_log) | 222 const BoundNetLog& net_log) |
| 219 : io_state_(STATE_RESOLVE_HOST), | 223 : io_state_(STATE_RESOLVE_HOST), |
| 220 factory_(factory), | 224 factory_(factory), |
| 221 host_resolver_(host_resolver), | 225 host_resolver_(host_resolver), |
| 222 server_id_(host_port_pair, is_https, privacy_mode), | 226 server_id_(host_port_pair, is_https, privacy_mode), |
| 227 server_and_origin_have_same_host_(server_and_origin_have_same_host), |
| 223 is_post_(is_post), | 228 is_post_(is_post), |
| 224 was_alternate_protocol_recently_broken_( | 229 was_alternative_service_recently_broken_( |
| 225 was_alternate_protocol_recently_broken), | 230 was_alternative_service_recently_broken), |
| 226 server_info_(server_info), | 231 server_info_(server_info), |
| 227 started_another_job_(false), | 232 started_another_job_(false), |
| 228 net_log_(net_log), | 233 net_log_(net_log), |
| 229 session_(nullptr), | 234 session_(nullptr), |
| 230 weak_factory_(this) { | 235 weak_factory_(this) { |
| 231 } | 236 } |
| 232 | 237 |
| 233 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, | 238 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, |
| 234 HostResolver* host_resolver, | 239 HostResolver* host_resolver, |
| 235 QuicClientSession* session, | 240 QuicClientSession* session, |
| 236 QuicServerId server_id) | 241 QuicServerId server_id) |
| 237 : io_state_(STATE_RESUME_CONNECT), | 242 : io_state_(STATE_RESUME_CONNECT), |
| 238 factory_(factory), | 243 factory_(factory), |
| 239 host_resolver_(host_resolver), // unused | 244 host_resolver_(host_resolver), // unused |
| 240 server_id_(server_id), | 245 server_id_(server_id), |
| 241 is_post_(false), // unused | 246 server_and_origin_have_same_host_(false), // unused |
| 242 was_alternate_protocol_recently_broken_(false), // unused | 247 is_post_(false), // unused |
| 243 started_another_job_(false), // unused | 248 was_alternative_service_recently_broken_(false), // unused |
| 244 net_log_(session->net_log()), // unused | 249 started_another_job_(false), // unused |
| 250 net_log_(session->net_log()), // unused |
| 245 session_(session), | 251 session_(session), |
| 246 weak_factory_(this) { | 252 weak_factory_(this) { |
| 247 } | 253 } |
| 248 | 254 |
| 249 QuicStreamFactory::Job::~Job() { | 255 QuicStreamFactory::Job::~Job() { |
| 250 // If disk cache has a pending WaitForDataReadyCallback, cancel that callback. | 256 // If disk cache has a pending WaitForDataReadyCallback, cancel that callback. |
| 251 if (server_info_) | 257 if (server_info_) |
| 252 server_info_->ResetWaitForDataReadyCallback(); | 258 server_info_->ResetWaitForDataReadyCallback(); |
| 253 } | 259 } |
| 254 | 260 |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 383 base::TimeDelta::FromMilliseconds(load_server_info_timeout_ms)); | 389 base::TimeDelta::FromMilliseconds(load_server_info_timeout_ms)); |
| 384 } | 390 } |
| 385 } | 391 } |
| 386 | 392 |
| 387 int rv = server_info_->WaitForDataReady( | 393 int rv = server_info_->WaitForDataReady( |
| 388 base::Bind(&QuicStreamFactory::Job::OnIOComplete, GetWeakPtr())); | 394 base::Bind(&QuicStreamFactory::Job::OnIOComplete, GetWeakPtr())); |
| 389 if (rv == ERR_IO_PENDING && factory_->enable_connection_racing()) { | 395 if (rv == ERR_IO_PENDING && factory_->enable_connection_racing()) { |
| 390 // If we are waiting to load server config from the disk cache, then start | 396 // If we are waiting to load server config from the disk cache, then start |
| 391 // another job. | 397 // another job. |
| 392 started_another_job_ = true; | 398 started_another_job_ = true; |
| 393 factory_->CreateAuxilaryJob(server_id_, is_post_, net_log_); | 399 factory_->CreateAuxilaryJob(server_id_, server_and_origin_have_same_host_, |
| 400 is_post_, net_log_); |
| 394 } | 401 } |
| 395 return rv; | 402 return rv; |
| 396 } | 403 } |
| 397 | 404 |
| 398 int QuicStreamFactory::Job::DoLoadServerInfoComplete(int rv) { | 405 int QuicStreamFactory::Job::DoLoadServerInfoComplete(int rv) { |
| 399 UMA_HISTOGRAM_TIMES("Net.QuicServerInfo.DiskCacheWaitForDataReadyTime", | 406 UMA_HISTOGRAM_TIMES("Net.QuicServerInfo.DiskCacheWaitForDataReadyTime", |
| 400 base::TimeTicks::Now() - dns_resolution_end_time_); | 407 base::TimeTicks::Now() - dns_resolution_end_time_); |
| 401 | 408 |
| 402 if (rv != OK) | 409 if (rv != OK) |
| 403 server_info_.reset(); | 410 server_info_.reset(); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 429 } | 436 } |
| 430 | 437 |
| 431 if (!session_->connection()->connected()) { | 438 if (!session_->connection()->connected()) { |
| 432 return ERR_CONNECTION_CLOSED; | 439 return ERR_CONNECTION_CLOSED; |
| 433 } | 440 } |
| 434 | 441 |
| 435 session_->StartReading(); | 442 session_->StartReading(); |
| 436 if (!session_->connection()->connected()) { | 443 if (!session_->connection()->connected()) { |
| 437 return ERR_QUIC_PROTOCOL_ERROR; | 444 return ERR_QUIC_PROTOCOL_ERROR; |
| 438 } | 445 } |
| 439 bool require_confirmation = | 446 bool require_confirmation = factory_->require_confirmation() || |
| 440 factory_->require_confirmation() || is_post_ || | 447 !server_and_origin_have_same_host_ || is_post_ || |
| 441 was_alternate_protocol_recently_broken_; | 448 was_alternative_service_recently_broken_; |
| 442 | 449 |
| 443 rv = session_->CryptoConnect( | 450 rv = session_->CryptoConnect( |
| 444 require_confirmation, | 451 require_confirmation, |
| 445 base::Bind(&QuicStreamFactory::Job::OnIOComplete, GetWeakPtr())); | 452 base::Bind(&QuicStreamFactory::Job::OnIOComplete, GetWeakPtr())); |
| 446 return rv; | 453 return rv; |
| 447 } | 454 } |
| 448 | 455 |
| 449 int QuicStreamFactory::Job::DoResumeConnect() { | 456 int QuicStreamFactory::Job::DoResumeConnect() { |
| 450 io_state_ = STATE_CONNECT_COMPLETE; | 457 io_state_ = STATE_CONNECT_COMPLETE; |
| 451 | 458 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 478 : factory_(factory) {} | 485 : factory_(factory) {} |
| 479 | 486 |
| 480 QuicStreamRequest::~QuicStreamRequest() { | 487 QuicStreamRequest::~QuicStreamRequest() { |
| 481 if (factory_ && !callback_.is_null()) | 488 if (factory_ && !callback_.is_null()) |
| 482 factory_->CancelRequest(this); | 489 factory_->CancelRequest(this); |
| 483 } | 490 } |
| 484 | 491 |
| 485 int QuicStreamRequest::Request(const HostPortPair& host_port_pair, | 492 int QuicStreamRequest::Request(const HostPortPair& host_port_pair, |
| 486 bool is_https, | 493 bool is_https, |
| 487 PrivacyMode privacy_mode, | 494 PrivacyMode privacy_mode, |
| 495 base::StringPiece origin_host, |
| 488 base::StringPiece method, | 496 base::StringPiece method, |
| 489 const BoundNetLog& net_log, | 497 const BoundNetLog& net_log, |
| 490 const CompletionCallback& callback) { | 498 const CompletionCallback& callback) { |
| 491 DCHECK(!stream_); | 499 DCHECK(!stream_); |
| 492 DCHECK(callback_.is_null()); | 500 DCHECK(callback_.is_null()); |
| 493 DCHECK(factory_); | 501 DCHECK(factory_); |
| 494 int rv = factory_->Create(host_port_pair, is_https, privacy_mode, method, | 502 bool server_and_origin_have_same_host = host_port_pair.host() == origin_host; |
| 495 net_log, this); | 503 int rv = |
| 504 factory_->Create(host_port_pair, is_https, privacy_mode, |
| 505 server_and_origin_have_same_host, method, net_log, this); |
| 496 if (rv == ERR_IO_PENDING) { | 506 if (rv == ERR_IO_PENDING) { |
| 497 host_port_pair_ = host_port_pair; | 507 host_port_pair_ = host_port_pair; |
| 498 net_log_ = net_log; | 508 net_log_ = net_log; |
| 499 callback_ = callback; | 509 callback_ = callback; |
| 500 } else { | 510 } else { |
| 501 factory_ = nullptr; | 511 factory_ = nullptr; |
| 502 } | 512 } |
| 503 if (rv == OK) | 513 if (rv == OK) |
| 504 DCHECK(stream_); | 514 DCHECK(stream_); |
| 505 return rv; | 515 return rv; |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 608 require_confirmation_ = require_confirmation; | 618 require_confirmation_ = require_confirmation; |
| 609 if (http_server_properties_ && (!(local_address_ == IPEndPoint()))) { | 619 if (http_server_properties_ && (!(local_address_ == IPEndPoint()))) { |
| 610 http_server_properties_->SetSupportsQuic(!require_confirmation, | 620 http_server_properties_->SetSupportsQuic(!require_confirmation, |
| 611 local_address_.address()); | 621 local_address_.address()); |
| 612 } | 622 } |
| 613 } | 623 } |
| 614 | 624 |
| 615 int QuicStreamFactory::Create(const HostPortPair& host_port_pair, | 625 int QuicStreamFactory::Create(const HostPortPair& host_port_pair, |
| 616 bool is_https, | 626 bool is_https, |
| 617 PrivacyMode privacy_mode, | 627 PrivacyMode privacy_mode, |
| 628 bool server_and_origin_have_same_host, |
| 618 base::StringPiece method, | 629 base::StringPiece method, |
| 619 const BoundNetLog& net_log, | 630 const BoundNetLog& net_log, |
| 620 QuicStreamRequest* request) { | 631 QuicStreamRequest* request) { |
| 621 QuicServerId server_id(host_port_pair, is_https, privacy_mode); | 632 QuicServerId server_id(host_port_pair, is_https, privacy_mode); |
| 622 if (HasActiveSession(server_id)) { | 633 if (HasActiveSession(server_id)) { |
| 623 request->set_stream(CreateIfSessionExists(server_id, net_log)); | 634 request->set_stream(CreateIfSessionExists(server_id, net_log)); |
| 624 return OK; | 635 return OK; |
| 625 } | 636 } |
| 626 | 637 |
| 627 if (HasActiveJob(server_id)) { | 638 if (HasActiveJob(server_id)) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 648 // If there is no entry for QUIC, consider that as a new server and | 659 // If there is no entry for QUIC, consider that as a new server and |
| 649 // don't wait for Cache thread to load the data for that server. | 660 // don't wait for Cache thread to load the data for that server. |
| 650 load_from_disk_cache = false; | 661 load_from_disk_cache = false; |
| 651 } | 662 } |
| 652 } | 663 } |
| 653 if (load_from_disk_cache && CryptoConfigCacheIsEmpty(server_id)) { | 664 if (load_from_disk_cache && CryptoConfigCacheIsEmpty(server_id)) { |
| 654 quic_server_info = quic_server_info_factory_->GetForServer(server_id); | 665 quic_server_info = quic_server_info_factory_->GetForServer(server_id); |
| 655 } | 666 } |
| 656 } | 667 } |
| 657 | 668 |
| 658 scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_pair, is_https, | 669 scoped_ptr<Job> job(new Job( |
| 659 WasQuicRecentlyBroken(server_id), privacy_mode, | 670 this, host_resolver_, host_port_pair, server_and_origin_have_same_host, |
| 660 method == "POST" /* is_post */, quic_server_info, | 671 is_https, WasQuicRecentlyBroken(server_id), privacy_mode, |
| 661 net_log)); | 672 method == "POST" /* is_post */, quic_server_info, net_log)); |
| 662 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, | 673 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, |
| 663 base::Unretained(this), job.get())); | 674 base::Unretained(this), job.get())); |
| 664 if (rv == ERR_IO_PENDING) { | 675 if (rv == ERR_IO_PENDING) { |
| 665 active_requests_[request] = server_id; | 676 active_requests_[request] = server_id; |
| 666 job_requests_map_[server_id].insert(request); | 677 job_requests_map_[server_id].insert(request); |
| 667 active_jobs_[server_id].insert(job.release()); | 678 active_jobs_[server_id].insert(job.release()); |
| 668 return rv; | 679 return rv; |
| 669 } | 680 } |
| 670 if (rv == OK) { | 681 if (rv == OK) { |
| 671 DCHECK(HasActiveSession(server_id)); | 682 DCHECK(HasActiveSession(server_id)); |
| 672 request->set_stream(CreateIfSessionExists(server_id, net_log)); | 683 request->set_stream(CreateIfSessionExists(server_id, net_log)); |
| 673 } | 684 } |
| 674 return rv; | 685 return rv; |
| 675 } | 686 } |
| 676 | 687 |
| 677 void QuicStreamFactory::CreateAuxilaryJob(const QuicServerId server_id, | 688 void QuicStreamFactory::CreateAuxilaryJob(const QuicServerId server_id, |
| 689 bool server_and_origin_have_same_host, |
| 678 bool is_post, | 690 bool is_post, |
| 679 const BoundNetLog& net_log) { | 691 const BoundNetLog& net_log) { |
| 680 Job* aux_job = new Job(this, host_resolver_, server_id.host_port_pair(), | 692 Job* aux_job = new Job(this, host_resolver_, server_id.host_port_pair(), |
| 681 server_id.is_https(), WasQuicRecentlyBroken(server_id), | 693 server_and_origin_have_same_host, server_id.is_https(), |
| 694 WasQuicRecentlyBroken(server_id), |
| 682 server_id.privacy_mode(), is_post, nullptr, net_log); | 695 server_id.privacy_mode(), is_post, nullptr, net_log); |
| 683 active_jobs_[server_id].insert(aux_job); | 696 active_jobs_[server_id].insert(aux_job); |
| 684 task_runner_->PostTask(FROM_HERE, | 697 task_runner_->PostTask(FROM_HERE, |
| 685 base::Bind(&QuicStreamFactory::Job::RunAuxilaryJob, | 698 base::Bind(&QuicStreamFactory::Job::RunAuxilaryJob, |
| 686 aux_job->GetWeakPtr())); | 699 aux_job->GetWeakPtr())); |
| 687 } | 700 } |
| 688 | 701 |
| 689 bool QuicStreamFactory::OnResolution( | 702 bool QuicStreamFactory::OnResolution( |
| 690 const QuicServerId& server_id, | 703 const QuicServerId& server_id, |
| 691 const AddressList& address_list) { | 704 const AddressList& address_list) { |
| (...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1210 // Since the session was active, there's no longer an | 1223 // Since the session was active, there's no longer an |
| 1211 // HttpStreamFactoryImpl::Job running which can mark it broken, unless the TCP | 1224 // HttpStreamFactoryImpl::Job running which can mark it broken, unless the TCP |
| 1212 // job also fails. So to avoid not using QUIC when we otherwise could, we mark | 1225 // job also fails. So to avoid not using QUIC when we otherwise could, we mark |
| 1213 // it as recently broken, which means that 0-RTT will be disabled but we'll | 1226 // it as recently broken, which means that 0-RTT will be disabled but we'll |
| 1214 // still race. | 1227 // still race. |
| 1215 http_server_properties_->MarkAlternativeServiceRecentlyBroken( | 1228 http_server_properties_->MarkAlternativeServiceRecentlyBroken( |
| 1216 alternative_service); | 1229 alternative_service); |
| 1217 } | 1230 } |
| 1218 | 1231 |
| 1219 } // namespace net | 1232 } // namespace net |
| OLD | NEW |