diff --git a/pkg/congestion/brutal.go b/pkg/congestion/brutal.go index 95e7e59..81ae293 100644 --- a/pkg/congestion/brutal.go +++ b/pkg/congestion/brutal.go @@ -20,6 +20,7 @@ type BrutalSender struct { pacer *pacer pktInfoSlots [pktInfoSlotCount]pktInfo + ackRate float64 } type pktInfo struct { @@ -32,9 +33,10 @@ func NewBrutalSender(bps congestion.ByteCount) *BrutalSender { bs := &BrutalSender{ bps: bps, maxDatagramSize: initMaxDatagramSize, + ackRate: 1, } - bs.pacer = newPacer(func(now time.Time) congestion.ByteCount { - return congestion.ByteCount(float64(bs.bps) / bs.getAckRate(now)) + bs.pacer = newPacer(func() congestion.ByteCount { + return congestion.ByteCount(float64(bs.bps) / bs.ackRate) }) return bs } @@ -60,7 +62,7 @@ func (b *BrutalSender) GetCongestionWindow() congestion.ByteCount { if rtt <= 0 { return 10240 } - return congestion.ByteCount(float64(b.bps) * rtt.Seconds() * 1.5 / b.getAckRate(time.Now())) + return congestion.ByteCount(float64(b.bps) * rtt.Seconds() * 1.5 / b.ackRate) } func (b *BrutalSender) OnPacketSent(sentTime time.Time, bytesInFlight congestion.ByteCount, @@ -80,6 +82,7 @@ func (b *BrutalSender) OnPacketAcked(number congestion.PacketNumber, ackedBytes b.pktInfoSlots[slot].AckCount = 1 b.pktInfoSlots[slot].LossCount = 0 } + b.updateAckRate(currentTimestamp) } func (b *BrutalSender) OnPacketLost(number congestion.PacketNumber, lostBytes congestion.ByteCount, @@ -94,6 +97,7 @@ func (b *BrutalSender) OnPacketLost(number congestion.PacketNumber, lostBytes co b.pktInfoSlots[slot].AckCount = 0 b.pktInfoSlots[slot].LossCount = 1 } + b.updateAckRate(currentTimestamp) } func (b *BrutalSender) SetMaxDatagramSize(size congestion.ByteCount) { @@ -101,8 +105,7 @@ func (b *BrutalSender) SetMaxDatagramSize(size congestion.ByteCount) { b.pacer.SetMaxDatagramSize(size) } -func (b *BrutalSender) getAckRate(now time.Time) float64 { - currentTimestamp := now.Unix() +func (b *BrutalSender) updateAckRate(currentTimestamp int64) { minTimestamp := currentTimestamp - pktInfoSlotCount var ackCount, lossCount uint64 for _, info := range b.pktInfoSlots { @@ -113,13 +116,13 @@ func (b *BrutalSender) getAckRate(now time.Time) float64 { lossCount += info.LossCount } if ackCount+lossCount < minSampleCount { - return 1 + b.ackRate = 1 } rate := float64(ackCount) / float64(ackCount+lossCount) if rate < minAckRate { - return minAckRate + b.ackRate = minAckRate } - return rate + b.ackRate = rate } func (b *BrutalSender) InSlowStart() bool { diff --git a/pkg/congestion/pacer.go b/pkg/congestion/pacer.go index 34bde7e..4370710 100644 --- a/pkg/congestion/pacer.go +++ b/pkg/congestion/pacer.go @@ -16,10 +16,10 @@ type pacer struct { budgetAtLastSent congestion.ByteCount maxDatagramSize congestion.ByteCount lastSentTime time.Time - getBandwidth func(time.Time) congestion.ByteCount // in bytes/s + getBandwidth func() congestion.ByteCount // in bytes/s } -func newPacer(getBandwidth func(time.Time) congestion.ByteCount) *pacer { +func newPacer(getBandwidth func() congestion.ByteCount) *pacer { p := &pacer{ budgetAtLastSent: maxBurstPackets * initMaxDatagramSize, maxDatagramSize: initMaxDatagramSize, @@ -40,15 +40,15 @@ func (p *pacer) SentPacket(sendTime time.Time, size congestion.ByteCount) { func (p *pacer) Budget(now time.Time) congestion.ByteCount { if p.lastSentTime.IsZero() { - return p.maxBurstSize(now) + return p.maxBurstSize() } - budget := p.budgetAtLastSent + (p.getBandwidth(now)*congestion.ByteCount(now.Sub(p.lastSentTime).Nanoseconds()))/1e9 - return minByteCount(p.maxBurstSize(now), budget) + budget := p.budgetAtLastSent + (p.getBandwidth()*congestion.ByteCount(now.Sub(p.lastSentTime).Nanoseconds()))/1e9 + return minByteCount(p.maxBurstSize(), budget) } -func (p *pacer) maxBurstSize(now time.Time) congestion.ByteCount { +func (p *pacer) maxBurstSize() congestion.ByteCount { return maxByteCount( - congestion.ByteCount((minPacingDelay+time.Millisecond).Nanoseconds())*p.getBandwidth(now)/1e9, + congestion.ByteCount((minPacingDelay+time.Millisecond).Nanoseconds())*p.getBandwidth()/1e9, maxBurstPackets*p.maxDatagramSize, ) } @@ -62,7 +62,7 @@ func (p *pacer) TimeUntilSend() time.Time { return p.lastSentTime.Add(maxDuration( minPacingDelay, time.Duration(math.Ceil(float64(p.maxDatagramSize-p.budgetAtLastSent)*1e9/ - float64(p.getBandwidth(time.Now()))))*time.Nanosecond, + float64(p.getBandwidth())))*time.Nanosecond, )) }