Add a new CurrentSupportedVersionsForClients() function to QUIC which should be used by clients to determine the QUIC versions they should speak. This list excludes obsolete versions, specifically gQUIC and draft-29. Also adds IsObsoleteSupportedVersion() and ObsoleteSupportedVersions(). Follow-up CLs will convert clients to use this new function. PiperOrigin-RevId: 565466007
diff --git a/quiche/quic/core/quic_versions.cc b/quiche/quic/core/quic_versions.cc index c0fd4fc..a765a33 100644 --- a/quiche/quic/core/quic_versions.cc +++ b/quiche/quic/core/quic_versions.cc
@@ -291,6 +291,36 @@ return versions; } +ParsedQuicVersionVector ObsoleteSupportedVersions() { + return ParsedQuicVersionVector{quic::ParsedQuicVersion::Q046(), + quic::ParsedQuicVersion::Q050(), + quic::ParsedQuicVersion::Draft29()}; +} + +bool IsObsoleteSupportedVersion(ParsedQuicVersion version) { + static const ParsedQuicVersionVector obsolete_versions = + ObsoleteSupportedVersions(); + for (const ParsedQuicVersion& obsolete_version : obsolete_versions) { + if (version == obsolete_version) { + return true; + } + } + return false; +} + +ParsedQuicVersionVector CurrentSupportedVersionsForClients() { + ParsedQuicVersionVector versions; + for (const ParsedQuicVersion& version : CurrentSupportedVersionsWithTls()) { + QUICHE_DCHECK_EQ(version.handshake_protocol, PROTOCOL_TLS1_3); + if (version.transport_version >= QUIC_VERSION_IETF_RFC_V1) { + versions.push_back(version); + } + } + QUIC_BUG_IF(quic_bug_10589_8, versions.empty()) + << "No supported client versions found."; + return versions; +} + ParsedQuicVersionVector CurrentSupportedHttp3Versions() { ParsedQuicVersionVector versions; for (const ParsedQuicVersion& version : CurrentSupportedVersions()) {
diff --git a/quiche/quic/core/quic_versions.h b/quiche/quic/core/quic_versions.h index 8958e33..da66a17 100644 --- a/quiche/quic/core/quic_versions.h +++ b/quiche/quic/core/quic_versions.h
@@ -418,6 +418,18 @@ // flags excluded. QUICHE_EXPORT ParsedQuicVersionVector CurrentSupportedVersions(); +// Obsolete QUIC supported versions are versions that are supported in +// QUICHE but which should not be used by by modern clients. +QUICHE_EXPORT ParsedQuicVersionVector ObsoleteSupportedVersions(); + +// Returns true if `version` is in `ObsoleteSupportedVersions`. +QUICHE_EXPORT bool IsObsoleteSupportedVersion(ParsedQuicVersion version); + +// Returns a vector of supported QUIC versions which should be used by clients. +// Server need to support old clients, but new client should only be using +// QUIC versions in this list. +QUICHE_EXPORT ParsedQuicVersionVector CurrentSupportedVersionsForClients(); + // Returns a vector of QUIC versions from |versions| which exclude any versions // which are disabled by flags. QUICHE_EXPORT ParsedQuicVersionVector
diff --git a/quiche/quic/core/quic_versions_test.cc b/quiche/quic/core/quic_versions_test.cc index bf0078c..4931c14 100644 --- a/quiche/quic/core/quic_versions_test.cc +++ b/quiche/quic/core/quic_versions_test.cc
@@ -502,6 +502,40 @@ } } +TEST(QuicVersionsTest, ObsoleteSupportedVersions) { + ParsedQuicVersionVector obsolete_versions = ObsoleteSupportedVersions(); + EXPECT_EQ(quic::ParsedQuicVersion::Q046(), obsolete_versions[0]); + EXPECT_EQ(quic::ParsedQuicVersion::Q050(), obsolete_versions[1]); + EXPECT_EQ(quic::ParsedQuicVersion::Draft29(), obsolete_versions[2]); +} + +TEST(QuicVersionsTest, IsObsoleteSupportedVersion) { + for (const ParsedQuicVersion& version : AllSupportedVersions()) { + bool is_obsolete = version.handshake_protocol != PROTOCOL_TLS1_3 || + version.transport_version < QUIC_VERSION_IETF_RFC_V1; + EXPECT_EQ(is_obsolete, IsObsoleteSupportedVersion(version)); + } +} + +TEST(QuicVersionsTest, CurrentSupportedVersionsForClients) { + ParsedQuicVersionVector supported_versions = CurrentSupportedVersions(); + ParsedQuicVersionVector client_versions = + CurrentSupportedVersionsForClients(); + for (auto& version : supported_versions) { + const bool is_obsolete = IsObsoleteSupportedVersion(version); + const bool is_supported = + absl::c_find(client_versions, version) != client_versions.end(); + // Every supported version which is not obsolete should be a supported + // client version. + EXPECT_EQ(!is_obsolete, is_supported); + } + // Every client version should be a supported version, of course. + for (auto& version : client_versions) { + EXPECT_TRUE(absl::c_find(supported_versions, version) != + supported_versions.end()); + } +} + } // namespace } // namespace test } // namespace quic