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