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