github.com/sagernet/quic-go@v0.43.1-beta.1/internal/wire/short_header.go (about) 1 package wire 2 3 import ( 4 "errors" 5 "fmt" 6 "io" 7 8 "github.com/sagernet/quic-go/internal/protocol" 9 "github.com/sagernet/quic-go/internal/utils" 10 ) 11 12 // ParseShortHeader parses a short header packet. 13 // It must be called after header protection was removed. 14 // Otherwise, the check for the reserved bits will (most likely) fail. 15 func ParseShortHeader(data []byte, connIDLen int) (length int, _ protocol.PacketNumber, _ protocol.PacketNumberLen, _ protocol.KeyPhaseBit, _ error) { 16 if len(data) == 0 { 17 return 0, 0, 0, 0, io.EOF 18 } 19 if data[0]&0x80 > 0 { 20 return 0, 0, 0, 0, errors.New("not a short header packet") 21 } 22 if data[0]&0x40 == 0 { 23 return 0, 0, 0, 0, errors.New("not a QUIC packet") 24 } 25 pnLen := protocol.PacketNumberLen(data[0]&0b11) + 1 26 if len(data) < 1+int(pnLen)+connIDLen { 27 return 0, 0, 0, 0, io.EOF 28 } 29 30 pos := 1 + connIDLen 31 var pn protocol.PacketNumber 32 switch pnLen { 33 case protocol.PacketNumberLen1: 34 pn = protocol.PacketNumber(data[pos]) 35 case protocol.PacketNumberLen2: 36 pn = protocol.PacketNumber(utils.BigEndian.Uint16(data[pos : pos+2])) 37 case protocol.PacketNumberLen3: 38 pn = protocol.PacketNumber(utils.BigEndian.Uint24(data[pos : pos+3])) 39 case protocol.PacketNumberLen4: 40 pn = protocol.PacketNumber(utils.BigEndian.Uint32(data[pos : pos+4])) 41 default: 42 return 0, 0, 0, 0, fmt.Errorf("invalid packet number length: %d", pnLen) 43 } 44 kp := protocol.KeyPhaseZero 45 if data[0]&0b100 > 0 { 46 kp = protocol.KeyPhaseOne 47 } 48 49 var err error 50 if data[0]&0x18 != 0 { 51 err = ErrInvalidReservedBits 52 } 53 return 1 + connIDLen + int(pnLen), pn, pnLen, kp, err 54 } 55 56 // AppendShortHeader writes a short header. 57 func AppendShortHeader(b []byte, connID protocol.ConnectionID, pn protocol.PacketNumber, pnLen protocol.PacketNumberLen, kp protocol.KeyPhaseBit) ([]byte, error) { 58 typeByte := 0x40 | uint8(pnLen-1) 59 if kp == protocol.KeyPhaseOne { 60 typeByte |= byte(1 << 2) 61 } 62 b = append(b, typeByte) 63 b = append(b, connID.Bytes()...) 64 return appendPacketNumber(b, pn, pnLen) 65 } 66 67 func ShortHeaderLen(dest protocol.ConnectionID, pnLen protocol.PacketNumberLen) protocol.ByteCount { 68 return 1 + protocol.ByteCount(dest.Len()) + protocol.ByteCount(pnLen) 69 } 70 71 func LogShortHeader(logger utils.Logger, dest protocol.ConnectionID, pn protocol.PacketNumber, pnLen protocol.PacketNumberLen, kp protocol.KeyPhaseBit) { 72 logger.Debugf("\tShort Header{DestConnectionID: %s, PacketNumber: %d, PacketNumberLen: %d, KeyPhase: %s}", dest, pn, pnLen, kp) 73 }