Chromium Code Reviews| 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 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 is_https, | 141 bool is_https, |
| 142 bool was_alternate_protocol_recently_broken, | 142 bool allow_zero_rtt, |
| 143 PrivacyMode privacy_mode, | 143 PrivacyMode privacy_mode, |
| 144 bool is_post, | 144 bool is_post, |
| 145 QuicServerInfo* server_info, | 145 QuicServerInfo* server_info, |
| 146 const BoundNetLog& net_log); | 146 const BoundNetLog& net_log); |
| 147 | 147 |
| 148 // Creates a new job to handle the resumption of for connecting an | 148 // Creates a new job to handle the resumption of for connecting an |
| 149 // existing session. | 149 // existing session. |
| 150 Job(QuicStreamFactory* factory, | 150 Job(QuicStreamFactory* factory, |
| 151 HostResolver* host_resolver, | 151 HostResolver* host_resolver, |
| 152 QuicClientSession* session, | 152 QuicClientSession* session, |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 187 STATE_CONNECT, | 187 STATE_CONNECT, |
| 188 STATE_RESUME_CONNECT, | 188 STATE_RESUME_CONNECT, |
| 189 STATE_CONNECT_COMPLETE, | 189 STATE_CONNECT_COMPLETE, |
| 190 }; | 190 }; |
| 191 IoState io_state_; | 191 IoState io_state_; |
| 192 | 192 |
| 193 QuicStreamFactory* factory_; | 193 QuicStreamFactory* factory_; |
| 194 SingleRequestHostResolver host_resolver_; | 194 SingleRequestHostResolver host_resolver_; |
| 195 QuicServerId server_id_; | 195 QuicServerId server_id_; |
| 196 bool is_post_; | 196 bool is_post_; |
| 197 bool was_alternate_protocol_recently_broken_; | 197 // True iff server and origin have the same hostname |
|
Ryan Hamilton
2015/05/18 14:29:52
ditto
Bence
2015/05/18 15:17:54
ditto
| |
| 198 // and alternative service was not recently broken. | |
| 199 bool allow_zero_rtt_; | |
|
Ryan Hamilton
2015/05/18 14:29:52
I'm not in love with this boolean combining two di
Bence
2015/05/18 15:17:54
Great idea, following the first suggestion. Thank
| |
| 198 scoped_ptr<QuicServerInfo> server_info_; | 200 scoped_ptr<QuicServerInfo> server_info_; |
| 199 bool started_another_job_; | 201 bool started_another_job_; |
| 200 const BoundNetLog net_log_; | 202 const BoundNetLog net_log_; |
| 201 QuicClientSession* session_; | 203 QuicClientSession* session_; |
| 202 CompletionCallback callback_; | 204 CompletionCallback callback_; |
| 203 AddressList address_list_; | 205 AddressList address_list_; |
| 204 base::TimeTicks dns_resolution_start_time_; | 206 base::TimeTicks dns_resolution_start_time_; |
| 205 base::TimeTicks dns_resolution_end_time_; | 207 base::TimeTicks dns_resolution_end_time_; |
| 206 base::WeakPtrFactory<Job> weak_factory_; | 208 base::WeakPtrFactory<Job> weak_factory_; |
| 207 DISALLOW_COPY_AND_ASSIGN(Job); | 209 DISALLOW_COPY_AND_ASSIGN(Job); |
| 208 }; | 210 }; |
| 209 | 211 |
| 210 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, | 212 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, |
| 211 HostResolver* host_resolver, | 213 HostResolver* host_resolver, |
| 212 const HostPortPair& host_port_pair, | 214 const HostPortPair& host_port_pair, |
| 213 bool is_https, | 215 bool is_https, |
| 214 bool was_alternate_protocol_recently_broken, | 216 bool allow_zero_rtt, |
| 215 PrivacyMode privacy_mode, | 217 PrivacyMode privacy_mode, |
| 216 bool is_post, | 218 bool is_post, |
| 217 QuicServerInfo* server_info, | 219 QuicServerInfo* server_info, |
| 218 const BoundNetLog& net_log) | 220 const BoundNetLog& net_log) |
| 219 : io_state_(STATE_RESOLVE_HOST), | 221 : io_state_(STATE_RESOLVE_HOST), |
| 220 factory_(factory), | 222 factory_(factory), |
| 221 host_resolver_(host_resolver), | 223 host_resolver_(host_resolver), |
| 222 server_id_(host_port_pair, is_https, privacy_mode), | 224 server_id_(host_port_pair, is_https, privacy_mode), |
| 223 is_post_(is_post), | 225 is_post_(is_post), |
| 224 was_alternate_protocol_recently_broken_( | 226 allow_zero_rtt_(allow_zero_rtt), |
| 225 was_alternate_protocol_recently_broken), | |
| 226 server_info_(server_info), | 227 server_info_(server_info), |
| 227 started_another_job_(false), | 228 started_another_job_(false), |
| 228 net_log_(net_log), | 229 net_log_(net_log), |
| 229 session_(nullptr), | 230 session_(nullptr), |
| 230 weak_factory_(this) { | 231 weak_factory_(this) { |
| 231 } | 232 } |
| 232 | 233 |
| 233 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, | 234 QuicStreamFactory::Job::Job(QuicStreamFactory* factory, |
| 234 HostResolver* host_resolver, | 235 HostResolver* host_resolver, |
| 235 QuicClientSession* session, | 236 QuicClientSession* session, |
| 236 QuicServerId server_id) | 237 QuicServerId server_id) |
| 237 : io_state_(STATE_RESUME_CONNECT), | 238 : io_state_(STATE_RESUME_CONNECT), |
| 238 factory_(factory), | 239 factory_(factory), |
| 239 host_resolver_(host_resolver), // unused | 240 host_resolver_(host_resolver), // unused |
| 240 server_id_(server_id), | 241 server_id_(server_id), |
| 241 is_post_(false), // unused | 242 is_post_(false), // unused |
| 242 was_alternate_protocol_recently_broken_(false), // unused | 243 allow_zero_rtt_(true), // unused |
| 243 started_another_job_(false), // unused | 244 started_another_job_(false), // unused |
| 244 net_log_(session->net_log()), // unused | 245 net_log_(session->net_log()), // unused |
| 245 session_(session), | 246 session_(session), |
| 246 weak_factory_(this) { | 247 weak_factory_(this) { |
| 247 } | 248 } |
| 248 | 249 |
| 249 QuicStreamFactory::Job::~Job() { | 250 QuicStreamFactory::Job::~Job() { |
| 250 // If disk cache has a pending WaitForDataReadyCallback, cancel that callback. | 251 // If disk cache has a pending WaitForDataReadyCallback, cancel that callback. |
| 251 if (server_info_) | 252 if (server_info_) |
| 252 server_info_->ResetWaitForDataReadyCallback(); | 253 server_info_->ResetWaitForDataReadyCallback(); |
| 253 } | 254 } |
| 254 | 255 |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 430 | 431 |
| 431 if (!session_->connection()->connected()) { | 432 if (!session_->connection()->connected()) { |
| 432 return ERR_CONNECTION_CLOSED; | 433 return ERR_CONNECTION_CLOSED; |
| 433 } | 434 } |
| 434 | 435 |
| 435 session_->StartReading(); | 436 session_->StartReading(); |
| 436 if (!session_->connection()->connected()) { | 437 if (!session_->connection()->connected()) { |
| 437 return ERR_QUIC_PROTOCOL_ERROR; | 438 return ERR_QUIC_PROTOCOL_ERROR; |
| 438 } | 439 } |
| 439 bool require_confirmation = | 440 bool require_confirmation = |
| 440 factory_->require_confirmation() || is_post_ || | 441 factory_->require_confirmation() || is_post_ || !allow_zero_rtt_; |
| 441 was_alternate_protocol_recently_broken_; | |
| 442 | 442 |
| 443 rv = session_->CryptoConnect( | 443 rv = session_->CryptoConnect( |
| 444 require_confirmation, | 444 require_confirmation, |
| 445 base::Bind(&QuicStreamFactory::Job::OnIOComplete, GetWeakPtr())); | 445 base::Bind(&QuicStreamFactory::Job::OnIOComplete, GetWeakPtr())); |
| 446 return rv; | 446 return rv; |
| 447 } | 447 } |
| 448 | 448 |
| 449 int QuicStreamFactory::Job::DoResumeConnect() { | 449 int QuicStreamFactory::Job::DoResumeConnect() { |
| 450 io_state_ = STATE_CONNECT_COMPLETE; | 450 io_state_ = STATE_CONNECT_COMPLETE; |
| 451 | 451 |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 478 : factory_(factory) {} | 478 : factory_(factory) {} |
| 479 | 479 |
| 480 QuicStreamRequest::~QuicStreamRequest() { | 480 QuicStreamRequest::~QuicStreamRequest() { |
| 481 if (factory_ && !callback_.is_null()) | 481 if (factory_ && !callback_.is_null()) |
| 482 factory_->CancelRequest(this); | 482 factory_->CancelRequest(this); |
| 483 } | 483 } |
| 484 | 484 |
| 485 int QuicStreamRequest::Request(const HostPortPair& host_port_pair, | 485 int QuicStreamRequest::Request(const HostPortPair& host_port_pair, |
| 486 bool is_https, | 486 bool is_https, |
| 487 PrivacyMode privacy_mode, | 487 PrivacyMode privacy_mode, |
| 488 base::StringPiece origin_host, | |
| 488 base::StringPiece method, | 489 base::StringPiece method, |
| 489 const BoundNetLog& net_log, | 490 const BoundNetLog& net_log, |
| 490 const CompletionCallback& callback) { | 491 const CompletionCallback& callback) { |
| 491 DCHECK(!stream_); | 492 DCHECK(!stream_); |
| 492 DCHECK(callback_.is_null()); | 493 DCHECK(callback_.is_null()); |
| 493 DCHECK(factory_); | 494 DCHECK(factory_); |
| 494 int rv = factory_->Create(host_port_pair, is_https, privacy_mode, method, | 495 origin_host_.assign(origin_host.data(), origin_host.size()); |
|
Ryan Hamilton
2015/05/18 14:29:52
It looks like this is the only place that origin_h
Bence
2015/05/18 15:17:54
Oops. Done.
| |
| 495 net_log, this); | 496 bool server_and_origin_have_same_host = host_port_pair.host() == origin_host; |
| 497 int rv = | |
| 498 factory_->Create(host_port_pair, is_https, privacy_mode, | |
| 499 server_and_origin_have_same_host, method, net_log, this); | |
| 496 if (rv == ERR_IO_PENDING) { | 500 if (rv == ERR_IO_PENDING) { |
| 497 host_port_pair_ = host_port_pair; | 501 host_port_pair_ = host_port_pair; |
| 498 net_log_ = net_log; | 502 net_log_ = net_log; |
| 499 callback_ = callback; | 503 callback_ = callback; |
| 500 } else { | 504 } else { |
| 501 factory_ = nullptr; | 505 factory_ = nullptr; |
| 502 } | 506 } |
| 503 if (rv == OK) | 507 if (rv == OK) |
| 504 DCHECK(stream_); | 508 DCHECK(stream_); |
| 505 return rv; | 509 return rv; |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 608 require_confirmation_ = require_confirmation; | 612 require_confirmation_ = require_confirmation; |
| 609 if (http_server_properties_ && (!(local_address_ == IPEndPoint()))) { | 613 if (http_server_properties_ && (!(local_address_ == IPEndPoint()))) { |
| 610 http_server_properties_->SetSupportsQuic(!require_confirmation, | 614 http_server_properties_->SetSupportsQuic(!require_confirmation, |
| 611 local_address_.address()); | 615 local_address_.address()); |
| 612 } | 616 } |
| 613 } | 617 } |
| 614 | 618 |
| 615 int QuicStreamFactory::Create(const HostPortPair& host_port_pair, | 619 int QuicStreamFactory::Create(const HostPortPair& host_port_pair, |
| 616 bool is_https, | 620 bool is_https, |
| 617 PrivacyMode privacy_mode, | 621 PrivacyMode privacy_mode, |
| 622 bool server_and_origin_have_same_host, | |
| 618 base::StringPiece method, | 623 base::StringPiece method, |
| 619 const BoundNetLog& net_log, | 624 const BoundNetLog& net_log, |
| 620 QuicStreamRequest* request) { | 625 QuicStreamRequest* request) { |
| 626 server_and_origin_have_same_host_ = server_and_origin_have_same_host; | |
| 621 QuicServerId server_id(host_port_pair, is_https, privacy_mode); | 627 QuicServerId server_id(host_port_pair, is_https, privacy_mode); |
| 622 if (HasActiveSession(server_id)) { | 628 if (HasActiveSession(server_id)) { |
| 623 request->set_stream(CreateIfSessionExists(server_id, net_log)); | 629 request->set_stream(CreateIfSessionExists(server_id, net_log)); |
| 624 return OK; | 630 return OK; |
| 625 } | 631 } |
| 626 | 632 |
| 627 if (HasActiveJob(server_id)) { | 633 if (HasActiveJob(server_id)) { |
| 628 active_requests_[request] = server_id; | 634 active_requests_[request] = server_id; |
| 629 job_requests_map_[server_id].insert(request); | 635 job_requests_map_[server_id].insert(request); |
| 630 return ERR_IO_PENDING; | 636 return ERR_IO_PENDING; |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 648 // If there is no entry for QUIC, consider that as a new server and | 654 // 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. | 655 // don't wait for Cache thread to load the data for that server. |
| 650 load_from_disk_cache = false; | 656 load_from_disk_cache = false; |
| 651 } | 657 } |
| 652 } | 658 } |
| 653 if (load_from_disk_cache && CryptoConfigCacheIsEmpty(server_id)) { | 659 if (load_from_disk_cache && CryptoConfigCacheIsEmpty(server_id)) { |
| 654 quic_server_info = quic_server_info_factory_->GetForServer(server_id); | 660 quic_server_info = quic_server_info_factory_->GetForServer(server_id); |
| 655 } | 661 } |
| 656 } | 662 } |
| 657 | 663 |
| 658 scoped_ptr<Job> job(new Job(this, host_resolver_, host_port_pair, is_https, | 664 scoped_ptr<Job> job(new Job( |
| 659 WasQuicRecentlyBroken(server_id), privacy_mode, | 665 this, host_resolver_, host_port_pair, is_https, |
| 660 method == "POST" /* is_post */, quic_server_info, | 666 server_and_origin_have_same_host && !WasQuicRecentlyBroken(server_id), |
| 661 net_log)); | 667 privacy_mode, method == "POST" /* is_post */, quic_server_info, net_log)); |
| 662 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, | 668 int rv = job->Run(base::Bind(&QuicStreamFactory::OnJobComplete, |
| 663 base::Unretained(this), job.get())); | 669 base::Unretained(this), job.get())); |
| 664 if (rv == ERR_IO_PENDING) { | 670 if (rv == ERR_IO_PENDING) { |
| 665 active_requests_[request] = server_id; | 671 active_requests_[request] = server_id; |
| 666 job_requests_map_[server_id].insert(request); | 672 job_requests_map_[server_id].insert(request); |
| 667 active_jobs_[server_id].insert(job.release()); | 673 active_jobs_[server_id].insert(job.release()); |
| 668 return rv; | 674 return rv; |
| 669 } | 675 } |
| 670 if (rv == OK) { | 676 if (rv == OK) { |
| 671 DCHECK(HasActiveSession(server_id)); | 677 DCHECK(HasActiveSession(server_id)); |
| 672 request->set_stream(CreateIfSessionExists(server_id, net_log)); | 678 request->set_stream(CreateIfSessionExists(server_id, net_log)); |
| 673 } | 679 } |
| 674 return rv; | 680 return rv; |
| 675 } | 681 } |
| 676 | 682 |
| 677 void QuicStreamFactory::CreateAuxilaryJob(const QuicServerId server_id, | 683 void QuicStreamFactory::CreateAuxilaryJob(const QuicServerId server_id, |
| 678 bool is_post, | 684 bool is_post, |
| 679 const BoundNetLog& net_log) { | 685 const BoundNetLog& net_log) { |
| 680 Job* aux_job = new Job(this, host_resolver_, server_id.host_port_pair(), | 686 Job* aux_job = new Job( |
| 681 server_id.is_https(), WasQuicRecentlyBroken(server_id), | 687 this, host_resolver_, server_id.host_port_pair(), server_id.is_https(), |
| 682 server_id.privacy_mode(), is_post, nullptr, net_log); | 688 server_and_origin_have_same_host_ && !WasQuicRecentlyBroken(server_id), |
|
Ryan Hamilton
2015/05/18 14:29:52
It looks like this method is only called from the
Bence
2015/05/18 15:17:55
Great idea, thanks. Done.
| |
| 689 server_id.privacy_mode(), is_post, nullptr, net_log); | |
| 683 active_jobs_[server_id].insert(aux_job); | 690 active_jobs_[server_id].insert(aux_job); |
| 684 task_runner_->PostTask(FROM_HERE, | 691 task_runner_->PostTask(FROM_HERE, |
| 685 base::Bind(&QuicStreamFactory::Job::RunAuxilaryJob, | 692 base::Bind(&QuicStreamFactory::Job::RunAuxilaryJob, |
| 686 aux_job->GetWeakPtr())); | 693 aux_job->GetWeakPtr())); |
| 687 } | 694 } |
| 688 | 695 |
| 689 bool QuicStreamFactory::OnResolution( | 696 bool QuicStreamFactory::OnResolution( |
| 690 const QuicServerId& server_id, | 697 const QuicServerId& server_id, |
| 691 const AddressList& address_list) { | 698 const AddressList& address_list) { |
| 692 DCHECK(!HasActiveSession(server_id)); | 699 DCHECK(!HasActiveSession(server_id)); |
| (...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1210 // Since the session was active, there's no longer an | 1217 // Since the session was active, there's no longer an |
| 1211 // HttpStreamFactoryImpl::Job running which can mark it broken, unless the TCP | 1218 // 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 | 1219 // 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 | 1220 // it as recently broken, which means that 0-RTT will be disabled but we'll |
| 1214 // still race. | 1221 // still race. |
| 1215 http_server_properties_->MarkAlternativeServiceRecentlyBroken( | 1222 http_server_properties_->MarkAlternativeServiceRecentlyBroken( |
| 1216 alternative_service); | 1223 alternative_service); |
| 1217 } | 1224 } |
| 1218 | 1225 |
| 1219 } // namespace net | 1226 } // namespace net |
| OLD | NEW |