gfe-relnote: In QUIC, add exponential backoff for PTO timeout when there is not RTT measurement. Protected by gfe2_reloadable_flag_quic_enable_version_draft_25_v3 and gfe2_reloadable_flag_quic_enable_version_draft_27.
Also change PTO timeout from 2 * initial_rtt to 3 * initial_rtt.
PiperOrigin-RevId: 308102591
Change-Id: If44e9e7f6107b7a95650e5f4744ea847d2b998d2
diff --git a/quic/core/quic_sent_packet_manager_test.cc b/quic/core/quic_sent_packet_manager_test.cc
index e846058..e63a9b8 100644
--- a/quic/core/quic_sent_packet_manager_test.cc
+++ b/quic/core/quic_sent_packet_manager_test.cc
@@ -3772,6 +3772,59 @@
EXPECT_EQ(expected_delay, manager_.GetPathDegradingDelay());
}
+// Regression test for b/154050235.
+TEST_F(QuicSentPacketManagerTest, ExponentialBackoffWithNoRttMeasurement) {
+ QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+ manager_.EnableIetfPtoAndLossDetection();
+ RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+ EXPECT_EQ(QuicTime::Delta::FromMilliseconds(kInitialRttMs),
+ rtt_stats->initial_rtt());
+ EXPECT_TRUE(rtt_stats->smoothed_rtt().IsZero());
+
+ SendCryptoPacket(1);
+ QuicTime::Delta expected_pto_delay =
+ QuicTime::Delta::FromMilliseconds(3 * kInitialRttMs);
+ EXPECT_EQ(clock_.Now() + expected_pto_delay,
+ manager_.GetRetransmissionTime());
+
+ // Invoke PTO.
+ clock_.AdvanceTime(expected_pto_delay);
+ manager_.OnRetransmissionTimeout();
+
+ EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+ .WillOnce(WithArgs<1>(Invoke([this]() { RetransmitCryptoPacket(3); })));
+ manager_.MaybeSendProbePackets();
+ // Verify exponential backoff of the PTO timeout.
+ EXPECT_EQ(clock_.Now() + 2 * expected_pto_delay,
+ manager_.GetRetransmissionTime());
+}
+
+TEST_F(QuicSentPacketManagerTest, PtoDelayWithTinyInitialRtt) {
+ manager_.EnableIetfPtoAndLossDetection();
+ RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+ // Assume client provided a tiny initial RTT.
+ rtt_stats->set_initial_rtt(QuicTime::Delta::FromMicroseconds(1));
+ EXPECT_EQ(QuicTime::Delta::FromMicroseconds(1), rtt_stats->initial_rtt());
+ EXPECT_TRUE(rtt_stats->smoothed_rtt().IsZero());
+
+ SendCryptoPacket(1);
+ QuicTime::Delta expected_pto_delay = QuicTime::Delta::FromMilliseconds(10);
+ // Verify kMinHandshakeTimeoutMs is respected.
+ EXPECT_EQ(clock_.Now() + expected_pto_delay,
+ manager_.GetRetransmissionTime());
+
+ // Invoke PTO.
+ clock_.AdvanceTime(expected_pto_delay);
+ manager_.OnRetransmissionTimeout();
+
+ EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+ .WillOnce(WithArgs<1>(Invoke([this]() { RetransmitCryptoPacket(3); })));
+ manager_.MaybeSendProbePackets();
+ // Verify exponential backoff of the PTO timeout.
+ EXPECT_EQ(clock_.Now() + 2 * expected_pto_delay,
+ manager_.GetRetransmissionTime());
+}
+
} // namespace
} // namespace test
} // namespace quic