github.com/apernet/quic-go@v0.43.1-0.20240515053213-5e9e635fd9f0/internal/ackhandler/packet_number_generator.go (about) 1 package ackhandler 2 3 import ( 4 "github.com/apernet/quic-go/internal/protocol" 5 "github.com/apernet/quic-go/internal/utils" 6 ) 7 8 type packetNumberGenerator interface { 9 Peek() protocol.PacketNumber 10 // Pop pops the packet number. 11 // It reports if the packet number (before the one just popped) was skipped. 12 // It never skips more than one packet number in a row. 13 Pop() (skipped bool, _ protocol.PacketNumber) 14 } 15 16 type sequentialPacketNumberGenerator struct { 17 next protocol.PacketNumber 18 } 19 20 var _ packetNumberGenerator = &sequentialPacketNumberGenerator{} 21 22 func newSequentialPacketNumberGenerator(initial protocol.PacketNumber) packetNumberGenerator { 23 return &sequentialPacketNumberGenerator{next: initial} 24 } 25 26 func (p *sequentialPacketNumberGenerator) Peek() protocol.PacketNumber { 27 return p.next 28 } 29 30 func (p *sequentialPacketNumberGenerator) Pop() (bool, protocol.PacketNumber) { 31 next := p.next 32 p.next++ 33 return false, next 34 } 35 36 // The skippingPacketNumberGenerator generates the packet number for the next packet 37 // it randomly skips a packet number every averagePeriod packets (on average). 38 // It is guaranteed to never skip two consecutive packet numbers. 39 type skippingPacketNumberGenerator struct { 40 period protocol.PacketNumber 41 maxPeriod protocol.PacketNumber 42 43 next protocol.PacketNumber 44 nextToSkip protocol.PacketNumber 45 46 rng utils.Rand 47 } 48 49 var _ packetNumberGenerator = &skippingPacketNumberGenerator{} 50 51 func newSkippingPacketNumberGenerator(initial, initialPeriod, maxPeriod protocol.PacketNumber) packetNumberGenerator { 52 g := &skippingPacketNumberGenerator{ 53 next: initial, 54 period: initialPeriod, 55 maxPeriod: maxPeriod, 56 } 57 g.generateNewSkip() 58 return g 59 } 60 61 func (p *skippingPacketNumberGenerator) Peek() protocol.PacketNumber { 62 if p.next == p.nextToSkip { 63 return p.next + 1 64 } 65 return p.next 66 } 67 68 func (p *skippingPacketNumberGenerator) Pop() (bool, protocol.PacketNumber) { 69 next := p.next 70 if p.next == p.nextToSkip { 71 next++ 72 p.next += 2 73 p.generateNewSkip() 74 return true, next 75 } 76 p.next++ // generate a new packet number for the next packet 77 return false, next 78 } 79 80 func (p *skippingPacketNumberGenerator) generateNewSkip() { 81 // make sure that there are never two consecutive packet numbers that are skipped 82 p.nextToSkip = p.next + 3 + protocol.PacketNumber(p.rng.Int31n(int32(2*p.period))) 83 p.period = min(2*p.period, p.maxPeriod) 84 }