Introduce QUIC_VERSION_IETF_DRAFT_25

To prepare for the arrival of draft-26 while still supporting draft-25, this CL prepares a new version that will stay on draft-25, while T099 while keep tracking the latest draft.

gfe-relnote: introduce QUIC version draft-25, protected by new disabled flag gfe2_reloadable_flag_quic_enable_version_draft_25
PiperOrigin-RevId: 296099999
Change-Id: I1c111929ebe0c09ba098ff3f6030fb1799df3344
diff --git a/quic/core/crypto/crypto_utils.cc b/quic/core/crypto/crypto_utils.cc
index b8e4fb4..0215d7f 100644
--- a/quic/core/crypto/crypto_utils.cc
+++ b/quic/core/crypto/crypto_utils.cc
@@ -115,7 +115,7 @@
 
 namespace {
 
-static_assert(kQuicIetfDraftVersion == 25, "Salts do not match draft version");
+static_assert(kQuicIetfDraftVersion == 26, "Salts do not match draft version");
 // Salt from https://tools.ietf.org/html/draft-ietf-quic-tls-25#section-5.2
 const uint8_t kDraft25InitialSalt[] = {0xc3, 0xee, 0xf7, 0x12, 0xc7, 0x2e, 0xbb,
                                        0x5a, 0x11, 0xa7, 0xd2, 0x43, 0x2b, 0xb4,
@@ -135,7 +135,7 @@
 
 const uint8_t* InitialSaltForVersion(const ParsedQuicVersion& version,
                                      size_t* out_len) {
-  static_assert(SupportedTransportVersions().size() == 6u,
+  static_assert(SupportedVersions().size() == 8u,
                 "Supported versions out of sync with initial encryption salts");
   switch (version.handshake_protocol) {
     case PROTOCOL_QUIC_CRYPTO:
@@ -159,6 +159,9 @@
         case QUIC_VERSION_50:
           *out_len = QUICHE_ARRAYSIZE(kT050Salt);
           return kT050Salt;
+        case QUIC_VERSION_IETF_DRAFT_25:
+          *out_len = QUICHE_ARRAYSIZE(kDraft25InitialSalt);
+          return kDraft25InitialSalt;
         case QUIC_VERSION_99:
           // ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_99) uses the IETF
           // salt.
@@ -180,7 +183,7 @@
 
 // Retry Integrity Protection Keys and Nonces.
 // https://tools.ietf.org/html/draft-ietf-quic-tls-25#section-5.8
-static_assert(kQuicIetfDraftVersion == 25, "Keys do not match draft version");
+static_assert(kQuicIetfDraftVersion == 26, "Keys do not match draft version");
 const uint8_t kDraft25RetryIntegrityKey[] = {0x4d, 0x32, 0xec, 0xdb, 0x2a, 0x21,
                                              0x33, 0xc8, 0x41, 0xe4, 0x04, 0x3d,
                                              0xf2, 0x7d, 0x44, 0x30};
@@ -213,7 +216,9 @@
         QUICHE_ARRAYSIZE(kT050RetryIntegrityNonce));
     return true;
   }
-  if (version == ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_99)) {
+  if (version ==
+          ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_25) ||
+      version == ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_99)) {
     *key = quiche::QuicheStringPiece(
         reinterpret_cast<const char*>(kDraft25RetryIntegrityKey),
         QUICHE_ARRAYSIZE(kDraft25RetryIntegrityKey));
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index a7eac86..28524c8 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -9888,7 +9888,8 @@
   if (!version().HasRetryIntegrityTag()) {
     return;
   }
-  if (version() != ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_99)) {
+  if (version() !=
+      ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_25)) {
     // TODO(dschinazi) generate retry packets for all versions once we have
     // server-side support for generating these programmatically.
     return;
diff --git a/quic/core/quic_dispatcher_test.cc b/quic/core/quic_dispatcher_test.cc
index 6510296..4ce9fa2 100644
--- a/quic/core/quic_dispatcher_test.cc
+++ b/quic/core/quic_dispatcher_test.cc
@@ -949,7 +949,7 @@
 
 TEST_P(QuicDispatcherTestOneVersion,
        RejectDeprecatedVersionsWithVersionNegotiation) {
-  static_assert(SupportedTransportVersions().size() == 6u,
+  static_assert(quic::SupportedVersions().size() == 8u,
                 "Please add deprecated versions to this test");
   QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
   CreateTimeWaitListManager();
diff --git a/quic/core/quic_framer.cc b/quic/core/quic_framer.cc
index 00bd6f4..c6231e8 100644
--- a/quic/core/quic_framer.cc
+++ b/quic/core/quic_framer.cc
@@ -320,8 +320,8 @@
 }
 
 bool IsValidFullPacketNumber(uint64_t full_packet_number,
-                             QuicTransportVersion version) {
-  return full_packet_number > 0 || version == QUIC_VERSION_99;
+                             ParsedQuicVersion version) {
+  return full_packet_number > 0 || version.HasIetfQuicFrames();
 }
 
 bool AppendIetfConnectionIds(bool version_flag,
@@ -1699,7 +1699,7 @@
     }
 
     if (hp_removal_failed ||
-        !IsValidFullPacketNumber(full_packet_number, transport_version())) {
+        !IsValidFullPacketNumber(full_packet_number, version())) {
       if (IsIetfStatelessResetPacket(*header)) {
         // This is a stateless reset packet.
         QuicIetfStatelessResetPacket packet(
@@ -2396,7 +2396,7 @@
     return RaiseError(QUIC_INVALID_PACKET_HEADER);
   }
 
-  if (!IsValidFullPacketNumber(full_packet_number, transport_version())) {
+  if (!IsValidFullPacketNumber(full_packet_number, version())) {
     set_detailed_error("packet numbers cannot be 0.");
     return RaiseError(QUIC_INVALID_PACKET_HEADER);
   }
diff --git a/quic/core/quic_framer_test.cc b/quic/core/quic_framer_test.cc
index 88845af..beac097 100644
--- a/quic/core/quic_framer_test.cc
+++ b/quic/core/quic_framer_test.cc
@@ -6543,7 +6543,7 @@
 
   unsigned char* packet = packet48;
   size_t packet_size = QUICHE_ARRAYSIZE(packet48);
-  if (framer_.transport_version() == QUIC_VERSION_99) {
+  if (framer_.version().HasIetfQuicFrames()) {
     packet = packet99;
     packet_size = QUICHE_ARRAYSIZE(packet99);
   }
@@ -6619,7 +6619,7 @@
   // clang-format on
 
   PacketFragments& fragments =
-      framer_.transport_version() == QUIC_VERSION_99 ? packet99 : packet48;
+      framer_.version().HasIetfQuicFrames() ? packet99 : packet48;
   std::unique_ptr<QuicEncryptedPacket> encrypted(
       AssemblePacketFromFragments(fragments));
   EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
@@ -12246,7 +12246,7 @@
 
   unsigned char* p = packet;
   size_t p_length = QUICHE_ARRAYSIZE(packet);
-  if (framer_.transport_version() == QUIC_VERSION_99) {
+  if (framer_.version().HasIetfQuicFrames()) {
     p = packet99;
     p_length = QUICHE_ARRAYSIZE(packet99);
   }
@@ -12624,7 +12624,7 @@
 
   unsigned char* p = packet;
   size_t p_length = QUICHE_ARRAYSIZE(packet);
-  if (framer_.transport_version() == QUIC_VERSION_99) {
+  if (framer_.version().HasIetfQuicFrames()) {
     p = packet99;
     p_length = QUICHE_ARRAYSIZE(packet99);
   }
@@ -12791,7 +12791,7 @@
 
   unsigned char* p = packet;
   size_t p_length = QUICHE_ARRAYSIZE(packet);
-  if (framer_.transport_version() == QUIC_VERSION_99) {
+  if (framer_.version().HasIetfQuicFrames()) {
     p = packet99;
     p_length = QUICHE_ARRAYSIZE(packet99);
   }
@@ -12897,7 +12897,7 @@
 
   unsigned char* p = packet;
   size_t p_length = QUICHE_ARRAYSIZE(packet);
-  if (framer_.transport_version() == QUIC_VERSION_99) {
+  if (framer_.version().HasIetfQuicFrames()) {
     p = packet99;
     p_length = QUICHE_ARRAYSIZE(packet99);
   }
diff --git a/quic/core/quic_version_manager.cc b/quic/core/quic_version_manager.cc
index 408149e..b6a3c53 100644
--- a/quic/core/quic_version_manager.cc
+++ b/quic/core/quic_version_manager.cc
@@ -16,6 +16,8 @@
 QuicVersionManager::QuicVersionManager(
     ParsedQuicVersionVector supported_versions)
     : enable_version_t099_(GetQuicReloadableFlag(quic_enable_version_t099)),
+      enable_version_draft_25_(
+          GetQuicReloadableFlag(quic_enable_version_draft_25)),
       disable_version_q050_(GetQuicReloadableFlag(quic_disable_version_q050)),
       enable_version_t050_(GetQuicReloadableFlag(quic_enable_version_t050)),
       disable_version_q049_(GetQuicReloadableFlag(quic_disable_version_q049)),
@@ -23,7 +25,7 @@
       disable_version_q046_(GetQuicReloadableFlag(quic_disable_version_q046)),
       disable_version_q043_(GetQuicReloadableFlag(quic_disable_version_q043)),
       allowed_supported_versions_(std::move(supported_versions)) {
-  static_assert(SupportedTransportVersions().size() == 6u,
+  static_assert(SupportedVersions().size() == 8u,
                 "Supported versions out of sync");
   RefilterSupportedVersions();
 }
@@ -42,9 +44,11 @@
 }
 
 void QuicVersionManager::MaybeRefilterSupportedVersions() {
-  static_assert(SupportedTransportVersions().size() == 6u,
+  static_assert(SupportedVersions().size() == 8u,
                 "Supported versions out of sync");
   if (enable_version_t099_ != GetQuicReloadableFlag(quic_enable_version_t099) ||
+      enable_version_draft_25_ !=
+          GetQuicReloadableFlag(quic_enable_version_draft_25) ||
       disable_version_q050_ !=
           GetQuicReloadableFlag(quic_disable_version_q050) ||
       enable_version_t050_ != GetQuicReloadableFlag(quic_enable_version_t050) ||
@@ -57,6 +61,8 @@
       disable_version_q043_ !=
           GetQuicReloadableFlag(quic_disable_version_q043)) {
     enable_version_t099_ = GetQuicReloadableFlag(quic_enable_version_t099);
+    enable_version_draft_25_ =
+        GetQuicReloadableFlag(quic_enable_version_draft_25);
     disable_version_q050_ = GetQuicReloadableFlag(quic_disable_version_q050);
     enable_version_t050_ = GetQuicReloadableFlag(quic_enable_version_t050);
     disable_version_q049_ = GetQuicReloadableFlag(quic_disable_version_q049);
diff --git a/quic/core/quic_version_manager.h b/quic/core/quic_version_manager.h
index 6dd363d..19b4928 100644
--- a/quic/core/quic_version_manager.h
+++ b/quic/core/quic_version_manager.h
@@ -43,6 +43,8 @@
   // Cached value of reloadable flags.
   // quic_enable_version_t099 flag
   bool enable_version_t099_;
+  // quic_enable_version_draft_25 flag
+  bool enable_version_draft_25_;
   // quic_disable_version_q050 flag
   bool disable_version_q050_;
   // quic_enable_version_t050 flag
diff --git a/quic/core/quic_version_manager_test.cc b/quic/core/quic_version_manager_test.cc
index 90179ba..dd3c064 100644
--- a/quic/core/quic_version_manager_test.cc
+++ b/quic/core/quic_version_manager_test.cc
@@ -16,9 +16,10 @@
 class QuicVersionManagerTest : public QuicTest {};
 
 TEST_F(QuicVersionManagerTest, QuicVersionManager) {
-  static_assert(SupportedVersions().size() == 7u,
+  static_assert(SupportedVersions().size() == 8u,
                 "Supported versions out of sync");
   SetQuicReloadableFlag(quic_enable_version_t099, false);
+  SetQuicReloadableFlag(quic_enable_version_draft_25, false);
   SetQuicReloadableFlag(quic_enable_version_t050, false);
   SetQuicReloadableFlag(quic_disable_version_q050, false);
   SetQuicReloadableFlag(quic_disable_version_q049, false);
@@ -51,6 +52,13 @@
   EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
             manager.GetSupportedVersions());
 
+  SetQuicReloadableFlag(quic_enable_version_draft_25, true);
+  expected_parsed_versions.push_back(
+      ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_25));
+  EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
+  EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
+            manager.GetSupportedVersions());
+
   SetQuicReloadableFlag(quic_enable_version_t050, true);
   expected_parsed_versions.push_back(
       ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_50));
diff --git a/quic/core/quic_versions.cc b/quic/core/quic_versions.cc
index 1599a31..cbfdcaa 100644
--- a/quic/core/quic_versions.cc
+++ b/quic/core/quic_versions.cc
@@ -62,7 +62,7 @@
 
 bool ParsedQuicVersion::AllowsLowFlowControlLimits() const {
   DCHECK(IsKnown());
-  return transport_version == QUIC_VERSION_99 &&
+  return transport_version >= QUIC_VERSION_IETF_DRAFT_25 &&
          handshake_protocol == PROTOCOL_TLS1_3;
 }
 
@@ -103,7 +103,7 @@
 
 bool ParsedQuicVersion::SupportsAntiAmplificationLimit() const {
   DCHECK(IsKnown());
-  return transport_version == QUIC_VERSION_99 &&
+  return transport_version >= QUIC_VERSION_IETF_DRAFT_25 &&
          handshake_protocol == PROTOCOL_TLS1_3;
 }
 
@@ -178,7 +178,7 @@
                << parsed_version.handshake_protocol;
       return 0;
   }
-  static_assert(SupportedTransportVersions().size() == 6u,
+  static_assert(SupportedVersions().size() == 8u,
                 "Supported versions out of sync");
   switch (parsed_version.transport_version) {
     case QUIC_VERSION_43:
@@ -191,6 +191,12 @@
       return MakeVersionLabel(proto, '0', '4', '9');
     case QUIC_VERSION_50:
       return MakeVersionLabel(proto, '0', '5', '0');
+    case QUIC_VERSION_IETF_DRAFT_25:
+      if (parsed_version.handshake_protocol == PROTOCOL_TLS1_3) {
+        return MakeVersionLabel(0xff, 0x00, 0x00, 25);
+      }
+      QUIC_BUG << "QUIC_VERSION_IETF_DRAFT_25 requires TLS";
+      return 0;
     case QUIC_VERSION_99:
       if (parsed_version.handshake_protocol == PROTOCOL_TLS1_3) {
         return MakeVersionLabel(0xff, 0x00, 0x00, kQuicIetfDraftVersion);
@@ -281,8 +287,13 @@
   filtered_versions.reserve(versions.size());
   for (ParsedQuicVersion version : versions) {
     if (version.transport_version == QUIC_VERSION_99) {
-      if (version.handshake_protocol == PROTOCOL_TLS1_3 &&
-          GetQuicReloadableFlag(quic_enable_version_t099)) {
+      QUIC_BUG_IF(version.handshake_protocol != PROTOCOL_TLS1_3);
+      if (GetQuicReloadableFlag(quic_enable_version_t099)) {
+        filtered_versions.push_back(version);
+      }
+    } else if (version.transport_version == QUIC_VERSION_IETF_DRAFT_25) {
+      QUIC_BUG_IF(version.handshake_protocol != PROTOCOL_TLS1_3);
+      if (GetQuicReloadableFlag(quic_enable_version_draft_25)) {
         filtered_versions.push_back(version);
       }
     } else if (version.transport_version == QUIC_VERSION_50) {
@@ -304,14 +315,17 @@
         filtered_versions.push_back(version);
       }
     } else if (version.transport_version == QUIC_VERSION_46) {
+      QUIC_BUG_IF(version.handshake_protocol != PROTOCOL_QUIC_CRYPTO);
       if (!GetQuicReloadableFlag(quic_disable_version_q046)) {
         filtered_versions.push_back(version);
       }
     } else if (version.transport_version == QUIC_VERSION_43) {
+      QUIC_BUG_IF(version.handshake_protocol != PROTOCOL_QUIC_CRYPTO);
       if (!GetQuicReloadableFlag(quic_disable_version_q043)) {
         filtered_versions.push_back(version);
       }
     } else {
+      QUIC_BUG << "QUIC version " << version << " has no flag protection";
       filtered_versions.push_back(version);
     }
   }
@@ -398,7 +412,7 @@
     return #x
 
 std::string QuicVersionToString(QuicTransportVersion transport_version) {
-  static_assert(SupportedTransportVersions().size() == 6u,
+  static_assert(SupportedTransportVersions().size() == 7u,
                 "Supported versions out of sync");
   switch (transport_version) {
     RETURN_STRING_LITERAL(QUIC_VERSION_43);
@@ -406,6 +420,7 @@
     RETURN_STRING_LITERAL(QUIC_VERSION_48);
     RETURN_STRING_LITERAL(QUIC_VERSION_49);
     RETURN_STRING_LITERAL(QUIC_VERSION_50);
+    RETURN_STRING_LITERAL(QUIC_VERSION_IETF_DRAFT_25);
     RETURN_STRING_LITERAL(QUIC_VERSION_99);
     RETURN_STRING_LITERAL(QUIC_VERSION_UNSUPPORTED);
     RETURN_STRING_LITERAL(QUIC_VERSION_RESERVED_FOR_NEGOTIATION);
@@ -509,10 +524,14 @@
 }
 
 std::string AlpnForVersion(ParsedQuicVersion parsed_version) {
-  if (parsed_version.handshake_protocol == PROTOCOL_TLS1_3 &&
-      parsed_version.transport_version == QUIC_VERSION_99) {
-    return "h3-" +
-           quiche::QuicheTextUtils::Uint64ToString(kQuicIetfDraftVersion);
+  if (parsed_version.handshake_protocol == PROTOCOL_TLS1_3) {
+    if (parsed_version.transport_version == QUIC_VERSION_IETF_DRAFT_25) {
+      return "h3-25";
+    }
+    if (parsed_version.transport_version == QUIC_VERSION_99) {
+      return "h3-" +
+             quiche::QuicheTextUtils::Uint64ToString(kQuicIetfDraftVersion);
+    }
   }
   return "h3-" + ParsedQuicVersionToString(parsed_version);
 }
@@ -522,12 +541,14 @@
 }
 
 void QuicEnableVersion(ParsedQuicVersion parsed_version) {
-  static_assert(SupportedTransportVersions().size() == 6u,
+  static_assert(SupportedVersions().size() == 8u,
                 "Supported versions out of sync");
   if (parsed_version.transport_version == QUIC_VERSION_99) {
-    if (parsed_version.handshake_protocol == PROTOCOL_TLS1_3) {
-      SetQuicReloadableFlag(quic_enable_version_t099, true);
-    }
+    QUIC_BUG_IF(parsed_version.handshake_protocol != PROTOCOL_TLS1_3);
+    SetQuicReloadableFlag(quic_enable_version_t099, true);
+  } else if (parsed_version.transport_version == QUIC_VERSION_IETF_DRAFT_25) {
+    QUIC_BUG_IF(parsed_version.handshake_protocol != PROTOCOL_TLS1_3);
+    SetQuicReloadableFlag(quic_enable_version_draft_25, true);
   } else if (parsed_version.transport_version == QUIC_VERSION_50) {
     if (parsed_version.handshake_protocol == PROTOCOL_QUIC_CRYPTO) {
       SetQuicReloadableFlag(quic_disable_version_q050, false);
diff --git a/quic/core/quic_versions.h b/quic/core/quic_versions.h
index 1f3738e..e2ab8d7 100644
--- a/quic/core/quic_versions.h
+++ b/quic/core/quic_versions.h
@@ -107,6 +107,7 @@
   QUIC_VERSION_49 = 49,  // Client connection IDs, long header lengths, IETF
                          // header format from draft-ietf-quic-invariants-06.
   QUIC_VERSION_50 = 50,  // Header protection and initial obfuscators.
+  QUIC_VERSION_IETF_DRAFT_25 = 70,  // draft-ietf-quic-transport-25.
   QUIC_VERSION_99 = 99,  // Dumping ground for IETF QUIC changes which are not
                          // yet ready for production.
   // QUIC_VERSION_RESERVED_FOR_NEGOTIATION is sent over the wire as ?a?a?a?a
@@ -124,7 +125,7 @@
     QuicTransportVersion transport_version);
 
 // IETF draft version most closely approximated by TLS + v99.
-enum : int { kQuicIetfDraftVersion = 25 };
+enum : int { kQuicIetfDraftVersion = 26 };
 
 // The crypto handshake protocols that can be used with QUIC.
 enum HandshakeProtocol {
@@ -156,6 +157,7 @@
       return transport_version == QUIC_VERSION_UNSUPPORTED;
     case PROTOCOL_QUIC_CRYPTO:
       return transport_version != QUIC_VERSION_UNSUPPORTED &&
+             transport_version != QUIC_VERSION_IETF_DRAFT_25 &&
              // We explicitly removed support for Q099 to reduce test load.
              transport_version != QUIC_VERSION_99;
     case PROTOCOL_TLS1_3:
@@ -313,10 +315,10 @@
 // skipped as necessary).
 //
 // See go/new-quic-version for more details on how to roll out new versions.
-constexpr std::array<QuicTransportVersion, 6> SupportedTransportVersions() {
-  return std::array<QuicTransportVersion, 6>(
-      {QUIC_VERSION_99, QUIC_VERSION_50, QUIC_VERSION_49, QUIC_VERSION_48,
-       QUIC_VERSION_46, QUIC_VERSION_43});
+constexpr std::array<QuicTransportVersion, 7> SupportedTransportVersions() {
+  return std::array<QuicTransportVersion, 7>(
+      {QUIC_VERSION_99, QUIC_VERSION_IETF_DRAFT_25, QUIC_VERSION_50,
+       QUIC_VERSION_49, QUIC_VERSION_48, QUIC_VERSION_46, QUIC_VERSION_43});
 }
 
 // This vector contains all crypto handshake protocols that are supported.
@@ -325,14 +327,15 @@
       {PROTOCOL_QUIC_CRYPTO, PROTOCOL_TLS1_3});
 }
 
-constexpr std::array<ParsedQuicVersion, 7> SupportedVersions() {
-  return std::array<ParsedQuicVersion, 7>({
+constexpr std::array<ParsedQuicVersion, 8> SupportedVersions() {
+  return std::array<ParsedQuicVersion, 8>({
       ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50),
       ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_49),
       ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_48),
       ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46),
       ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43),
       ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_99),
+      ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_25),
       ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_50),
   });
 }
@@ -485,7 +488,7 @@
 // * GOAWAY is moved to HTTP layer.
 QUIC_EXPORT_PRIVATE constexpr bool VersionUsesHttp3(
     QuicTransportVersion transport_version) {
-  return transport_version >= QUIC_VERSION_99;
+  return transport_version >= QUIC_VERSION_IETF_DRAFT_25;
 }
 
 // Returns whether the transport_version supports the variable length integer
@@ -499,7 +502,7 @@
 // frames or not.
 QUIC_EXPORT_PRIVATE constexpr bool VersionHasIetfQuicFrames(
     QuicTransportVersion transport_version) {
-  return transport_version >= QUIC_VERSION_99;
+  return transport_version >= QUIC_VERSION_IETF_DRAFT_25;
 }
 
 // Returns whether this version supports long header 8-bit encoded
diff --git a/quic/core/quic_versions_test.cc b/quic/core/quic_versions_test.cc
index ae48f1b..55c38bd 100644
--- a/quic/core/quic_versions_test.cc
+++ b/quic/core/quic_versions_test.cc
@@ -267,9 +267,10 @@
 }
 
 TEST_F(QuicVersionsTest, FilterSupportedVersionsAllVersions) {
-  static_assert(SupportedTransportVersions().size() == 6u,
+  static_assert(SupportedVersions().size() == 8u,
                 "Supported versions out of sync");
   SetQuicReloadableFlag(quic_enable_version_t099, true);
+  SetQuicReloadableFlag(quic_enable_version_draft_25, true);
   SetQuicReloadableFlag(quic_enable_version_t050, true);
   SetQuicReloadableFlag(quic_disable_version_q050, false);
   SetQuicReloadableFlag(quic_disable_version_q049, false);
@@ -291,6 +292,8 @@
   expected_parsed_versions.push_back(
       ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_99));
   expected_parsed_versions.push_back(
+      ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_25));
+  expected_parsed_versions.push_back(
       ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_50));
 
   ASSERT_EQ(expected_parsed_versions,
@@ -299,9 +302,10 @@
 }
 
 TEST_F(QuicVersionsTest, FilterSupportedVersionsNo99) {
-  static_assert(SupportedTransportVersions().size() == 6u,
+  static_assert(SupportedVersions().size() == 8u,
                 "Supported versions out of sync");
   SetQuicReloadableFlag(quic_enable_version_t099, false);
+  SetQuicReloadableFlag(quic_enable_version_draft_25, true);
   SetQuicReloadableFlag(quic_enable_version_t050, true);
   SetQuicReloadableFlag(quic_disable_version_q050, false);
   SetQuicReloadableFlag(quic_disable_version_q049, false);
@@ -321,6 +325,8 @@
   expected_parsed_versions.push_back(
       ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43));
   expected_parsed_versions.push_back(
+      ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_25));
+  expected_parsed_versions.push_back(
       ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_50));
 
   ASSERT_EQ(expected_parsed_versions,
@@ -328,9 +334,10 @@
 }
 
 TEST_F(QuicVersionsTest, FilterSupportedVersionsNoFlags) {
-  static_assert(SupportedTransportVersions().size() == 6u,
+  static_assert(SupportedVersions().size() == 8u,
                 "Supported versions out of sync");
   SetQuicReloadableFlag(quic_enable_version_t099, false);
+  SetQuicReloadableFlag(quic_enable_version_draft_25, false);
   SetQuicReloadableFlag(quic_enable_version_t050, false);
   SetQuicReloadableFlag(quic_disable_version_q050, false);
   SetQuicReloadableFlag(quic_disable_version_q049, false);
@@ -392,19 +399,20 @@
 // This test may appear to be so simplistic as to be unnecessary,
 // yet a typo was made in doing the #defines and it was caught
 // only in some test far removed from here... Better safe than sorry.
-TEST_F(QuicVersionsTest, CheckVersionNumbersForTypos) {
-  static_assert(SupportedTransportVersions().size() == 6u,
+TEST_F(QuicVersionsTest, CheckTransportVersionNumbersForTypos) {
+  static_assert(SupportedTransportVersions().size() == 7u,
                 "Supported versions out of sync");
   EXPECT_EQ(QUIC_VERSION_43, 43);
   EXPECT_EQ(QUIC_VERSION_46, 46);
   EXPECT_EQ(QUIC_VERSION_48, 48);
   EXPECT_EQ(QUIC_VERSION_49, 49);
   EXPECT_EQ(QUIC_VERSION_50, 50);
+  EXPECT_EQ(QUIC_VERSION_IETF_DRAFT_25, 70);
   EXPECT_EQ(QUIC_VERSION_99, 99);
 }
 
 TEST_F(QuicVersionsTest, AlpnForVersion) {
-  static_assert(SupportedTransportVersions().size() == 6u,
+  static_assert(SupportedVersions().size() == 8u,
                 "Supported versions out of sync");
   ParsedQuicVersion parsed_version_q048 =
       ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_48);
@@ -414,6 +422,8 @@
       ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50);
   ParsedQuicVersion parsed_version_t050 =
       ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_50);
+  ParsedQuicVersion parsed_version_draft_25 =
+      ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_25);
   ParsedQuicVersion parsed_version_t099 =
       ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_99);
 
@@ -421,16 +431,19 @@
   EXPECT_EQ("h3-Q049", AlpnForVersion(parsed_version_q049));
   EXPECT_EQ("h3-Q050", AlpnForVersion(parsed_version_q050));
   EXPECT_EQ("h3-T050", AlpnForVersion(parsed_version_t050));
-  EXPECT_EQ("h3-25", AlpnForVersion(parsed_version_t099));
-  static_assert(kQuicIetfDraftVersion == 25,
+  EXPECT_EQ("h3-25", AlpnForVersion(parsed_version_draft_25));
+  EXPECT_EQ("h3-26", AlpnForVersion(parsed_version_t099));
+  static_assert(kQuicIetfDraftVersion == 26,
                 "ALPN does not match draft version");
 }
 
 TEST_F(QuicVersionsTest, QuicEnableVersion) {
-  static_assert(SupportedTransportVersions().size() == 6u,
+  static_assert(SupportedVersions().size() == 8u,
                 "Supported versions out of sync");
   ParsedQuicVersion parsed_version_t099 =
       ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_99);
+  ParsedQuicVersion parsed_version_draft_25 =
+      ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_25);
   ParsedQuicVersion parsed_version_q050 =
       ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50);
   ParsedQuicVersion parsed_version_t050 =
@@ -445,6 +458,13 @@
 
   {
     QuicFlagSaver flag_saver;
+    SetQuicReloadableFlag(quic_enable_version_draft_25, false);
+    QuicEnableVersion(parsed_version_draft_25);
+    EXPECT_TRUE(GetQuicReloadableFlag(quic_enable_version_draft_25));
+  }
+
+  {
+    QuicFlagSaver flag_saver;
     SetQuicReloadableFlag(quic_disable_version_q050, true);
     QuicEnableVersion(parsed_version_q050);
     EXPECT_FALSE(GetQuicReloadableFlag(quic_disable_version_q050));
@@ -456,6 +476,14 @@
     QuicEnableVersion(parsed_version_t050);
     EXPECT_TRUE(GetQuicReloadableFlag(quic_enable_version_t050));
   }
+
+  {
+    QuicFlagSaver flag_saver;
+    for (const ParsedQuicVersion& version : SupportedVersions()) {
+      QuicEnableVersion(version);
+    }
+    ASSERT_EQ(AllSupportedVersions(), CurrentSupportedVersions());
+  }
 }
 
 TEST_F(QuicVersionsTest, ReservedForNegotiation) {
@@ -484,6 +512,22 @@
   EXPECT_EQ(SupportedVersions().size(), index);
 }
 
+TEST_F(QuicVersionsTest, SupportedVersionsAllDistinct) {
+  for (size_t index1 = 0; index1 < SupportedVersions().size(); ++index1) {
+    ParsedQuicVersion version1 = SupportedVersions()[index1];
+    for (size_t index2 = index1 + 1; index2 < SupportedVersions().size();
+         ++index2) {
+      ParsedQuicVersion version2 = SupportedVersions()[index2];
+      EXPECT_NE(version1, version2) << version1 << " " << version2;
+      EXPECT_NE(CreateQuicVersionLabel(version1),
+                CreateQuicVersionLabel(version2))
+          << version1 << " " << version2;
+      EXPECT_NE(AlpnForVersion(version1), AlpnForVersion(version2))
+          << version1 << " " << version2;
+    }
+  }
+}
+
 }  // namespace
 }  // namespace test
 }  // namespace quic
diff --git a/quic/tools/quic_toy_server.cc b/quic/tools/quic_toy_server.cc
index 390dcf6..45c7b1f 100644
--- a/quic/tools/quic_toy_server.cc
+++ b/quic/tools/quic_toy_server.cc
@@ -62,7 +62,9 @@
   ParsedQuicVersionVector supported_versions;
   if (GetQuicFlag(FLAGS_quic_ietf_draft)) {
     QuicVersionInitializeSupportForIetfDraft();
-    supported_versions = {ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_99)};
+    supported_versions = {
+        ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_99),
+        ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_25)};
   } else {
     supported_versions = AllSupportedVersions();
   }