Add support for IETF QUIC draft 29

This version marks the IETF Working Group Last Call, and is expected to be stable for quite some time.

Add new quic version, protected by gfe2_reloadable_flag_quic_enable_version_draft_29

PiperOrigin-RevId: 315947833
Change-Id: Ic8227cdb106bb3e80bdbf157645f6d7ddeacdd07
diff --git a/quic/core/crypto/crypto_utils.cc b/quic/core/crypto/crypto_utils.cc
index 94d738a..3cdfeae 100644
--- a/quic/core/crypto/crypto_utils.cc
+++ b/quic/core/crypto/crypto_utils.cc
@@ -122,6 +122,11 @@
                                        0x5a, 0x11, 0xa7, 0xd2, 0x43, 0x2b, 0xb4,
                                        0x63, 0x65, 0xbe, 0xf9, 0xf5, 0x02};
 
+// Salt from https://tools.ietf.org/html/draft-ietf-quic-tls-29#section-5.2
+const uint8_t kDraft29InitialSalt[] = {0xaf, 0xbf, 0xec, 0x28, 0x99, 0x93, 0xd2,
+                                       0x4c, 0x9e, 0x97, 0x86, 0xf1, 0x9c, 0x61,
+                                       0x11, 0xe0, 0x43, 0x90, 0xa8, 0x99};
+
 // Salts used by deployed versions of QUIC. When introducing a new version,
 // generate a new salt by running `openssl rand -hex 20`.
 
@@ -136,7 +141,7 @@
 
 const uint8_t* InitialSaltForVersion(const ParsedQuicVersion& version,
                                      size_t* out_len) {
-  static_assert(SupportedVersions().size() == 9u,
+  static_assert(SupportedVersions().size() == 10u,
                 "Supported versions out of sync with initial encryption salts");
   switch (version.handshake_protocol) {
     case PROTOCOL_QUIC_CRYPTO:
@@ -171,6 +176,9 @@
           // draft-28 uses the same salt as draft-25.
           *out_len = QUICHE_ARRAYSIZE(kDraft25InitialSalt);
           return kDraft25InitialSalt;
+        case QUIC_VERSION_IETF_DRAFT_29:
+          *out_len = QUICHE_ARRAYSIZE(kDraft29InitialSalt);
+          return kDraft29InitialSalt;
         default:
           QUIC_BUG << "No initial obfuscation salt for version " << version;
       }
@@ -194,6 +202,14 @@
                                              0xf2, 0x7d, 0x44, 0x30};
 const uint8_t kDraft25RetryIntegrityNonce[] = {
     0x4d, 0x16, 0x11, 0xd0, 0x55, 0x13, 0xa5, 0x52, 0xc5, 0x87, 0xd5, 0x75};
+
+// https://tools.ietf.org/html/draft-ietf-quic-tls-29#section-5.8
+const uint8_t kDraft29RetryIntegrityKey[] = {0xcc, 0xce, 0x18, 0x7e, 0xd0, 0x9a,
+                                             0x09, 0xd0, 0x57, 0x28, 0x15, 0x5a,
+                                             0x6c, 0xb9, 0x6b, 0xe1};
+const uint8_t kDraft29RetryIntegrityNonce[] = {
+    0xe5, 0x49, 0x30, 0xf9, 0x7f, 0x21, 0x36, 0xf0, 0x53, 0x0a, 0x8c, 0x1c};
+
 // Keys used by Google versions of QUIC. When introducing a new version,
 // generate a new key by running `openssl rand -hex 16`.
 const uint8_t kT050RetryIntegrityKey[] = {0xc9, 0x2d, 0x32, 0x3d, 0x9c, 0xe3,
@@ -235,6 +251,15 @@
         QUICHE_ARRAYSIZE(kDraft25RetryIntegrityNonce));
     return true;
   }
+  if (version == ParsedQuicVersion::Draft29()) {
+    *key = quiche::QuicheStringPiece(
+        reinterpret_cast<const char*>(kDraft29RetryIntegrityKey),
+        QUICHE_ARRAYSIZE(kDraft29RetryIntegrityKey));
+    *nonce = quiche::QuicheStringPiece(
+        reinterpret_cast<const char*>(kDraft29RetryIntegrityNonce),
+        QUICHE_ARRAYSIZE(kDraft29RetryIntegrityNonce));
+    return true;
+  }
   QUIC_BUG << "Attempted to get retry integrity keys for version " << version;
   return false;
 }
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index 316aa1b..25f9abd 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -10428,19 +10428,23 @@
       0xff, 0xff, 0x00, 0x00, 0x1c, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50, 0x2a,
       0x42, 0x62, 0xb5, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0xf7, 0x1a, 0x5f, 0x12,
       0xaf, 0xe3, 0xec, 0xf8, 0x00, 0x1a, 0x92, 0x0e, 0x6f, 0xdf, 0x1d, 0x63};
+  char retry_packet29[] = {
+      0xff, 0xff, 0x00, 0x00, 0x1d, 0x00, 0x08, 0xf0, 0x67, 0xa5, 0x50, 0x2a,
+      0x42, 0x62, 0xb5, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0xd1, 0x69, 0x26, 0xd8,
+      0x1f, 0x6f, 0x9c, 0xa2, 0x95, 0x3a, 0x8a, 0xa4, 0x57, 0x5e, 0x1e, 0x49};
 
   char* retry_packet;
   size_t retry_packet_length;
-  if (version() ==
-      ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_28)) {
+  if (version() == ParsedQuicVersion::Draft29()) {
+    retry_packet = retry_packet29;
+    retry_packet_length = QUICHE_ARRAYSIZE(retry_packet29);
+  } else if (version() == ParsedQuicVersion::Draft28()) {
     retry_packet = retry_packet28;
     retry_packet_length = QUICHE_ARRAYSIZE(retry_packet28);
-  } else if (version() ==
-             ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_27)) {
+  } else if (version() == ParsedQuicVersion::Draft27()) {
     retry_packet = retry_packet27;
     retry_packet_length = QUICHE_ARRAYSIZE(retry_packet27);
-  } else if (version() ==
-             ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_25)) {
+  } else if (version() == ParsedQuicVersion::Draft25()) {
     retry_packet = retry_packet25;
     retry_packet_length = QUICHE_ARRAYSIZE(retry_packet25);
   } else {
diff --git a/quic/core/quic_dispatcher_test.cc b/quic/core/quic_dispatcher_test.cc
index 8f5fd33..c478abf 100644
--- a/quic/core/quic_dispatcher_test.cc
+++ b/quic/core/quic_dispatcher_test.cc
@@ -1029,7 +1029,7 @@
 
 TEST_P(QuicDispatcherTestOneVersion,
        RejectDeprecatedVersionsWithVersionNegotiation) {
-  static_assert(quic::SupportedVersions().size() == 9u,
+  static_assert(quic::SupportedVersions().size() == 10u,
                 "Please add deprecated versions to this test");
   QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
   CreateTimeWaitListManager();
@@ -2260,7 +2260,9 @@
 // Regression test for b/117874922.
 TEST_P(BufferedPacketStoreTest, ProcessBufferedChloWithDifferentVersion) {
   // Ensure the preferred version is not supported by the server.
-  SetQuicReloadableFlag(quic_enable_version_draft_28, false);
+  SetQuicReloadableFlag(quic_enable_version_draft_29, false);
+  ASSERT_EQ(AllSupportedVersions()[0], ParsedQuicVersion::Draft29());
+
   uint64_t last_connection_id = kMaxNumSessionsToCreate + 5;
   ParsedQuicVersionVector supported_versions = CurrentSupportedVersions();
   for (uint64_t conn_id = 1; conn_id <= last_connection_id; ++conn_id) {
diff --git a/quic/core/quic_version_manager.cc b/quic/core/quic_version_manager.cc
index 4d33d48..9785f9c 100644
--- a/quic/core/quic_version_manager.cc
+++ b/quic/core/quic_version_manager.cc
@@ -15,7 +15,9 @@
 
 QuicVersionManager::QuicVersionManager(
     ParsedQuicVersionVector supported_versions)
-    : enable_version_draft_28_(
+    : enable_version_draft_29_(
+          GetQuicReloadableFlag(quic_enable_version_draft_29)),
+      enable_version_draft_28_(
           GetQuicReloadableFlag(quic_enable_version_draft_28)),
       enable_version_draft_27_(
           GetQuicReloadableFlag(quic_enable_version_draft_27)),
@@ -28,7 +30,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(SupportedVersions().size() == 9u,
+  static_assert(SupportedVersions().size() == 10u,
                 "Supported versions out of sync");
   RefilterSupportedVersions();
 }
@@ -58,9 +60,11 @@
 }
 
 void QuicVersionManager::MaybeRefilterSupportedVersions() {
-  static_assert(SupportedVersions().size() == 9u,
+  static_assert(SupportedVersions().size() == 10u,
                 "Supported versions out of sync");
-  if (enable_version_draft_28_ !=
+  if (enable_version_draft_29_ !=
+          GetQuicReloadableFlag(quic_enable_version_draft_29) ||
+      enable_version_draft_28_ !=
           GetQuicReloadableFlag(quic_enable_version_draft_28) ||
       enable_version_draft_27_ !=
           GetQuicReloadableFlag(quic_enable_version_draft_27) ||
@@ -78,6 +82,8 @@
           GetQuicReloadableFlag(quic_disable_version_q046) ||
       disable_version_q043_ !=
           GetQuicReloadableFlag(quic_disable_version_q043)) {
+    enable_version_draft_29_ =
+        GetQuicReloadableFlag(quic_enable_version_draft_29);
     enable_version_draft_28_ =
         GetQuicReloadableFlag(quic_enable_version_draft_28);
     enable_version_draft_27_ =
diff --git a/quic/core/quic_version_manager.h b/quic/core/quic_version_manager.h
index dcfe6a8..1375995 100644
--- a/quic/core/quic_version_manager.h
+++ b/quic/core/quic_version_manager.h
@@ -52,6 +52,8 @@
 
  private:
   // Cached value of reloadable flags.
+  // quic_enable_version_draft_29 flag
+  bool enable_version_draft_29_;
   // quic_enable_version_draft_28 flag
   bool enable_version_draft_28_;
   // quic_enable_version_draft_27 flag
diff --git a/quic/core/quic_version_manager_test.cc b/quic/core/quic_version_manager_test.cc
index 81514a9..221e296 100644
--- a/quic/core/quic_version_manager_test.cc
+++ b/quic/core/quic_version_manager_test.cc
@@ -18,8 +18,9 @@
 class QuicVersionManagerTest : public QuicTest {};
 
 TEST_F(QuicVersionManagerTest, QuicVersionManager) {
-  static_assert(SupportedVersions().size() == 9u,
+  static_assert(SupportedVersions().size() == 10u,
                 "Supported versions out of sync");
+  SetQuicReloadableFlag(quic_enable_version_draft_29, false);
   SetQuicReloadableFlag(quic_enable_version_draft_28, false);
   SetQuicReloadableFlag(quic_enable_version_draft_27, false);
   SetQuicReloadableFlag(quic_enable_version_draft_25_v3, false);
@@ -55,10 +56,9 @@
               ElementsAre("h3-T050", "h3-Q050", "h3-Q049", "h3-Q048", "h3-Q046",
                           "h3-Q043"));
 
-  SetQuicReloadableFlag(quic_enable_version_draft_28, true);
-  expected_parsed_versions.insert(
-      expected_parsed_versions.begin(),
-      ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_28));
+  SetQuicReloadableFlag(quic_enable_version_draft_29, true);
+  expected_parsed_versions.insert(expected_parsed_versions.begin(),
+                                  ParsedQuicVersion::Draft29());
   EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
   EXPECT_EQ(expected_parsed_versions.size() - 2,
             manager.GetSupportedVersionsWithQuicCrypto().size());
@@ -67,13 +67,13 @@
   EXPECT_EQ(CurrentSupportedVersionsWithQuicCrypto(),
             manager.GetSupportedVersionsWithQuicCrypto());
   EXPECT_THAT(manager.GetSupportedAlpns(),
-              ElementsAre("h3-28", "h3-T050", "h3-Q050", "h3-Q049", "h3-Q048",
+              ElementsAre("h3-29", "h3-T050", "h3-Q050", "h3-Q049", "h3-Q048",
                           "h3-Q046", "h3-Q043"));
 
-  SetQuicReloadableFlag(quic_enable_version_draft_27, true);
+  SetQuicReloadableFlag(quic_enable_version_draft_28, true);
   expected_parsed_versions.insert(
       expected_parsed_versions.begin() + 1,
-      ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_27));
+      ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_28));
   EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
   EXPECT_EQ(expected_parsed_versions.size() - 3,
             manager.GetSupportedVersionsWithQuicCrypto().size());
@@ -82,21 +82,37 @@
   EXPECT_EQ(CurrentSupportedVersionsWithQuicCrypto(),
             manager.GetSupportedVersionsWithQuicCrypto());
   EXPECT_THAT(manager.GetSupportedAlpns(),
-              ElementsAre("h3-28", "h3-27", "h3-T050", "h3-Q050", "h3-Q049",
+              ElementsAre("h3-29", "h3-28", "h3-T050", "h3-Q050", "h3-Q049",
                           "h3-Q048", "h3-Q046", "h3-Q043"));
 
-  SetQuicReloadableFlag(quic_enable_version_draft_25_v3, true);
+  SetQuicReloadableFlag(quic_enable_version_draft_27, true);
   expected_parsed_versions.insert(
       expected_parsed_versions.begin() + 2,
-      ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_25));
+      ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_27));
   EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
   EXPECT_EQ(expected_parsed_versions.size() - 4,
             manager.GetSupportedVersionsWithQuicCrypto().size());
+  EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
+            manager.GetSupportedVersions());
   EXPECT_EQ(CurrentSupportedVersionsWithQuicCrypto(),
             manager.GetSupportedVersionsWithQuicCrypto());
   EXPECT_THAT(manager.GetSupportedAlpns(),
-              ElementsAre("h3-28", "h3-27", "h3-25", "h3-T050", "h3-Q050",
+              ElementsAre("h3-29", "h3-28", "h3-27", "h3-T050", "h3-Q050",
                           "h3-Q049", "h3-Q048", "h3-Q046", "h3-Q043"));
+
+  SetQuicReloadableFlag(quic_enable_version_draft_25_v3, true);
+  expected_parsed_versions.insert(
+      expected_parsed_versions.begin() + 3,
+      ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_25));
+  EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
+  EXPECT_EQ(expected_parsed_versions.size() - 5,
+            manager.GetSupportedVersionsWithQuicCrypto().size());
+  EXPECT_EQ(CurrentSupportedVersionsWithQuicCrypto(),
+            manager.GetSupportedVersionsWithQuicCrypto());
+  EXPECT_THAT(
+      manager.GetSupportedAlpns(),
+      ElementsAre("h3-29", "h3-28", "h3-27", "h3-25", "h3-T050", "h3-Q050",
+                  "h3-Q049", "h3-Q048", "h3-Q046", "h3-Q043"));
 }
 
 }  // namespace
diff --git a/quic/core/quic_versions.cc b/quic/core/quic_versions.cc
index 192ba99..2ca800b 100644
--- a/quic/core/quic_versions.cc
+++ b/quic/core/quic_versions.cc
@@ -216,7 +216,7 @@
                << parsed_version.handshake_protocol;
       return 0;
   }
-  static_assert(SupportedVersions().size() == 9u,
+  static_assert(SupportedVersions().size() == 10u,
                 "Supported versions out of sync");
   switch (parsed_version.transport_version) {
     case QUIC_VERSION_43:
@@ -247,6 +247,12 @@
       }
       QUIC_BUG << "QUIC_VERSION_IETF_DRAFT_28 requires TLS";
       return 0;
+    case QUIC_VERSION_IETF_DRAFT_29:
+      if (parsed_version.handshake_protocol == PROTOCOL_TLS1_3) {
+        return MakeVersionLabel(0xff, 0x00, 0x00, 29);
+      }
+      QUIC_BUG << "QUIC_VERSION_IETF_DRAFT_29 requires TLS";
+      return 0;
     case QUIC_VERSION_RESERVED_FOR_NEGOTIATION:
       return CreateRandomVersionLabelForNegotiation();
     default:
@@ -403,7 +409,12 @@
   ParsedQuicVersionVector filtered_versions;
   filtered_versions.reserve(versions.size());
   for (const ParsedQuicVersion& version : versions) {
-    if (version.transport_version == QUIC_VERSION_IETF_DRAFT_28) {
+    if (version.transport_version == QUIC_VERSION_IETF_DRAFT_29) {
+      QUIC_BUG_IF(version.handshake_protocol != PROTOCOL_TLS1_3);
+      if (GetQuicReloadableFlag(quic_enable_version_draft_29)) {
+        filtered_versions.push_back(version);
+      }
+    } else if (version.transport_version == QUIC_VERSION_IETF_DRAFT_28) {
       QUIC_BUG_IF(version.handshake_protocol != PROTOCOL_TLS1_3);
       if (GetQuicReloadableFlag(quic_enable_version_draft_28)) {
         filtered_versions.push_back(version);
@@ -534,7 +545,7 @@
     return #x
 
 std::string QuicVersionToString(QuicTransportVersion transport_version) {
-  static_assert(SupportedTransportVersions().size() == 8u,
+  static_assert(SupportedTransportVersions().size() == 9u,
                 "Supported versions out of sync");
   switch (transport_version) {
     RETURN_STRING_LITERAL(QUIC_VERSION_43);
@@ -545,6 +556,7 @@
     RETURN_STRING_LITERAL(QUIC_VERSION_IETF_DRAFT_25);
     RETURN_STRING_LITERAL(QUIC_VERSION_IETF_DRAFT_27);
     RETURN_STRING_LITERAL(QUIC_VERSION_IETF_DRAFT_28);
+    RETURN_STRING_LITERAL(QUIC_VERSION_IETF_DRAFT_29);
     RETURN_STRING_LITERAL(QUIC_VERSION_UNSUPPORTED);
     RETURN_STRING_LITERAL(QUIC_VERSION_RESERVED_FOR_NEGOTIATION);
   }
@@ -647,7 +659,9 @@
 
 std::string AlpnForVersion(ParsedQuicVersion parsed_version) {
   if (parsed_version.handshake_protocol == PROTOCOL_TLS1_3) {
-    if (parsed_version.transport_version == QUIC_VERSION_IETF_DRAFT_28) {
+    if (parsed_version.transport_version == QUIC_VERSION_IETF_DRAFT_29) {
+      return "h3-29";
+    } else if (parsed_version.transport_version == QUIC_VERSION_IETF_DRAFT_28) {
       return "h3-28";
     } else if (parsed_version.transport_version == QUIC_VERSION_IETF_DRAFT_27) {
       return "h3-27";
@@ -665,9 +679,12 @@
 }
 
 void QuicEnableVersion(ParsedQuicVersion parsed_version) {
-  static_assert(SupportedVersions().size() == 9u,
+  static_assert(SupportedVersions().size() == 10u,
                 "Supported versions out of sync");
-  if (parsed_version.transport_version == QUIC_VERSION_IETF_DRAFT_28) {
+  if (parsed_version.transport_version == QUIC_VERSION_IETF_DRAFT_29) {
+    QUIC_BUG_IF(parsed_version.handshake_protocol != PROTOCOL_TLS1_3);
+    SetQuicReloadableFlag(quic_enable_version_draft_29, true);
+  } else if (parsed_version.transport_version == QUIC_VERSION_IETF_DRAFT_28) {
     QUIC_BUG_IF(parsed_version.handshake_protocol != PROTOCOL_TLS1_3);
     SetQuicReloadableFlag(quic_enable_version_draft_28, true);
   } else if (parsed_version.transport_version == QUIC_VERSION_IETF_DRAFT_27) {
diff --git a/quic/core/quic_versions.h b/quic/core/quic_versions.h
index 7a1d73f..227e20a 100644
--- a/quic/core/quic_versions.h
+++ b/quic/core/quic_versions.h
@@ -120,6 +120,7 @@
   QUIC_VERSION_IETF_DRAFT_25 = 70,  // draft-ietf-quic-transport-25.
   QUIC_VERSION_IETF_DRAFT_27 = 71,  // draft-ietf-quic-transport-27.
   QUIC_VERSION_IETF_DRAFT_28 = 72,  // draft-ietf-quic-transport-28.
+  QUIC_VERSION_IETF_DRAFT_29 = 73,  // draft-ietf-quic-transport-29.
   // Version 99 was a dumping ground for IETF QUIC changes which were not yet
   // yet ready for production between 2018-02 and 2020-02.
 
@@ -134,8 +135,9 @@
 
 // This array contains QUIC transport versions which we currently support.
 // DEPRECATED. Use SupportedVersions() instead.
-constexpr std::array<QuicTransportVersion, 8> SupportedTransportVersions() {
-  return {QUIC_VERSION_IETF_DRAFT_28,
+constexpr std::array<QuicTransportVersion, 9> SupportedTransportVersions() {
+  return {QUIC_VERSION_IETF_DRAFT_29,
+          QUIC_VERSION_IETF_DRAFT_28,
           QUIC_VERSION_IETF_DRAFT_27,
           QUIC_VERSION_IETF_DRAFT_25,
           QUIC_VERSION_50,
@@ -199,7 +201,8 @@
       return transport_version != QUIC_VERSION_UNSUPPORTED &&
              transport_version != QUIC_VERSION_IETF_DRAFT_25 &&
              transport_version != QUIC_VERSION_IETF_DRAFT_27 &&
-             transport_version != QUIC_VERSION_IETF_DRAFT_28;
+             transport_version != QUIC_VERSION_IETF_DRAFT_28 &&
+             transport_version != QUIC_VERSION_IETF_DRAFT_29;
     case PROTOCOL_TLS1_3:
       // The TLS handshake is only deployable if CRYPTO frames are also used.
       // We explicitly removed support for T048 and T049 to reduce test load.
@@ -250,6 +253,10 @@
            transport_version != other.transport_version;
   }
 
+  static constexpr ParsedQuicVersion Draft29() {
+    return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_29);
+  }
+
   static constexpr ParsedQuicVersion Draft28() {
     return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_28);
   }
@@ -422,13 +429,13 @@
   return {PROTOCOL_TLS1_3, PROTOCOL_QUIC_CRYPTO};
 }
 
-constexpr std::array<ParsedQuicVersion, 9> SupportedVersions() {
+constexpr std::array<ParsedQuicVersion, 10> SupportedVersions() {
   return {
-      ParsedQuicVersion::Draft28(), ParsedQuicVersion::Draft27(),
-      ParsedQuicVersion::Draft25(), ParsedQuicVersion::T050(),
-      ParsedQuicVersion::Q050(),    ParsedQuicVersion::Q049(),
-      ParsedQuicVersion::Q048(),    ParsedQuicVersion::Q046(),
-      ParsedQuicVersion::Q043(),
+      ParsedQuicVersion::Draft29(), ParsedQuicVersion::Draft28(),
+      ParsedQuicVersion::Draft27(), ParsedQuicVersion::Draft25(),
+      ParsedQuicVersion::T050(),    ParsedQuicVersion::Q050(),
+      ParsedQuicVersion::Q049(),    ParsedQuicVersion::Q048(),
+      ParsedQuicVersion::Q046(),    ParsedQuicVersion::Q043(),
   };
 }
 
diff --git a/quic/core/quic_versions_test.cc b/quic/core/quic_versions_test.cc
index 67c8f47..b6e16f7 100644
--- a/quic/core/quic_versions_test.cc
+++ b/quic/core/quic_versions_test.cc
@@ -246,6 +246,8 @@
             ParseQuicVersionString("T050"));
   EXPECT_EQ(ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_50),
             ParseQuicVersionString("h3-T050"));
+  EXPECT_EQ(ParsedQuicVersion::Draft29(), ParseQuicVersionString("ff00001d"));
+  EXPECT_EQ(ParsedQuicVersion::Draft29(), ParseQuicVersionString("h3-29"));
   EXPECT_EQ(ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_28),
             ParseQuicVersionString("ff00001c"));
   EXPECT_EQ(ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_28),
@@ -270,6 +272,7 @@
                                      QUIC_VERSION_IETF_DRAFT_27);
   ParsedQuicVersion version_draft_28(PROTOCOL_TLS1_3,
                                      QUIC_VERSION_IETF_DRAFT_28);
+  ParsedQuicVersion version_draft_29 = ParsedQuicVersion::Draft29();
 
   EXPECT_THAT(ParseQuicVersionVectorString(""), IsEmpty());
 
@@ -292,6 +295,8 @@
               ElementsAre(version_draft_27, version_draft_25));
   EXPECT_THAT(ParseQuicVersionVectorString("h3-28,h3-27"),
               ElementsAre(version_draft_28, version_draft_27));
+  EXPECT_THAT(ParseQuicVersionVectorString("h3-29,h3-27"),
+              ElementsAre(version_draft_29, version_draft_27));
 
   EXPECT_THAT(ParseQuicVersionVectorString("h3-27,50"),
               ElementsAre(version_draft_27, version_q050));
@@ -448,8 +453,9 @@
 }
 
 TEST_F(QuicVersionsTest, FilterSupportedVersionsAllVersions) {
-  static_assert(SupportedVersions().size() == 9u,
+  static_assert(SupportedVersions().size() == 10u,
                 "Supported versions out of sync");
+  SetQuicReloadableFlag(quic_enable_version_draft_29, true);
   SetQuicReloadableFlag(quic_enable_version_draft_28, true);
   SetQuicReloadableFlag(quic_enable_version_draft_27, true);
   SetQuicReloadableFlag(quic_enable_version_draft_25_v3, true);
@@ -461,6 +467,7 @@
   SetQuicReloadableFlag(quic_disable_version_q043, false);
 
   ParsedQuicVersionVector expected_parsed_versions;
+  expected_parsed_versions.push_back(ParsedQuicVersion::Draft29());
   expected_parsed_versions.push_back(
       ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_28));
   expected_parsed_versions.push_back(
@@ -486,9 +493,10 @@
 }
 
 TEST_F(QuicVersionsTest, FilterSupportedVersionsWithoutFirstVersion) {
-  static_assert(SupportedVersions().size() == 9u,
+  static_assert(SupportedVersions().size() == 10u,
                 "Supported versions out of sync");
-  SetQuicReloadableFlag(quic_enable_version_draft_28, false);
+  SetQuicReloadableFlag(quic_enable_version_draft_29, false);
+  SetQuicReloadableFlag(quic_enable_version_draft_28, true);
   SetQuicReloadableFlag(quic_enable_version_draft_27, true);
   SetQuicReloadableFlag(quic_enable_version_draft_25_v3, true);
   SetQuicReloadableFlag(quic_disable_version_t050, false);
@@ -499,6 +507,7 @@
   SetQuicReloadableFlag(quic_disable_version_q043, false);
 
   ParsedQuicVersionVector expected_parsed_versions;
+  expected_parsed_versions.push_back(ParsedQuicVersion::Draft28());
   expected_parsed_versions.push_back(
       ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_27));
   expected_parsed_versions.push_back(
@@ -521,8 +530,9 @@
 }
 
 TEST_F(QuicVersionsTest, FilterSupportedVersionsNoEnabledFlags) {
-  static_assert(SupportedVersions().size() == 9u,
+  static_assert(SupportedVersions().size() == 10u,
                 "Supported versions out of sync");
+  SetQuicReloadableFlag(quic_enable_version_draft_29, false);
   SetQuicReloadableFlag(quic_enable_version_draft_28, false);
   SetQuicReloadableFlag(quic_enable_version_draft_27, false);
   SetQuicReloadableFlag(quic_enable_version_draft_25_v3, false);
@@ -591,7 +601,7 @@
 // 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, CheckTransportVersionNumbersForTypos) {
-  static_assert(SupportedTransportVersions().size() == 8u,
+  static_assert(SupportedTransportVersions().size() == 9u,
                 "Supported versions out of sync");
   EXPECT_EQ(QUIC_VERSION_43, 43);
   EXPECT_EQ(QUIC_VERSION_46, 46);
@@ -601,10 +611,11 @@
   EXPECT_EQ(QUIC_VERSION_IETF_DRAFT_25, 70);
   EXPECT_EQ(QUIC_VERSION_IETF_DRAFT_27, 71);
   EXPECT_EQ(QUIC_VERSION_IETF_DRAFT_28, 72);
+  EXPECT_EQ(QUIC_VERSION_IETF_DRAFT_29, 73);
 }
 
 TEST_F(QuicVersionsTest, AlpnForVersion) {
-  static_assert(SupportedVersions().size() == 9u,
+  static_assert(SupportedVersions().size() == 10u,
                 "Supported versions out of sync");
   ParsedQuicVersion parsed_version_q048 =
       ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_48);
@@ -628,10 +639,11 @@
   EXPECT_EQ("h3-25", AlpnForVersion(parsed_version_draft_25));
   EXPECT_EQ("h3-27", AlpnForVersion(parsed_version_draft_27));
   EXPECT_EQ("h3-28", AlpnForVersion(parsed_version_draft_28));
+  EXPECT_EQ("h3-29", AlpnForVersion(ParsedQuicVersion::Draft29()));
 }
 
 TEST_F(QuicVersionsTest, QuicEnableVersion) {
-  static_assert(SupportedVersions().size() == 9u,
+  static_assert(SupportedVersions().size() == 10u,
                 "Supported versions out of sync");
   ParsedQuicVersion parsed_version_draft_28 =
       ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_28);
@@ -646,6 +658,13 @@
 
   {
     QuicFlagSaver flag_saver;
+    SetQuicReloadableFlag(quic_enable_version_draft_29, false);
+    QuicEnableVersion(ParsedQuicVersion::Draft29());
+    EXPECT_TRUE(GetQuicReloadableFlag(quic_enable_version_draft_29));
+  }
+
+  {
+    QuicFlagSaver flag_saver;
     SetQuicReloadableFlag(quic_enable_version_draft_28, false);
     QuicEnableVersion(parsed_version_draft_28);
     EXPECT_TRUE(GetQuicReloadableFlag(quic_enable_version_draft_28));
diff --git a/quic/test_tools/quic_test_utils.cc b/quic/test_tools/quic_test_utils.cc
index bc10611..cac6d3d 100644
--- a/quic/test_tools/quic_test_utils.cc
+++ b/quic/test_tools/quic_test_utils.cc
@@ -842,6 +842,7 @@
 }
 
 void DisableQuicVersionsWithTls() {
+  SetQuicReloadableFlag(quic_enable_version_draft_29, false);
   SetQuicReloadableFlag(quic_enable_version_draft_28, false);
   SetQuicReloadableFlag(quic_enable_version_draft_27, false);
   SetQuicReloadableFlag(quic_enable_version_draft_25_v3, false);