| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- package wire
- import (
- "bytes"
- "errors"
- "io"
- "v2ray.com/core/external/github.com/lucas-clemente/quic-go/internal/protocol"
- "v2ray.com/core/external/github.com/lucas-clemente/quic-go/internal/qerr"
- "v2ray.com/core/external/github.com/lucas-clemente/quic-go/internal/utils"
- )
- // The Header is the version independent part of the header
- type Header struct {
- Version protocol.VersionNumber
- SrcConnectionID protocol.ConnectionID
- DestConnectionID protocol.ConnectionID
- IsLongHeader bool
- Type protocol.PacketType
- Length protocol.ByteCount
- Token []byte
- SupportedVersions []protocol.VersionNumber // sent in a Version Negotiation Packet
- OrigDestConnectionID protocol.ConnectionID // sent in the Retry packet
- typeByte byte
- parsedLen protocol.ByteCount // how many bytes were read while parsing this header
- }
- // ParseHeader parses the header.
- // For short header packets: up to the packet number.
- // For long header packets:
- // * if we understand the version: up to the packet number
- // * if not, only the invariant part of the header
- func ParseHeader(b *bytes.Reader, shortHeaderConnIDLen int) (*Header, error) {
- startLen := b.Len()
- h, err := parseHeaderImpl(b, shortHeaderConnIDLen)
- if err != nil {
- return nil, err
- }
- h.parsedLen = protocol.ByteCount(startLen - b.Len())
- return h, nil
- }
- func parseHeaderImpl(b *bytes.Reader, shortHeaderConnIDLen int) (*Header, error) {
- typeByte, err := b.ReadByte()
- if err != nil {
- return nil, err
- }
- h := &Header{
- typeByte: typeByte,
- IsLongHeader: typeByte&0x80 > 0,
- }
- if !h.IsLongHeader {
- if h.typeByte&0x40 == 0 {
- return nil, errors.New("not a QUIC packet")
- }
- if err := h.parseShortHeader(b, shortHeaderConnIDLen); err != nil {
- return nil, err
- }
- return h, nil
- }
- if err := h.parseLongHeader(b); err != nil {
- return nil, err
- }
- return h, nil
- }
- func (h *Header) parseShortHeader(b *bytes.Reader, shortHeaderConnIDLen int) error {
- var err error
- h.DestConnectionID, err = protocol.ReadConnectionID(b, shortHeaderConnIDLen)
- return err
- }
- func (h *Header) parseLongHeader(b *bytes.Reader) error {
- v, err := utils.BigEndian.ReadUint32(b)
- if err != nil {
- return err
- }
- h.Version = protocol.VersionNumber(v)
- if !h.IsVersionNegotiation() && h.typeByte&0x40 == 0 {
- return errors.New("not a QUIC packet")
- }
- connIDLenByte, err := b.ReadByte()
- if err != nil {
- return err
- }
- dcil, scil := decodeConnIDLen(connIDLenByte)
- h.DestConnectionID, err = protocol.ReadConnectionID(b, dcil)
- if err != nil {
- return err
- }
- h.SrcConnectionID, err = protocol.ReadConnectionID(b, scil)
- if err != nil {
- return err
- }
- if h.Version == 0 {
- return h.parseVersionNegotiationPacket(b)
- }
- // If we don't understand the version, we have no idea how to interpret the rest of the bytes
- if !protocol.IsSupportedVersion(protocol.SupportedVersions, h.Version) {
- return nil
- }
- switch (h.typeByte & 0x30) >> 4 {
- case 0x0:
- h.Type = protocol.PacketTypeInitial
- case 0x1:
- h.Type = protocol.PacketType0RTT
- case 0x2:
- h.Type = protocol.PacketTypeHandshake
- case 0x3:
- h.Type = protocol.PacketTypeRetry
- }
- if h.Type == protocol.PacketTypeRetry {
- odcil := decodeSingleConnIDLen(h.typeByte & 0xf)
- h.OrigDestConnectionID, err = protocol.ReadConnectionID(b, odcil)
- if err != nil {
- return err
- }
- h.Token = make([]byte, b.Len())
- if _, err := io.ReadFull(b, h.Token); err != nil {
- return err
- }
- return nil
- }
- if h.Type == protocol.PacketTypeInitial {
- tokenLen, err := utils.ReadVarInt(b)
- if err != nil {
- return err
- }
- if tokenLen > uint64(b.Len()) {
- return io.EOF
- }
- h.Token = make([]byte, tokenLen)
- if _, err := io.ReadFull(b, h.Token); err != nil {
- return err
- }
- }
- pl, err := utils.ReadVarInt(b)
- if err != nil {
- return err
- }
- h.Length = protocol.ByteCount(pl)
- return nil
- }
- func (h *Header) parseVersionNegotiationPacket(b *bytes.Reader) error {
- if b.Len() == 0 {
- return qerr.Error(qerr.InvalidVersionNegotiationPacket, "empty version list")
- }
- h.SupportedVersions = make([]protocol.VersionNumber, b.Len()/4)
- for i := 0; b.Len() > 0; i++ {
- v, err := utils.BigEndian.ReadUint32(b)
- if err != nil {
- return qerr.InvalidVersionNegotiationPacket
- }
- h.SupportedVersions[i] = protocol.VersionNumber(v)
- }
- return nil
- }
- // IsVersionNegotiation says if this a version negotiation packet
- func (h *Header) IsVersionNegotiation() bool {
- return h.IsLongHeader && h.Version == 0
- }
- // ParsedLen returns the number of bytes that were consumed when parsing the header
- func (h *Header) ParsedLen() protocol.ByteCount {
- return h.parsedLen
- }
- // ParseExtended parses the version dependent part of the header.
- // The Reader has to be set such that it points to the first byte of the header.
- func (h *Header) ParseExtended(b *bytes.Reader, ver protocol.VersionNumber) (*ExtendedHeader, error) {
- return h.toExtendedHeader().parse(b, ver)
- }
- func (h *Header) toExtendedHeader() *ExtendedHeader {
- return &ExtendedHeader{Header: *h}
- }
- func decodeConnIDLen(enc byte) (int /*dest conn id len*/, int /*src conn id len*/) {
- return decodeSingleConnIDLen(enc >> 4), decodeSingleConnIDLen(enc & 0xf)
- }
- func decodeSingleConnIDLen(enc uint8) int {
- if enc == 0 {
- return 0
- }
- return int(enc) + 3
- }
|