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