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());