gfe-relnote: Replace the usage of ConnectionData::encryption_level in quic_time_wait_list_manager with a new TimeWaitAction SEND_CONNECTION_CLOSE_PACKETS. Protected by gfe2_restart_flag_replace_time_wait_list_encryption_level.
ConnectionData::encryption_level can be deprecated after this change.
PiperOrigin-RevId: 308152741
Change-Id: I877573f632b8c99fc740f803252fa9c6f5a08f79
diff --git a/quic/core/quic_dispatcher.cc b/quic/core/quic_dispatcher.cc
index 36932c3..18b6e56 100644
--- a/quic/core/quic_dispatcher.cc
+++ b/quic/core/quic_dispatcher.cc
@@ -591,7 +591,11 @@
QuicTimeWaitListManager::SEND_STATELESS_RESET;
if (connection->termination_packets() != nullptr &&
!connection->termination_packets()->empty()) {
- action = QuicTimeWaitListManager::SEND_TERMINATION_PACKETS;
+ if (GetQuicRestartFlag(quic_replace_time_wait_list_encryption_level)) {
+ action = QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS;
+ } else {
+ action = QuicTimeWaitListManager::SEND_TERMINATION_PACKETS;
+ }
} else {
if (!connection->IsHandshakeComplete()) {
if (!VersionHasIetfInvariantHeader(connection->transport_version())) {
diff --git a/quic/core/quic_time_wait_list_manager.cc b/quic/core/quic_time_wait_list_manager.cc
index 2b0c267..433a3ab 100644
--- a/quic/core/quic_time_wait_list_manager.cc
+++ b/quic/core/quic_time_wait_list_manager.cc
@@ -162,12 +162,13 @@
if (!connection_data->ietf_quic) {
QUIC_CODE_COUNT(quic_received_short_header_packet_for_gquic);
}
- if (connection_data->encryption_level == ENCRYPTION_INITIAL) {
+ if (GetQuicRestartFlag(
+ quic_replace_time_wait_list_encryption_level) ||
+ connection_data->encryption_level == ENCRYPTION_INITIAL) {
+ // TODO(b/153096082) Rename this code count.
QUIC_CODE_COUNT(
quic_encryption_none_termination_packets_for_short_header);
- // Send stateless reset in response to short header packets,
- // because ENCRYPTION_INITIAL termination packets will not be
- // processed by clients.
+ // Send stateless reset in response to short header packets.
SendPublicReset(self_address, peer_address, connection_id,
connection_data->ietf_quic,
std::move(packet_context));
@@ -190,6 +191,19 @@
packet_context.get());
}
return;
+
+ case SEND_CONNECTION_CLOSE_PACKETS:
+ if (connection_data->termination_packets.empty()) {
+ QUIC_BUG << "There are no termination packets.";
+ return;
+ }
+ for (const auto& packet : connection_data->termination_packets) {
+ SendOrQueuePacket(std::make_unique<QueuedPacket>(
+ self_address, peer_address, packet->Clone()),
+ packet_context.get());
+ }
+ return;
+
case SEND_STATELESS_RESET:
if (header_format == IETF_QUIC_LONG_HEADER_PACKET) {
QUIC_CODE_COUNT(quic_stateless_reset_long_header_packet);
diff --git a/quic/core/quic_time_wait_list_manager.h b/quic/core/quic_time_wait_list_manager.h
index c9a5261..64138de 100644
--- a/quic/core/quic_time_wait_list_manager.h
+++ b/quic/core/quic_time_wait_list_manager.h
@@ -44,6 +44,9 @@
// Send specified termination packets, error if termination packet is
// unavailable.
SEND_TERMINATION_PACKETS,
+ // The same as SEND_TERMINATION_PACKETS except that the corresponding
+ // termination packets are provided by the connection.
+ SEND_CONNECTION_CLOSE_PACKETS,
// Send stateless reset (public reset for GQUIC).
SEND_STATELESS_RESET,
@@ -244,6 +247,7 @@
int num_packets;
bool ietf_quic;
QuicTime time_added;
+ // TODO(b/153096082) Remove this field.
// Encryption level of termination_packets.
EncryptionLevel encryption_level;
// These packets may contain CONNECTION_CLOSE frames, or SREJ messages.
diff --git a/quic/core/quic_time_wait_list_manager_test.cc b/quic/core/quic_time_wait_list_manager_test.cc
index b07c83e..9e09a80 100644
--- a/quic/core/quic_time_wait_list_manager_test.cc
+++ b/quic/core/quic_time_wait_list_manager_test.cc
@@ -322,9 +322,12 @@
termination_packets.push_back(
std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
new char[kConnectionCloseLength], kConnectionCloseLength, true)));
- AddConnectionId(connection_id_, QuicVersionMax(),
- QuicTimeWaitListManager::SEND_TERMINATION_PACKETS,
- &termination_packets);
+ AddConnectionId(
+ connection_id_, QuicVersionMax(),
+ GetQuicRestartFlag(quic_replace_time_wait_list_encryption_level)
+ ? QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS
+ : QuicTimeWaitListManager::SEND_TERMINATION_PACKETS,
+ &termination_packets);
EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
self_address_.host(), peer_address_, _))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
@@ -342,9 +345,12 @@
termination_packets.push_back(
std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
new char[kConnectionCloseLength], kConnectionCloseLength, true)));
- AddConnectionId(connection_id_, QuicVersionMax(),
- QuicTimeWaitListManager::SEND_TERMINATION_PACKETS,
- &termination_packets);
+ AddConnectionId(
+ connection_id_, QuicVersionMax(),
+ GetQuicRestartFlag(quic_replace_time_wait_list_encryption_level)
+ ? QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS
+ : QuicTimeWaitListManager::SEND_TERMINATION_PACKETS,
+ &termination_packets);
EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
self_address_.host(), peer_address_, _))
.Times(2)
@@ -646,6 +652,30 @@
IETF_QUIC_SHORT_HEADER_PACKET, std::make_unique<QuicPerPacketContext>());
}
+TEST_F(QuicTimeWaitListManagerTest,
+ SendConnectionClosePacketsInResponseToShortHeaders) {
+ SetQuicRestartFlag(quic_replace_time_wait_list_encryption_level, true);
+ const size_t kConnectionCloseLength = 100;
+ EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id_));
+ std::vector<std::unique_ptr<QuicEncryptedPacket>> termination_packets;
+ termination_packets.push_back(
+ std::unique_ptr<QuicEncryptedPacket>(new QuicEncryptedPacket(
+ new char[kConnectionCloseLength], kConnectionCloseLength, true)));
+ // Add a CONNECTION_CLOSE termination packet.
+ time_wait_list_manager_.AddConnectionIdToTimeWait(
+ connection_id_, /*ietf_quic=*/true,
+ QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS,
+ ENCRYPTION_INITIAL, &termination_packets);
+ EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
+ self_address_.host(), peer_address_, _))
+ .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
+
+ // Processes IETF short header packet.
+ time_wait_list_manager_.ProcessPacket(
+ self_address_, peer_address_, connection_id_,
+ IETF_QUIC_SHORT_HEADER_PACKET, std::make_unique<QuicPerPacketContext>());
+}
+
} // namespace
} // namespace test
} // namespace quic