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) {