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