github.com/quic-go/quic-go@v0.44.0/internal/ackhandler/packet_number_generator.go (about)

     1  package ackhandler
     2  
     3  import (
     4  	"github.com/quic-go/quic-go/internal/protocol"
     5  	"github.com/quic-go/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  }