1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-09-19 10:26:10 -04:00
v2fly/external/github.com/lucas-clemente/quic-go/internal/ackhandler/packet_number_generator.go

79 lines
2.0 KiB
Go
Raw Normal View History

2018-11-23 11:04:53 -05:00
package ackhandler
2018-11-20 17:51:25 -05:00
import (
"crypto/rand"
"math"
2019-01-17 09:33:18 -05:00
"v2ray.com/core/external/github.com/lucas-clemente/quic-go/internal/protocol"
"v2ray.com/core/external/github.com/lucas-clemente/quic-go/internal/wire"
2018-11-20 17:51:25 -05:00
)
// The packetNumberGenerator generates the packet number for the next packet
// it randomly skips a packet number every averagePeriod packets (on average)
// it is guarantued to never skip two consecutive packet numbers
type packetNumberGenerator struct {
averagePeriod protocol.PacketNumber
next protocol.PacketNumber
nextToSkip protocol.PacketNumber
2018-11-23 11:04:53 -05:00
history []protocol.PacketNumber
2018-11-20 17:51:25 -05:00
}
func newPacketNumberGenerator(initial, averagePeriod protocol.PacketNumber) *packetNumberGenerator {
2018-11-23 11:04:53 -05:00
g := &packetNumberGenerator{
2018-11-20 17:51:25 -05:00
next: initial,
averagePeriod: averagePeriod,
}
2018-11-23 11:04:53 -05:00
g.generateNewSkip()
return g
2018-11-20 17:51:25 -05:00
}
func (p *packetNumberGenerator) Peek() protocol.PacketNumber {
return p.next
}
func (p *packetNumberGenerator) Pop() protocol.PacketNumber {
next := p.next
// generate a new packet number for the next packet
p.next++
if p.next == p.nextToSkip {
2018-11-23 11:04:53 -05:00
if len(p.history)+1 > protocol.MaxTrackedSkippedPackets {
p.history = p.history[1:]
}
p.history = append(p.history, p.next)
2018-11-20 17:51:25 -05:00
p.next++
p.generateNewSkip()
}
return next
}
2018-11-23 11:04:53 -05:00
func (p *packetNumberGenerator) generateNewSkip() {
num := p.getRandomNumber()
2018-11-20 17:51:25 -05:00
skip := protocol.PacketNumber(num) * (p.averagePeriod - 1) / (math.MaxUint16 / 2)
// make sure that there are never two consecutive packet numbers that are skipped
p.nextToSkip = p.next + 2 + skip
}
// getRandomNumber() generates a cryptographically secure random number between 0 and MaxUint16 (= 65535)
// The expectation value is 65535/2
2018-11-23 11:04:53 -05:00
func (p *packetNumberGenerator) getRandomNumber() uint16 {
2018-11-20 17:51:25 -05:00
b := make([]byte, 2)
2018-11-23 11:04:53 -05:00
rand.Read(b) // ignore the error here
2018-11-20 17:51:25 -05:00
num := uint16(b[0])<<8 + uint16(b[1])
2018-11-23 11:04:53 -05:00
return num
}
func (p *packetNumberGenerator) Validate(ack *wire.AckFrame) bool {
for _, pn := range p.history {
if ack.AcksPacket(pn) {
return false
}
}
return true
2018-11-20 17:51:25 -05:00
}