QuicDispatcher discards packets with known version but invalid destination connection ID.
Protected by FLAGS_quic_reloadable_flag_quic_discard_packets_with_invalid_cid.
PiperOrigin-RevId: 371762573
Change-Id: Ie34e797be1c97d7fa38b5f68b56c1b5875e7d378
diff --git a/quic/core/quic_dispatcher.cc b/quic/core/quic_dispatcher.cc
index 1c9c763..ccf2c3f 100644
--- a/quic/core/quic_dispatcher.cc
+++ b/quic/core/quic_dispatcher.cc
@@ -502,6 +502,21 @@
return true;
}
+ if (GetQuicReloadableFlag(quic_discard_packets_with_invalid_cid)) {
+ QUIC_RELOADABLE_FLAG_COUNT(quic_discard_packets_with_invalid_cid);
+ if (packet_info.version_flag && packet_info.version.IsKnown() &&
+ !QuicUtils::IsConnectionIdLengthValidForVersion(
+ server_connection_id.length(),
+ packet_info.version.transport_version)) {
+ QUIC_DLOG(INFO) << "Packet with destination connection ID "
+ << server_connection_id << " is invalid with version "
+ << packet_info.version;
+ // Drop the packet silently.
+ QUIC_CODE_COUNT(quic_dropped_invalid_initial_connection_id);
+ return true;
+ }
+ }
+
// Packets with connection IDs for active connections are processed
// immediately.
auto it = reference_counted_session_map_.find(server_connection_id);
diff --git a/quic/core/quic_dispatcher_test.cc b/quic/core/quic_dispatcher_test.cc
index d113844..5a7a709 100644
--- a/quic/core/quic_dispatcher_test.cc
+++ b/quic/core/quic_dispatcher_test.cc
@@ -167,6 +167,7 @@
std::string custom_packet_context_;
+ using QuicDispatcher::MaybeDispatchPacket;
using QuicDispatcher::SetAllowShortInitialServerConnectionIds;
using QuicDispatcher::writer;
@@ -1101,6 +1102,31 @@
ProcessFirstFlight(client_address, EmptyQuicConnectionId());
}
+TEST_P(QuicDispatcherTestAllVersions,
+ DropPacketWithKnownVersionAndInvalidInitialConnectionId) {
+ SetQuicReloadableFlag(quic_discard_packets_with_invalid_cid, true);
+ CreateTimeWaitListManager();
+
+ QuicSocketAddress server_address;
+ QuicSocketAddress client_address(QuicIpAddress::Loopback4(), 1);
+
+ // dispatcher_ should drop this packet with invalid connection ID.
+ EXPECT_CALL(*dispatcher_, CreateQuicSession(_, _, _, _, _, _)).Times(0);
+ EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, _, _, _, _))
+ .Times(0);
+ EXPECT_CALL(*time_wait_list_manager_, AddConnectionIdToTimeWait(_, _, _))
+ .Times(0);
+ absl::string_view cid_str = "123456789abcdefg123456789abcdefg";
+ QuicConnectionId invalid_connection_id(cid_str.data(), cid_str.length());
+ QuicReceivedPacket packet("packet", 6, QuicTime::Zero());
+ ReceivedPacketInfo packet_info(server_address, client_address, packet);
+ packet_info.version_flag = true;
+ packet_info.version = version_;
+ packet_info.destination_connection_id = invalid_connection_id;
+
+ ASSERT_TRUE(dispatcher_->MaybeDispatchPacket(packet_info));
+}
+
void QuicDispatcherTestBase::
TestVersionNegotiationForUnknownVersionInvalidShortInitialConnectionId(
const QuicConnectionId& server_connection_id,
diff --git a/quic/core/quic_flags_list.h b/quic/core/quic_flags_list.h
index 023e6a4..b5b0abe 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_discard_packets_with_invalid_cid, false)
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_donot_pto_half_rtt_data, false)
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_donot_reset_ideal_next_packet_send_time, false)
QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_donot_write_mid_packet_processing, true)