gfe-relnote: Do not flush clear coalesced packets while sending multiple connection close packets. Protected by --gfe2_reloadable_flag_quic_close_all_encryptions_levels2
PiperOrigin-RevId: 282844268
Change-Id: I005056ad594f776a9a36198d012f7169737622b3
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index 0c6c542..37d3d36 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -337,6 +337,7 @@
final_bytes_of_previous_packet_(0),
use_tagging_decrypter_(false),
packets_write_attempts_(0),
+ connection_close_packets_(0),
clock_(clock),
write_pause_time_delta_(QuicTime::Delta::Zero()),
max_packet_size_(kMaxOutgoingPacketSize),
@@ -405,7 +406,9 @@
last_packet_size_ = packet.length();
last_packet_header_ = framer_.header();
-
+ if (!framer_.connection_close_frames().empty()) {
+ ++connection_close_packets_;
+ }
if (!write_pause_time_delta_.IsZero()) {
clock_->AdvanceTime(write_pause_time_delta_);
}
@@ -553,6 +556,10 @@
uint32_t packets_write_attempts() { return packets_write_attempts_; }
+ uint32_t connection_close_packets() const {
+ return connection_close_packets_;
+ }
+
void Reset() { framer_.Reset(); }
void SetSupportedVersions(const ParsedQuicVersionVector& versions) {
@@ -586,6 +593,7 @@
uint32_t final_bytes_of_previous_packet_;
bool use_tagging_decrypter_;
uint32_t packets_write_attempts_;
+ uint32_t connection_close_packets_;
MockClock* clock_;
// If non-zero, the clock will pause during WritePacket for this amount of
// time.
@@ -8044,7 +8052,7 @@
ProcessAckPacket(&ack);
}
-TEST_P(QuicConnectionTest, DonotForceSendingAckOnPacketTooLarge) {
+TEST_P(QuicConnectionTest, DoNotForceSendingAckOnPacketTooLarge) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
// Send an ack by simulating delayed ack alarm firing.
ProcessPacket(1);
@@ -8055,13 +8063,74 @@
EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
SimulateNextPacketTooLarge();
connection_.SendStreamDataWithString(3, "foo", 0, NO_FIN);
- EXPECT_EQ(1u, writer_->frame_count());
- EXPECT_FALSE(writer_->connection_close_frames().empty());
+ EXPECT_EQ(1u, writer_->connection_close_frames().size());
// Ack frame is not bundled in connection close packet.
EXPECT_TRUE(writer_->ack_frames().empty());
+ if (writer_->padding_frames().empty()) {
+ EXPECT_EQ(1u, writer_->frame_count());
+ } else {
+ EXPECT_EQ(2u, writer_->frame_count());
+ }
+
TestConnectionCloseQuicErrorCode(QUIC_PACKET_WRITE_ERROR);
}
+TEST_P(QuicConnectionTest, CloseConnectionAllLevels) {
+ SetQuicReloadableFlag(quic_close_all_encryptions_levels2, true);
+
+ EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+ const QuicErrorCode kQuicErrorCode = QUIC_INTERNAL_ERROR;
+ connection_.CloseConnection(
+ kQuicErrorCode, "Some random error message",
+ ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+
+ EXPECT_EQ(2u, QuicConnectionPeer::GetNumEncryptionLevels(&connection_));
+
+ TestConnectionCloseQuicErrorCode(kQuicErrorCode);
+ EXPECT_EQ(1u, writer_->connection_close_frames().size());
+
+ if (!connection_.version().CanSendCoalescedPackets()) {
+ // Each connection close packet should be sent in distinct UDP packets.
+ EXPECT_EQ(QuicConnectionPeer::GetNumEncryptionLevels(&connection_),
+ writer_->connection_close_packets());
+ EXPECT_EQ(QuicConnectionPeer::GetNumEncryptionLevels(&connection_),
+ writer_->packets_write_attempts());
+ return;
+ }
+
+ // A single UDP packet should be sent with multiple connection close packets
+ // coalesced together.
+ EXPECT_EQ(1u, writer_->packets_write_attempts());
+
+ // Only the first packet has been processed yet.
+ EXPECT_EQ(1u, writer_->connection_close_packets());
+
+ // ProcessPacket resets the visitor and frees the coalesced packet.
+ ASSERT_TRUE(writer_->coalesced_packet() != nullptr);
+ auto packet = writer_->coalesced_packet()->Clone();
+ writer_->framer()->ProcessPacket(*packet);
+ EXPECT_EQ(1u, writer_->connection_close_packets());
+ ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
+}
+
+TEST_P(QuicConnectionTest, CloseConnectionOneLevel) {
+ SetQuicReloadableFlag(quic_close_all_encryptions_levels2, false);
+
+ EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
+ const QuicErrorCode kQuicErrorCode = QUIC_INTERNAL_ERROR;
+ connection_.CloseConnection(
+ kQuicErrorCode, "Some random error message",
+ ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+
+ EXPECT_EQ(2u, QuicConnectionPeer::GetNumEncryptionLevels(&connection_));
+
+ TestConnectionCloseQuicErrorCode(kQuicErrorCode);
+ EXPECT_EQ(1u, writer_->connection_close_frames().size());
+ EXPECT_EQ(1u, writer_->connection_close_packets());
+ EXPECT_EQ(1u, writer_->packets_write_attempts());
+ ASSERT_TRUE(writer_->coalesced_packet() == nullptr);
+}
+
// Regression test for b/63620844.
TEST_P(QuicConnectionTest, FailedToWriteHandshakePacket) {
SimulateNextPacketTooLarge();