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