Neuter initial packet in the coalescer when discarding initial keys.
PiperOrigin-RevId: 328808677
Change-Id: I34a3dbc33c52146fb88d65c60cdfc5ca8bcf1cf7
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index e4cc987..7133bab 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -11880,6 +11880,45 @@
EXPECT_EQ(clock_.Now() + timeout, connection_.GetTimeoutAlarm()->deadline());
}
+// Regression test for b/166255274
+TEST_P(QuicConnectionTest,
+ ReserializeInitialPacketInCoalescerAfterDiscardingInitialKey) {
+ SetQuicReloadableFlag(
+ quic_neuter_initial_packet_in_coalescer_with_initial_key_discarded, true);
+ if (!connection_.version().CanSendCoalescedPackets()) {
+ return;
+ }
+ use_tagging_decrypter();
+ connection_.SetEncrypter(ENCRYPTION_INITIAL,
+ std::make_unique<TaggingEncrypter>(0x01));
+ connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+ EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
+ ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+ EXPECT_TRUE(connection_.HasPendingAcks());
+ connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+ std::make_unique<TaggingEncrypter>(0x02));
+ connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+ {
+ QuicConnection::ScopedPacketFlusher flusher(&connection_);
+ connection_.GetAckAlarm()->Fire();
+ // Verify this ACK packet is on hold.
+ EXPECT_EQ(0u, writer_->packets_write_attempts());
+
+ // Discard INITIAL key while there is an INITIAL packet in the coalescer.
+ connection_.RemoveEncrypter(ENCRYPTION_INITIAL);
+ connection_.NeuterUnencryptedPackets();
+ }
+ // If not setting
+ // quic_neuter_initial_packet_in_coalescer_with_initial_key_discarded, there
+ // will be pending frames in the creator.
+ EXPECT_FALSE(connection_.packet_creator().HasPendingFrames());
+ // The ACK frame is deleted along with initial_packet_ in coalescer. Sending
+ // connection close would cause this (released) ACK frame be serialized (and
+ // crashes).
+ EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
+ ProcessDataPacketAtLevel(1000, false, ENCRYPTION_FORWARD_SECURE);
+}
+
} // namespace
} // namespace test
} // namespace quic