gfe-relnote: (n/a) When processing an ack in QuicSentPacketManager, cap ack_delay to peer advertised max ack delay. Protected by --gfe2_reloadable_flag_quic_sanitize_ack_delay.
PiperOrigin-RevId: 285253596
Change-Id: Ifc1035c86c5409ca723cb77cabbdb1bb15c49d05
diff --git a/quic/core/quic_sent_packet_manager.cc b/quic/core/quic_sent_packet_manager.cc
index f4d3579..fdf4f03 100644
--- a/quic/core/quic_sent_packet_manager.cc
+++ b/quic/core/quic_sent_packet_manager.cc
@@ -106,7 +106,8 @@
pto_exponential_backoff_start_point_(0),
pto_rttvar_multiplier_(4),
neuter_handshake_packets_once_(
- GetQuicReloadableFlag(quic_neuter_handshake_packets_once2)) {
+ GetQuicReloadableFlag(quic_neuter_handshake_packets_once2)),
+ sanitize_ack_delay_(GetQuicReloadableFlag(quic_sanitize_ack_delay)) {
SetSendAlgorithm(congestion_control_type);
}
@@ -1132,6 +1133,10 @@
QuicTime ack_receive_time) {
DCHECK(packets_acked_.empty());
DCHECK_LE(largest_acked, unacked_packets_.largest_sent_packet());
+ if (sanitize_ack_delay_ && ack_delay_time > peer_max_ack_delay()) {
+ QUIC_RELOADABLE_FLAG_COUNT(quic_sanitize_ack_delay);
+ ack_delay_time = peer_max_ack_delay();
+ }
rtt_updated_ =
MaybeUpdateRTT(largest_acked, ack_delay_time, ack_receive_time);
last_ack_frame_.ack_delay_time = ack_delay_time;
diff --git a/quic/core/quic_sent_packet_manager.h b/quic/core/quic_sent_packet_manager.h
index 5a3f2ca..ae62dfb 100644
--- a/quic/core/quic_sent_packet_manager.h
+++ b/quic/core/quic_sent_packet_manager.h
@@ -654,6 +654,9 @@
// Latched value of quic_neuter_handshake_packets_once2.
const bool neuter_handshake_packets_once_;
+
+ // Latched value of quic_sanitize_ack_delay.
+ const bool sanitize_ack_delay_;
};
} // namespace quic
diff --git a/quic/core/quic_sent_packet_manager_test.cc b/quic/core/quic_sent_packet_manager_test.cc
index fe7a81f..625ba99 100644
--- a/quic/core/quic_sent_packet_manager_test.cc
+++ b/quic/core/quic_sent_packet_manager_test.cc
@@ -789,6 +789,33 @@
EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt());
}
+TEST_F(QuicSentPacketManagerTest, RttWithDeltaExceedingLimit) {
+ // Initialize min and smoothed rtt to 10ms.
+ RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+ rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(10),
+ QuicTime::Delta::Zero(), QuicTime::Zero());
+
+ QuicTime::Delta send_delta = QuicTime::Delta::FromMilliseconds(100);
+ QuicTime::Delta ack_delay =
+ QuicTime::Delta::FromMilliseconds(5) + manager_.peer_max_ack_delay();
+ ASSERT_GT(send_delta - rtt_stats->min_rtt(), ack_delay);
+ SendDataPacket(1);
+ clock_.AdvanceTime(send_delta);
+
+ ExpectAck(1);
+ manager_.OnAckFrameStart(QuicPacketNumber(1), ack_delay, clock_.Now());
+ manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+ EXPECT_EQ(PACKETS_NEWLY_ACKED,
+ manager_.OnAckFrameEnd(clock_.Now(), QuicPacketNumber(1),
+ ENCRYPTION_FORWARD_SECURE));
+
+ QuicTime::Delta expected_rtt_sample =
+ GetQuicReloadableFlag(quic_sanitize_ack_delay)
+ ? send_delta - manager_.peer_max_ack_delay()
+ : send_delta - ack_delay;
+ EXPECT_EQ(expected_rtt_sample, manager_.GetRttStats()->latest_rtt());
+}
+
TEST_F(QuicSentPacketManagerTest, RttZeroDelta) {
// Expect that the RTT is the time between send and receive since the
// ack_delay_time is zero.
@@ -1610,7 +1637,7 @@
// original value and OnRetransmissionTimeout is not called or reverted.
uint64_t acked[] = {1, 2};
ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0);
- manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+ manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Zero(),
clock_.Now());
manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
EXPECT_EQ(PACKETS_NEWLY_ACKED,