Support 20byte connection IDs in QUIC v99

gfe-relnote: change max connection ID length, protected by disabled flag quic_enable_v99
PiperOrigin-RevId: 261237446
Change-Id: Iba22fe96d6a392c97f75f92f5c3b9ed7b11e3828
diff --git a/quic/core/quic_connection_id.cc b/quic/core/quic_connection_id.cc
index 7d0f8d7..c6ef07b 100644
--- a/quic/core/quic_connection_id.cc
+++ b/quic/core/quic_connection_id.cc
@@ -53,13 +53,13 @@
 QuicConnectionId::QuicConnectionId() : QuicConnectionId(nullptr, 0) {}
 
 QuicConnectionId::QuicConnectionId(const char* data, uint8_t length) {
-  static_assert(
-      kQuicMaxConnectionIdLength <= std::numeric_limits<uint8_t>::max(),
-      "kQuicMaxConnectionIdLength too high");
-  if (length > kQuicMaxConnectionIdLength) {
+  static_assert(kQuicMaxConnectionIdAllVersionsLength <=
+                    std::numeric_limits<uint8_t>::max(),
+                "kQuicMaxConnectionIdAllVersionsLength too high");
+  if (length > kQuicMaxConnectionIdAllVersionsLength) {
     QUIC_BUG << "Attempted to create connection ID of length "
              << static_cast<int>(length);
-    length = kQuicMaxConnectionIdLength;
+    length = kQuicMaxConnectionIdAllVersionsLength;
   }
   length_ = length;
   if (length_ == 0) {
@@ -126,10 +126,10 @@
 }
 
 void QuicConnectionId::set_length(uint8_t length) {
-  if (length > kQuicMaxConnectionIdLength) {
+  if (length > kQuicMaxConnectionIdAllVersionsLength) {
     QUIC_BUG << "Attempted to set connection ID length to "
              << static_cast<int>(length);
-    length = kQuicMaxConnectionIdLength;
+    length = kQuicMaxConnectionIdAllVersionsLength;
   }
   if (GetQuicRestartFlag(quic_use_allocated_connection_ids)) {
     QUIC_RESTART_FLAG_COUNT_N(quic_use_allocated_connection_ids, 5, 6);
@@ -166,8 +166,8 @@
 size_t QuicConnectionId::Hash() const {
   if (!GetQuicRestartFlag(quic_connection_id_use_siphash)) {
     uint64_t data_bytes[3] = {0, 0, 0};
-    static_assert(sizeof(data_bytes) >= kQuicMaxConnectionIdLength,
-                  "kQuicMaxConnectionIdLength changed");
+    static_assert(sizeof(data_bytes) >= kQuicMaxConnectionIdAllVersionsLength,
+                  "kQuicMaxConnectionIdAllVersionsLength changed");
     memcpy(data_bytes, data(), length_);
     // This Hash function is designed to return the same value as the host byte
     // order representation when the connection ID length is 64 bits.
diff --git a/quic/core/quic_connection_id.h b/quic/core/quic_connection_id.h
index f1861e0..0b8c06a 100644
--- a/quic/core/quic_connection_id.h
+++ b/quic/core/quic_connection_id.h
@@ -26,7 +26,15 @@
 };
 
 // Maximum connection ID length that we support in any packet or version.
-const uint8_t kQuicMaxConnectionIdLength = 18;
+const uint8_t kQuicMaxConnectionIdAllVersionsLength = 20;
+
+// Maximum connection ID length supported by versions that use the encoding from
+// draft-ietf-quic-invariants-06.
+const uint8_t kQuicMaxConnectionIdWithLengthPrefixLength = 20;
+
+// Maximum connection ID length supported by versions that use the encoding from
+// draft-ietf-quic-invariants-05.
+const uint8_t kQuicMaxConnectionId4BitLength = 18;
 
 // kQuicDefaultConnectionIdLength is the only supported length for QUIC
 // versions < v99, and is the default picked for all versions.
@@ -99,7 +107,7 @@
   union {
     // When quic_use_allocated_connection_ids is false, the connection ID is
     // stored in the first |length_| bytes of |data_|.
-    char data_[kQuicMaxConnectionIdLength];
+    char data_[kQuicMaxConnectionIdAllVersionsLength];
     // When quic_use_allocated_connection_ids is true, if the connection ID
     // fits in |data_short_|, it is stored in the first |length_| bytes of
     // |data_short_|. Otherwise it is stored in |data_long_| which is
diff --git a/quic/core/quic_connection_id_test.cc b/quic/core/quic_connection_id_test.cc
index 0d4b190..d80babb 100644
--- a/quic/core/quic_connection_id_test.cc
+++ b/quic/core/quic_connection_id_test.cc
@@ -98,10 +98,10 @@
     // 32bit platforms.
     return;
   }
-  const char connection_id_bytes[kQuicMaxConnectionIdLength] = {};
-  for (uint8_t i = 0; i < kQuicMaxConnectionIdLength - 1; ++i) {
+  const char connection_id_bytes[kQuicMaxConnectionIdAllVersionsLength] = {};
+  for (uint8_t i = 0; i < sizeof(connection_id_bytes) - 1; ++i) {
     QuicConnectionId connection_id_i(connection_id_bytes, i);
-    for (uint8_t j = i + 1; j < kQuicMaxConnectionIdLength; ++j) {
+    for (uint8_t j = i + 1; j < sizeof(connection_id_bytes); ++j) {
       QuicConnectionId connection_id_j(connection_id_bytes, j);
       EXPECT_NE(connection_id_i.Hash(), connection_id_j.Hash());
     }
diff --git a/quic/core/quic_data_reader.cc b/quic/core/quic_data_reader.cc
index 71395dd..d4f28a0 100644
--- a/quic/core/quic_data_reader.cc
+++ b/quic/core/quic_data_reader.cc
@@ -136,7 +136,7 @@
 
 bool QuicDataReader::ReadConnectionId(QuicConnectionId* connection_id,
                                       uint8_t length) {
-  if (length > kQuicMaxConnectionIdLength) {
+  if (length > kQuicMaxConnectionIdAllVersionsLength) {
     QUIC_BUG << "Attempted to read connection ID with length too high "
              << static_cast<int>(length);
     return false;
@@ -172,7 +172,7 @@
   if (!ReadUInt8(&connection_id_length)) {
     return false;
   }
-  if (connection_id_length > kQuicMaxConnectionIdLength) {
+  if (connection_id_length > kQuicMaxConnectionIdAllVersionsLength) {
     return false;
   }
   return ReadConnectionId(connection_id, connection_id_length);
diff --git a/quic/core/quic_data_writer_test.cc b/quic/core/quic_data_writer_test.cc
index 352f27c..301bfa6 100644
--- a/quic/core/quic_data_writer_test.cc
+++ b/quic/core/quic_data_writer_test.cc
@@ -262,8 +262,8 @@
       0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
   };
   EXPECT_EQ(connection_id.length(), QUIC_ARRAYSIZE(big_endian));
-  ASSERT_LE(connection_id.length(), kQuicMaxConnectionIdLength);
-  char buffer[kQuicMaxConnectionIdLength];
+  ASSERT_LE(connection_id.length(), 255);
+  char buffer[255];
   QuicDataWriter writer(connection_id.length(), buffer, GetParam().endianness);
   EXPECT_TRUE(writer.WriteConnectionId(connection_id));
   test::CompareCharArraysWithHexError("connection_id", buffer,
@@ -285,7 +285,7 @@
   };
   EXPECT_EQ(QUIC_ARRAYSIZE(length_prefixed_connection_id),
             kConnectionIdLengthSize + connection_id.length());
-  char buffer[kConnectionIdLengthSize + kQuicMaxConnectionIdLength] = {};
+  char buffer[kConnectionIdLengthSize + 255] = {};
   QuicDataWriter writer(QUIC_ARRAYSIZE(buffer), buffer);
   EXPECT_TRUE(writer.WriteLengthPrefixedConnectionId(connection_id));
   test::CompareCharArraysWithHexError(
@@ -1150,8 +1150,9 @@
 
 TEST_P(QuicDataWriterTest, InvalidConnectionIdLengthRead) {
   static const uint8_t bad_connection_id_length = 200;
-  static_assert(bad_connection_id_length > kQuicMaxConnectionIdLength,
-                "bad lengths");
+  static_assert(
+      bad_connection_id_length > kQuicMaxConnectionIdAllVersionsLength,
+      "bad lengths");
   char buffer[255] = {};
   QuicDataReader reader(buffer, sizeof(buffer));
   QuicConnectionId connection_id;
diff --git a/quic/core/quic_framer.cc b/quic/core/quic_framer.cc
index bd0a724..91d4a0a 100644
--- a/quic/core/quic_framer.cc
+++ b/quic/core/quic_framer.cc
@@ -6611,7 +6611,7 @@
     QUIC_BUG << "Invalid packet_length";
     return false;
   }
-  if (destination_connection_id_length > kQuicMaxConnectionIdLength ||
+  if (destination_connection_id_length > kQuicMaxConnectionId4BitLength ||
       destination_connection_id_length <
           kQuicMinimumInitialConnectionIdLength) {
     QUIC_BUG << "Invalid connection_id_length";
diff --git a/quic/core/quic_framer_test.cc b/quic/core/quic_framer_test.cc
index f6f5eda..32432fb 100644
--- a/quic/core/quic_framer_test.cc
+++ b/quic/core/quic_framer_test.cc
@@ -14164,7 +14164,7 @@
   };
   // clang-format on
   char probe_payload_bytes[] = {0x56, 0x4e, 0x20, 0x70, 0x6c, 0x7a, 0x20, 0x21};
-  char parsed_probe_payload_bytes[kQuicMaxConnectionIdLength] = {};
+  char parsed_probe_payload_bytes[255] = {};
   uint8_t parsed_probe_payload_length = 0;
   std::string parse_detailed_error = "";
   EXPECT_TRUE(QuicFramer::ParseServerVersionNegotiationProbeResponse(
@@ -14195,7 +14195,7 @@
   };
   // clang-format on
   char probe_payload_bytes[] = {0x56, 0x4e, 0x20, 0x70, 0x6c, 0x7a, 0x20, 0x21};
-  char parsed_probe_payload_bytes[kQuicMaxConnectionIdLength] = {};
+  char parsed_probe_payload_bytes[255] = {};
   uint8_t parsed_probe_payload_length = 0;
   std::string parse_detailed_error = "";
   EXPECT_TRUE(QuicFramer::ParseServerVersionNegotiationProbeResponse(
diff --git a/quic/core/quic_utils.cc b/quic/core/quic_utils.cc
index 4ff7489..58996f6 100644
--- a/quic/core/quic_utils.cc
+++ b/quic/core/quic_utils.cc
@@ -554,9 +554,9 @@
   if (!VersionHasLengthPrefixedConnectionIds(transport_version)) {
     return connection_id_length8 == 0 ||
            (connection_id_length8 >= 4 &&
-            connection_id_length8 <= kQuicMaxConnectionIdLength);
+            connection_id_length8 <= kQuicMaxConnectionId4BitLength);
   }
-  return connection_id_length8 <= kQuicMaxConnectionIdLength;
+  return connection_id_length8 <= kQuicMaxConnectionIdWithLengthPrefixLength;
 }
 
 // static
@@ -570,8 +570,8 @@
 QuicUint128 QuicUtils::GenerateStatelessResetToken(
     QuicConnectionId connection_id) {
   uint64_t data_bytes[3] = {0, 0, 0};
-  static_assert(sizeof(data_bytes) >= kQuicMaxConnectionIdLength,
-                "kQuicMaxConnectionIdLength changed");
+  static_assert(sizeof(data_bytes) >= kQuicMaxConnectionIdAllVersionsLength,
+                "kQuicMaxConnectionIdAllVersionsLength changed");
   memcpy(data_bytes, connection_id.data(), connection_id.length());
   // This is designed so that the common case of 64bit connection IDs
   // produces a stateless reset token that is equal to the connection ID