github.com/danielpfeifer02/quic-go-prio-packs@v0.41.0-28/internal/protocol/packet_number.go (about) 1 package protocol 2 3 import "github.com/danielpfeifer02/quic-go-prio-packs/crypto_turnoff" 4 5 // A PacketNumber in QUIC 6 type PacketNumber int64 7 8 // InvalidPacketNumber is a packet number that is never sent. 9 // In QUIC, 0 is a valid packet number. 10 const InvalidPacketNumber PacketNumber = -1 11 12 // PacketNumberLen is the length of the packet number in bytes 13 type PacketNumberLen uint8 14 15 const ( 16 // PacketNumberLen1 is a packet number length of 1 byte 17 PacketNumberLen1 PacketNumberLen = 1 18 // PacketNumberLen2 is a packet number length of 2 bytes 19 PacketNumberLen2 PacketNumberLen = 2 20 // PacketNumberLen3 is a packet number length of 3 bytes 21 PacketNumberLen3 PacketNumberLen = 3 22 // PacketNumberLen4 is a packet number length of 4 bytes 23 PacketNumberLen4 PacketNumberLen = 4 24 ) 25 26 // DecodePacketNumber calculates the packet number based on the received packet number, its length and the last seen packet number 27 func DecodePacketNumber( 28 packetNumberLength PacketNumberLen, 29 lastPacketNumber PacketNumber, 30 wirePacketNumber PacketNumber, 31 ) PacketNumber { 32 33 if crypto_turnoff.CRYPTO_TURNED_OFF { 34 return wirePacketNumber 35 } 36 37 var epochDelta PacketNumber 38 switch packetNumberLength { 39 case PacketNumberLen1: 40 epochDelta = PacketNumber(1) << 8 41 case PacketNumberLen2: 42 epochDelta = PacketNumber(1) << 16 43 case PacketNumberLen3: 44 epochDelta = PacketNumber(1) << 24 45 case PacketNumberLen4: 46 epochDelta = PacketNumber(1) << 32 47 } 48 epoch := lastPacketNumber & ^(epochDelta - 1) 49 var prevEpochBegin PacketNumber 50 if epoch > epochDelta { 51 prevEpochBegin = epoch - epochDelta 52 } 53 nextEpochBegin := epoch + epochDelta 54 return closestTo( 55 lastPacketNumber+1, 56 epoch+wirePacketNumber, 57 closestTo(lastPacketNumber+1, prevEpochBegin+wirePacketNumber, nextEpochBegin+wirePacketNumber), 58 ) 59 } 60 61 func closestTo(target, a, b PacketNumber) PacketNumber { 62 if delta(target, a) < delta(target, b) { 63 return a 64 } 65 return b 66 } 67 68 func delta(a, b PacketNumber) PacketNumber { 69 if a < b { 70 return b - a 71 } 72 return a - b 73 } 74 75 // GetPacketNumberLengthForHeader gets the length of the packet number for the public header 76 // it never chooses a PacketNumberLen of 1 byte, since this is too short under certain circumstances 77 func GetPacketNumberLengthForHeader(packetNumber, leastUnacked PacketNumber) PacketNumberLen { 78 diff := uint64(packetNumber - leastUnacked) 79 if diff < (1 << (16 - 1)) { 80 return PacketNumberLen2 81 } 82 if diff < (1 << (24 - 1)) { 83 return PacketNumberLen3 84 } 85 return PacketNumberLen4 86 }