Make sure MaybeCoalescePacketOfHigherSpace is not re-entrant to avoid infinite loop. Protected by gfe2_reloadable_flag_quic_coalesced_packet_of_higher_space2 which replaces gfe2_reloadable_flag_quic_coalesced_packet_of_higher_space.

PiperOrigin-RevId: 323822656
Change-Id: Ie651e714ced763fb7041d8e3737ae241478691bd
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index 5db917f..5f1ff0c 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -10444,7 +10444,7 @@
                            _, _));
   EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
   connection_.GetRetransmissionAlarm()->Fire();
-  if (GetQuicReloadableFlag(quic_coalesced_packet_of_higher_space)) {
+  if (GetQuicReloadableFlag(quic_coalesced_packet_of_higher_space2)) {
     // Verify 1-RTT packet gets coalesced with handshake retransmission.
     EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
   } else {
@@ -10463,7 +10463,7 @@
   QuicPacketNumber handshake_retransmission =
       GetQuicReloadableFlag(quic_default_on_pto) ? QuicPacketNumber(5)
                                                  : QuicPacketNumber(7);
-  if (GetQuicReloadableFlag(quic_coalesced_packet_of_higher_space)) {
+  if (GetQuicReloadableFlag(quic_coalesced_packet_of_higher_space2)) {
     handshake_retransmission += 1;
     EXPECT_CALL(*send_algorithm_,
                 OnPacketSent(_, _, handshake_retransmission + 1, _, _));
@@ -10472,7 +10472,7 @@
               OnPacketSent(_, _, handshake_retransmission, _, _));
   EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
   connection_.GetRetransmissionAlarm()->Fire();
-  if (GetQuicReloadableFlag(quic_coalesced_packet_of_higher_space)) {
+  if (GetQuicReloadableFlag(quic_coalesced_packet_of_higher_space2)) {
     // Verify 1-RTT packet gets coalesced with handshake retransmission.
     EXPECT_EQ(0x01010101u, writer_->final_bytes_of_last_packet());
   } else {
@@ -10489,7 +10489,7 @@
   QuicPacketNumber application_retransmission =
       GetQuicReloadableFlag(quic_default_on_pto) ? QuicPacketNumber(6)
                                                  : QuicPacketNumber(9);
-  if (GetQuicReloadableFlag(quic_coalesced_packet_of_higher_space)) {
+  if (GetQuicReloadableFlag(quic_coalesced_packet_of_higher_space2)) {
     application_retransmission += 2;
   }
   EXPECT_CALL(*send_algorithm_,
@@ -11268,7 +11268,7 @@
   connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
                            std::make_unique<TaggingEncrypter>(0x02));
   connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
-  if (GetQuicReloadableFlag(quic_coalesced_packet_of_higher_space)) {
+  if (GetQuicReloadableFlag(quic_coalesced_packet_of_higher_space2)) {
     EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(2);
   } else {
     EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
@@ -11445,7 +11445,7 @@
   connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
                            std::make_unique<TaggingEncrypter>(0x02));
   connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
-  if (GetQuicReloadableFlag(quic_coalesced_packet_of_higher_space)) {
+  if (GetQuicReloadableFlag(quic_coalesced_packet_of_higher_space2)) {
     // Verify HANDSHAKE packet is coalesced with INITIAL retransmission.
     EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(2);
   } else {
@@ -11475,7 +11475,7 @@
   // Because retransmitted INITIAL gets received so HANDSHAKE 2 gets processed.
   frames.clear();
   QuicAckFrame ack_frame2;
-  if (GetQuicReloadableFlag(quic_coalesced_packet_of_higher_space)) {
+  if (GetQuicReloadableFlag(quic_coalesced_packet_of_higher_space2)) {
     // HANDSHAKE 5 is also processed.
     ack_frame2 = InitAckFrame(
         {{QuicPacketNumber(2), QuicPacketNumber(3)},
@@ -11486,7 +11486,7 @@
   ack_frame2.ack_delay_time = QuicTime::Delta::Zero();
   frames.push_back(QuicFrame(&ack_frame2));
   ProcessFramesPacketAtLevel(1, frames, ENCRYPTION_HANDSHAKE);
-  if (GetQuicReloadableFlag(quic_coalesced_packet_of_higher_space)) {
+  if (GetQuicReloadableFlag(quic_coalesced_packet_of_higher_space2)) {
     // Verify RTT inflation gets mitigated.
     EXPECT_EQ(rtt_stats->latest_rtt(), kTestRTT);
   } else {
@@ -11496,6 +11496,57 @@
   }
 }
 
+// Regression test for b/161228202
+TEST_P(QuicConnectionTest, CoalscingPacketCausesInfiniteLoop) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  set_perspective(Perspective::IS_SERVER);
+  use_tagging_decrypter();
+  // Receives packet 1000 in initial data.
+  if (QuicVersionUsesCryptoFrames(connection_.transport_version())) {
+    EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+  }
+  EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
+
+  // Set anti amplification factor to 2, such that RetransmitDataOfSpaceIfAny
+  // makes no forward progress and causes infinite loop.
+  SetQuicFlag(FLAGS_quic_anti_amplification_factor, 2);
+
+  ProcessCryptoPacketAtLevel(1000, ENCRYPTION_INITIAL);
+  EXPECT_TRUE(connection_.HasPendingAcks());
+
+  connection_.SetEncrypter(ENCRYPTION_INITIAL,
+                           std::make_unique<TaggingEncrypter>(0x01));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL);
+  // Send INITIAL 1.
+  std::string initial_crypto_data(512, 'a');
+  connection_.SendCryptoDataWithString(initial_crypto_data, 0,
+                                       ENCRYPTION_INITIAL);
+  ASSERT_TRUE(connection_.sent_packet_manager()
+                  .GetRetransmissionTime()
+                  .IsInitialized());
+  QuicTime::Delta pto_timeout =
+      connection_.sent_packet_manager().GetRetransmissionTime() - clock_.Now();
+  // Send Handshake 2.
+  connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
+                           std::make_unique<TaggingEncrypter>(0x02));
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+  if (GetQuicReloadableFlag(quic_coalesced_packet_of_higher_space2)) {
+    // Verify HANDSHAKE packet is coalesced with INITIAL retransmission.
+    EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(2);
+  } else {
+    EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
+  }
+  std::string handshake_crypto_data(1024, 'a');
+  connection_.SendCryptoDataWithString(handshake_crypto_data, 0,
+                                       ENCRYPTION_HANDSHAKE);
+
+  // INITIAL 1 gets lost and PTO fires.
+  clock_.AdvanceTime(pto_timeout);
+  connection_.GetRetransmissionAlarm()->Fire();
+}
+
 }  // namespace
 }  // namespace test
 }  // namespace quic