1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #ifndef NET_HTTP_ALTERNATIVE_SERVICE_H_ 6*6777b538SAndroid Build Coastguard Worker #define NET_HTTP_ALTERNATIVE_SERVICE_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #include <stdint.h> 9*6777b538SAndroid Build Coastguard Worker 10*6777b538SAndroid Build Coastguard Worker #include <algorithm> 11*6777b538SAndroid Build Coastguard Worker #include <ostream> 12*6777b538SAndroid Build Coastguard Worker #include <string> 13*6777b538SAndroid Build Coastguard Worker 14*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h" 15*6777b538SAndroid Build Coastguard Worker #include "net/base/host_port_pair.h" 16*6777b538SAndroid Build Coastguard Worker #include "net/base/net_export.h" 17*6777b538SAndroid Build Coastguard Worker #include "net/http/alternate_protocol_usage.h" 18*6777b538SAndroid Build Coastguard Worker #include "net/quic/quic_http_utils.h" 19*6777b538SAndroid Build Coastguard Worker #include "net/socket/next_proto.h" 20*6777b538SAndroid Build Coastguard Worker #include "net/third_party/quiche/src/quiche/quic/core/quic_versions.h" 21*6777b538SAndroid Build Coastguard Worker #include "net/third_party/quiche/src/quiche/spdy/core/spdy_protocol.h" 22*6777b538SAndroid Build Coastguard Worker 23*6777b538SAndroid Build Coastguard Worker namespace net { 24*6777b538SAndroid Build Coastguard Worker 25*6777b538SAndroid Build Coastguard Worker // Log a histogram to reflect |usage|. 26*6777b538SAndroid Build Coastguard Worker NET_EXPORT void HistogramAlternateProtocolUsage(AlternateProtocolUsage usage, 27*6777b538SAndroid Build Coastguard Worker bool is_google_host); 28*6777b538SAndroid Build Coastguard Worker 29*6777b538SAndroid Build Coastguard Worker enum BrokenAlternateProtocolLocation { 30*6777b538SAndroid Build Coastguard Worker BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_JOB = 0, 31*6777b538SAndroid Build Coastguard Worker BROKEN_ALTERNATE_PROTOCOL_LOCATION_QUIC_SESSION_POOL = 1, 32*6777b538SAndroid Build Coastguard Worker BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_JOB_ALT = 2, 33*6777b538SAndroid Build Coastguard Worker BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_STREAM_FACTORY_JOB_MAIN = 3, 34*6777b538SAndroid Build Coastguard Worker BROKEN_ALTERNATE_PROTOCOL_LOCATION_QUIC_HTTP_STREAM = 4, 35*6777b538SAndroid Build Coastguard Worker BROKEN_ALTERNATE_PROTOCOL_LOCATION_HTTP_NETWORK_TRANSACTION = 5, 36*6777b538SAndroid Build Coastguard Worker BROKEN_ALTERNATE_PROTOCOL_LOCATION_MAX, 37*6777b538SAndroid Build Coastguard Worker }; 38*6777b538SAndroid Build Coastguard Worker 39*6777b538SAndroid Build Coastguard Worker // Log a histogram to reflect |location|. 40*6777b538SAndroid Build Coastguard Worker NET_EXPORT void HistogramBrokenAlternateProtocolLocation( 41*6777b538SAndroid Build Coastguard Worker BrokenAlternateProtocolLocation location); 42*6777b538SAndroid Build Coastguard Worker 43*6777b538SAndroid Build Coastguard Worker // Returns true if |protocol| is a valid protocol. 44*6777b538SAndroid Build Coastguard Worker NET_EXPORT bool IsAlternateProtocolValid(NextProto protocol); 45*6777b538SAndroid Build Coastguard Worker 46*6777b538SAndroid Build Coastguard Worker // Returns true if |protocol| is enabled, based on |is_http2_enabled| 47*6777b538SAndroid Build Coastguard Worker // and |is_quic_enabled|.. 48*6777b538SAndroid Build Coastguard Worker NET_EXPORT bool IsProtocolEnabled(NextProto protocol, 49*6777b538SAndroid Build Coastguard Worker bool is_http2_enabled, 50*6777b538SAndroid Build Coastguard Worker bool is_quic_enabled); 51*6777b538SAndroid Build Coastguard Worker 52*6777b538SAndroid Build Coastguard Worker // (protocol, host, port) triple as defined in 53*6777b538SAndroid Build Coastguard Worker // https://tools.ietf.org/id/draft-ietf-httpbis-alt-svc-06.html 54*6777b538SAndroid Build Coastguard Worker // 55*6777b538SAndroid Build Coastguard Worker // TODO(mmenke): Seems like most of this stuff should be de-inlined. 56*6777b538SAndroid Build Coastguard Worker struct NET_EXPORT AlternativeService { AlternativeServiceAlternativeService57*6777b538SAndroid Build Coastguard Worker AlternativeService() : protocol(kProtoUnknown), host(), port(0) {} 58*6777b538SAndroid Build Coastguard Worker AlternativeServiceAlternativeService59*6777b538SAndroid Build Coastguard Worker AlternativeService(NextProto protocol, const std::string& host, uint16_t port) 60*6777b538SAndroid Build Coastguard Worker : protocol(protocol), host(host), port(port) {} 61*6777b538SAndroid Build Coastguard Worker AlternativeServiceAlternativeService62*6777b538SAndroid Build Coastguard Worker AlternativeService(NextProto protocol, const HostPortPair& host_port_pair) 63*6777b538SAndroid Build Coastguard Worker : protocol(protocol), 64*6777b538SAndroid Build Coastguard Worker host(host_port_pair.host()), 65*6777b538SAndroid Build Coastguard Worker port(host_port_pair.port()) {} 66*6777b538SAndroid Build Coastguard Worker 67*6777b538SAndroid Build Coastguard Worker AlternativeService(const AlternativeService& alternative_service) = default; 68*6777b538SAndroid Build Coastguard Worker AlternativeService& operator=(const AlternativeService& alternative_service) = 69*6777b538SAndroid Build Coastguard Worker default; 70*6777b538SAndroid Build Coastguard Worker host_port_pairAlternativeService71*6777b538SAndroid Build Coastguard Worker HostPortPair host_port_pair() const { return HostPortPair(host, port); } 72*6777b538SAndroid Build Coastguard Worker 73*6777b538SAndroid Build Coastguard Worker bool operator==(const AlternativeService& other) const { 74*6777b538SAndroid Build Coastguard Worker return protocol == other.protocol && host == other.host && 75*6777b538SAndroid Build Coastguard Worker port == other.port; 76*6777b538SAndroid Build Coastguard Worker } 77*6777b538SAndroid Build Coastguard Worker 78*6777b538SAndroid Build Coastguard Worker bool operator!=(const AlternativeService& other) const { 79*6777b538SAndroid Build Coastguard Worker return !this->operator==(other); 80*6777b538SAndroid Build Coastguard Worker } 81*6777b538SAndroid Build Coastguard Worker 82*6777b538SAndroid Build Coastguard Worker bool operator<(const AlternativeService& other) const { 83*6777b538SAndroid Build Coastguard Worker return std::tie(protocol, host, port) < 84*6777b538SAndroid Build Coastguard Worker std::tie(other.protocol, other.host, other.port); 85*6777b538SAndroid Build Coastguard Worker } 86*6777b538SAndroid Build Coastguard Worker 87*6777b538SAndroid Build Coastguard Worker // Output format: "protocol host:port", e.g. "h2 www.google.com:1234". 88*6777b538SAndroid Build Coastguard Worker std::string ToString() const; 89*6777b538SAndroid Build Coastguard Worker 90*6777b538SAndroid Build Coastguard Worker NextProto protocol; 91*6777b538SAndroid Build Coastguard Worker std::string host; 92*6777b538SAndroid Build Coastguard Worker uint16_t port; 93*6777b538SAndroid Build Coastguard Worker }; 94*6777b538SAndroid Build Coastguard Worker 95*6777b538SAndroid Build Coastguard Worker NET_EXPORT_PRIVATE std::ostream& operator<<( 96*6777b538SAndroid Build Coastguard Worker std::ostream& os, 97*6777b538SAndroid Build Coastguard Worker const AlternativeService& alternative_service); 98*6777b538SAndroid Build Coastguard Worker 99*6777b538SAndroid Build Coastguard Worker class NET_EXPORT_PRIVATE AlternativeServiceInfo { 100*6777b538SAndroid Build Coastguard Worker public: 101*6777b538SAndroid Build Coastguard Worker static AlternativeServiceInfo CreateHttp2AlternativeServiceInfo( 102*6777b538SAndroid Build Coastguard Worker const AlternativeService& alternative_service, 103*6777b538SAndroid Build Coastguard Worker base::Time expiration); 104*6777b538SAndroid Build Coastguard Worker 105*6777b538SAndroid Build Coastguard Worker static AlternativeServiceInfo CreateQuicAlternativeServiceInfo( 106*6777b538SAndroid Build Coastguard Worker const AlternativeService& alternative_service, 107*6777b538SAndroid Build Coastguard Worker base::Time expiration, 108*6777b538SAndroid Build Coastguard Worker const quic::ParsedQuicVersionVector& advertised_versions); 109*6777b538SAndroid Build Coastguard Worker 110*6777b538SAndroid Build Coastguard Worker AlternativeServiceInfo(); 111*6777b538SAndroid Build Coastguard Worker ~AlternativeServiceInfo(); 112*6777b538SAndroid Build Coastguard Worker 113*6777b538SAndroid Build Coastguard Worker AlternativeServiceInfo( 114*6777b538SAndroid Build Coastguard Worker const AlternativeServiceInfo& alternative_service_info); 115*6777b538SAndroid Build Coastguard Worker 116*6777b538SAndroid Build Coastguard Worker AlternativeServiceInfo& operator=( 117*6777b538SAndroid Build Coastguard Worker const AlternativeServiceInfo& alternative_service_info); 118*6777b538SAndroid Build Coastguard Worker 119*6777b538SAndroid Build Coastguard Worker bool operator==(const AlternativeServiceInfo& other) const { 120*6777b538SAndroid Build Coastguard Worker return alternative_service_ == other.alternative_service() && 121*6777b538SAndroid Build Coastguard Worker expiration_ == other.expiration() && 122*6777b538SAndroid Build Coastguard Worker advertised_versions_ == other.advertised_versions(); 123*6777b538SAndroid Build Coastguard Worker } 124*6777b538SAndroid Build Coastguard Worker 125*6777b538SAndroid Build Coastguard Worker bool operator!=(const AlternativeServiceInfo& other) const { 126*6777b538SAndroid Build Coastguard Worker return !this->operator==(other); 127*6777b538SAndroid Build Coastguard Worker } 128*6777b538SAndroid Build Coastguard Worker 129*6777b538SAndroid Build Coastguard Worker std::string ToString() const; 130*6777b538SAndroid Build Coastguard Worker set_alternative_service(const AlternativeService & alternative_service)131*6777b538SAndroid Build Coastguard Worker void set_alternative_service(const AlternativeService& alternative_service) { 132*6777b538SAndroid Build Coastguard Worker alternative_service_ = alternative_service; 133*6777b538SAndroid Build Coastguard Worker } 134*6777b538SAndroid Build Coastguard Worker set_protocol(const NextProto & protocol)135*6777b538SAndroid Build Coastguard Worker void set_protocol(const NextProto& protocol) { 136*6777b538SAndroid Build Coastguard Worker alternative_service_.protocol = protocol; 137*6777b538SAndroid Build Coastguard Worker } 138*6777b538SAndroid Build Coastguard Worker set_host(const std::string & host)139*6777b538SAndroid Build Coastguard Worker void set_host(const std::string& host) { alternative_service_.host = host; } 140*6777b538SAndroid Build Coastguard Worker set_port(uint16_t port)141*6777b538SAndroid Build Coastguard Worker void set_port(uint16_t port) { alternative_service_.port = port; } 142*6777b538SAndroid Build Coastguard Worker set_expiration(const base::Time & expiration)143*6777b538SAndroid Build Coastguard Worker void set_expiration(const base::Time& expiration) { 144*6777b538SAndroid Build Coastguard Worker expiration_ = expiration; 145*6777b538SAndroid Build Coastguard Worker } 146*6777b538SAndroid Build Coastguard Worker set_advertised_versions(const quic::ParsedQuicVersionVector & advertised_versions)147*6777b538SAndroid Build Coastguard Worker void set_advertised_versions( 148*6777b538SAndroid Build Coastguard Worker const quic::ParsedQuicVersionVector& advertised_versions) { 149*6777b538SAndroid Build Coastguard Worker if (alternative_service_.protocol != kProtoQUIC) { 150*6777b538SAndroid Build Coastguard Worker return; 151*6777b538SAndroid Build Coastguard Worker } 152*6777b538SAndroid Build Coastguard Worker 153*6777b538SAndroid Build Coastguard Worker advertised_versions_ = advertised_versions; 154*6777b538SAndroid Build Coastguard Worker std::sort(advertised_versions_.begin(), advertised_versions_.end(), 155*6777b538SAndroid Build Coastguard Worker TransportVersionLessThan); 156*6777b538SAndroid Build Coastguard Worker } 157*6777b538SAndroid Build Coastguard Worker alternative_service()158*6777b538SAndroid Build Coastguard Worker const AlternativeService& alternative_service() const { 159*6777b538SAndroid Build Coastguard Worker return alternative_service_; 160*6777b538SAndroid Build Coastguard Worker } 161*6777b538SAndroid Build Coastguard Worker protocol()162*6777b538SAndroid Build Coastguard Worker NextProto protocol() const { return alternative_service_.protocol; } 163*6777b538SAndroid Build Coastguard Worker host_port_pair()164*6777b538SAndroid Build Coastguard Worker HostPortPair host_port_pair() const { 165*6777b538SAndroid Build Coastguard Worker return alternative_service_.host_port_pair(); 166*6777b538SAndroid Build Coastguard Worker } 167*6777b538SAndroid Build Coastguard Worker expiration()168*6777b538SAndroid Build Coastguard Worker base::Time expiration() const { return expiration_; } 169*6777b538SAndroid Build Coastguard Worker advertised_versions()170*6777b538SAndroid Build Coastguard Worker const quic::ParsedQuicVersionVector& advertised_versions() const { 171*6777b538SAndroid Build Coastguard Worker return advertised_versions_; 172*6777b538SAndroid Build Coastguard Worker } 173*6777b538SAndroid Build Coastguard Worker 174*6777b538SAndroid Build Coastguard Worker private: 175*6777b538SAndroid Build Coastguard Worker AlternativeServiceInfo( 176*6777b538SAndroid Build Coastguard Worker const AlternativeService& alternative_service, 177*6777b538SAndroid Build Coastguard Worker base::Time expiration, 178*6777b538SAndroid Build Coastguard Worker const quic::ParsedQuicVersionVector& advertised_versions); 179*6777b538SAndroid Build Coastguard Worker 180*6777b538SAndroid Build Coastguard Worker static bool TransportVersionLessThan(const quic::ParsedQuicVersion& lhs, 181*6777b538SAndroid Build Coastguard Worker const quic::ParsedQuicVersion& rhs); 182*6777b538SAndroid Build Coastguard Worker 183*6777b538SAndroid Build Coastguard Worker AlternativeService alternative_service_; 184*6777b538SAndroid Build Coastguard Worker base::Time expiration_; 185*6777b538SAndroid Build Coastguard Worker 186*6777b538SAndroid Build Coastguard Worker // Lists all the QUIC versions that are advertised by the server and supported 187*6777b538SAndroid Build Coastguard Worker // by Chrome. If empty, defaults to versions used by the current instance of 188*6777b538SAndroid Build Coastguard Worker // the netstack. This list is sorted according to the server's preference. 189*6777b538SAndroid Build Coastguard Worker quic::ParsedQuicVersionVector advertised_versions_; 190*6777b538SAndroid Build Coastguard Worker }; 191*6777b538SAndroid Build Coastguard Worker 192*6777b538SAndroid Build Coastguard Worker using AlternativeServiceInfoVector = std::vector<AlternativeServiceInfo>; 193*6777b538SAndroid Build Coastguard Worker 194*6777b538SAndroid Build Coastguard Worker NET_EXPORT_PRIVATE AlternativeServiceInfoVector ProcessAlternativeServices( 195*6777b538SAndroid Build Coastguard Worker const spdy::SpdyAltSvcWireFormat::AlternativeServiceVector& 196*6777b538SAndroid Build Coastguard Worker alternative_service_vector, 197*6777b538SAndroid Build Coastguard Worker bool is_http2_enabled, 198*6777b538SAndroid Build Coastguard Worker bool is_quic_enabled, 199*6777b538SAndroid Build Coastguard Worker const quic::ParsedQuicVersionVector& supported_quic_versions); 200*6777b538SAndroid Build Coastguard Worker 201*6777b538SAndroid Build Coastguard Worker } // namespace net 202*6777b538SAndroid Build Coastguard Worker 203*6777b538SAndroid Build Coastguard Worker #endif // NET_HTTP_ALTERNATIVE_SERVICE_H_ 204