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(