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,