From 7c46e845a6e4d1355c1a4515fb8e94ebec2c89c3 Mon Sep 17 00:00:00 2001 From: Toby Date: Tue, 10 Oct 2023 19:54:43 -0700 Subject: [PATCH] fix: BBR memory leak --- core/internal/congestion/bbr/bbr_sender.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/core/internal/congestion/bbr/bbr_sender.go b/core/internal/congestion/bbr/bbr_sender.go index 9cf9cf6..4afb078 100644 --- a/core/internal/congestion/bbr/bbr_sender.go +++ b/core/internal/congestion/bbr/bbr_sender.go @@ -482,10 +482,19 @@ func (b *bbrSender) OnCongestionEventEx(priorInFlight congestion.ByteCount, even b.calculateRecoveryWindow(bytesAcked, bytesLost) // Cleanup internal state. - if len(lostPackets) != 0 { - lastLostPacket := lostPackets[len(lostPackets)-1].PacketNumber - b.sampler.RemoveObsoletePackets(lastLostPacket) + // This is where we clean up obsolete (acked or lost) packets from the bandwidth sampler. + // The "least unacked" should actually be FirstOutstanding, but since we are not passing + // that through OnCongestionEventEx, we will only do an estimate using acked/lost packets + // for now. Because of fast retransmission, they should differ by no more than 2 packets. + // (this is controlled by packetThreshold in quic-go's sentPacketHandler) + var leastUnacked congestion.PacketNumber + if len(ackedPackets) != 0 { + leastUnacked = ackedPackets[len(ackedPackets)-1].PacketNumber - 2 + } else { + leastUnacked = lostPackets[len(lostPackets)-1].PacketNumber + 1 } + b.sampler.RemoveObsoletePackets(leastUnacked) + if isRoundStart { b.numLossEventsInRound = 0 b.bytesLostInRound = 0