mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2025-12-19 08:20:05 +08:00
Some checks failed
Test / test (1.20, macos-13) (push) Has been cancelled
Test / test (1.20, macos-latest) (push) Has been cancelled
Test / test (1.20, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.20, ubuntu-latest) (push) Has been cancelled
Test / test (1.20, windows-latest) (push) Has been cancelled
Test / test (1.21, macos-13) (push) Has been cancelled
Test / test (1.21, macos-latest) (push) Has been cancelled
Test / test (1.21, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.21, ubuntu-latest) (push) Has been cancelled
Test / test (1.21, windows-latest) (push) Has been cancelled
Test / test (1.22, macos-13) (push) Has been cancelled
Test / test (1.22, macos-latest) (push) Has been cancelled
Test / test (1.22, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.22, ubuntu-latest) (push) Has been cancelled
Test / test (1.22, windows-latest) (push) Has been cancelled
Test / test (1.23, macos-13) (push) Has been cancelled
Test / test (1.23, macos-latest) (push) Has been cancelled
Test / test (1.23, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.23, ubuntu-latest) (push) Has been cancelled
Test / test (1.23, windows-latest) (push) Has been cancelled
Test / test (1.24, macos-13) (push) Has been cancelled
Test / test (1.24, macos-latest) (push) Has been cancelled
Test / test (1.24, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.24, ubuntu-latest) (push) Has been cancelled
Test / test (1.24, windows-latest) (push) Has been cancelled
Test / test (1.25, macos-13) (push) Has been cancelled
Test / test (1.25, macos-latest) (push) Has been cancelled
Test / test (1.25, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.25, ubuntu-latest) (push) Has been cancelled
Test / test (1.25, windows-latest) (push) Has been cancelled
Trigger CMFA Update / trigger-CMFA-update (push) Has been cancelled
88 lines
2.1 KiB
Go
88 lines
2.1 KiB
Go
package congestion
|
|
|
|
import (
|
|
"github.com/metacubex/quic-go/congestion"
|
|
"github.com/metacubex/quic-go/monotime"
|
|
|
|
"math"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
maxBurstPackets = 10
|
|
minPacingDelay = time.Millisecond
|
|
)
|
|
|
|
// The pacer implements a token bucket pacing algorithm.
|
|
type pacer struct {
|
|
budgetAtLastSent congestion.ByteCount
|
|
maxDatagramSize congestion.ByteCount
|
|
lastSentTime monotime.Time
|
|
getBandwidth func() congestion.ByteCount // in bytes/s
|
|
}
|
|
|
|
func newPacer(getBandwidth func() congestion.ByteCount) *pacer {
|
|
p := &pacer{
|
|
budgetAtLastSent: maxBurstPackets * initMaxDatagramSize,
|
|
maxDatagramSize: initMaxDatagramSize,
|
|
getBandwidth: getBandwidth,
|
|
}
|
|
return p
|
|
}
|
|
|
|
func (p *pacer) SentPacket(sendTime monotime.Time, size congestion.ByteCount) {
|
|
budget := p.Budget(sendTime)
|
|
if size > budget {
|
|
p.budgetAtLastSent = 0
|
|
} else {
|
|
p.budgetAtLastSent = budget - size
|
|
}
|
|
p.lastSentTime = sendTime
|
|
}
|
|
|
|
func (p *pacer) Budget(now monotime.Time) congestion.ByteCount {
|
|
if p.lastSentTime.IsZero() {
|
|
return p.maxBurstSize()
|
|
}
|
|
budget := p.budgetAtLastSent + (p.getBandwidth()*congestion.ByteCount(now.Sub(p.lastSentTime).Nanoseconds()))/1e9
|
|
return minByteCount(p.maxBurstSize(), budget)
|
|
}
|
|
|
|
func (p *pacer) maxBurstSize() congestion.ByteCount {
|
|
return maxByteCount(
|
|
congestion.ByteCount((minPacingDelay+time.Millisecond).Nanoseconds())*p.getBandwidth()/1e9,
|
|
maxBurstPackets*p.maxDatagramSize,
|
|
)
|
|
}
|
|
|
|
// TimeUntilSend returns when the next packet should be sent.
|
|
// It returns the zero value of monotime.Time if a packet can be sent immediately.
|
|
func (p *pacer) TimeUntilSend() monotime.Time {
|
|
if p.budgetAtLastSent >= p.maxDatagramSize {
|
|
return monotime.Time(0)
|
|
}
|
|
return p.lastSentTime.Add(maxDuration(
|
|
minPacingDelay,
|
|
time.Duration(math.Ceil(float64(p.maxDatagramSize-p.budgetAtLastSent)*1e9/
|
|
float64(p.getBandwidth())))*time.Nanosecond,
|
|
))
|
|
}
|
|
|
|
func (p *pacer) SetMaxDatagramSize(s congestion.ByteCount) {
|
|
p.maxDatagramSize = s
|
|
}
|
|
|
|
func maxByteCount(a, b congestion.ByteCount) congestion.ByteCount {
|
|
if a < b {
|
|
return b
|
|
}
|
|
return a
|
|
}
|
|
|
|
func minByteCount(a, b congestion.ByteCount) congestion.ByteCount {
|
|
if a < b {
|
|
return a
|
|
}
|
|
return b
|
|
}
|