Add a new ExtractQuicVersionFromAltSvcEntry method to SpdyUtils for parsing QUIC versions out of Alt-Svc entries. Will be used in both Chrome and Envoy. PiperOrigin-RevId: 427540864
diff --git a/quic/core/http/spdy_utils.cc b/quic/core/http/spdy_utils.cc index 74c9c53..5b74407 100644 --- a/quic/core/http/spdy_utils.cc +++ b/quic/core/http/spdy_utils.cc
@@ -13,6 +13,7 @@ #include "absl/strings/str_split.h" #include "absl/strings/string_view.h" #include "absl/types/optional.h" +#include "quic/core/quic_versions.h" #include "quic/platform/api/quic_flag_utils.h" #include "quic/platform/api/quic_flags.h" #include "quic/platform/api/quic_logging.h" @@ -194,4 +195,23 @@ (*headers)["datagram-flow-id"] = absl::StrCat(flow_id); } +// static +ParsedQuicVersion SpdyUtils::ExtractQuicVersionFromAltSvcEntry( + const spdy::SpdyAltSvcWireFormat::AlternativeService& + alternative_service_entry, + const ParsedQuicVersionVector& supported_versions) { + for (const ParsedQuicVersion& version : supported_versions) { + if (version.AlpnDeferToRFCv1()) { + // Versions with share an ALPN with v1 are currently unable to be + // advertised with Alt-Svc. + continue; + } + if (AlpnForVersion(version) == alternative_service_entry.protocol_id) { + return version; + } + } + + return ParsedQuicVersion::Unsupported(); +} + } // namespace quic
diff --git a/quic/core/http/spdy_utils.h b/quic/core/http/spdy_utils.h index 01fae4f..85099ab 100644 --- a/quic/core/http/spdy_utils.h +++ b/quic/core/http/spdy_utils.h
@@ -14,6 +14,7 @@ #include "quic/core/http/quic_header_list.h" #include "quic/core/quic_packets.h" #include "quic/platform/api/quic_export.h" +#include "spdy/core/spdy_alt_svc_wire_format.h" #include "spdy/core/spdy_header_block.h" namespace quic { @@ -61,6 +62,14 @@ // Adds the "datagram-flow-id" header. static void AddDatagramFlowIdHeader(spdy::SpdyHeaderBlock* headers, QuicDatagramStreamId flow_id); + + // Returns the advertised QUIC version from the specified alternative service + // advertisement, or ParsedQuicVersion::Unsupported() if no supported version + // is advertised. + static ParsedQuicVersion ExtractQuicVersionFromAltSvcEntry( + const spdy::SpdyAltSvcWireFormat::AlternativeService& + alternative_service_entry, + const ParsedQuicVersionVector& supported_versions); }; } // namespace quic
diff --git a/quic/core/http/spdy_utils_test.cc b/quic/core/http/spdy_utils_test.cc index 918739d..85c5cec 100644 --- a/quic/core/http/spdy_utils_test.cc +++ b/quic/core/http/spdy_utils_test.cc
@@ -2,12 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "quic/core/http/spdy_utils.h" + #include <memory> #include <string> #include "absl/base/macros.h" #include "absl/strings/string_view.h" -#include "quic/core/http/spdy_utils.h" +#include "quic/core/quic_versions.h" #include "quic/platform/api/quic_test.h" using spdy::SpdyHeaderBlock; @@ -408,5 +410,33 @@ ValidateDatagramFlowId("44; ecn-ect0, 42, 48; ecn-ce, 46; ecn-ect1", 42); } +using ExtractQuicVersionFromAltSvcEntry = QuicTest; + +TEST_F(ExtractQuicVersionFromAltSvcEntry, SupportedVersion) { + ParsedQuicVersionVector supported_versions = AllSupportedVersions(); + spdy::SpdyAltSvcWireFormat::AlternativeService entry; + for (const ParsedQuicVersion& version : supported_versions) { + entry.protocol_id = AlpnForVersion(version); + ParsedQuicVersion expected_version = version; + // Versions with share an ALPN with v1 are currently unable to be + // advertised with Alt-Svc. + if (entry.protocol_id == AlpnForVersion(ParsedQuicVersion::RFCv1()) && + version != ParsedQuicVersion::RFCv1()) { + expected_version = ParsedQuicVersion::RFCv1(); + } + EXPECT_EQ(expected_version, SpdyUtils::ExtractQuicVersionFromAltSvcEntry( + entry, supported_versions)) + << "version: " << version; + } +} + +TEST_F(ExtractQuicVersionFromAltSvcEntry, UnsupportedVersion) { + spdy::SpdyAltSvcWireFormat::AlternativeService entry; + entry.protocol_id = "quic"; + EXPECT_EQ(ParsedQuicVersion::Unsupported(), + SpdyUtils::ExtractQuicVersionFromAltSvcEntry( + entry, AllSupportedVersions())); +} + } // namespace test } // namespace quic