Introduce QUIC version T051

This version is a minor upgrade to T050 that brings in features that have been added to draft-27 and draft-29. This will allow us to remove multiple codepaths when we deprecate T050 and draft-25.

Introduce QUIC version T051, protected by gfe2_reloadable_flag_quic_enable_version_t051

PiperOrigin-RevId: 324040649
Change-Id: I3501bf03939f29bd17416510f43bc85d30832e29
diff --git a/quic/core/crypto/crypto_utils.cc b/quic/core/crypto/crypto_utils.cc
index 033fcfd..3be4286 100644
--- a/quic/core/crypto/crypto_utils.cc
+++ b/quic/core/crypto/crypto_utils.cc
@@ -138,26 +138,30 @@
 const uint8_t kT050Salt[] = {0x7f, 0xf5, 0x79, 0xe5, 0xac, 0xd0, 0x72,
                              0x91, 0x55, 0x80, 0x30, 0x4c, 0x43, 0xa2,
                              0x36, 0x7c, 0x60, 0x48, 0x83, 0x10};
+// Salt to use for initial obfuscators in version T051.
+const uint8_t kT051Salt[] = {0x7a, 0x4e, 0xde, 0xf4, 0xe7, 0xcc, 0xee,
+                             0x5f, 0xa4, 0x50, 0x6c, 0x19, 0x12, 0x4f,
+                             0xc8, 0xcc, 0xda, 0x6e, 0x03, 0x3d};
 
 const uint8_t* InitialSaltForVersion(const ParsedQuicVersion& version,
                                      size_t* out_len) {
-  static_assert(SupportedVersions().size() == 7u,
+  static_assert(SupportedVersions().size() == 8u,
                 "Supported versions out of sync with initial encryption salts");
   if (version == ParsedQuicVersion::Draft29()) {
     *out_len = QUICHE_ARRAYSIZE(kDraft29InitialSalt);
     return kDraft29InitialSalt;
-  }
-  if (version == ParsedQuicVersion::Draft27() ||
-      version == ParsedQuicVersion::Draft25() ||
-      version == ParsedQuicVersion::ReservedForNegotiation()) {
+  } else if (version == ParsedQuicVersion::Draft27() ||
+             version == ParsedQuicVersion::Draft25() ||
+             version == ParsedQuicVersion::ReservedForNegotiation()) {
     *out_len = QUICHE_ARRAYSIZE(kDraft25InitialSalt);
     return kDraft25InitialSalt;
-  }
-  if (version == ParsedQuicVersion::T050()) {
+  } else if (version == ParsedQuicVersion::T051()) {
+    *out_len = QUICHE_ARRAYSIZE(kT051Salt);
+    return kT051Salt;
+  } else if (version == ParsedQuicVersion::T050()) {
     *out_len = QUICHE_ARRAYSIZE(kT050Salt);
     return kT050Salt;
-  }
-  if (version == ParsedQuicVersion::Q050()) {
+  } else if (version == ParsedQuicVersion::Q050()) {
     *out_len = QUICHE_ARRAYSIZE(kQ050Salt);
     return kQ050Salt;
   }
@@ -190,20 +194,26 @@
 const uint8_t kT050RetryIntegrityKey[] = {0xc9, 0x2d, 0x32, 0x3d, 0x9c, 0xe3,
                                           0x0d, 0xa0, 0x88, 0xb9, 0xb7, 0xbb,
                                           0xdc, 0xcd, 0x50, 0xc8};
+const uint8_t kT051RetryIntegrityKey[] = {0x2e, 0xb9, 0x61, 0xa6, 0x79, 0x56,
+                                          0xf8, 0x79, 0x53, 0x14, 0xda, 0xfb,
+                                          0x2e, 0xbc, 0x83, 0xd7};
 // Nonces used by Google versions of QUIC. When introducing a new version,
 // generate a new nonce by running `openssl rand -hex 12`.
 const uint8_t kT050RetryIntegrityNonce[] = {0x26, 0xe4, 0xd6, 0x23, 0x83, 0xd5,
                                             0xc7, 0x60, 0xea, 0x02, 0xb4, 0x1f};
+const uint8_t kT051RetryIntegrityNonce[] = {0xb5, 0x0e, 0x4e, 0x53, 0x4c, 0xfc,
+                                            0x0b, 0xbb, 0x85, 0xf2, 0xf9, 0xca};
 
 bool RetryIntegrityKeysForVersion(const ParsedQuicVersion& version,
                                   quiche::QuicheStringPiece* key,
                                   quiche::QuicheStringPiece* nonce) {
+  static_assert(SupportedVersions().size() == 8u,
+                "Supported versions out of sync with retry integrity keys");
   if (!version.HasRetryIntegrityTag()) {
     QUIC_BUG << "Attempted to get retry integrity keys for invalid version "
              << version;
     return false;
-  }
-  if (version == ParsedQuicVersion::Draft29()) {
+  } else if (version == ParsedQuicVersion::Draft29()) {
     *key = quiche::QuicheStringPiece(
         reinterpret_cast<const char*>(kDraft29RetryIntegrityKey),
         QUICHE_ARRAYSIZE(kDraft29RetryIntegrityKey));
@@ -211,9 +221,8 @@
         reinterpret_cast<const char*>(kDraft29RetryIntegrityNonce),
         QUICHE_ARRAYSIZE(kDraft29RetryIntegrityNonce));
     return true;
-  }
-  if (version == ParsedQuicVersion::Draft25() ||
-      version == ParsedQuicVersion::Draft27()) {
+  } else if (version == ParsedQuicVersion::Draft25() ||
+             version == ParsedQuicVersion::Draft27()) {
     *key = quiche::QuicheStringPiece(
         reinterpret_cast<const char*>(kDraft25RetryIntegrityKey),
         QUICHE_ARRAYSIZE(kDraft25RetryIntegrityKey));
@@ -221,8 +230,15 @@
         reinterpret_cast<const char*>(kDraft25RetryIntegrityNonce),
         QUICHE_ARRAYSIZE(kDraft25RetryIntegrityNonce));
     return true;
-  }
-  if (version == ParsedQuicVersion::T050()) {
+  } else if (version == ParsedQuicVersion::T051()) {
+    *key = quiche::QuicheStringPiece(
+        reinterpret_cast<const char*>(kT051RetryIntegrityKey),
+        QUICHE_ARRAYSIZE(kT051RetryIntegrityKey));
+    *nonce = quiche::QuicheStringPiece(
+        reinterpret_cast<const char*>(kT051RetryIntegrityNonce),
+        QUICHE_ARRAYSIZE(kT051RetryIntegrityNonce));
+    return true;
+  } else if (version == ParsedQuicVersion::T050()) {
     *key = quiche::QuicheStringPiece(
         reinterpret_cast<const char*>(kT050RetryIntegrityKey),
         QUICHE_ARRAYSIZE(kT050RetryIntegrityKey));
diff --git a/quic/core/http/quic_spdy_stream_test.cc b/quic/core/http/quic_spdy_stream_test.cc
index 64ef39a..bc09fc0 100644
--- a/quic/core/http/quic_spdy_stream_test.cc
+++ b/quic/core/http/quic_spdy_stream_test.cc
@@ -90,8 +90,7 @@
             session()->connection()->client_connection_id());
       }
     }
-    if (session()->connection()->version().handshake_protocol ==
-        PROTOCOL_TLS1_3) {
+    if (session()->version().UsesTls()) {
       TransportParameters transport_parameters;
       EXPECT_TRUE(
           session()->config()->FillTransportParameters(&transport_parameters));
@@ -109,12 +108,14 @@
         ENCRYPTION_FORWARD_SECURE,
         std::make_unique<NullEncrypter>(session()->perspective()));
     session()->OnConfigNegotiated();
-    if (session()->connection()->version().handshake_protocol ==
-        PROTOCOL_TLS1_3) {
+    if (session()->version().UsesTls()) {
       session()->OnOneRttKeysAvailable();
     } else {
       session()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
     }
+    if (session()->version().HasHandshakeDone()) {
+      EXPECT_CALL(*this, HasPendingRetransmission());
+    }
     session()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
   }
 
diff --git a/quic/core/quic_dispatcher_test.cc b/quic/core/quic_dispatcher_test.cc
index a5f5f91..0dcf035 100644
--- a/quic/core/quic_dispatcher_test.cc
+++ b/quic/core/quic_dispatcher_test.cc
@@ -1086,7 +1086,7 @@
 
 TEST_P(QuicDispatcherTestOneVersion,
        RejectDeprecatedVersionsWithVersionNegotiation) {
-  static_assert(quic::SupportedVersions().size() == 7u,
+  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_version_manager.cc b/quic/core/quic_version_manager.cc
index dc1d074..57db3c9 100644
--- a/quic/core/quic_version_manager.cc
+++ b/quic/core/quic_version_manager.cc
@@ -21,12 +21,13 @@
           GetQuicReloadableFlag(quic_disable_version_draft_27)),
       disable_version_draft_25_(
           GetQuicReloadableFlag(quic_disable_version_draft_25)),
-      disable_version_q050_(GetQuicReloadableFlag(quic_disable_version_q050)),
+      enable_version_t051_(GetQuicReloadableFlag(quic_enable_version_t051)),
       disable_version_t050_(GetQuicReloadableFlag(quic_disable_version_t050)),
+      disable_version_q050_(GetQuicReloadableFlag(quic_disable_version_q050)),
       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() == 7u,
+  static_assert(SupportedVersions().size() == 8u,
                 "Supported versions out of sync");
   RefilterSupportedVersions();
 }
@@ -56,7 +57,7 @@
 }
 
 void QuicVersionManager::MaybeRefilterSupportedVersions() {
-  static_assert(SupportedVersions().size() == 7u,
+  static_assert(SupportedVersions().size() == 8u,
                 "Supported versions out of sync");
   if (disable_version_draft_29_ !=
           GetQuicReloadableFlag(quic_disable_version_draft_29) ||
@@ -64,10 +65,11 @@
           GetQuicReloadableFlag(quic_disable_version_draft_27) ||
       disable_version_draft_25_ !=
           GetQuicReloadableFlag(quic_disable_version_draft_25) ||
-      disable_version_q050_ !=
-          GetQuicReloadableFlag(quic_disable_version_q050) ||
+      enable_version_t051_ != GetQuicReloadableFlag(quic_enable_version_t051) ||
       disable_version_t050_ !=
           GetQuicReloadableFlag(quic_disable_version_t050) ||
+      disable_version_q050_ !=
+          GetQuicReloadableFlag(quic_disable_version_q050) ||
       disable_version_q046_ !=
           GetQuicReloadableFlag(quic_disable_version_q046) ||
       disable_version_q043_ !=
@@ -78,8 +80,9 @@
         GetQuicReloadableFlag(quic_disable_version_draft_27);
     disable_version_draft_25_ =
         GetQuicReloadableFlag(quic_disable_version_draft_25);
-    disable_version_q050_ = GetQuicReloadableFlag(quic_disable_version_q050);
+    enable_version_t051_ = GetQuicReloadableFlag(quic_enable_version_t051);
     disable_version_t050_ = GetQuicReloadableFlag(quic_disable_version_t050);
+    disable_version_q050_ = GetQuicReloadableFlag(quic_disable_version_q050);
     disable_version_q046_ = GetQuicReloadableFlag(quic_disable_version_q046);
     disable_version_q043_ = GetQuicReloadableFlag(quic_disable_version_q043);
 
diff --git a/quic/core/quic_version_manager.h b/quic/core/quic_version_manager.h
index 0360485..9eb69ed 100644
--- a/quic/core/quic_version_manager.h
+++ b/quic/core/quic_version_manager.h
@@ -58,10 +58,12 @@
   bool disable_version_draft_27_;
   // quic_disable_version_draft_25 flag
   bool disable_version_draft_25_;
-  // quic_disable_version_q050 flag
-  bool disable_version_q050_;
+  // quic_enable_version_t051 flag
+  bool enable_version_t051_;
   // quic_disable_version_t050 flag
   bool disable_version_t050_;
+  // quic_disable_version_q050 flag
+  bool disable_version_q050_;
   // quic_disable_version_q046 flag
   bool disable_version_q046_;
   // quic_disable_version_q043 flag
diff --git a/quic/core/quic_version_manager_test.cc b/quic/core/quic_version_manager_test.cc
index 5f95871..eec910c 100644
--- a/quic/core/quic_version_manager_test.cc
+++ b/quic/core/quic_version_manager_test.cc
@@ -18,7 +18,7 @@
 class QuicVersionManagerTest : public QuicTest {};
 
 TEST_F(QuicVersionManagerTest, QuicVersionManager) {
-  static_assert(SupportedVersions().size() == 7u,
+  static_assert(SupportedVersions().size() == 8u,
                 "Supported versions out of sync");
   for (const ParsedQuicVersion& version : AllSupportedVersions()) {
     QuicEnableVersion(version);
@@ -29,6 +29,7 @@
   QuicVersionManager manager(AllSupportedVersions());
 
   ParsedQuicVersionVector expected_parsed_versions;
+  expected_parsed_versions.push_back(ParsedQuicVersion::T051());
   expected_parsed_versions.push_back(ParsedQuicVersion::T050());
   expected_parsed_versions.push_back(ParsedQuicVersion::Q050());
   expected_parsed_versions.push_back(ParsedQuicVersion::Q046());
@@ -40,47 +41,52 @@
             manager.GetSupportedVersions());
   EXPECT_EQ(CurrentSupportedVersionsWithQuicCrypto(),
             manager.GetSupportedVersionsWithQuicCrypto());
-  EXPECT_THAT(manager.GetSupportedAlpns(),
-              ElementsAre("h3-T050", "h3-Q050", "h3-Q046", "h3-Q043"));
+  EXPECT_THAT(
+      manager.GetSupportedAlpns(),
+      ElementsAre("h3-T051", "h3-T050", "h3-Q050", "h3-Q046", "h3-Q043"));
 
+  int offset = 0;
   QuicEnableVersion(ParsedQuicVersion::Draft29());
-  expected_parsed_versions.insert(expected_parsed_versions.begin(),
+  expected_parsed_versions.insert(expected_parsed_versions.begin() + offset,
                                   ParsedQuicVersion::Draft29());
   EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
-  EXPECT_EQ(expected_parsed_versions.size() - 2,
+  EXPECT_EQ(expected_parsed_versions.size() - 3 - offset,
             manager.GetSupportedVersionsWithQuicCrypto().size());
   EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
             manager.GetSupportedVersions());
   EXPECT_EQ(CurrentSupportedVersionsWithQuicCrypto(),
             manager.GetSupportedVersionsWithQuicCrypto());
   EXPECT_THAT(manager.GetSupportedAlpns(),
-              ElementsAre("h3-29", "h3-T050", "h3-Q050", "h3-Q046", "h3-Q043"));
-
-  QuicEnableVersion(ParsedQuicVersion::Draft27());
-  expected_parsed_versions.insert(expected_parsed_versions.begin() + 1,
-                                  ParsedQuicVersion::Draft27());
-  EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
-  EXPECT_EQ(expected_parsed_versions.size() - 3,
-            manager.GetSupportedVersionsWithQuicCrypto().size());
-  EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
-            manager.GetSupportedVersions());
-  EXPECT_EQ(CurrentSupportedVersionsWithQuicCrypto(),
-            manager.GetSupportedVersionsWithQuicCrypto());
-  EXPECT_THAT(manager.GetSupportedAlpns(),
-              ElementsAre("h3-29", "h3-27", "h3-T050", "h3-Q050", "h3-Q046",
+              ElementsAre("h3-29", "h3-T051", "h3-T050", "h3-Q050", "h3-Q046",
                           "h3-Q043"));
 
+  offset++;
+  QuicEnableVersion(ParsedQuicVersion::Draft27());
+  expected_parsed_versions.insert(expected_parsed_versions.begin() + offset,
+                                  ParsedQuicVersion::Draft27());
+  EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
+  EXPECT_EQ(expected_parsed_versions.size() - 3 - offset,
+            manager.GetSupportedVersionsWithQuicCrypto().size());
+  EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()),
+            manager.GetSupportedVersions());
+  EXPECT_EQ(CurrentSupportedVersionsWithQuicCrypto(),
+            manager.GetSupportedVersionsWithQuicCrypto());
+  EXPECT_THAT(manager.GetSupportedAlpns(),
+              ElementsAre("h3-29", "h3-27", "h3-T051", "h3-T050", "h3-Q050",
+                          "h3-Q046", "h3-Q043"));
+
+  offset++;
   QuicEnableVersion(ParsedQuicVersion::Draft25());
-  expected_parsed_versions.insert(expected_parsed_versions.begin() + 2,
+  expected_parsed_versions.insert(expected_parsed_versions.begin() + offset,
                                   ParsedQuicVersion::Draft25());
   EXPECT_EQ(expected_parsed_versions, manager.GetSupportedVersions());
-  EXPECT_EQ(expected_parsed_versions.size() - 4,
+  EXPECT_EQ(expected_parsed_versions.size() - 3 - offset,
             manager.GetSupportedVersionsWithQuicCrypto().size());
   EXPECT_EQ(CurrentSupportedVersionsWithQuicCrypto(),
             manager.GetSupportedVersionsWithQuicCrypto());
   EXPECT_THAT(manager.GetSupportedAlpns(),
-              ElementsAre("h3-29", "h3-27", "h3-25", "h3-T050", "h3-Q050",
-                          "h3-Q046", "h3-Q043"));
+              ElementsAre("h3-29", "h3-27", "h3-25", "h3-T051", "h3-T050",
+                          "h3-Q050", "h3-Q046", "h3-Q043"));
 }
 
 }  // namespace
diff --git a/quic/core/quic_versions.cc b/quic/core/quic_versions.cc
index 1ba151c..fbd6c0f 100644
--- a/quic/core/quic_versions.cc
+++ b/quic/core/quic_versions.cc
@@ -40,7 +40,7 @@
 }
 
 void SetVersionFlag(const ParsedQuicVersion& version, bool should_enable) {
-  static_assert(SupportedVersions().size() == 7u,
+  static_assert(SupportedVersions().size() == 8u,
                 "Supported versions out of sync");
   const bool enable = should_enable;
   const bool disable = !should_enable;
@@ -50,6 +50,8 @@
     SetQuicReloadableFlag(quic_disable_version_draft_27, disable);
   } else if (version == ParsedQuicVersion::Draft25()) {
     SetQuicReloadableFlag(quic_disable_version_draft_25, disable);
+  } else if (version == ParsedQuicVersion::T051()) {
+    SetQuicReloadableFlag(quic_enable_version_t051, enable);
   } else if (version == ParsedQuicVersion::T050()) {
     SetQuicReloadableFlag(quic_disable_version_t050, disable);
   } else if (version == ParsedQuicVersion::Q050()) {
@@ -177,19 +179,25 @@
 
 bool ParsedQuicVersion::HasHandshakeDone() const {
   DCHECK(IsKnown());
-  return HasIetfQuicFrames() && handshake_protocol == PROTOCOL_TLS1_3;
+  // HANDSHAKE_DONE is supported in T051 and all IETF drafts since draft-25.
+  return UsesTls() && transport_version > QUIC_VERSION_50;
 }
 
 bool ParsedQuicVersion::HasVarIntTransportParams() const {
   DCHECK(IsKnown());
-  // Variable-length integer transport parameters were added in draft-27.
-  return transport_version > QUIC_VERSION_IETF_DRAFT_25;
+  // Variable-length integer transport parameters are supported in T051 and
+  // all IETF drafts since draft-27.
+  return UsesTls() && transport_version > QUIC_VERSION_50 &&
+         transport_version != QUIC_VERSION_IETF_DRAFT_25;
 }
 
 bool ParsedQuicVersion::AuthenticatesHandshakeConnectionIds() const {
   DCHECK(IsKnown());
-  // Authentication of handshake connection IDs was added in draft-28.
-  return transport_version > QUIC_VERSION_IETF_DRAFT_27;
+  // Authentication of handshake connection IDs is supported in T051 and
+  // all IETF drafts since draft-28.
+  return UsesTls() && transport_version > QUIC_VERSION_50 &&
+         transport_version != QUIC_VERSION_IETF_DRAFT_25 &&
+         transport_version != QUIC_VERSION_IETF_DRAFT_27;
 }
 
 bool ParsedQuicVersion::UsesTls() const {
@@ -233,7 +241,7 @@
 }
 
 QuicVersionLabel CreateQuicVersionLabel(ParsedQuicVersion parsed_version) {
-  static_assert(SupportedVersions().size() == 7u,
+  static_assert(SupportedVersions().size() == 8u,
                 "Supported versions out of sync");
   if (parsed_version == ParsedQuicVersion::Draft29()) {
     return MakeVersionLabel(0xff, 0x00, 0x00, 29);
@@ -241,6 +249,8 @@
     return MakeVersionLabel(0xff, 0x00, 0x00, 27);
   } else if (parsed_version == ParsedQuicVersion::Draft25()) {
     return MakeVersionLabel(0xff, 0x00, 0x00, 25);
+  } else if (parsed_version == ParsedQuicVersion::T051()) {
+    return MakeVersionLabel('T', '0', '5', '1');
   } else if (parsed_version == ParsedQuicVersion::T050()) {
     return MakeVersionLabel('T', '0', '5', '0');
   } else if (parsed_version == ParsedQuicVersion::Q050()) {
@@ -423,6 +433,10 @@
       if (!GetQuicReloadableFlag(quic_disable_version_draft_25)) {
         filtered_versions.push_back(version);
       }
+    } else if (version == ParsedQuicVersion::T051()) {
+      if (GetQuicReloadableFlag(quic_enable_version_t051)) {
+        filtered_versions.push_back(version);
+      }
     } else if (version == ParsedQuicVersion::T050()) {
       if (!GetQuicReloadableFlag(quic_disable_version_t050)) {
         filtered_versions.push_back(version);
@@ -527,12 +541,13 @@
     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);
     RETURN_STRING_LITERAL(QUIC_VERSION_46);
     RETURN_STRING_LITERAL(QUIC_VERSION_50);
+    RETURN_STRING_LITERAL(QUIC_VERSION_51);
     RETURN_STRING_LITERAL(QUIC_VERSION_IETF_DRAFT_25);
     RETURN_STRING_LITERAL(QUIC_VERSION_IETF_DRAFT_27);
     RETURN_STRING_LITERAL(QUIC_VERSION_IETF_DRAFT_29);
@@ -554,7 +569,7 @@
 }
 
 std::string ParsedQuicVersionToString(ParsedQuicVersion version) {
-  static_assert(SupportedVersions().size() == 7u,
+  static_assert(SupportedVersions().size() == 8u,
                 "Supported versions out of sync");
   if (version == UnsupportedQuicVersion()) {
     return "0";
diff --git a/quic/core/quic_versions.h b/quic/core/quic_versions.h
index aaceba1..7ea590a 100644
--- a/quic/core/quic_versions.h
+++ b/quic/core/quic_versions.h
@@ -117,6 +117,7 @@
   // Version 49 added client connection IDs, long header lengths, and the IETF
   // header format from draft-ietf-quic-invariants-06
   QUIC_VERSION_50 = 50,  // Header protection and initial obfuscators.
+  QUIC_VERSION_51 = 51,  // draft-29 features but with GoogleQUIC frames.
   QUIC_VERSION_IETF_DRAFT_25 = 70,  // draft-ietf-quic-transport-25.
   QUIC_VERSION_IETF_DRAFT_27 = 71,  // draft-ietf-quic-transport-27.
   // Number 72 used to represent draft-ietf-quic-transport-28.
@@ -135,10 +136,11 @@
 
 // This array contains QUIC transport versions which we currently support.
 // DEPRECATED. Use SupportedVersions() instead.
-constexpr std::array<QuicTransportVersion, 6> SupportedTransportVersions() {
+constexpr std::array<QuicTransportVersion, 7> SupportedTransportVersions() {
   return {QUIC_VERSION_IETF_DRAFT_29,
           QUIC_VERSION_IETF_DRAFT_27,
           QUIC_VERSION_IETF_DRAFT_25,
+          QUIC_VERSION_51,
           QUIC_VERSION_50,
           QUIC_VERSION_46,
           QUIC_VERSION_43};
@@ -197,6 +199,7 @@
       return transport_version == QUIC_VERSION_UNSUPPORTED;
     case PROTOCOL_QUIC_CRYPTO:
       return transport_version != QUIC_VERSION_UNSUPPORTED &&
+             transport_version != QUIC_VERSION_51 &&
              transport_version != QUIC_VERSION_IETF_DRAFT_25 &&
              transport_version != QUIC_VERSION_IETF_DRAFT_27 &&
              transport_version != QUIC_VERSION_IETF_DRAFT_29;
@@ -259,6 +262,10 @@
     return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_IETF_DRAFT_25);
   }
 
+  static constexpr ParsedQuicVersion T051() {
+    return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_51);
+  }
+
   static constexpr ParsedQuicVersion T050() {
     return ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_50);
   }
@@ -415,12 +422,12 @@
   return {PROTOCOL_TLS1_3, PROTOCOL_QUIC_CRYPTO};
 }
 
-constexpr std::array<ParsedQuicVersion, 7> SupportedVersions() {
+constexpr std::array<ParsedQuicVersion, 8> SupportedVersions() {
   return {
       ParsedQuicVersion::Draft29(), ParsedQuicVersion::Draft27(),
-      ParsedQuicVersion::Draft25(), ParsedQuicVersion::T050(),
-      ParsedQuicVersion::Q050(),    ParsedQuicVersion::Q046(),
-      ParsedQuicVersion::Q043(),
+      ParsedQuicVersion::Draft25(), ParsedQuicVersion::T051(),
+      ParsedQuicVersion::T050(),    ParsedQuicVersion::Q050(),
+      ParsedQuicVersion::Q046(),    ParsedQuicVersion::Q043(),
   };
 }
 
@@ -604,7 +611,7 @@
 // * GOAWAY is moved to HTTP layer.
 QUIC_EXPORT_PRIVATE constexpr bool VersionUsesHttp3(
     QuicTransportVersion transport_version) {
-  return transport_version >= QUIC_VERSION_IETF_DRAFT_25;
+  return transport_version > QUIC_VERSION_51;
 }
 
 // Returns whether the transport_version supports the variable length integer
diff --git a/quic/core/quic_versions_test.cc b/quic/core/quic_versions_test.cc
index 64f0706..a79be65 100644
--- a/quic/core/quic_versions_test.cc
+++ b/quic/core/quic_versions_test.cc
@@ -520,28 +520,27 @@
 // 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() == 6u,
+  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_50, 50);
+  EXPECT_EQ(QUIC_VERSION_51, 51);
   EXPECT_EQ(QUIC_VERSION_IETF_DRAFT_25, 70);
   EXPECT_EQ(QUIC_VERSION_IETF_DRAFT_27, 71);
   EXPECT_EQ(QUIC_VERSION_IETF_DRAFT_29, 73);
 }
 
 TEST_F(QuicVersionsTest, AlpnForVersion) {
-  static_assert(SupportedVersions().size() == 7u,
+  static_assert(SupportedVersions().size() == 8u,
                 "Supported versions out of sync");
-  ParsedQuicVersion parsed_version_q050 = ParsedQuicVersion::Q050();
-  ParsedQuicVersion parsed_version_t050 = ParsedQuicVersion::T050();
-  ParsedQuicVersion parsed_version_draft_25 = ParsedQuicVersion::Draft25();
-  ParsedQuicVersion parsed_version_draft_27 = ParsedQuicVersion::Draft27();
-
-  EXPECT_EQ("h3-Q050", AlpnForVersion(parsed_version_q050));
-  EXPECT_EQ("h3-T050", AlpnForVersion(parsed_version_t050));
-  EXPECT_EQ("h3-25", AlpnForVersion(parsed_version_draft_25));
-  EXPECT_EQ("h3-27", AlpnForVersion(parsed_version_draft_27));
+  EXPECT_EQ("h3-Q043", AlpnForVersion(ParsedQuicVersion::Q043()));
+  EXPECT_EQ("h3-Q046", AlpnForVersion(ParsedQuicVersion::Q046()));
+  EXPECT_EQ("h3-Q050", AlpnForVersion(ParsedQuicVersion::Q050()));
+  EXPECT_EQ("h3-T050", AlpnForVersion(ParsedQuicVersion::T050()));
+  EXPECT_EQ("h3-T051", AlpnForVersion(ParsedQuicVersion::T051()));
+  EXPECT_EQ("h3-25", AlpnForVersion(ParsedQuicVersion::Draft25()));
+  EXPECT_EQ("h3-27", AlpnForVersion(ParsedQuicVersion::Draft27()));
   EXPECT_EQ("h3-29", AlpnForVersion(ParsedQuicVersion::Draft29()));
 }