In quic, add a connection option to enable more aggressive pto timeout before any rtt sample is available. not protected. PiperOrigin-RevId: 317280920 Change-Id: Ia607d240d11d3365eef0518c76fb9d5e86c1d55e
diff --git a/quic/core/crypto/crypto_protocol.h b/quic/core/crypto/crypto_protocol.h index fc7d363..c178aa2 100644 --- a/quic/core/crypto/crypto_protocol.h +++ b/quic/core/crypto/crypto_protocol.h
@@ -233,6 +233,8 @@ // earliest in flight sent time // and at least 1.5*srtt from // last sent packet. +const QuicTag kAPTO = TAG('A', 'P', 'T', 'O'); // Use 1.5 * initial RTT before + // any RTT sample is available. const QuicTag kELDT = TAG('E', 'L', 'D', 'T'); // Enable Loss Detection Tuning
diff --git a/quic/core/quic_sent_packet_manager.cc b/quic/core/quic_sent_packet_manager.cc index d74a487..eeeddf2 100644 --- a/quic/core/quic_sent_packet_manager.cc +++ b/quic/core/quic_sent_packet_manager.cc
@@ -107,7 +107,8 @@ one_rtt_packet_acked_(false), one_rtt_packet_sent_(false), first_pto_srtt_multiplier_(0), - use_standard_deviation_for_pto_(false) { + use_standard_deviation_for_pto_(false), + pto_multiplier_without_rtt_samples_(3) { SetSendAlgorithm(congestion_control_type); if (pto_enabled_) { QUIC_RELOADABLE_FLAG_COUNT_N(quic_default_on_pto, 1, 2); @@ -197,6 +198,9 @@ } else if (config.HasClientSentConnectionOption(kPLE2, perspective)) { first_pto_srtt_multiplier_ = 1.5; } + if (config.HasClientSentConnectionOption(kAPTO, perspective)) { + pto_multiplier_without_rtt_samples_ = 1.5; + } if (config.HasClientSentConnectionOption(kPSDA, perspective)) { use_standard_deviation_for_pto_ = true; rtt_stats_.EnableStandardDeviationCalculation(); @@ -1230,8 +1234,9 @@ if (rtt_stats_.smoothed_rtt().IsZero()) { // Respect kMinHandshakeTimeoutMs to avoid a potential amplification attack. QUIC_BUG_IF(rtt_stats_.initial_rtt().IsZero()); - return std::max(3 * rtt_stats_.initial_rtt(), - QuicTime::Delta::FromMilliseconds(kMinHandshakeTimeoutMs)) * + return std::max( + pto_multiplier_without_rtt_samples_ * rtt_stats_.initial_rtt(), + QuicTime::Delta::FromMilliseconds(kMinHandshakeTimeoutMs)) * (1 << consecutive_pto_count_); } const QuicTime::Delta rtt_var = use_standard_deviation_for_pto_
diff --git a/quic/core/quic_sent_packet_manager.h b/quic/core/quic_sent_packet_manager.h index af32eba..ca43d3d 100644 --- a/quic/core/quic_sent_packet_manager.h +++ b/quic/core/quic_sent_packet_manager.h
@@ -658,6 +658,10 @@ // If true, use standard deviation (instead of mean deviation) when // calculating PTO timeout. bool use_standard_deviation_for_pto_; + + // The multiplier for caculating PTO timeout before any RTT sample is + // available. + float pto_multiplier_without_rtt_samples_; }; } // namespace quic
diff --git a/quic/core/quic_sent_packet_manager_test.cc b/quic/core/quic_sent_packet_manager_test.cc index 90c7e15..33b2470 100644 --- a/quic/core/quic_sent_packet_manager_test.cc +++ b/quic/core/quic_sent_packet_manager_test.cc
@@ -4096,6 +4096,30 @@ manager_.GetRetransmissionTime()); } +TEST_F(QuicSentPacketManagerTest, + AggressivePtoBeforeAnyRttSamplesAreAvailable) { + manager_.EnableMultiplePacketNumberSpacesSupport(); + EXPECT_CALL(*send_algorithm_, PacingRate(_)) + .WillRepeatedly(Return(QuicBandwidth::Zero())); + EXPECT_CALL(*send_algorithm_, GetCongestionWindow()) + .WillRepeatedly(Return(10 * kDefaultTCPMSS)); + RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats()); + + QuicConfig config; + QuicTagVector options; + options.push_back(kAPTO); + QuicConfigPeer::SetReceivedConnectionOptions(&config, options); + EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)); + EXPECT_CALL(*network_change_visitor_, OnCongestionChange()); + manager_.SetFromConfig(config); + + // Send INITIAL 1. + SendDataPacket(1, ENCRYPTION_INITIAL); + // Verify retransmission timeout is expected. + EXPECT_EQ(clock_.Now() + 1.5 * rtt_stats->initial_rtt(), + manager_.GetRetransmissionTime()); +} + } // namespace } // namespace test } // namespace quic