Add kAFF1 enabling the usage of smoothed RTT in the computation of ack delay in AckFrequencyFrame. Protected by FLAGS_quic_reloadable_flag_quic_can_send_ack_frequency. PiperOrigin-RevId: 337381712 Change-Id: Icdc57863d57e54a516fe73139903e974097800e5
diff --git a/quic/core/crypto/crypto_protocol.h b/quic/core/crypto/crypto_protocol.h index ab0ef01..57c9989 100644 --- a/quic/core/crypto/crypto_protocol.h +++ b/quic/core/crypto/crypto_protocol.h
@@ -165,6 +165,8 @@ // 1 RTT of not receiving. const QuicTag kAFFE = TAG('A', 'F', 'F', 'E'); // Enable client receiving // AckFrequencyFrame. +const QuicTag kAFF1 = TAG('A', 'F', 'F', '1'); // Use SRTT in building + // AckFrequencyFrame. const QuicTag kSSLR = TAG('S', 'S', 'L', 'R'); // Slow Start Large Reduction. const QuicTag kNPRR = TAG('N', 'P', 'R', 'R'); // Pace at unity instead of PRR const QuicTag k2RTO = TAG('2', 'R', 'T', 'O'); // Close connection on 2 RTOs
diff --git a/quic/core/quic_sent_packet_manager.cc b/quic/core/quic_sent_packet_manager.cc index b98f65c..bdad0e4 100644 --- a/quic/core/quic_sent_packet_manager.cc +++ b/quic/core/quic_sent_packet_manager.cc
@@ -150,6 +150,9 @@ peer_min_ack_delay_ = QuicTime::Delta::FromMilliseconds(config.ReceivedMinAckDelayMs()); } + if (config.HasClientSentConnectionOption(kAFF1, perspective)) { + use_smoothed_rtt_in_ack_delay_ = true; + } } if (config.HasClientSentConnectionOption(kMAD0, perspective)) { rtt_stats_.set_ignore_max_ack_delay(true); @@ -725,7 +728,8 @@ QUIC_RELOADABLE_FLAG_COUNT(quic_can_send_ack_frequency); frame.packet_tolerance = kMaxRetransmittablePacketsBeforeAck; - auto rtt = rtt_stats_.MinOrInitialRtt(); + auto rtt = use_smoothed_rtt_in_ack_delay_ ? rtt_stats_.SmoothedOrInitialRtt() + : rtt_stats_.MinOrInitialRtt(); frame.max_ack_delay = rtt * kAckDecimationDelay; frame.max_ack_delay = std::max(frame.max_ack_delay, peer_min_ack_delay_);
diff --git a/quic/core/quic_sent_packet_manager.h b/quic/core/quic_sent_packet_manager.h index ef5972a..64cd4c0 100644 --- a/quic/core/quic_sent_packet_manager.h +++ b/quic/core/quic_sent_packet_manager.h
@@ -659,6 +659,9 @@ // AckFrequencyFrame. QuicTime::Delta peer_min_ack_delay_ = QuicTime::Delta::Infinite(); + // Use smoothed RTT for computing max_ack_delay in AckFrequency frame. + bool use_smoothed_rtt_in_ack_delay_ = false; + // The history of outstanding max_ack_delays sent to peer. Outstanding means // a max_ack_delay is sent as part of the last acked AckFrequencyFrame or // an unacked AckFrequencyFrame after that.
diff --git a/quic/core/quic_sent_packet_manager_test.cc b/quic/core/quic_sent_packet_manager_test.cc index 4bb16a3..5504e8e 100644 --- a/quic/core/quic_sent_packet_manager_test.cc +++ b/quic/core/quic_sent_packet_manager_test.cc
@@ -4420,7 +4420,7 @@ EXPECT_EQ(message_frame->message_length, 0); } -TEST_F(QuicSentPacketManagerTest, SendAckFrequencyFrame) { +TEST_F(QuicSentPacketManagerTest, BuildAckFrequencyFrame) { SetQuicReloadableFlag(quic_can_send_ack_frequency, true); EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)); EXPECT_CALL(*network_change_visitor_, OnCongestionChange()); @@ -4447,6 +4447,35 @@ EXPECT_EQ(frame.packet_tolerance, 10u); } +TEST_F(QuicSentPacketManagerTest, BuildAckFrequencyFrameWithSRTT) { + SetQuicReloadableFlag(quic_can_send_ack_frequency, true); + EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)); + EXPECT_CALL(*network_change_visitor_, OnCongestionChange()); + QuicConfig config; + QuicConfigPeer::SetReceivedMinAckDelayMs(&config, /*min_ack_delay_ms=*/1); + QuicTagVector quic_tag_vector; + quic_tag_vector.push_back(kAFF1); // SRTT enabling tag. + QuicConfigPeer::SetReceivedConnectionOptions(&config, quic_tag_vector); + manager_.SetFromConfig(config); + manager_.SetHandshakeConfirmed(); + + // Set up RTTs. + auto* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats()); + rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(8), + /*ack_delay=*/QuicTime::Delta::Zero(), + /*now=*/QuicTime::Zero()); + // Make sure srtt and min_rtt are different. + rtt_stats->UpdateRtt( + QuicTime::Delta::FromMilliseconds(16), + /*ack_delay=*/QuicTime::Delta::Zero(), + /*now=*/QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(24)); + + auto frame = manager_.GetUpdatedAckFrequencyFrame(); + EXPECT_EQ(frame.max_ack_delay, + std::max(rtt_stats->SmoothedOrInitialRtt() * 0.25, + QuicTime::Delta::FromMilliseconds(1u))); +} + } // namespace } // namespace test } // namespace quic