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 <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 |