Let QuicReceivedPacketManager trim ack ranges when packet is received, instead of when sending acks. Protected by FLAGS_quic_rpm_trim_ack_ranges_early. PiperOrigin-RevId: 547664172
diff --git a/quiche/quic/core/quic_flags_list.h b/quiche/quic/core/quic_flags_list.h index 072b449..0d8d539 100644 --- a/quiche/quic/core/quic_flags_list.h +++ b/quiche/quic/core/quic_flags_list.h
@@ -27,6 +27,8 @@ QUIC_FLAG(quic_reloadable_flag_quic_enable_mtu_discovery_at_server, false) // If true, QuicGsoBatchWriter will support release time if it is available and the process has the permission to do so. QUIC_FLAG(quic_restart_flag_quic_support_release_time_for_gso, false) +// If true, QuicReceivedPacketManager will trim ack ranges when packet is received. +QUIC_FLAG(quic_reloadable_flag_quic_rpm_trim_ack_ranges_early, true) // If true, ack frequency frame can be sent from server to client. QUIC_FLAG(quic_reloadable_flag_quic_can_send_ack_frequency, true) // If true, allow client to enable BBRv2 on server via connection option \'B2ON\'.
diff --git a/quiche/quic/core/quic_received_packet_manager.cc b/quiche/quic/core/quic_received_packet_manager.cc index 6b566f4..b941e8c 100644 --- a/quiche/quic/core/quic_received_packet_manager.cc +++ b/quiche/quic/core/quic_received_packet_manager.cc
@@ -14,6 +14,7 @@ #include "quiche/quic/core/quic_connection_stats.h" #include "quiche/quic/core/quic_types.h" #include "quiche/quic/platform/api/quic_bug_tracker.h" +#include "quiche/quic/platform/api/quic_flag_utils.h" #include "quiche/quic/platform/api/quic_flags.h" #include "quiche/quic/platform/api/quic_logging.h" @@ -104,6 +105,7 @@ time_largest_observed_ = receipt_time; } ack_frame_.packets.Add(packet_number); + MaybeTrimAckRanges(); if (save_timestamps_) { // The timestamp format only handles packets in time order. @@ -151,6 +153,19 @@ } } +void QuicReceivedPacketManager::MaybeTrimAckRanges() { + if (!trim_ack_ranges_early_) { + return; + } + + QUIC_RELOADABLE_FLAG_COUNT_N(quic_rpm_trim_ack_ranges_early, 1, 2); + while (max_ack_ranges_ > 0 && + ack_frame_.packets.NumIntervals() > max_ack_ranges_) { + QUIC_RELOADABLE_FLAG_COUNT_N(quic_rpm_trim_ack_ranges_early, 2, 2); + ack_frame_.packets.RemoveSmallestInterval(); + } +} + bool QuicReceivedPacketManager::IsMissing(QuicPacketNumber packet_number) { return LargestAcked(ack_frame_).IsInitialized() && packet_number < LargestAcked(ack_frame_) &&
diff --git a/quiche/quic/core/quic_received_packet_manager.h b/quiche/quic/core/quic_received_packet_manager.h index 0f80865..79e55af 100644 --- a/quiche/quic/core/quic_received_packet_manager.h +++ b/quiche/quic/core/quic_received_packet_manager.h
@@ -145,6 +145,8 @@ return last_ack_frequency_frame_sequence_number_ >= 0; } + void MaybeTrimAckRanges(); + // Least packet number of the the packet sent by the peer for which it // hasn't received an ack. QuicPacketNumber peer_least_packet_awaiting_ack_; @@ -204,6 +206,9 @@ // Whether the most recent packet was missing before it was received. bool was_last_packet_missing_; + const bool trim_ack_ranges_early_ = + GetQuicReloadableFlag(quic_rpm_trim_ack_ranges_early); + // Last sent largest acked, which gets updated when ACK was successfully sent. QuicPacketNumber last_sent_largest_acked_;
diff --git a/quiche/quic/core/quic_received_packet_manager_test.cc b/quiche/quic/core/quic_received_packet_manager_test.cc index b3bc9b7..b1d46db 100644 --- a/quiche/quic/core/quic_received_packet_manager_test.cc +++ b/quiche/quic/core/quic_received_packet_manager_test.cc
@@ -184,6 +184,21 @@ } } +TEST_F(QuicReceivedPacketManagerTest, TrimAckRangesEarly) { + const size_t kMaxAckRanges = 10; + received_manager_.set_max_ack_ranges(kMaxAckRanges); + for (size_t i = 0; i < kMaxAckRanges + 10; ++i) { + RecordPacketReceipt(1 + 2 * i); + if (i < kMaxAckRanges || + !GetQuicReloadableFlag(quic_rpm_trim_ack_ranges_early)) { + EXPECT_EQ(i + 1, received_manager_.ack_frame().packets.NumIntervals()); + } else { + EXPECT_EQ(kMaxAckRanges, + received_manager_.ack_frame().packets.NumIntervals()); + } + } +} + TEST_F(QuicReceivedPacketManagerTest, IgnoreOutOfOrderTimestamps) { EXPECT_FALSE(received_manager_.ack_frame_updated()); RecordPacketReceipt(1, QuicTime::Zero());