gfe-relnote: In QUIC, add a helper function to get N consecutive retransmission timeout delay. Only affecting client, no functional change expected, not protected.
PiperOrigin-RevId: 302223043
Change-Id: Ib4a58463fd54de2835ef9c7d39b7b5f235c9e336
diff --git a/quic/core/quic_sent_packet_manager.cc b/quic/core/quic_sent_packet_manager.cc
index de43e39..4443bf6 100644
--- a/quic/core/quic_sent_packet_manager.cc
+++ b/quic/core/quic_sent_packet_manager.cc
@@ -1101,14 +1101,8 @@
}
const QuicTime::Delta QuicSentPacketManager::GetPathDegradingDelay() const {
- QuicTime::Delta delay = QuicTime::Delta::Zero();
- for (size_t i = 0; i < max_tail_loss_probes_; ++i) {
- delay = delay + GetTailLossProbeDelay(i);
- }
- for (size_t i = 0; i < kNumRetransmissionDelaysForPathDegradingDelay; ++i) {
- delay = delay + GetRetransmissionDelay(i);
- }
- return delay;
+ return GetNConsecutiveRetransmissionTimeoutDelay(
+ max_tail_loss_probes_ + kNumRetransmissionDelaysForPathDegradingDelay);
}
const QuicTime::Delta QuicSentPacketManager::GetCryptoRetransmissionDelay()
@@ -1130,10 +1124,9 @@
delay_ms << consecutive_crypto_retransmission_count_);
}
-const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay(
- size_t consecutive_tlp_count) const {
+const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay() const {
QuicTime::Delta srtt = rtt_stats_.SmoothedOrInitialRtt();
- if (enable_half_rtt_tail_loss_probe_ && consecutive_tlp_count == 0u) {
+ if (enable_half_rtt_tail_loss_probe_ && consecutive_tlp_count_ == 0u) {
if (unacked_packets().HasUnackedStreamData()) {
// Enable TLPR if there are pending data packets.
return std::max(min_tlp_timeout_, srtt * 0.5);
@@ -1148,8 +1141,7 @@
return std::max(min_tlp_timeout_, 2 * srtt);
}
-const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay(
- size_t consecutive_rto_count) const {
+const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay() const {
QuicTime::Delta retransmission_delay = QuicTime::Delta::Zero();
if (rtt_stats_.smoothed_rtt().IsZero()) {
// We are in the initial state, use default timeout values.
@@ -1166,7 +1158,7 @@
// Calculate exponential back off.
retransmission_delay =
retransmission_delay *
- (1 << std::min<size_t>(consecutive_rto_count, kMaxRetransmissions));
+ (1 << std::min<size_t>(consecutive_rto_count_, kMaxRetransmissions));
if (retransmission_delay.ToMilliseconds() > kMaxRetransmissionTimeMs) {
return QuicTime::Delta::FromMilliseconds(kMaxRetransmissionTimeMs);
@@ -1433,5 +1425,39 @@
decrypted_packet_level)];
}
+QuicTime::Delta
+QuicSentPacketManager::GetNConsecutiveRetransmissionTimeoutDelay(
+ int num_timeouts) const {
+ QuicTime::Delta total_delay = QuicTime::Delta::Zero();
+ const QuicTime::Delta srtt = rtt_stats_.SmoothedOrInitialRtt();
+ int num_tlps =
+ std::min(num_timeouts, static_cast<int>(max_tail_loss_probes_));
+ num_timeouts -= num_tlps;
+ if (num_tlps > 0) {
+ if (enable_half_rtt_tail_loss_probe_ &&
+ unacked_packets().HasUnackedStreamData()) {
+ total_delay = total_delay + std::max(min_tlp_timeout_, srtt * 0.5);
+ --num_tlps;
+ }
+ if (num_tlps > 0) {
+ const QuicTime::Delta tlp_delay =
+ std::max(2 * srtt, unacked_packets_.HasMultipleInFlightPackets()
+ ? min_tlp_timeout_
+ : (1.5 * srtt + (min_rto_timeout_ * 0.5)));
+ total_delay = total_delay + num_tlps * tlp_delay;
+ }
+ }
+ if (num_timeouts == 0) {
+ return total_delay;
+ }
+
+ const QuicTime::Delta retransmission_delay =
+ rtt_stats_.smoothed_rtt().IsZero()
+ ? QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs)
+ : std::max(srtt + 4 * rtt_stats_.mean_deviation(), min_rto_timeout_);
+ total_delay = total_delay + ((1 << num_timeouts) - 1) * retransmission_delay;
+ return total_delay;
+}
+
#undef ENDPOINT // undef for jumbo builds
} // namespace quic
diff --git a/quic/core/quic_sent_packet_manager.h b/quic/core/quic_sent_packet_manager.h
index 718c06d..8bff097 100644
--- a/quic/core/quic_sent_packet_manager.h
+++ b/quic/core/quic_sent_packet_manager.h
@@ -417,28 +417,13 @@
// Returns the timeout for retransmitting crypto handshake packets.
const QuicTime::Delta GetCryptoRetransmissionDelay() const;
- // Returns the timeout for a new tail loss probe. |consecutive_tlp_count| is
- // the number of consecutive tail loss probes that have already been sent.
- const QuicTime::Delta GetTailLossProbeDelay(
- size_t consecutive_tlp_count) const;
-
// Calls GetTailLossProbeDelay() with values from the current state of this
// packet manager as its params.
- const QuicTime::Delta GetTailLossProbeDelay() const {
- return GetTailLossProbeDelay(consecutive_tlp_count_);
- }
-
- // Returns the retransmission timeout, after which a full RTO occurs.
- // |consecutive_rto_count| is the number of consecutive RTOs that have already
- // occurred.
- const QuicTime::Delta GetRetransmissionDelay(
- size_t consecutive_rto_count) const;
+ const QuicTime::Delta GetTailLossProbeDelay() const;
// Calls GetRetransmissionDelay() with values from the current state of this
// packet manager as its params.
- const QuicTime::Delta GetRetransmissionDelay() const {
- return GetRetransmissionDelay(consecutive_rto_count_);
- }
+ const QuicTime::Delta GetRetransmissionDelay() const;
// Returns the probe timeout.
const QuicTime::Delta GetProbeTimeoutDelay() const;
@@ -520,6 +505,11 @@
// multiple packet number space is enabled.
bool ShouldArmPtoForApplicationData() const;
+ // A helper function to return total delay of |num_timeouts| retransmission
+ // timeout with TLP and RTO mode.
+ QuicTime::Delta GetNConsecutiveRetransmissionTimeoutDelay(
+ int num_timeouts) const;
+
// Newly serialized retransmittable packets are added to this map, which
// contains owning pointers to any contained frames. If a packet is
// retransmitted, this map will contain entries for both the old and the new
diff --git a/quic/core/quic_sent_packet_manager_test.cc b/quic/core/quic_sent_packet_manager_test.cc
index 93c36cd..19f5dd1 100644
--- a/quic/core/quic_sent_packet_manager_test.cc
+++ b/quic/core/quic_sent_packet_manager_test.cc
@@ -1659,8 +1659,6 @@
for (int i = 0; i < 5; ++i) {
EXPECT_EQ(delay,
QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
- EXPECT_EQ(delay,
- QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_, i));
delay = delay + delay;
EXPECT_CALL(notifier_, RetransmitFrames(_, _))
.WillOnce(WithArgs<1>(Invoke([this, i](TransmissionType type) {
@@ -1679,8 +1677,6 @@
EXPECT_EQ(QuicTime::Delta::FromSeconds(60),
QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
- EXPECT_EQ(QuicTime::Delta::FromSeconds(60),
- QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_, 0));
}
TEST_F(QuicSentPacketManagerTest, GetTransmissionDelayExponentialBackoff) {
@@ -1691,8 +1687,6 @@
for (int i = 0; i < 5; ++i) {
EXPECT_EQ(delay,
QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
- EXPECT_EQ(delay,
- QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_, i));
delay = delay + delay;
EXPECT_CALL(notifier_, RetransmitFrames(_, _))
.WillOnce(WithArgs<1>(Invoke([this, i](TransmissionType type) {
@@ -1717,8 +1711,6 @@
QuicTime::Delta::FromMilliseconds(kRttMs + kRttMs / 2 * 4);
EXPECT_EQ(expected_delay,
QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
- EXPECT_EQ(expected_delay,
- QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_, 0));
for (int i = 0; i < 100; ++i) {
// Run to make sure that we converge.
@@ -1736,8 +1728,6 @@
QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_)
.ToMilliseconds(),
1);
- EXPECT_EQ(QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_, 0),
- QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
}
TEST_F(QuicSentPacketManagerTest, GetLossDelay) {
@@ -1986,8 +1976,6 @@
// The TLP with fewer than 2 packets outstanding includes 1/2 min RTO(200ms).
EXPECT_EQ(QuicTime::Delta::FromMicroseconds(100002),
QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
- EXPECT_EQ(QuicTime::Delta::FromMicroseconds(100002),
- QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_, 0));
// Send two packets, and the TLP should be 1ms.
QuicTime::Delta expected_tlp_delay = QuicTime::Delta::FromMilliseconds(1);
@@ -1995,8 +1983,6 @@
SendDataPacket(2);
EXPECT_EQ(expected_tlp_delay,
QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
- EXPECT_EQ(expected_tlp_delay,
- QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_, 0));
}
TEST_F(QuicSentPacketManagerTest, NegotiateNoMinTLPFromOptionsAtClient) {
@@ -2019,16 +2005,12 @@
// The TLP with fewer than 2 packets outstanding includes 1/2 min RTO(200ms).
EXPECT_EQ(QuicTime::Delta::FromMicroseconds(100002),
QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
- EXPECT_EQ(QuicTime::Delta::FromMicroseconds(100002),
- QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_, 0));
// Send two packets, and the TLP should be 1ms.
QuicTime::Delta expected_tlp_delay = QuicTime::Delta::FromMilliseconds(1);
SendDataPacket(1);
SendDataPacket(2);
EXPECT_EQ(expected_tlp_delay,
QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
- EXPECT_EQ(expected_tlp_delay,
- QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_, 0));
}
TEST_F(QuicSentPacketManagerTest, NegotiateNoMinRTOFromOptionsAtServer) {
@@ -2047,14 +2029,10 @@
QuicTime::Delta expected_rto_delay = QuicTime::Delta::FromMilliseconds(1);
EXPECT_EQ(expected_rto_delay,
QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
- EXPECT_EQ(expected_rto_delay,
- QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_, 0));
// The TLP with fewer than 2 packets outstanding includes 1/2 min RTO(0ms).
QuicTime::Delta expected_tlp_delay = QuicTime::Delta::FromMicroseconds(502);
EXPECT_EQ(expected_tlp_delay,
QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
- EXPECT_EQ(expected_tlp_delay,
- QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_, 0));
}
TEST_F(QuicSentPacketManagerTest, NegotiateNoMinRTOFromOptionsAtClient) {
@@ -2074,14 +2052,10 @@
QuicTime::Delta expected_rto_delay = QuicTime::Delta::FromMilliseconds(1);
EXPECT_EQ(expected_rto_delay,
QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
- EXPECT_EQ(expected_rto_delay,
- QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_, 0));
// The TLP with fewer than 2 packets outstanding includes 1/2 min RTO(0ms).
QuicTime::Delta expected_tlp_delay = QuicTime::Delta::FromMicroseconds(502);
EXPECT_EQ(expected_tlp_delay,
QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
- EXPECT_EQ(expected_tlp_delay,
- QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_, 0));
}
TEST_F(QuicSentPacketManagerTest, NegotiateNoTLPFromOptionsAtServer) {
@@ -3759,6 +3733,49 @@
QuicSentPacketManagerPeer::UsePacketThresholdForRuntPackets(&manager_));
}
+TEST_F(QuicSentPacketManagerTest, GetPathDegradingDelay) {
+ QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
+ // Before RTT sample is available.
+ // 2 TLPs + 2 RTOs.
+ QuicTime::Delta expected_delay = QuicTime::Delta::Zero();
+ for (size_t i = 0; i < 2; ++i) {
+ QuicSentPacketManagerPeer::SetConsecutiveTlpCount(&manager_, i);
+ expected_delay =
+ expected_delay +
+ QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_);
+ }
+ for (size_t i = 0; i < 2; ++i) {
+ QuicSentPacketManagerPeer::SetConsecutiveRtoCount(&manager_, i);
+ expected_delay =
+ expected_delay +
+ QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_);
+ }
+ EXPECT_EQ(expected_delay, manager_.GetPathDegradingDelay());
+
+ expected_delay = QuicTime::Delta::Zero();
+ QuicSentPacketManagerPeer::SetConsecutiveTlpCount(&manager_, 0);
+ QuicSentPacketManagerPeer::SetConsecutiveRtoCount(&manager_, 0);
+
+ // After RTT sample is available.
+ RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+ rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+ QuicTime::Delta::Zero(), QuicTime::Zero());
+ // 2 TLPs + 2 RTOs.
+ for (size_t i = 0; i < 2; ++i) {
+ QuicSentPacketManagerPeer::SetConsecutiveTlpCount(&manager_, i);
+ expected_delay =
+ expected_delay +
+ QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_);
+ }
+ for (size_t i = 0; i < 2; ++i) {
+ QuicSentPacketManagerPeer::SetConsecutiveRtoCount(&manager_, i);
+ expected_delay =
+ expected_delay +
+ QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_);
+ }
+ EXPECT_EQ(expected_delay, manager_.GetPathDegradingDelay());
+}
+
} // namespace
} // namespace test
} // namespace quic
diff --git a/quic/test_tools/quic_sent_packet_manager_peer.cc b/quic/test_tools/quic_sent_packet_manager_peer.cc
index 9666145..f831898 100644
--- a/quic/test_tools/quic_sent_packet_manager_peer.cc
+++ b/quic/test_tools/quic_sent_packet_manager_peer.cc
@@ -102,26 +102,12 @@
// static
QuicTime::Delta QuicSentPacketManagerPeer::GetRetransmissionDelay(
- const QuicSentPacketManager* sent_packet_manager,
- size_t consecutive_rto_count) {
- return sent_packet_manager->GetRetransmissionDelay(consecutive_rto_count);
-}
-
-// static
-QuicTime::Delta QuicSentPacketManagerPeer::GetRetransmissionDelay(
const QuicSentPacketManager* sent_packet_manager) {
return sent_packet_manager->GetRetransmissionDelay();
}
// static
QuicTime::Delta QuicSentPacketManagerPeer::GetTailLossProbeDelay(
- const QuicSentPacketManager* sent_packet_manager,
- size_t consecutive_tlp_count) {
- return sent_packet_manager->GetTailLossProbeDelay(consecutive_tlp_count);
-}
-
-// static
-QuicTime::Delta QuicSentPacketManagerPeer::GetTailLossProbeDelay(
const QuicSentPacketManager* sent_packet_manager) {
return sent_packet_manager->GetTailLossProbeDelay();
}
diff --git a/quic/test_tools/quic_sent_packet_manager_peer.h b/quic/test_tools/quic_sent_packet_manager_peer.h
index aaa615b..d57c499 100644
--- a/quic/test_tools/quic_sent_packet_manager_peer.h
+++ b/quic/test_tools/quic_sent_packet_manager_peer.h
@@ -55,14 +55,8 @@
TransmissionType transmission_type);
static QuicTime::Delta GetRetransmissionDelay(
- const QuicSentPacketManager* sent_packet_manager,
- size_t consecutive_rto_count);
- static QuicTime::Delta GetRetransmissionDelay(
const QuicSentPacketManager* sent_packet_manager);
static QuicTime::Delta GetTailLossProbeDelay(
- const QuicSentPacketManager* sent_packet_manager,
- size_t consecutive_tlp_count);
- static QuicTime::Delta GetTailLossProbeDelay(
const QuicSentPacketManager* sent_packet_manager);
static size_t GetNumRetransmittablePackets(