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 <algorithm> | 7 #include <algorithm> |
8 #include <set> | 8 #include <set> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
54 #include "base/win/windows_version.h" | 54 #include "base/win/windows_version.h" |
55 #endif | 55 #endif |
56 | 56 |
57 #if defined(USE_OPENSSL) | 57 #if defined(USE_OPENSSL) |
58 #include <openssl/aead.h> | 58 #include <openssl/aead.h> |
59 #include "crypto/openssl_util.h" | 59 #include "crypto/openssl_util.h" |
60 #else | 60 #else |
61 #include "base/cpu.h" | 61 #include "base/cpu.h" |
62 #endif | 62 #endif |
63 | 63 |
64 #if BUILDFLAG(ENABLE_BIDIRECTIONAL_STREAM) | |
65 #include "net/http/bidirectional_stream_job.h" | |
66 #include "net/quic/bidirectional_stream_quic_impl.h" | |
67 #endif | |
68 | |
64 using std::min; | 69 using std::min; |
65 using NetworkHandle = net::NetworkChangeNotifier::NetworkHandle; | 70 using NetworkHandle = net::NetworkChangeNotifier::NetworkHandle; |
66 | 71 |
67 namespace net { | 72 namespace net { |
68 | 73 |
69 namespace { | 74 namespace { |
70 | 75 |
71 enum CreateSessionFailure { | 76 enum CreateSessionFailure { |
72 CREATION_ERROR_CONNECTING_SOCKET, | 77 CREATION_ERROR_CONNECTING_SOCKET, |
73 CREATION_ERROR_SETTING_RECEIVE_BUFFER, | 78 CREATION_ERROR_SETTING_RECEIVE_BUFFER, |
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
491 session_ = nullptr; | 496 session_ = nullptr; |
492 return OK; | 497 return OK; |
493 } | 498 } |
494 | 499 |
495 factory_->ActivateSession(server_id_, session_); | 500 factory_->ActivateSession(server_id_, session_); |
496 | 501 |
497 return OK; | 502 return OK; |
498 } | 503 } |
499 | 504 |
500 QuicStreamRequest::QuicStreamRequest(QuicStreamFactory* factory) | 505 QuicStreamRequest::QuicStreamRequest(QuicStreamFactory* factory) |
501 : factory_(factory) {} | 506 : factory_(factory), for_bidirectional_(false) {} |
502 | 507 |
503 QuicStreamRequest::~QuicStreamRequest() { | 508 QuicStreamRequest::~QuicStreamRequest() { |
504 if (factory_ && !callback_.is_null()) | 509 if (factory_ && !callback_.is_null()) |
505 factory_->CancelRequest(this); | 510 factory_->CancelRequest(this); |
506 } | 511 } |
507 | 512 |
508 int QuicStreamRequest::Request(const HostPortPair& host_port_pair, | 513 int QuicStreamRequest::Request(const HostPortPair& host_port_pair, |
509 PrivacyMode privacy_mode, | 514 PrivacyMode privacy_mode, |
510 int cert_verify_flags, | 515 int cert_verify_flags, |
511 const GURL& url, | 516 const GURL& url, |
512 base::StringPiece method, | 517 base::StringPiece method, |
513 const BoundNetLog& net_log, | 518 const BoundNetLog& net_log, |
514 const CompletionCallback& callback) { | 519 const CompletionCallback& callback, |
520 bool for_bidirectional) { | |
515 DCHECK(!stream_); | 521 DCHECK(!stream_); |
522 #if BUILDFLAG(ENABLE_BIDIRECTIONAL_STREAM) | |
523 DCHECK(!bidirectional_stream_job_); | |
524 #endif | |
516 DCHECK(callback_.is_null()); | 525 DCHECK(callback_.is_null()); |
517 DCHECK(factory_); | 526 DCHECK(factory_); |
518 origin_host_ = url.host(); | 527 origin_host_ = url.host(); |
519 privacy_mode_ = privacy_mode; | 528 privacy_mode_ = privacy_mode; |
529 for_bidirectional_ = for_bidirectional; | |
530 | |
520 int rv = factory_->Create(host_port_pair, privacy_mode, cert_verify_flags, | 531 int rv = factory_->Create(host_port_pair, privacy_mode, cert_verify_flags, |
521 url, method, net_log, this); | 532 url, method, net_log, this); |
522 if (rv == ERR_IO_PENDING) { | 533 if (rv == ERR_IO_PENDING) { |
523 host_port_pair_ = host_port_pair; | 534 host_port_pair_ = host_port_pair; |
524 net_log_ = net_log; | 535 net_log_ = net_log; |
525 callback_ = callback; | 536 callback_ = callback; |
526 } else { | 537 } else { |
527 factory_ = nullptr; | 538 factory_ = nullptr; |
528 } | 539 } |
529 if (rv == OK) | 540 if (rv == OK) { |
541 #if BUILDFLAG(ENABLE_BIDIRECTIONAL_STREAM) | |
542 DCHECK(stream_ || (for_bidirectional_ && bidirectional_stream_job_)); | |
Ryan Hamilton
2016/03/03 04:14:57
This would be true if both stream_ and bidirection
xunjieli
2016/03/03 16:54:19
Done.
| |
543 #else | |
530 DCHECK(stream_); | 544 DCHECK(stream_); |
545 #endif | |
546 } | |
531 return rv; | 547 return rv; |
532 } | 548 } |
533 | 549 |
534 void QuicStreamRequest::set_stream(scoped_ptr<QuicHttpStream> stream) { | 550 void QuicStreamRequest::InitializeStreamFromSession( |
535 DCHECK(stream); | 551 QuicChromiumClientSession* session) { |
536 stream_ = std::move(stream); | 552 DCHECK(session); |
553 if (for_bidirectional_) { | |
554 #if BUILDFLAG(ENABLE_BIDIRECTIONAL_STREAM) | |
555 bidirectional_stream_job_.reset( | |
556 new BidirectionalStreamQuicImpl(session->GetWeakPtr())); | |
557 #else | |
558 DCHECK(false); | |
559 #endif | |
560 } else { | |
561 stream_.reset(new QuicHttpStream(session->GetWeakPtr())); | |
562 } | |
Ryan Hamilton
2016/03/03 04:14:58
How about instead of creating the QuicHttpStream o
xunjieli
2016/03/03 16:54:19
Done. Great idea! But this would change the semant
Ryan Hamilton
2016/03/07 20:12:37
Good point. I think you'll need to change HttpStre
xunjieli
2016/03/08 15:39:31
Done.
| |
537 } | 563 } |
538 | 564 |
539 void QuicStreamRequest::OnRequestComplete(int rv) { | 565 void QuicStreamRequest::OnRequestComplete(int rv) { |
540 factory_ = nullptr; | 566 factory_ = nullptr; |
541 callback_.Run(rv); | 567 callback_.Run(rv); |
542 } | 568 } |
543 | 569 |
544 base::TimeDelta QuicStreamRequest::GetTimeDelayForWaitingJob() const { | 570 base::TimeDelta QuicStreamRequest::GetTimeDelayForWaitingJob() const { |
545 if (!factory_) | 571 if (!factory_) |
546 return base::TimeDelta(); | 572 return base::TimeDelta(); |
547 return factory_->GetTimeDelayForWaitingJob( | 573 return factory_->GetTimeDelayForWaitingJob( |
548 QuicServerId(host_port_pair_, privacy_mode_)); | 574 QuicServerId(host_port_pair_, privacy_mode_)); |
549 } | 575 } |
550 | 576 |
551 scoped_ptr<QuicHttpStream> QuicStreamRequest::ReleaseStream() { | 577 scoped_ptr<QuicHttpStream> QuicStreamRequest::ReleaseStream() { |
552 DCHECK(stream_); | 578 DCHECK(stream_); |
579 DCHECK(!for_bidirectional_); | |
553 return std::move(stream_); | 580 return std::move(stream_); |
554 } | 581 } |
555 | 582 |
583 #if BUILDFLAG(ENABLE_BIDIRECTIONAL_STREAM) | |
584 scoped_ptr<BidirectionalStreamJob> | |
585 QuicStreamRequest::ReleaseBidirectionalStreamJob() { | |
586 DCHECK(bidirectional_stream_job_); | |
587 DCHECK(for_bidirectional_); | |
588 | |
589 return std::move(bidirectional_stream_job_); | |
590 } | |
591 #endif | |
592 | |
556 QuicStreamFactory::QuicStreamFactory( | 593 QuicStreamFactory::QuicStreamFactory( |
557 HostResolver* host_resolver, | 594 HostResolver* host_resolver, |
558 ClientSocketFactory* client_socket_factory, | 595 ClientSocketFactory* client_socket_factory, |
559 base::WeakPtr<HttpServerProperties> http_server_properties, | 596 base::WeakPtr<HttpServerProperties> http_server_properties, |
560 CertVerifier* cert_verifier, | 597 CertVerifier* cert_verifier, |
561 CTPolicyEnforcer* ct_policy_enforcer, | 598 CTPolicyEnforcer* ct_policy_enforcer, |
562 ChannelIDService* channel_id_service, | 599 ChannelIDService* channel_id_service, |
563 TransportSecurityState* transport_security_state, | 600 TransportSecurityState* transport_security_state, |
564 CTVerifier* cert_transparency_verifier, | 601 CTVerifier* cert_transparency_verifier, |
565 SocketPerformanceWatcherFactory* socket_performance_watcher_factory, | 602 SocketPerformanceWatcherFactory* socket_performance_watcher_factory, |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
771 const BoundNetLog& net_log, | 808 const BoundNetLog& net_log, |
772 QuicStreamRequest* request) { | 809 QuicStreamRequest* request) { |
773 // Enforce session affinity for promised streams. | 810 // Enforce session affinity for promised streams. |
774 QuicClientPromisedInfo* promised = | 811 QuicClientPromisedInfo* promised = |
775 push_promise_index_.GetPromised(url.spec()); | 812 push_promise_index_.GetPromised(url.spec()); |
776 if (promised) { | 813 if (promised) { |
777 QuicChromiumClientSession* session = | 814 QuicChromiumClientSession* session = |
778 static_cast<QuicChromiumClientSession*>(promised->session()); | 815 static_cast<QuicChromiumClientSession*>(promised->session()); |
779 DCHECK(session); | 816 DCHECK(session); |
780 if (session->server_id().privacy_mode() == privacy_mode) { | 817 if (session->server_id().privacy_mode() == privacy_mode) { |
781 request->set_stream(CreateFromSession(session)); | 818 request->InitializeStreamFromSession(session); |
782 ++num_push_streams_created_; | 819 ++num_push_streams_created_; |
783 return OK; | 820 return OK; |
784 } | 821 } |
785 // This should happen extremely rarely (if ever), but if somehow a | 822 // This should happen extremely rarely (if ever), but if somehow a |
786 // request comes in with a mismatched privacy mode, consider the | 823 // request comes in with a mismatched privacy mode, consider the |
787 // promise borked. | 824 // promise borked. |
788 promised->Cancel(); | 825 promised->Cancel(); |
789 } | 826 } |
790 | 827 |
791 QuicServerId server_id(host_port_pair, privacy_mode); | 828 QuicServerId server_id(host_port_pair, privacy_mode); |
792 // TODO(rtenneti): crbug.com/498823 - delete active_sessions_.empty() checks. | 829 // TODO(rtenneti): crbug.com/498823 - delete active_sessions_.empty() checks. |
793 if (!active_sessions_.empty()) { | 830 if (!active_sessions_.empty()) { |
794 SessionMap::iterator it = active_sessions_.find(server_id); | 831 SessionMap::iterator it = active_sessions_.find(server_id); |
795 if (it != active_sessions_.end()) { | 832 if (it != active_sessions_.end()) { |
796 QuicChromiumClientSession* session = it->second; | 833 QuicChromiumClientSession* session = it->second; |
797 if (!session->CanPool(url.host(), privacy_mode)) | 834 if (!session->CanPool(url.host(), privacy_mode)) |
798 return ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN; | 835 return ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN; |
799 request->set_stream(CreateFromSession(session)); | 836 request->InitializeStreamFromSession(session); |
800 return OK; | 837 return OK; |
801 } | 838 } |
802 } | 839 } |
803 | 840 |
804 if (HasActiveJob(server_id)) { | 841 if (HasActiveJob(server_id)) { |
805 active_requests_[request] = server_id; | 842 active_requests_[request] = server_id; |
806 job_requests_map_[server_id].insert(request); | 843 job_requests_map_[server_id].insert(request); |
807 return ERR_IO_PENDING; | 844 return ERR_IO_PENDING; |
808 } | 845 } |
809 | 846 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
845 // related changes. | 882 // related changes. |
846 if (active_sessions_.empty()) | 883 if (active_sessions_.empty()) |
847 return ERR_QUIC_PROTOCOL_ERROR; | 884 return ERR_QUIC_PROTOCOL_ERROR; |
848 SessionMap::iterator it = active_sessions_.find(server_id); | 885 SessionMap::iterator it = active_sessions_.find(server_id); |
849 DCHECK(it != active_sessions_.end()); | 886 DCHECK(it != active_sessions_.end()); |
850 if (it == active_sessions_.end()) | 887 if (it == active_sessions_.end()) |
851 return ERR_QUIC_PROTOCOL_ERROR; | 888 return ERR_QUIC_PROTOCOL_ERROR; |
852 QuicChromiumClientSession* session = it->second; | 889 QuicChromiumClientSession* session = it->second; |
853 if (!session->CanPool(url.host(), privacy_mode)) | 890 if (!session->CanPool(url.host(), privacy_mode)) |
854 return ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN; | 891 return ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN; |
855 request->set_stream(CreateFromSession(session)); | 892 request->InitializeStreamFromSession(session); |
856 } | 893 } |
857 return rv; | 894 return rv; |
858 } | 895 } |
859 | 896 |
860 void QuicStreamFactory::CreateAuxilaryJob(const QuicServerId server_id, | 897 void QuicStreamFactory::CreateAuxilaryJob(const QuicServerId server_id, |
861 int cert_verify_flags, | 898 int cert_verify_flags, |
862 bool server_and_origin_have_same_host, | 899 bool server_and_origin_have_same_host, |
863 bool is_post, | 900 bool is_post, |
864 const BoundNetLog& net_log) { | 901 const BoundNetLog& net_log) { |
865 Job* aux_job = new Job( | 902 Job* aux_job = new Job( |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
923 RequestSet::iterator old_request_it = request_it; | 960 RequestSet::iterator old_request_it = request_it; |
924 ++request_it; | 961 ++request_it; |
925 // Remove request from containers so that OnRequestComplete() is not | 962 // Remove request from containers so that OnRequestComplete() is not |
926 // called later again on the same request. | 963 // called later again on the same request. |
927 job_requests_map_[server_id].erase(old_request_it); | 964 job_requests_map_[server_id].erase(old_request_it); |
928 active_requests_.erase(request); | 965 active_requests_.erase(request); |
929 // Notify request of certificate error. | 966 // Notify request of certificate error. |
930 request->OnRequestComplete(ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN); | 967 request->OnRequestComplete(ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN); |
931 continue; | 968 continue; |
932 } | 969 } |
933 request->set_stream(CreateFromSession(session)); | 970 request->InitializeStreamFromSession(session); |
934 ++request_it; | 971 ++request_it; |
935 } | 972 } |
936 } | 973 } |
937 | 974 |
938 while (!job_requests_map_[server_id].empty()) { | 975 while (!job_requests_map_[server_id].empty()) { |
939 RequestSet::iterator it = job_requests_map_[server_id].begin(); | 976 RequestSet::iterator it = job_requests_map_[server_id].begin(); |
940 QuicStreamRequest* request = *it; | 977 QuicStreamRequest* request = *it; |
941 job_requests_map_[server_id].erase(it); | 978 job_requests_map_[server_id].erase(it); |
942 active_requests_.erase(request); | 979 active_requests_.erase(request); |
943 // Even though we're invoking callbacks here, we don't need to worry | 980 // Even though we're invoking callbacks here, we don't need to worry |
(...skipping 728 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1672 // Since the session was active, there's no longer an | 1709 // Since the session was active, there's no longer an |
1673 // HttpStreamFactoryImpl::Job running which can mark it broken, unless the TCP | 1710 // HttpStreamFactoryImpl::Job running which can mark it broken, unless the TCP |
1674 // job also fails. So to avoid not using QUIC when we otherwise could, we mark | 1711 // job also fails. So to avoid not using QUIC when we otherwise could, we mark |
1675 // it as recently broken, which means that 0-RTT will be disabled but we'll | 1712 // it as recently broken, which means that 0-RTT will be disabled but we'll |
1676 // still race. | 1713 // still race. |
1677 http_server_properties_->MarkAlternativeServiceRecentlyBroken( | 1714 http_server_properties_->MarkAlternativeServiceRecentlyBroken( |
1678 alternative_service); | 1715 alternative_service); |
1679 } | 1716 } |
1680 | 1717 |
1681 } // namespace net | 1718 } // namespace net |
OLD | NEW |