Introduce QUIC v49
This new version adds support for:
- client connection IDs
- latest QUIC invariants (length-prefixed connection IDs)
- long header lengths
gfe-relnote: add QUIC v49, protected by quic_enable_v49
PiperOrigin-RevId: 270337654
Change-Id: I563251f8ad170e38b356a9964cd92d89b9df47c8
diff --git a/quic/core/quic_dispatcher_test.cc b/quic/core/quic_dispatcher_test.cc
index f2114c2..2c757a4 100644
--- a/quic/core/quic_dispatcher_test.cc
+++ b/quic/core/quic_dispatcher_test.cc
@@ -934,11 +934,12 @@
TEST_F(QuicDispatcherTest, SupportedTransportVersionsChangeInFlight) {
SetQuicReloadableFlag(quic_use_parse_public_header, true);
- static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 6u,
+ static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 7u,
"Supported versions out of sync");
SetQuicReloadableFlag(quic_disable_version_39, false);
SetQuicReloadableFlag(quic_enable_version_47, true);
SetQuicReloadableFlag(quic_enable_version_48_2, true);
+ SetQuicReloadableFlag(quic_enable_version_49, true);
SetQuicReloadableFlag(quic_enable_version_99, true);
VerifyVersionNotSupported(QuicVersionReservedForNegotiation());
@@ -947,6 +948,16 @@
QuicVersionMin().transport_version));
VerifyVersionSupported(QuicVersionMax());
+ // Turn off version 49.
+ SetQuicReloadableFlag(quic_enable_version_49, false);
+ VerifyVersionNotSupported(
+ ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_49));
+
+ // Turn on version 49.
+ SetQuicReloadableFlag(quic_enable_version_49, true);
+ VerifyVersionSupported(
+ ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_49));
+
// Turn off version 48.
SetQuicReloadableFlag(quic_enable_version_48_2, false);
VerifyVersionNotSupported(
@@ -979,7 +990,7 @@
}
TEST_F(QuicDispatcherTest, RejectDeprecatedVersionsWithVersionNegotiation) {
- static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 6u,
+ static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 7u,
"Please add deprecated versions to this test");
QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
CreateTimeWaitListManager();
diff --git a/quic/core/quic_framer_test.cc b/quic/core/quic_framer_test.cc
index deb66d3..fd8d287 100644
--- a/quic/core/quic_framer_test.cc
+++ b/quic/core/quic_framer_test.cc
@@ -1210,7 +1210,7 @@
// padding frame
0x00,
};
- unsigned char packet99[] = {
+ unsigned char packet49[] = {
// public flags (long header with packet type HANDSHAKE and
// 4-byte packet number)
0xE3,
@@ -1232,9 +1232,9 @@
// clang-format on
unsigned char* p = packet;
size_t p_length = QUIC_ARRAYSIZE(packet);
- if (framer_.transport_version() == QUIC_VERSION_99) {
- p = packet99;
- p_length = QUIC_ARRAYSIZE(packet99);
+ if (framer_.transport_version() >= QUIC_VERSION_49) {
+ p = packet49;
+ p_length = QUIC_ARRAYSIZE(packet49);
} else if (framer_.transport_version() >= QUIC_VERSION_46) {
p = packet46;
p_length = QUIC_ARRAYSIZE(packet46);
@@ -1440,7 +1440,7 @@
{0x12, 0x34, 0x56, 0x78}},
};
- PacketFragments packet99 = {
+ PacketFragments packet49 = {
// type (long header with packet type ZERO_RTT_PROTECTED and 4 bytes
// packet number)
{"Unable to read first byte.",
@@ -1467,8 +1467,8 @@
// clang-format on
PacketFragments& fragments =
- framer_.transport_version() == QUIC_VERSION_99
- ? packet99
+ framer_.transport_version() >= QUIC_VERSION_49
+ ? packet49
: (framer_.transport_version() >= QUIC_VERSION_46 ? packet46
: packet);
std::unique_ptr<QuicEncryptedPacket> encrypted(
@@ -1797,7 +1797,7 @@
0x00, 0x00, 0x00, 0x00
};
- unsigned char packet99[] = {
+ unsigned char packet49[] = {
// type: Long header with packet type ZERO_RTT_PROTECTED and 1 byte packet
// number.
0xD0,
@@ -1831,9 +1831,9 @@
unsigned char* p = packet;
size_t p_size = QUIC_ARRAYSIZE(packet);
- if (framer_.transport_version() == QUIC_VERSION_99) {
- p = packet99;
- p_size = QUIC_ARRAYSIZE(packet99);
+ if (framer_.transport_version() >= QUIC_VERSION_49) {
+ p = packet49;
+ p_size = QUIC_ARRAYSIZE(packet49);
} else if (framer_.transport_version() >= QUIC_VERSION_46) {
p = packet46;
p_size = QUIC_ARRAYSIZE(packet46);
@@ -1884,7 +1884,7 @@
0x00, 0x00, 0x00, 0x00
};
- unsigned char packet99[] = {
+ unsigned char packet49[] = {
// type (long header, ZERO_RTT_PROTECTED, 4-byte packet number)
0xD3,
// version tag
@@ -1906,9 +1906,9 @@
unsigned char* p = packet;
size_t p_size = QUIC_ARRAYSIZE(packet);
- if (framer_.transport_version() >= QUIC_VERSION_99) {
- p = packet99;
- p_size = QUIC_ARRAYSIZE(packet99);
+ if (framer_.transport_version() >= QUIC_VERSION_49) {
+ p = packet49;
+ p_size = QUIC_ARRAYSIZE(packet49);
} else if (framer_.transport_version() >= QUIC_VERSION_46) {
p = packet46;
p_size = QUIC_ARRAYSIZE(packet46);
@@ -2257,7 +2257,7 @@
0x00,
};
- unsigned char packet99[] = {
+ unsigned char packet49[] = {
// type (long header, ZERO_RTT_PROTECTED, 4-byte packet number)
0xD3,
// version tag
@@ -2279,9 +2279,9 @@
unsigned char* p = packet;
size_t p_length = QUIC_ARRAYSIZE(packet);
- if (framer_.transport_version() == QUIC_VERSION_99) {
- p = packet99;
- p_length = QUIC_ARRAYSIZE(packet99);
+ if (framer_.transport_version() >= QUIC_VERSION_49) {
+ p = packet49;
+ p_length = QUIC_ARRAYSIZE(packet49);
} else if (framer_.transport_version() >= QUIC_VERSION_46) {
p = packet46;
p_length = QUIC_ARRAYSIZE(packet46);
@@ -2678,6 +2678,49 @@
'r', 'l', 'd', '!'}},
};
+ PacketFragments packet49 = {
+ // public flags (long header with packet type ZERO_RTT_PROTECTED and
+ // 4-byte packet number)
+ {"",
+ {0xD3}},
+ // version tag
+ {"",
+ {QUIC_VERSION_BYTES}},
+ // destination connection ID length
+ {"",
+ {0x08}},
+ // destination connection ID
+ {"",
+ {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
+ // source connection ID length
+ {"",
+ {0x00}},
+ // long header packet length
+ {"",
+ {0x1E}},
+ // packet number
+ {"",
+ {0x12, 0x34, 0x56, 0x78}},
+ // frame type (stream frame with fin)
+ {"",
+ {0xFE}},
+ // stream id
+ {"Long header payload length longer than packet.",
+ {0x02, 0x03, 0x04}},
+ // offset
+ {"Long header payload length longer than packet.",
+ {0x3A, 0x98, 0xFE, 0xDC,
+ 0x32, 0x10, 0x76, 0x54}},
+ {"Long header payload length longer than packet.",
+ {
+ // data length
+ 0x00, 0x0c,
+ // data
+ 'h', 'e', 'l', 'l',
+ 'o', ' ', 'w', 'o',
+ 'r', 'l', 'd', '!'}},
+ };
+
PacketFragments packet99 = {
// public flags (long header with packet type ZERO_RTT_PROTECTED and
// 4-byte packet number)
@@ -2733,8 +2776,10 @@
PacketFragments& fragments =
VersionHasIetfQuicFrames(framer_.transport_version())
? packet99
- : (framer_.transport_version() >= QUIC_VERSION_46 ? packet46
- : packet);
+ : (framer_.transport_version() >= QUIC_VERSION_49
+ ? packet49
+ : (framer_.transport_version() >= QUIC_VERSION_46 ? packet46
+ : packet));
std::unique_ptr<QuicEncryptedPacket> encrypted(
AssemblePacketFromFragments(fragments));
EXPECT_TRUE(framer_.ProcessPacket(*encrypted));
@@ -2755,7 +2800,7 @@
CheckStreamFrameData("hello world!", visitor_.stream_frames_[0].get());
CheckFramingBoundaries(fragments,
- framer_.transport_version() == QUIC_VERSION_99
+ framer_.transport_version() >= QUIC_VERSION_49
? QUIC_INVALID_PACKET_HEADER
: QUIC_INVALID_STREAM_DATA);
}
@@ -5330,7 +5375,7 @@
'Q', '2', '.', '0'}},
};
- PacketFragments packet99 = {
+ PacketFragments packet49 = {
// type (long header)
{"",
{0x8F}},
@@ -5354,8 +5399,8 @@
QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
PacketFragments& fragments =
- framer_.transport_version() >= QUIC_VERSION_99
- ? packet99
+ framer_.transport_version() >= QUIC_VERSION_49
+ ? packet49
: framer_.transport_version() > QUIC_VERSION_43 ? packet46 : packet;
std::unique_ptr<QuicEncryptedPacket> encrypted(
AssemblePacketFromFragments(fragments));
@@ -5486,7 +5531,7 @@
'H', 'e', 'l', 'l', 'o', ' ', 't', 'h', 'i', 's',
' ', 'i', 's', ' ', 'R', 'E', 'T', 'R', 'Y', '!',
};
- unsigned char packet99[] = {
+ unsigned char packet49[] = {
// public flags (long header with packet type RETRY)
0xF0,
// version
@@ -5509,9 +5554,9 @@
unsigned char* p = packet;
size_t p_length = QUIC_ARRAYSIZE(packet);
- if (framer_.transport_version() == QUIC_VERSION_99) {
- p = packet99;
- p_length = QUIC_ARRAYSIZE(packet99);
+ if (framer_.transport_version() >= QUIC_VERSION_49) {
+ p = packet49;
+ p_length = QUIC_ARRAYSIZE(packet49);
}
QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
EXPECT_TRUE(framer_.ProcessPacket(encrypted));
@@ -6131,6 +6176,32 @@
'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!',
};
+ unsigned char packet49[] = {
+ // type (long header with packet type ZERO_RTT_PROTECTED)
+ 0xD3,
+ // version tag
+ QUIC_VERSION_BYTES,
+ // destination connection ID length
+ 0x08,
+ // destination connection ID
+ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+ // source connection ID length
+ 0x00,
+ // length
+ 0x40, 0x1D,
+ // packet number
+ 0x12, 0x34, 0x56, 0x78,
+
+ // frame type (stream frame with fin and no length)
+ 0xDF,
+ // stream id
+ 0x01, 0x02, 0x03, 0x04,
+ // offset
+ 0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+ // data
+ 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!',
+ };
+
unsigned char packet99[] = {
// type (long header with packet type ZERO_RTT_PROTECTED)
0xD3,
@@ -6167,6 +6238,9 @@
if (VersionHasIetfQuicFrames(framer_.transport_version())) {
p = packet99;
p_size = QUIC_ARRAYSIZE(packet99);
+ } else if (framer_.transport_version() >= QUIC_VERSION_49) {
+ p = packet49;
+ p_size = QUIC_ARRAYSIZE(packet49);
} else if (framer_.transport_version() >= QUIC_VERSION_46) {
p = packet46;
p_size = QUIC_ARRAYSIZE(packet46);
@@ -6364,7 +6438,7 @@
0xDA, 0x5A, 0x3A, 0x3A,
QUIC_VERSION_BYTES,
};
- unsigned char packet99[] = {
+ unsigned char packet49[] = {
// type (long header)
0xC0,
// version tag
@@ -6382,9 +6456,9 @@
// clang-format on
unsigned char* p = packet;
size_t p_size = QUIC_ARRAYSIZE(packet);
- if (framer_.transport_version() >= QUIC_VERSION_99) {
- p = packet99;
- p_size = QUIC_ARRAYSIZE(packet99);
+ if (framer_.transport_version() >= QUIC_VERSION_49) {
+ p = packet49;
+ p_size = QUIC_ARRAYSIZE(packet49);
} else if (framer_.transport_version() > QUIC_VERSION_43) {
p = packet46;
p_size = QUIC_ARRAYSIZE(packet46);
@@ -12134,6 +12208,64 @@
0x1E,
// packet number
0x12, 0x34, 0x56, 0x78,
+ // frame type (stream frame with fin)
+ 0xFE,
+ // stream id
+ 0x02, 0x03, 0x04,
+ // offset
+ 0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+ // data length
+ 0x00, 0x0c,
+ // data
+ 'h', 'e', 'l', 'l',
+ 'o', ' ', 'w', 'o',
+ 'r', 'l', 'd', '!',
+ // second coalesced packet
+ // public flags (long header with packet type ZERO_RTT_PROTECTED and
+ // 4-byte packet number)
+ 0xD3,
+ // version
+ QUIC_VERSION_BYTES,
+ // destination connection ID length
+ 0x08,
+ // destination connection ID
+ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+ // source connection ID length
+ 0x00,
+ // long header packet length
+ 0x1E,
+ // packet number
+ 0x12, 0x34, 0x56, 0x79,
+ // frame type (stream frame with fin)
+ 0xFE,
+ // stream id
+ 0x02, 0x03, 0x04,
+ // offset
+ 0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+ // data length
+ 0x00, 0x0c,
+ // data
+ 'H', 'E', 'L', 'L',
+ 'O', '_', 'W', 'O',
+ 'R', 'L', 'D', '?',
+ };
+ unsigned char packet99[] = {
+ // first coalesced packet
+ // public flags (long header with packet type ZERO_RTT_PROTECTED and
+ // 4-byte packet number)
+ 0xD3,
+ // version
+ QUIC_VERSION_BYTES,
+ // destination connection ID length
+ 0x08,
+ // destination connection ID
+ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+ // source connection ID length
+ 0x00,
+ // long header packet length
+ 0x1E,
+ // packet number
+ 0x12, 0x34, 0x56, 0x78,
// frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
0x08 | 0x01 | 0x02 | 0x04,
// stream id
@@ -12179,7 +12311,14 @@
};
// clang-format on
- QuicEncryptedPacket encrypted(AsChars(packet), QUIC_ARRAYSIZE(packet), false);
+ unsigned char* p = packet;
+ size_t p_length = QUIC_ARRAYSIZE(packet);
+ if (framer_.transport_version() == QUIC_VERSION_99) {
+ p = packet99;
+ p_length = QUIC_ARRAYSIZE(packet99);
+ }
+
+ QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
EXPECT_TRUE(framer_.ProcessPacket(encrypted));
EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
@@ -12261,7 +12400,7 @@
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
- unsigned char packet99[] = {
+ unsigned char packet49[] = {
// public flags (long header with packet type HANDSHAKE and
// 4-byte packet number)
0xE3,
@@ -12286,9 +12425,9 @@
// clang-format on
unsigned char* p = packet;
size_t p_length = QUIC_ARRAYSIZE(packet);
- if (framer_.transport_version() == QUIC_VERSION_99) {
- p = packet99;
- p_length = QUIC_ARRAYSIZE(packet99);
+ if (framer_.transport_version() >= QUIC_VERSION_49) {
+ p = packet49;
+ p_length = QUIC_ARRAYSIZE(packet49);
} else if (framer_.transport_version() >= QUIC_VERSION_46) {
p = packet46;
p_length = QUIC_ARRAYSIZE(packet46);
@@ -12369,7 +12508,7 @@
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
- unsigned char packet99[] = {
+ unsigned char packet49[] = {
// public flags (long header with packet type HANDSHAKE and
// 4-byte packet number)
0xE3,
@@ -12394,9 +12533,9 @@
// clang-format on
unsigned char* p = packet;
size_t p_length = QUIC_ARRAYSIZE(packet);
- if (framer_.transport_version() == QUIC_VERSION_99) {
- p = packet99;
- p_length = QUIC_ARRAYSIZE(packet99);
+ if (framer_.transport_version() >= QUIC_VERSION_49) {
+ p = packet49;
+ p_length = QUIC_ARRAYSIZE(packet49);
} else if (framer_.transport_version() >= QUIC_VERSION_46) {
p = packet46;
p_length = QUIC_ARRAYSIZE(packet46);
@@ -12458,6 +12597,64 @@
0x1E,
// packet number
0x12, 0x34, 0x56, 0x78,
+ // frame type (stream frame with fin)
+ 0xFE,
+ // stream id
+ 0x02, 0x03, 0x04,
+ // offset
+ 0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+ // data length
+ 0x00, 0x0c,
+ // data
+ 'h', 'e', 'l', 'l',
+ 'o', ' ', 'w', 'o',
+ 'r', 'l', 'd', '!',
+ // second coalesced packet
+ // public flags (long header with packet type ZERO_RTT_PROTECTED and
+ // 4-byte packet number)
+ 0xD3,
+ // version
+ QUIC_VERSION_BYTES,
+ // destination connection ID length
+ 0x08,
+ // destination connection ID
+ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+ // source connection ID length
+ 0x00,
+ // long header packet length
+ 0x1E,
+ // packet number
+ 0x12, 0x34, 0x56, 0x79,
+ // frame type (stream frame with fin)
+ 0xFE,
+ // stream id
+ 0x02, 0x03, 0x04,
+ // offset
+ 0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+ // data length
+ 0x00, 0x0c,
+ // data
+ 'H', 'E', 'L', 'L',
+ 'O', '_', 'W', 'O',
+ 'R', 'L', 'D', '?',
+ };
+ unsigned char packet99[] = {
+ // first coalesced packet
+ // public flags (long header with packet type HANDSHAKE and
+ // 4-byte packet number)
+ 0xE3,
+ // version
+ QUIC_VERSION_BYTES,
+ // destination connection ID length
+ 0x08,
+ // destination connection ID
+ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+ // source connection ID length
+ 0x00,
+ // long header packet length
+ 0x1E,
+ // packet number
+ 0x12, 0x34, 0x56, 0x78,
// frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
0x08 | 0x01 | 0x02 | 0x04,
// stream id
@@ -12504,7 +12701,15 @@
// clang-format on
const size_t length_of_first_coalesced_packet = 46;
- QuicEncryptedPacket encrypted(AsChars(packet), QUIC_ARRAYSIZE(packet), false);
+ unsigned char* p = packet;
+ size_t p_length = QUIC_ARRAYSIZE(packet);
+ if (framer_.transport_version() == QUIC_VERSION_99) {
+ p = packet99;
+ p_length = QUIC_ARRAYSIZE(packet99);
+ }
+
+ QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
+
EXPECT_FALSE(framer_.ProcessPacket(encrypted));
EXPECT_EQ(QUIC_DECRYPTION_FAILURE, framer_.error());
@@ -12515,10 +12720,10 @@
ASSERT_EQ(1u, visitor_.undecryptable_has_decryption_keys_.size());
// Make sure we only receive the first undecryptable packet and not the
// full packet including the second coalesced packet.
- CompareCharArraysWithHexError(
- "undecryptable packet", visitor_.undecryptable_packets_[0]->data(),
- visitor_.undecryptable_packets_[0]->length(), AsChars(packet),
- length_of_first_coalesced_packet);
+ CompareCharArraysWithHexError("undecryptable packet",
+ visitor_.undecryptable_packets_[0]->data(),
+ visitor_.undecryptable_packets_[0]->length(),
+ AsChars(p), length_of_first_coalesced_packet);
EXPECT_EQ(ENCRYPTION_HANDSHAKE,
visitor_.undecryptable_decryption_levels_[0]);
EXPECT_TRUE(visitor_.undecryptable_has_decryption_keys_[0]);
@@ -12567,6 +12772,64 @@
0x1E,
// packet number
0x12, 0x34, 0x56, 0x78,
+ // frame type (stream frame with fin)
+ 0xFE,
+ // stream id
+ 0x02, 0x03, 0x04,
+ // offset
+ 0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+ // data length
+ 0x00, 0x0c,
+ // data
+ 'h', 'e', 'l', 'l',
+ 'o', ' ', 'w', 'o',
+ 'r', 'l', 'd', '!',
+ // second coalesced packet
+ // public flags (long header with packet type ZERO_RTT_PROTECTED and
+ // 4-byte packet number)
+ 0xD3,
+ // version
+ QUIC_VERSION_BYTES,
+ // destination connection ID length
+ 0x08,
+ // destination connection ID
+ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x11,
+ // source connection ID length
+ 0x00,
+ // long header packet length
+ 0x1E,
+ // packet number
+ 0x12, 0x34, 0x56, 0x79,
+ // frame type (stream frame with fin)
+ 0xFE,
+ // stream id
+ 0x02, 0x03, 0x04,
+ // offset
+ 0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+ // data length
+ 0x00, 0x0c,
+ // data
+ 'H', 'E', 'L', 'L',
+ 'O', '_', 'W', 'O',
+ 'R', 'L', 'D', '?',
+ };
+ unsigned char packet99[] = {
+ // first coalesced packet
+ // public flags (long header with packet type ZERO_RTT_PROTECTED and
+ // 4-byte packet number)
+ 0xD3,
+ // version
+ QUIC_VERSION_BYTES,
+ // destination connection ID length
+ 0x08,
+ // destination connection ID
+ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+ // source connection ID length
+ 0x00,
+ // long header packet length
+ 0x1E,
+ // packet number
+ 0x12, 0x34, 0x56, 0x78,
// frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
0x08 | 0x01 | 0x02 | 0x04,
// stream id
@@ -12612,7 +12875,15 @@
};
// clang-format on
- QuicEncryptedPacket encrypted(AsChars(packet), QUIC_ARRAYSIZE(packet), false);
+ unsigned char* p = packet;
+ size_t p_length = QUIC_ARRAYSIZE(packet);
+ if (framer_.transport_version() == QUIC_VERSION_99) {
+ p = packet99;
+ p_length = QUIC_ARRAYSIZE(packet99);
+ }
+
+ QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
+
EXPECT_QUIC_PEER_BUG(EXPECT_TRUE(framer_.ProcessPacket(encrypted)),
"Server: Received mismatched coalesced header.*");
@@ -12654,6 +12925,41 @@
0x1E,
// packet number
0x12, 0x34, 0x56, 0x78,
+ // frame type (stream frame with fin)
+ 0xFE,
+ // stream id
+ 0x02, 0x03, 0x04,
+ // offset
+ 0x3A, 0x98, 0xFE, 0xDC, 0x32, 0x10, 0x76, 0x54,
+ // data length
+ 0x00, 0x0c,
+ // data
+ 'h', 'e', 'l', 'l',
+ 'o', ' ', 'w', 'o',
+ 'r', 'l', 'd', '!',
+ // second coalesced packet
+ // public flags (long header with packet type ZERO_RTT_PROTECTED and
+ // 4-byte packet number)
+ 0xD3,
+ // version would be here but we cut off the invalid coalesced header.
+ };
+ unsigned char packet99[] = {
+ // first coalesced packet
+ // public flags (long header with packet type ZERO_RTT_PROTECTED and
+ // 4-byte packet number)
+ 0xD3,
+ // version
+ QUIC_VERSION_BYTES,
+ // destination connection ID length
+ 0x08,
+ // destination connection ID
+ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+ // source connection ID length
+ 0x00,
+ // long header packet length
+ 0x1E,
+ // packet number
+ 0x12, 0x34, 0x56, 0x78,
// frame type (IETF_STREAM frame with FIN, LEN, and OFFSET bits set)
0x08 | 0x01 | 0x02 | 0x04,
// stream id
@@ -12675,7 +12981,15 @@
};
// clang-format on
- QuicEncryptedPacket encrypted(AsChars(packet), QUIC_ARRAYSIZE(packet), false);
+ unsigned char* p = packet;
+ size_t p_length = QUIC_ARRAYSIZE(packet);
+ if (framer_.transport_version() == QUIC_VERSION_99) {
+ p = packet99;
+ p_length = QUIC_ARRAYSIZE(packet99);
+ }
+
+ QuicEncryptedPacket encrypted(AsChars(p), p_length, false);
+
EXPECT_QUIC_PEER_BUG(EXPECT_TRUE(framer_.ProcessPacket(encrypted)),
"Server: Failed to parse received coalesced header.*");
@@ -13240,8 +13554,9 @@
sizeof(expected_packet));
QuicEncryptedPacket encrypted(reinterpret_cast<const char*>(packet),
sizeof(packet), false);
- if (framer_.transport_version() < QUIC_VERSION_99) {
- // We can only parse the connection ID with a v99 parser.
+ if (!framer_.version().HasLengthPrefixedConnectionIds()) {
+ // We can only parse the connection ID with a parser expecting
+ // length-prefixed connection IDs.
EXPECT_FALSE(framer_.ProcessPacket(encrypted));
return;
}
@@ -13529,7 +13844,7 @@
// padding frame
0x00,
};
- unsigned char packet99[] = {
+ unsigned char packet49[] = {
// public flags (long header with packet type HANDSHAKE and
// 4-byte packet number)
0xE3,
@@ -13551,9 +13866,9 @@
// clang-format on
unsigned char* p = packet;
size_t p_length = QUIC_ARRAYSIZE(packet);
- if (framer_.transport_version() == QUIC_VERSION_99) {
- p = packet99;
- p_length = QUIC_ARRAYSIZE(packet99);
+ if (framer_.transport_version() >= QUIC_VERSION_49) {
+ p = packet49;
+ p_length = QUIC_ARRAYSIZE(packet49);
}
const bool parse_success =
framer_.ProcessPacket(QuicEncryptedPacket(AsChars(p), p_length, false));
@@ -13597,7 +13912,7 @@
// padding frame
0x00,
};
- unsigned char packet99[] = {
+ unsigned char packet49[] = {
// public flags (long header with packet type HANDSHAKE and
// 4-byte packet number)
0xE3,
@@ -13617,9 +13932,9 @@
// clang-format on
unsigned char* p = packet;
size_t p_length = QUIC_ARRAYSIZE(packet);
- if (framer_.transport_version() == QUIC_VERSION_99) {
- p = packet99;
- p_length = QUIC_ARRAYSIZE(packet99);
+ if (framer_.transport_version() >= QUIC_VERSION_49) {
+ p = packet49;
+ p_length = QUIC_ARRAYSIZE(packet49);
}
const bool parse_success =
framer_.ProcessPacket(QuicEncryptedPacket(AsChars(p), p_length, false));
diff --git a/quic/core/quic_version_manager.cc b/quic/core/quic_version_manager.cc
index 6fd36b2..849dfc5 100644
--- a/quic/core/quic_version_manager.cc
+++ b/quic/core/quic_version_manager.cc
@@ -5,6 +5,7 @@
#include "net/third_party/quiche/src/quic/core/quic_version_manager.h"
#include "net/third_party/quiche/src/quic/core/quic_versions.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
@@ -15,11 +16,14 @@
QuicVersionManager::QuicVersionManager(
ParsedQuicVersionVector supported_versions)
: enable_version_99_(GetQuicReloadableFlag(quic_enable_version_99)),
+ enable_version_49_(GetQuicReloadableFlag(quic_enable_version_49)),
enable_version_48_(GetQuicReloadableFlag(quic_enable_version_48_2)),
enable_version_47_(GetQuicReloadableFlag(quic_enable_version_47)),
disable_version_39_(GetQuicReloadableFlag(quic_disable_version_39)),
enable_tls_(GetQuicReloadableFlag(quic_supports_tls_handshake)),
allowed_supported_versions_(std::move(supported_versions)) {
+ static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 7u,
+ "Supported versions out of sync");
RefilterSupportedVersions();
}
@@ -37,12 +41,16 @@
}
void QuicVersionManager::MaybeRefilterSupportedVersions() {
+ static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 7u,
+ "Supported versions out of sync");
if (enable_version_99_ != GetQuicReloadableFlag(quic_enable_version_99) ||
+ enable_version_49_ != GetQuicReloadableFlag(quic_enable_version_49) ||
enable_version_48_ != GetQuicReloadableFlag(quic_enable_version_48_2) ||
enable_version_47_ != GetQuicReloadableFlag(quic_enable_version_47) ||
disable_version_39_ != GetQuicReloadableFlag(quic_disable_version_39) ||
enable_tls_ != GetQuicReloadableFlag(quic_supports_tls_handshake)) {
enable_version_99_ = GetQuicReloadableFlag(quic_enable_version_99);
+ enable_version_49_ = GetQuicReloadableFlag(quic_enable_version_49);
enable_version_48_ = GetQuicReloadableFlag(quic_enable_version_48_2);
enable_version_47_ = GetQuicReloadableFlag(quic_enable_version_47);
disable_version_39_ = GetQuicReloadableFlag(quic_disable_version_39);
diff --git a/quic/core/quic_version_manager.h b/quic/core/quic_version_manager.h
index a0c2d6f..ffa2bb2 100644
--- a/quic/core/quic_version_manager.h
+++ b/quic/core/quic_version_manager.h
@@ -40,6 +40,8 @@
private:
// quic_enable_version_99 flag
bool enable_version_99_;
+ // quic_enable_version_49 flag
+ bool enable_version_49_;
// quic_enable_version_48_2 flag
bool enable_version_48_;
// quic_enable_version_47 flag
diff --git a/quic/core/quic_version_manager_test.cc b/quic/core/quic_version_manager_test.cc
index 7afd55d..c8e4807 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(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 6u,
+ static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 7u,
"Supported versions out of sync");
SetQuicReloadableFlag(quic_enable_version_99, false);
+ SetQuicReloadableFlag(quic_enable_version_49, false);
SetQuicReloadableFlag(quic_enable_version_48_2, false);
SetQuicReloadableFlag(quic_enable_version_47, false);
SetQuicReloadableFlag(quic_disable_version_39, true);
@@ -46,13 +47,20 @@
QUIC_VERSION_39}),
manager.GetSupportedTransportVersions());
- SetQuicReloadableFlag(quic_enable_version_99, true);
+ SetQuicReloadableFlag(quic_enable_version_49, true);
SetQuicReloadableFlag(quic_use_parse_public_header, true);
- EXPECT_EQ(QuicTransportVersionVector({QUIC_VERSION_99, QUIC_VERSION_48,
+ EXPECT_EQ(QuicTransportVersionVector({QUIC_VERSION_49, QUIC_VERSION_48,
QUIC_VERSION_47, QUIC_VERSION_46,
QUIC_VERSION_43, QUIC_VERSION_39}),
manager.GetSupportedTransportVersions());
+ SetQuicReloadableFlag(quic_enable_version_99, true);
+ EXPECT_EQ(
+ QuicTransportVersionVector(
+ {QUIC_VERSION_99, QUIC_VERSION_49, QUIC_VERSION_48, QUIC_VERSION_47,
+ QUIC_VERSION_46, QUIC_VERSION_43, QUIC_VERSION_39}),
+ manager.GetSupportedTransportVersions());
+
// Ensure that all versions are now supported.
EXPECT_EQ(FilterSupportedTransportVersions(AllSupportedTransportVersions()),
manager.GetSupportedTransportVersions());
diff --git a/quic/core/quic_versions.cc b/quic/core/quic_versions.cc
index c69452a..64cfcca 100644
--- a/quic/core/quic_versions.cc
+++ b/quic/core/quic_versions.cc
@@ -76,7 +76,7 @@
}
bool ParsedQuicVersion::SupportsClientConnectionIds() const {
- return transport_version >= QUIC_VERSION_99;
+ return transport_version > QUIC_VERSION_48;
}
bool ParsedQuicVersion::HasLengthPrefixedConnectionIds() const {
@@ -90,7 +90,7 @@
bool VersionHasLengthPrefixedConnectionIds(
QuicTransportVersion transport_version) {
- return transport_version >= QUIC_VERSION_99;
+ return transport_version > QUIC_VERSION_48;
}
std::ostream& operator<<(std::ostream& os, const ParsedQuicVersion& version) {
@@ -112,6 +112,8 @@
<< parsed_version.handshake_protocol;
return 0;
}
+ static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 7u,
+ "Supported versions out of sync");
switch (parsed_version.transport_version) {
case QUIC_VERSION_39:
return MakeVersionLabel(proto, '0', '3', '9');
@@ -123,6 +125,8 @@
return MakeVersionLabel(proto, '0', '4', '7');
case QUIC_VERSION_48:
return MakeVersionLabel(proto, '0', '4', '8');
+ case QUIC_VERSION_49:
+ return MakeVersionLabel(proto, '0', '4', '9');
case QUIC_VERSION_99:
if (parsed_version.handshake_protocol == PROTOCOL_TLS1_3) {
return MakeVersionLabel(0xff, 0x00, 0x00, kQuicIetfDraftVersion);
@@ -264,6 +268,11 @@
GetQuicReloadableFlag(quic_use_parse_public_header)) {
filtered_versions.push_back(version);
}
+ } else if (version.transport_version == QUIC_VERSION_49) {
+ if (GetQuicReloadableFlag(quic_enable_version_49) &&
+ GetQuicReloadableFlag(quic_use_parse_public_header)) {
+ filtered_versions.push_back(version);
+ }
} else if (version.transport_version == QUIC_VERSION_48) {
if (GetQuicReloadableFlag(quic_enable_version_48_2)) {
filtered_versions.push_back(version);
@@ -363,12 +372,15 @@
return #x
std::string QuicVersionToString(QuicTransportVersion transport_version) {
+ static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 7u,
+ "Supported versions out of sync");
switch (transport_version) {
RETURN_STRING_LITERAL(QUIC_VERSION_39);
RETURN_STRING_LITERAL(QUIC_VERSION_43);
RETURN_STRING_LITERAL(QUIC_VERSION_46);
RETURN_STRING_LITERAL(QUIC_VERSION_47);
RETURN_STRING_LITERAL(QUIC_VERSION_48);
+ RETURN_STRING_LITERAL(QUIC_VERSION_49);
RETURN_STRING_LITERAL(QUIC_VERSION_99);
default:
return "QUIC_VERSION_UNSUPPORTED";
@@ -418,7 +430,7 @@
// version negotiation packets for those versions. This function keeps track
// of the versions that ever supported the 4bit connection ID length encoding
// that we know about. Google QUIC 43 and earlier used a different encoding,
- // and Google QUIC 49 will start using the new length prefixed encoding.
+ // and Google QUIC 49 and later use the new length prefixed encoding.
// Similarly, only IETF drafts 11 to 21 used this encoding.
// Check Q044, Q045, Q046, Q047 and Q048.
@@ -469,11 +481,14 @@
if (parsed_version.handshake_protocol == PROTOCOL_TLS1_3) {
SetQuicReloadableFlag(quic_supports_tls_handshake, true);
}
- static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 6u,
+ static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 7u,
"Supported versions out of sync");
if (parsed_version.transport_version == QUIC_VERSION_99) {
SetQuicReloadableFlag(quic_enable_version_99, true);
}
+ if (parsed_version.transport_version == QUIC_VERSION_49) {
+ SetQuicReloadableFlag(quic_enable_version_49, true);
+ }
if (parsed_version.transport_version == QUIC_VERSION_48) {
SetQuicReloadableFlag(quic_enable_version_48_2, true);
}
diff --git a/quic/core/quic_versions.h b/quic/core/quic_versions.h
index 8a992ec..2137677 100644
--- a/quic/core/quic_versions.h
+++ b/quic/core/quic_versions.h
@@ -105,6 +105,8 @@
// bit.
QUIC_VERSION_47 = 47, // Allow variable-length QUIC connection IDs.
QUIC_VERSION_48 = 48, // Use CRYPTO frames for the handshake.
+ QUIC_VERSION_49 = 49, // Client connection IDs, long header lengths, IETF
+ // header format from draft-ietf-quic-invariants-06.
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
@@ -212,7 +214,7 @@
//
// See go/new-quic-version for more details on how to roll out new versions.
static const QuicTransportVersion kSupportedTransportVersions[] = {
- QUIC_VERSION_99, QUIC_VERSION_48, QUIC_VERSION_47,
+ QUIC_VERSION_99, QUIC_VERSION_49, QUIC_VERSION_48, QUIC_VERSION_47,
QUIC_VERSION_46, QUIC_VERSION_43, QUIC_VERSION_39,
};
@@ -411,7 +413,7 @@
// length field as defined by IETF QUIC draft-13 and later.
QUIC_EXPORT_PRIVATE inline bool QuicVersionHasLongHeaderLengths(
QuicTransportVersion transport_version) {
- return transport_version == QUIC_VERSION_99;
+ return transport_version >= QUIC_VERSION_49;
}
// Returns whether |transport_version| uses CRYPTO frames for the handshake
diff --git a/quic/core/quic_versions_test.cc b/quic/core/quic_versions_test.cc
index d1b5032..a037639 100644
--- a/quic/core/quic_versions_test.cc
+++ b/quic/core/quic_versions_test.cc
@@ -293,9 +293,12 @@
TEST_F(QuicVersionsTest, FilterSupportedTransportVersionsAllVersions) {
QuicTransportVersionVector all_versions = AllSupportedTransportVersions();
+ static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 7u,
+ "Supported versions out of sync");
SetQuicReloadableFlag(quic_disable_version_39, false);
SetQuicReloadableFlag(quic_enable_version_47, true);
SetQuicReloadableFlag(quic_enable_version_48_2, true);
+ SetQuicReloadableFlag(quic_enable_version_49, true);
SetQuicReloadableFlag(quic_enable_version_99, true);
SetQuicReloadableFlag(quic_use_parse_public_header, true);
ParsedQuicVersionVector parsed_versions;
@@ -303,7 +306,7 @@
parsed_versions.push_back(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, version));
}
QuicTransportVersionVector expected_versions = {
- QUIC_VERSION_99, QUIC_VERSION_48, QUIC_VERSION_47,
+ QUIC_VERSION_99, QUIC_VERSION_49, QUIC_VERSION_48, QUIC_VERSION_47,
QUIC_VERSION_46, QUIC_VERSION_43, QUIC_VERSION_39};
ParsedQuicVersionVector expected_parsed_versions;
for (QuicTransportVersion version : expected_versions) {
@@ -317,9 +320,39 @@
TEST_F(QuicVersionsTest, FilterSupportedTransportVersionsNo99) {
QuicTransportVersionVector all_versions = AllSupportedTransportVersions();
+ static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 7u,
+ "Supported versions out of sync");
SetQuicReloadableFlag(quic_disable_version_39, false);
SetQuicReloadableFlag(quic_enable_version_47, true);
SetQuicReloadableFlag(quic_enable_version_48_2, true);
+ SetQuicReloadableFlag(quic_enable_version_49, true);
+ SetQuicReloadableFlag(quic_enable_version_99, false);
+ SetQuicReloadableFlag(quic_use_parse_public_header, true);
+ ParsedQuicVersionVector parsed_versions;
+ for (QuicTransportVersion version : all_versions) {
+ parsed_versions.push_back(ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, version));
+ }
+ QuicTransportVersionVector expected_versions = {
+ QUIC_VERSION_49, QUIC_VERSION_48, QUIC_VERSION_47,
+ QUIC_VERSION_46, QUIC_VERSION_43, QUIC_VERSION_39};
+ ParsedQuicVersionVector expected_parsed_versions;
+ for (QuicTransportVersion version : expected_versions) {
+ expected_parsed_versions.push_back(
+ ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, version));
+ }
+
+ ASSERT_EQ(expected_versions, FilterSupportedTransportVersions(all_versions));
+ ASSERT_EQ(expected_parsed_versions, FilterSupportedVersions(parsed_versions));
+}
+
+TEST_F(QuicVersionsTest, FilterSupportedTransportVersionsNo49) {
+ QuicTransportVersionVector all_versions = AllSupportedTransportVersions();
+ static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 7u,
+ "Supported versions out of sync");
+ SetQuicReloadableFlag(quic_disable_version_39, false);
+ SetQuicReloadableFlag(quic_enable_version_47, true);
+ SetQuicReloadableFlag(quic_enable_version_48_2, true);
+ SetQuicReloadableFlag(quic_enable_version_49, false);
SetQuicReloadableFlag(quic_enable_version_99, false);
ParsedQuicVersionVector parsed_versions;
for (QuicTransportVersion version : all_versions) {
@@ -340,9 +373,12 @@
TEST_F(QuicVersionsTest, FilterSupportedTransportVersionsNo48) {
QuicTransportVersionVector all_versions = AllSupportedTransportVersions();
+ static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 7u,
+ "Supported versions out of sync");
SetQuicReloadableFlag(quic_disable_version_39, false);
SetQuicReloadableFlag(quic_enable_version_47, true);
SetQuicReloadableFlag(quic_enable_version_48_2, false);
+ SetQuicReloadableFlag(quic_enable_version_49, false);
SetQuicReloadableFlag(quic_enable_version_99, false);
ParsedQuicVersionVector parsed_versions;
for (QuicTransportVersion version : all_versions) {
@@ -362,9 +398,12 @@
TEST_F(QuicVersionsTest, FilterSupportedTransportVersionsNo47) {
QuicTransportVersionVector all_versions = AllSupportedTransportVersions();
+ static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 7u,
+ "Supported versions out of sync");
SetQuicReloadableFlag(quic_disable_version_39, false);
SetQuicReloadableFlag(quic_enable_version_47, false);
SetQuicReloadableFlag(quic_enable_version_48_2, false);
+ SetQuicReloadableFlag(quic_enable_version_49, false);
SetQuicReloadableFlag(quic_enable_version_99, false);
ParsedQuicVersionVector parsed_versions;
for (QuicTransportVersion version : all_versions) {
@@ -384,9 +423,12 @@
TEST_F(QuicVersionsTest, FilterSupportedTransportVersionsNo39) {
QuicTransportVersionVector all_versions = AllSupportedTransportVersions();
+ static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 7u,
+ "Supported versions out of sync");
SetQuicReloadableFlag(quic_disable_version_39, true);
SetQuicReloadableFlag(quic_enable_version_47, false);
SetQuicReloadableFlag(quic_enable_version_48_2, false);
+ SetQuicReloadableFlag(quic_enable_version_49, false);
SetQuicReloadableFlag(quic_enable_version_99, false);
ParsedQuicVersionVector parsed_versions;
for (QuicTransportVersion version : all_versions) {
@@ -443,17 +485,20 @@
// 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(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 6u,
+ static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 7u,
"Supported versions out of sync");
EXPECT_EQ(QUIC_VERSION_39, 39);
EXPECT_EQ(QUIC_VERSION_43, 43);
EXPECT_EQ(QUIC_VERSION_46, 46);
EXPECT_EQ(QUIC_VERSION_47, 47);
EXPECT_EQ(QUIC_VERSION_48, 48);
+ EXPECT_EQ(QUIC_VERSION_49, 49);
EXPECT_EQ(QUIC_VERSION_99, 99);
}
TEST_F(QuicVersionsTest, AlpnForVersion) {
+ static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 7u,
+ "Supported versions out of sync");
ParsedQuicVersion parsed_version_q047 =
ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_47);
ParsedQuicVersion parsed_version_t047 =
@@ -462,6 +507,10 @@
ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_48);
ParsedQuicVersion parsed_version_t048 =
ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_48);
+ ParsedQuicVersion parsed_version_q049 =
+ ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_49);
+ ParsedQuicVersion parsed_version_t049 =
+ ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_49);
ParsedQuicVersion parsed_version_t099 =
ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_99);
@@ -469,10 +518,14 @@
EXPECT_EQ("h3-T047", AlpnForVersion(parsed_version_t047));
EXPECT_EQ("h3-Q048", AlpnForVersion(parsed_version_q048));
EXPECT_EQ("h3-T048", AlpnForVersion(parsed_version_t048));
+ EXPECT_EQ("h3-Q049", AlpnForVersion(parsed_version_q049));
+ EXPECT_EQ("h3-T049", AlpnForVersion(parsed_version_t049));
EXPECT_EQ("h3-23", AlpnForVersion(parsed_version_t099));
}
TEST_F(QuicVersionsTest, QuicEnableVersion) {
+ static_assert(QUIC_ARRAYSIZE(kSupportedTransportVersions) == 7u,
+ "Supported versions out of sync");
SetQuicReloadableFlag(quic_supports_tls_handshake, true);
ParsedQuicVersion parsed_version_q047 =
ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_47);
@@ -482,12 +535,17 @@
ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_48);
ParsedQuicVersion parsed_version_t048 =
ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_48);
+ ParsedQuicVersion parsed_version_q049 =
+ ParsedQuicVersion(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_49);
+ ParsedQuicVersion parsed_version_t049 =
+ ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_49);
ParsedQuicVersion parsed_version_t099 =
ParsedQuicVersion(PROTOCOL_TLS1_3, QUIC_VERSION_99);
SetQuicReloadableFlag(quic_supports_tls_handshake, false);
SetQuicReloadableFlag(quic_disable_version_39, false);
SetQuicReloadableFlag(quic_enable_version_47, false);
SetQuicReloadableFlag(quic_enable_version_48_2, false);
+ SetQuicReloadableFlag(quic_enable_version_49, false);
SetQuicReloadableFlag(quic_enable_version_99, false);
{
@@ -528,6 +586,26 @@
{
QuicFlagSaver flag_saver;
+ QuicEnableVersion(parsed_version_q049);
+ EXPECT_FALSE(GetQuicReloadableFlag(quic_supports_tls_handshake));
+ EXPECT_FALSE(GetQuicReloadableFlag(quic_enable_version_47));
+ EXPECT_FALSE(GetQuicReloadableFlag(quic_enable_version_48_2));
+ EXPECT_TRUE(GetQuicReloadableFlag(quic_enable_version_49));
+ EXPECT_FALSE(GetQuicReloadableFlag(quic_enable_version_99));
+ }
+
+ {
+ QuicFlagSaver flag_saver;
+ QuicEnableVersion(parsed_version_t049);
+ EXPECT_TRUE(GetQuicReloadableFlag(quic_supports_tls_handshake));
+ EXPECT_FALSE(GetQuicReloadableFlag(quic_enable_version_47));
+ EXPECT_FALSE(GetQuicReloadableFlag(quic_enable_version_48_2));
+ EXPECT_TRUE(GetQuicReloadableFlag(quic_enable_version_49));
+ EXPECT_FALSE(GetQuicReloadableFlag(quic_enable_version_99));
+ }
+
+ {
+ QuicFlagSaver flag_saver;
QuicEnableVersion(parsed_version_t099);
EXPECT_TRUE(GetQuicReloadableFlag(quic_supports_tls_handshake));
EXPECT_FALSE(GetQuicReloadableFlag(quic_enable_version_47));