mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-06 13:47:35 +03:00
57 lines
1.8 KiB
Go
57 lines
1.8 KiB
Go
package protocol
|
|
|
|
// A PacketNumber in QUIC
|
|
type PacketNumber int64
|
|
|
|
// InvalidPacketNumber is a packet number that is never sent.
|
|
// In QUIC, 0 is a valid packet number.
|
|
const InvalidPacketNumber PacketNumber = -1
|
|
|
|
// PacketNumberLen is the length of the packet number in bytes
|
|
type PacketNumberLen uint8
|
|
|
|
const (
|
|
// PacketNumberLen1 is a packet number length of 1 byte
|
|
PacketNumberLen1 PacketNumberLen = 1
|
|
// PacketNumberLen2 is a packet number length of 2 bytes
|
|
PacketNumberLen2 PacketNumberLen = 2
|
|
// PacketNumberLen3 is a packet number length of 3 bytes
|
|
PacketNumberLen3 PacketNumberLen = 3
|
|
// PacketNumberLen4 is a packet number length of 4 bytes
|
|
PacketNumberLen4 PacketNumberLen = 4
|
|
)
|
|
|
|
// DecodePacketNumber calculates the packet number based its length and the last seen packet number
|
|
// This function is taken from https://www.rfc-editor.org/rfc/rfc9000.html#section-a.3.
|
|
func DecodePacketNumber(length PacketNumberLen, largest PacketNumber, truncated PacketNumber) PacketNumber {
|
|
expected := largest + 1
|
|
win := PacketNumber(1 << (length * 8))
|
|
hwin := win / 2
|
|
mask := win - 1
|
|
candidate := (expected & ^mask) | truncated
|
|
if candidate <= expected-hwin && candidate < 1<<62-win {
|
|
return candidate + win
|
|
}
|
|
if candidate > expected+hwin && candidate >= win {
|
|
return candidate - win
|
|
}
|
|
return candidate
|
|
}
|
|
|
|
// PacketNumberLengthForHeader gets the length of the packet number for the public header
|
|
// it never chooses a PacketNumberLen of 1 byte, since this is too short under certain circumstances
|
|
func PacketNumberLengthForHeader(pn, largestAcked PacketNumber) PacketNumberLen {
|
|
var numUnacked PacketNumber
|
|
if largestAcked == InvalidPacketNumber {
|
|
numUnacked = pn + 1
|
|
} else {
|
|
numUnacked = pn - largestAcked
|
|
}
|
|
if numUnacked < 1<<(16-1) {
|
|
return PacketNumberLen2
|
|
}
|
|
if numUnacked < 1<<(24-1) {
|
|
return PacketNumberLen3
|
|
}
|
|
return PacketNumberLen4
|
|
}
|