Do not synthesize and verify source connection id for QuicPacketHeader generated from short header packet.
Protected by FLAGS_quic_reloadable_flag_quic_do_not_synthesize_source_cid_for_short_header.
PiperOrigin-RevId: 360981332
Change-Id: Ie6d918738d76936f0f2758ce07171dfe526671ff
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
index f7cb8f4..0bdc1bf 100644
--- a/quic/core/quic_connection.cc
+++ b/quic/core/quic_connection.cc
@@ -1007,10 +1007,16 @@
framer_.set_drop_incoming_retry_packets(true);
}
+ bool skip_server_connection_id_validation =
+ framer_.do_not_synthesize_source_cid_for_short_header() &&
+ perspective_ == Perspective::IS_CLIENT &&
+ header.form == IETF_QUIC_SHORT_HEADER_PACKET;
+
QuicConnectionId server_connection_id =
GetServerConnectionIdAsRecipient(header, perspective_);
- if (server_connection_id != server_connection_id_ &&
+ if (!skip_server_connection_id_validation &&
+ server_connection_id != server_connection_id_ &&
!HasIncomingConnectionId(server_connection_id)) {
if (PacketCanReplaceConnectionId(header, perspective_)) {
QUIC_DLOG(INFO) << ENDPOINT << "Accepting packet with new connection ID "
@@ -1038,6 +1044,14 @@
return true;
}
+ if (framer_.do_not_synthesize_source_cid_for_short_header() &&
+ perspective_ == Perspective::IS_SERVER &&
+ header.form == IETF_QUIC_SHORT_HEADER_PACKET) {
+ QUIC_RELOADABLE_FLAG_COUNT_N(
+ quic_do_not_synthesize_source_cid_for_short_header, 3, 3);
+ return true;
+ }
+
QuicConnectionId client_connection_id =
GetClientConnectionIdAsRecipient(header, perspective_);
@@ -1069,7 +1083,10 @@
// Check that any public reset packet with a different connection ID that was
// routed to this QuicConnection has been redirected before control reaches
// here.
- QUICHE_DCHECK(GetServerConnectionIdAsRecipient(header, perspective_) ==
+ QUICHE_DCHECK((framer_.do_not_synthesize_source_cid_for_short_header() &&
+ perspective_ == Perspective::IS_CLIENT &&
+ header.form == IETF_QUIC_SHORT_HEADER_PACKET) ||
+ GetServerConnectionIdAsRecipient(header, perspective_) ==
server_connection_id_ ||
HasIncomingConnectionId(
GetServerConnectionIdAsRecipient(header, perspective_)) ||
diff --git a/quic/core/quic_flags_list.h b/quic/core/quic_flags_list.h
index 83b2a65..7f4f82d 100644
--- a/quic/core/quic_flags_list.h
+++ b/quic/core/quic_flags_list.h
@@ -33,6 +33,7 @@
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_q050, false)
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_disable_version_t051, false)
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_discard_initial_packet_with_key_dropped, true)
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_do_not_synthesize_source_cid_for_short_header, false)
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_donot_reset_ideal_next_packet_send_time, false)
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_dont_defer_sending, true)
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_enable_alps_client, false)
diff --git a/quic/core/quic_framer.cc b/quic/core/quic_framer.cc
index e7565f6..2c20a44 100644
--- a/quic/core/quic_framer.cc
+++ b/quic/core/quic_framer.cc
@@ -433,6 +433,10 @@
version_ = supported_versions_[0];
QUICHE_DCHECK(version_.IsKnown())
<< ParsedQuicVersionVectorToString(supported_versions_);
+ if (do_not_synthesize_source_cid_for_short_header_) {
+ QUIC_RELOADABLE_FLAG_COUNT_N(
+ quic_do_not_synthesize_source_cid_for_short_header, 1, 3);
+ }
}
QuicFramer::~QuicFramer() {}
@@ -2701,14 +2705,28 @@
}
bool QuicFramer::ValidateReceivedConnectionIds(const QuicPacketHeader& header) {
- if (!QuicUtils::IsConnectionIdValidForVersion(
+ bool skip_server_connection_id_validation =
+ do_not_synthesize_source_cid_for_short_header_ &&
+ perspective_ == Perspective::IS_CLIENT &&
+ header.form == IETF_QUIC_SHORT_HEADER_PACKET;
+ if (!skip_server_connection_id_validation &&
+ !QuicUtils::IsConnectionIdValidForVersion(
GetServerConnectionIdAsRecipient(header, perspective_),
transport_version())) {
set_detailed_error("Received server connection ID with invalid length.");
return false;
}
- if (version_.SupportsClientConnectionIds() &&
+ bool skip_client_connection_id_validation =
+ do_not_synthesize_source_cid_for_short_header_ &&
+ perspective_ == Perspective::IS_SERVER &&
+ header.form == IETF_QUIC_SHORT_HEADER_PACKET;
+ if (skip_client_connection_id_validation) {
+ QUIC_RELOADABLE_FLAG_COUNT_N(
+ quic_do_not_synthesize_source_cid_for_short_header, 2, 3);
+ }
+ if (!skip_client_connection_id_validation &&
+ version_.SupportsClientConnectionIds() &&
!QuicUtils::IsConnectionIdValidForVersion(
GetClientConnectionIdAsRecipient(header, perspective_),
transport_version())) {
@@ -2743,7 +2761,8 @@
header->destination_connection_id_included = CONNECTION_ID_PRESENT;
header->source_connection_id_included =
header->version_flag ? CONNECTION_ID_PRESENT : CONNECTION_ID_ABSENT;
- if (header->source_connection_id_included == CONNECTION_ID_ABSENT) {
+ if (!do_not_synthesize_source_cid_for_short_header_ &&
+ header->source_connection_id_included == CONNECTION_ID_ABSENT) {
QUICHE_DCHECK(header->source_connection_id.IsEmpty());
if (perspective_ == Perspective::IS_CLIENT) {
header->source_connection_id = last_serialized_server_connection_id_;
@@ -2838,10 +2857,12 @@
set_detailed_error("Client connection ID not supported in this version.");
return false;
}
- if (perspective_ == Perspective::IS_CLIENT) {
- header->source_connection_id = last_serialized_server_connection_id_;
- } else {
- header->source_connection_id = last_serialized_client_connection_id_;
+ if (!do_not_synthesize_source_cid_for_short_header_) {
+ if (perspective_ == Perspective::IS_CLIENT) {
+ header->source_connection_id = last_serialized_server_connection_id_;
+ } else {
+ header->source_connection_id = last_serialized_client_connection_id_;
+ }
}
}
diff --git a/quic/core/quic_framer.h b/quic/core/quic_framer.h
index fe395ce..5362718 100644
--- a/quic/core/quic_framer.h
+++ b/quic/core/quic_framer.h
@@ -709,6 +709,10 @@
drop_incoming_retry_packets_ = drop_incoming_retry_packets;
}
+ bool do_not_synthesize_source_cid_for_short_header() const {
+ return do_not_synthesize_source_cid_for_short_header_;
+ }
+
private:
friend class test::QuicFramerPeer;
@@ -1168,6 +1172,11 @@
bool reject_unexpected_ietf_frame_types_ =
GetQuicReloadableFlag(quic_reject_unexpected_ietf_frame_types);
+ // Indicates whether source connection ID should be synthesized when read
+ // short header packet.
+ const bool do_not_synthesize_source_cid_for_short_header_ =
+ GetQuicReloadableFlag(quic_do_not_synthesize_source_cid_for_short_header);
+
// The length in bytes of the last packet number written to an IETF-framed
// packet.
size_t last_written_packet_number_length_;
diff --git a/quic/core/quic_framer_test.cc b/quic/core/quic_framer_test.cc
index 02201b3..1ecd036 100644
--- a/quic/core/quic_framer_test.cc
+++ b/quic/core/quic_framer_test.cc
@@ -1476,7 +1476,9 @@
ASSERT_TRUE(visitor_.header_.get());
EXPECT_EQ(FramerTestConnectionId(),
visitor_.header_->destination_connection_id);
- EXPECT_EQ(TestConnectionId(0x33), visitor_.header_->source_connection_id);
+ if (!framer_.do_not_synthesize_source_cid_for_short_header()) {
+ EXPECT_EQ(TestConnectionId(0x33), visitor_.header_->source_connection_id);
+ }
}
// In short header packets from client to server, the client connection ID
@@ -1510,7 +1512,9 @@
ASSERT_TRUE(visitor_.header_.get());
EXPECT_EQ(FramerTestConnectionId(),
visitor_.header_->destination_connection_id);
- EXPECT_EQ(TestConnectionId(0x33), visitor_.header_->source_connection_id);
+ if (!framer_.do_not_synthesize_source_cid_for_short_header()) {
+ EXPECT_EQ(TestConnectionId(0x33), visitor_.header_->source_connection_id);
+ }
}
TEST_P(QuicFramerTest, PacketHeaderWith0ByteConnectionId) {
@@ -1560,7 +1564,9 @@
EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
EXPECT_THAT(framer_.error(), IsError(QUIC_MISSING_PAYLOAD));
ASSERT_TRUE(visitor_.header_.get());
- EXPECT_EQ(FramerTestConnectionId(), visitor_.header_->source_connection_id);
+ if (!framer_.do_not_synthesize_source_cid_for_short_header()) {
+ EXPECT_EQ(FramerTestConnectionId(), visitor_.header_->source_connection_id);
+ }
EXPECT_FALSE(visitor_.header_->reset_flag);
EXPECT_FALSE(visitor_.header_->version_flag);
EXPECT_EQ(kPacketNumber, visitor_.header_->packet_number);