github.com/quic-go/quic-go@v0.44.0/internal/wire/short_header.go (about)

     1  package wire
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"io"
     7  
     8  	"github.com/quic-go/quic-go/internal/protocol"
     9  	"github.com/quic-go/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  }