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 |