Allow variable length connection IDs for unsupported versions
This solves an IETF interop issue where other implementation were failing to trigger version negotiation with a destination connection ID length > 8.
gfe-relnote: allow using QUIC version negotiation with custom connection ID lengths, protected by gfe2_restart_flag_quic_allow_variable_length_connection_id_for_negotiation
PiperOrigin-RevId: 247647676
Change-Id: I5709072f50264f6f207c8e8689d0ed5dd5f6a712
diff --git a/quic/core/http/end_to_end_test.cc b/quic/core/http/end_to_end_test.cc
index 777291d..04567f1 100644
--- a/quic/core/http/end_to_end_test.cc
+++ b/quic/core/http/end_to_end_test.cc
@@ -770,6 +770,33 @@
.length());
}
+TEST_P(EndToEndTest, ForcedVersionNegotiationAndBadConnectionIdLength) {
+ if (!GetQuicRestartFlag(
+ quic_allow_variable_length_connection_id_for_negotiation)) {
+ ASSERT_TRUE(Initialize());
+ return;
+ }
+ if (!QuicUtils::VariableLengthConnectionIdAllowedForVersion(
+ GetParam().negotiated_version.transport_version)) {
+ ASSERT_TRUE(Initialize());
+ return;
+ }
+ client_supported_versions_.insert(client_supported_versions_.begin(),
+ QuicVersionReservedForNegotiation());
+ QuicConnectionId connection_id =
+ TestConnectionIdNineBytesLong(UINT64_C(0xBADbadBADbad));
+ override_connection_id_ = &connection_id;
+ ASSERT_TRUE(Initialize());
+ ASSERT_TRUE(ServerSendsVersionNegotiation());
+ EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
+ EXPECT_EQ("200", client_->response_headers()->find(":status")->second);
+ EXPECT_EQ(kQuicDefaultConnectionIdLength, client_->client()
+ ->client_session()
+ ->connection()
+ ->connection_id()
+ .length());
+}
+
TEST_P(EndToEndTest, MixGoodAndBadConnectionIdLengths) {
if (!QuicUtils::VariableLengthConnectionIdAllowedForVersion(
GetParam().negotiated_version.transport_version)) {
diff --git a/quic/core/quic_utils.cc b/quic/core/quic_utils.cc
index e1caf89..85ce4f2 100644
--- a/quic/core/quic_utils.cc
+++ b/quic/core/quic_utils.cc
@@ -15,6 +15,7 @@
#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_endian.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"
#include "net/third_party/quiche/src/quic/platform/api/quic_prefetch.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_uint128.h"
@@ -505,7 +506,16 @@
// static
bool QuicUtils::VariableLengthConnectionIdAllowedForVersion(
QuicTransportVersion version) {
- return version >= QUIC_VERSION_47;
+ if (!GetQuicRestartFlag(
+ quic_allow_variable_length_connection_id_for_negotiation)) {
+ return version >= QUIC_VERSION_47;
+ }
+ QUIC_RESTART_FLAG_COUNT(
+ quic_allow_variable_length_connection_id_for_negotiation);
+ // We allow variable length connection IDs for unsupported versions to
+ // ensure that IETF version negotiation works when other implementations
+ // trigger version negotiation with custom connection ID lengths.
+ return version >= QUIC_VERSION_47 || version == QUIC_VERSION_UNSUPPORTED;
}
// static
diff --git a/quic/core/quic_versions.cc b/quic/core/quic_versions.cc
index 002062f..c4564a7 100644
--- a/quic/core/quic_versions.cc
+++ b/quic/core/quic_versions.cc
@@ -446,6 +446,8 @@
SetQuicRestartFlag(quic_no_server_conn_ver_negotiation2, true);
SetQuicRestartFlag(quic_server_drop_version_negotiation, true);
SetQuicRestartFlag(quic_enable_accept_random_ipn, true);
+ SetQuicRestartFlag(quic_allow_variable_length_connection_id_for_negotiation,
+ true);
}
void QuicEnableVersion(ParsedQuicVersion parsed_version) {