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 |