gfe-relnote: In QUIC, when RTO fires and there is no packet to be RTOed, let connection send data. Protected by gfe2_reloadable_flag_quic_fix_rto_retransmission2 which replaces gfe2_reloadable_flag_quic_fix_rto_retransmission.

This fix only applies for version > 39.

PiperOrigin-RevId: 262347120
Change-Id: Ic164c2f9e7117c3f9af43f1f1a3e8b369d8a3052
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index 39d2760..26c70f1 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -4159,25 +4159,25 @@
   // Simulate the retransmission alarm firing.
   clock_.AdvanceTime(DefaultRetransmissionTime());
   // RTO fires, but there is no packet to be RTOed.
-  if (GetQuicReloadableFlag(quic_fix_rto_retransmission)) {
+  if (GetQuicReloadableFlag(quic_fix_rto_retransmission2)) {
     EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
   } else {
     EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
   }
   connection_.GetRetransmissionAlarm()->Fire();
-  if (GetQuicReloadableFlag(quic_fix_rto_retransmission)) {
+  if (GetQuicReloadableFlag(quic_fix_rto_retransmission2)) {
     EXPECT_EQ(1u, writer_->rst_stream_frames().size());
   }
 
   EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(40);
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(20);
-  if (GetQuicReloadableFlag(quic_fix_rto_retransmission)) {
+  if (GetQuicReloadableFlag(quic_fix_rto_retransmission2)) {
     EXPECT_CALL(visitor_, WillingAndAbleToWrite())
         .WillRepeatedly(Return(false));
   } else {
     EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillRepeatedly(Return(true));
   }
-  if (GetQuicReloadableFlag(quic_fix_rto_retransmission)) {
+  if (GetQuicReloadableFlag(quic_fix_rto_retransmission2)) {
     EXPECT_CALL(visitor_, OnAckNeedsRetransmittableFrame()).Times(1);
   } else {
     // Since there is a buffered RST_STREAM, no retransmittable frame is bundled
@@ -8685,6 +8685,62 @@
   EXPECT_TRUE(connection_.connected());
 }
 
+// Regresstion test for b/138962304.
+TEST_P(QuicConnectionTest, RtoAndWriteBlocked) {
+  if (!QuicConnectionPeer::GetSentPacketManager(&connection_)
+           ->fix_rto_retransmission()) {
+    return;
+  }
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  QuicStreamId stream_id = 2;
+  QuicPacketNumber last_data_packet;
+  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_data_packet);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Writer gets blocked.
+  writer_->SetWriteBlocked();
+
+  // Cancel the stream.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AtLeast(1));
+  SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 3);
+
+  // Retransmission timer fires in RTO mode.
+  connection_.GetRetransmissionAlarm()->Fire();
+  // Verify no packets get flushed when writer is blocked.
+  EXPECT_EQ(0u, connection_.NumQueuedPackets());
+}
+
+// Regresstion test for b/138962304.
+TEST_P(QuicConnectionTest, TlpAndWriteBlocked) {
+  if (!QuicConnectionPeer::GetSentPacketManager(&connection_)
+           ->fix_rto_retransmission()) {
+    return;
+  }
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+  connection_.SetMaxTailLossProbes(1);
+
+  QuicStreamId stream_id = 2;
+  QuicPacketNumber last_data_packet;
+  SendStreamDataToPeer(stream_id, "foo", 0, NO_FIN, &last_data_packet);
+  SendStreamDataToPeer(4, "foo", 0, NO_FIN, &last_data_packet);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Writer gets blocked.
+  writer_->SetWriteBlocked();
+
+  // Cancel stream 2.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AtLeast(1));
+  SendRstStream(stream_id, QUIC_ERROR_PROCESSING_STREAM, 3);
+
+  // Retransmission timer fires in TLP mode.
+  connection_.GetRetransmissionAlarm()->Fire();
+  // Verify one packets is forced flushed when writer is blocked.
+  EXPECT_EQ(1u, connection_.NumQueuedPackets());
+}
+
 }  // namespace
 }  // namespace test
 }  // namespace quic