mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-03 20:27:35 +03:00
use the new packet number format
This commit is contained in:
parent
52380835b9
commit
bfb467e9b8
9 changed files with 113 additions and 296 deletions
|
@ -1,5 +1,21 @@
|
|||
package protocol
|
||||
|
||||
// PacketNumberLen is the length of the packet number in bytes
|
||||
type PacketNumberLen uint8
|
||||
|
||||
const (
|
||||
// PacketNumberLenInvalid is the default value and not a valid length for a packet number
|
||||
PacketNumberLenInvalid PacketNumberLen = 0
|
||||
// PacketNumberLen1 is a packet number length of 1 byte
|
||||
PacketNumberLen1 PacketNumberLen = 1
|
||||
// PacketNumberLen2 is a packet number length of 2 bytes
|
||||
PacketNumberLen2 PacketNumberLen = 2
|
||||
// PacketNumberLen3 is a packet number length of 3 bytes
|
||||
PacketNumberLen3 PacketNumberLen = 3
|
||||
// PacketNumberLen4 is a packet number length of 4 bytes
|
||||
PacketNumberLen4 PacketNumberLen = 4
|
||||
)
|
||||
|
||||
// InferPacketNumber calculates the packet number based on the received packet number, its length and the last seen packet number
|
||||
func InferPacketNumber(
|
||||
packetNumberLength PacketNumberLen,
|
||||
|
@ -9,11 +25,13 @@ func InferPacketNumber(
|
|||
var epochDelta PacketNumber
|
||||
switch packetNumberLength {
|
||||
case PacketNumberLen1:
|
||||
epochDelta = PacketNumber(1) << 7
|
||||
epochDelta = PacketNumber(1) << 8
|
||||
case PacketNumberLen2:
|
||||
epochDelta = PacketNumber(1) << 14
|
||||
epochDelta = PacketNumber(1) << 16
|
||||
case PacketNumberLen3:
|
||||
epochDelta = PacketNumber(1) << 24
|
||||
case PacketNumberLen4:
|
||||
epochDelta = PacketNumber(1) << 30
|
||||
epochDelta = PacketNumber(1) << 32
|
||||
}
|
||||
epoch := lastPacketNumber & ^(epochDelta - 1)
|
||||
prevEpochBegin := epoch - epochDelta
|
||||
|
@ -43,9 +61,12 @@ func delta(a, b PacketNumber) PacketNumber {
|
|||
// it never chooses a PacketNumberLen of 1 byte, since this is too short under certain circumstances
|
||||
func GetPacketNumberLengthForHeader(packetNumber, leastUnacked PacketNumber) PacketNumberLen {
|
||||
diff := uint64(packetNumber - leastUnacked)
|
||||
if diff < (1 << (14 - 1)) {
|
||||
if diff < (1 << (16 - 1)) {
|
||||
return PacketNumberLen2
|
||||
}
|
||||
if diff < (1 << (24 - 1)) {
|
||||
return PacketNumberLen3
|
||||
}
|
||||
return PacketNumberLen4
|
||||
}
|
||||
|
||||
|
@ -57,5 +78,8 @@ func GetPacketNumberLength(packetNumber PacketNumber) PacketNumberLen {
|
|||
if packetNumber < (1 << (uint8(PacketNumberLen2) * 8)) {
|
||||
return PacketNumberLen2
|
||||
}
|
||||
if packetNumber < (1 << (uint8(PacketNumberLen3) * 8)) {
|
||||
return PacketNumberLen3
|
||||
}
|
||||
return PacketNumberLen4
|
||||
}
|
||||
|
|
|
@ -12,18 +12,12 @@ import (
|
|||
var _ = Describe("packet number calculation", func() {
|
||||
Context("infering a packet number", func() {
|
||||
getEpoch := func(len PacketNumberLen) uint64 {
|
||||
switch len {
|
||||
case PacketNumberLen1:
|
||||
return uint64(1) << 7
|
||||
case PacketNumberLen2:
|
||||
return uint64(1) << 14
|
||||
case PacketNumberLen4:
|
||||
return uint64(1) << 30
|
||||
default:
|
||||
if len > 4 {
|
||||
Fail("invalid packet number len")
|
||||
}
|
||||
return uint64(1) << (len * 8)
|
||||
}
|
||||
|
||||
check := func(length PacketNumberLen, expected, last uint64) {
|
||||
epoch := getEpoch(length)
|
||||
epochMask := epoch - 1
|
||||
|
@ -151,8 +145,13 @@ var _ = Describe("packet number calculation", func() {
|
|||
Expect(length).To(Equal(PacketNumberLen2))
|
||||
})
|
||||
|
||||
It("sends out higher packet numbers as 4 bytes, if a lot of ACKs are missing", func() {
|
||||
It("sends out higher packet numbers as 3 bytes, if a lot of ACKs are missing", func() {
|
||||
length := GetPacketNumberLengthForHeader(40000, 2)
|
||||
Expect(length).To(Equal(PacketNumberLen3))
|
||||
})
|
||||
|
||||
It("sends out higher packet numbers as 4 bytes, if a lot of ACKs are missing", func() {
|
||||
length := GetPacketNumberLengthForHeader(40000000, 2)
|
||||
Expect(length).To(Equal(PacketNumberLen4))
|
||||
})
|
||||
})
|
||||
|
@ -225,6 +224,10 @@ var _ = Describe("packet number calculation", func() {
|
|||
Expect(GetPacketNumberLength(0xFFFF)).To(Equal(PacketNumberLen2))
|
||||
})
|
||||
|
||||
It("3 byte", func() {
|
||||
Expect(GetPacketNumberLength(0xFFFFFF)).To(Equal(PacketNumberLen3))
|
||||
})
|
||||
|
||||
It("4 byte", func() {
|
||||
Expect(GetPacketNumberLength(0xFFFFFFFF)).To(Equal(PacketNumberLen4))
|
||||
})
|
||||
|
|
|
@ -7,20 +7,6 @@ import (
|
|||
// A PacketNumber in QUIC
|
||||
type PacketNumber uint64
|
||||
|
||||
// PacketNumberLen is the length of the packet number in bytes
|
||||
type PacketNumberLen uint8
|
||||
|
||||
const (
|
||||
// PacketNumberLenInvalid is the default value and not a valid length for a packet number
|
||||
PacketNumberLenInvalid PacketNumberLen = 0
|
||||
// PacketNumberLen1 is a packet number length of 1 byte
|
||||
PacketNumberLen1 PacketNumberLen = 1
|
||||
// PacketNumberLen2 is a packet number length of 2 bytes
|
||||
PacketNumberLen2 PacketNumberLen = 2
|
||||
// PacketNumberLen4 is a packet number length of 4 bytes
|
||||
PacketNumberLen4 PacketNumberLen = 4
|
||||
)
|
||||
|
||||
// The PacketType is the Long Header Type
|
||||
type PacketType uint8
|
||||
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
)
|
||||
|
||||
// ReadVarIntPacketNumber reads a number in the QUIC varint packet number format
|
||||
func ReadVarIntPacketNumber(b *bytes.Reader) (protocol.PacketNumber, protocol.PacketNumberLen, error) {
|
||||
b1, err := b.ReadByte()
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
if b1&0x80 == 0 {
|
||||
return protocol.PacketNumber(b1), protocol.PacketNumberLen1, nil
|
||||
}
|
||||
b2, err := b.ReadByte()
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
if b1&0x40 == 0 {
|
||||
return protocol.PacketNumber(uint64(b1&0x3f)<<8 + uint64(b2)), protocol.PacketNumberLen2, nil
|
||||
}
|
||||
b3, err := b.ReadByte()
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
b4, err := b.ReadByte()
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
return protocol.PacketNumber(uint64(b1&0x3f)<<24 + uint64(b2)<<16 + uint64(b3)<<8 + uint64(b4)), protocol.PacketNumberLen4, nil
|
||||
}
|
||||
|
||||
// WriteVarIntPacketNumber writes a packet number in the QUIC varint packet number format
|
||||
func WriteVarIntPacketNumber(b *bytes.Buffer, i protocol.PacketNumber, len protocol.PacketNumberLen) error {
|
||||
switch len {
|
||||
case protocol.PacketNumberLen1:
|
||||
b.WriteByte(uint8(i & 0x7f))
|
||||
case protocol.PacketNumberLen2:
|
||||
b.Write([]byte{(uint8(i>>8) & 0x3f) | 0x80, uint8(i)})
|
||||
case protocol.PacketNumberLen4:
|
||||
b.Write([]byte{(uint8(i>>24) & 0x3f) | 0xc0, uint8(i >> 16), uint8(i >> 8), uint8(i)})
|
||||
default:
|
||||
return fmt.Errorf("invalid packet number length: %d", len)
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -1,157 +0,0 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
|
||||
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Varint packet number encoding / decoding", func() {
|
||||
Context("Decoding", func() {
|
||||
It("reads a 1 byte number", func() {
|
||||
b := bytes.NewReader([]byte{0x19}) // 00011001
|
||||
p, len, err := ReadVarIntPacketNumber(b)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(len).To(Equal(protocol.PacketNumberLen1))
|
||||
Expect(p).To(Equal(protocol.PacketNumber(0x19)))
|
||||
})
|
||||
|
||||
It("errors when given an empty reader", func() {
|
||||
_, _, err := ReadVarIntPacketNumber(bytes.NewReader(nil))
|
||||
Expect(err).To(MatchError(io.EOF))
|
||||
})
|
||||
|
||||
It("reads a 2 byte number", func() {
|
||||
b := bytes.NewReader([]byte{0xb7, 0x19}) // first byte: 10110111
|
||||
p, len, err := ReadVarIntPacketNumber(b)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(len).To(Equal(protocol.PacketNumberLen2))
|
||||
Expect(p).To(Equal(protocol.PacketNumber(0x3719)))
|
||||
})
|
||||
|
||||
It("errors on EOF when reading a 2 byte number", func() {
|
||||
b := bytes.NewReader([]byte{0xb7}) // first byte: 10110111
|
||||
_, _, err := ReadVarIntPacketNumber(b)
|
||||
Expect(err).To(MatchError(io.EOF))
|
||||
})
|
||||
|
||||
It("reads a 4 byte number", func() {
|
||||
b := bytes.NewReader([]byte{0xe5, 0x89, 0xfa, 0x19}) // first byte: 11100101
|
||||
p, len, err := ReadVarIntPacketNumber(b)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(len).To(Equal(protocol.PacketNumberLen4))
|
||||
Expect(p).To(Equal(protocol.PacketNumber(0x2589fa19)))
|
||||
})
|
||||
|
||||
It("errors on EOF after the 3rd byte when reading a 4 byte number", func() {
|
||||
b := bytes.NewReader([]byte{0xe5, 0x89}) // first byte: 11100101
|
||||
_, _, err := ReadVarIntPacketNumber(b)
|
||||
Expect(err).To(MatchError(io.EOF))
|
||||
})
|
||||
|
||||
It("errors on EOF after the 4th byte when reading a 4 byte number", func() {
|
||||
b := bytes.NewReader([]byte{0xe5, 0x89, 0xfa}) // first byte: 11100101
|
||||
_, _, err := ReadVarIntPacketNumber(b)
|
||||
Expect(err).To(MatchError(io.EOF))
|
||||
})
|
||||
})
|
||||
|
||||
Context("Encoding", func() {
|
||||
It("writes a 1 byte packet number", func() {
|
||||
b := &bytes.Buffer{}
|
||||
err := WriteVarIntPacketNumber(b, 0x42, protocol.PacketNumberLen1)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(b.Len()).To(Equal(1))
|
||||
p, len, err := ReadVarIntPacketNumber(bytes.NewReader(b.Bytes()))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(len).To(Equal(protocol.PacketNumberLen1))
|
||||
Expect(p).To(Equal(protocol.PacketNumber(0x42)))
|
||||
})
|
||||
|
||||
It("only uses the least significant 7 bits when writing a 1 byte packet number", func() {
|
||||
b := &bytes.Buffer{}
|
||||
err := WriteVarIntPacketNumber(b, 0x1234ea, protocol.PacketNumberLen1)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(b.Len()).To(Equal(1))
|
||||
p, len, err := ReadVarIntPacketNumber(bytes.NewReader(b.Bytes()))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(len).To(Equal(protocol.PacketNumberLen1))
|
||||
Expect(p).To(Equal(protocol.PacketNumber(0x6a)))
|
||||
})
|
||||
|
||||
It("writes a small 2 byte packet number", func() {
|
||||
b := &bytes.Buffer{}
|
||||
err := WriteVarIntPacketNumber(b, 0x42, protocol.PacketNumberLen2)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(b.Len()).To(Equal(2))
|
||||
p, len, err := ReadVarIntPacketNumber(bytes.NewReader(b.Bytes()))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(len).To(Equal(protocol.PacketNumberLen2))
|
||||
Expect(p).To(Equal(protocol.PacketNumber(0x42)))
|
||||
})
|
||||
|
||||
It("writes a 2 byte packet number", func() {
|
||||
b := &bytes.Buffer{}
|
||||
err := WriteVarIntPacketNumber(b, 0x1337, protocol.PacketNumberLen2)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(b.Len()).To(Equal(2))
|
||||
p, len, err := ReadVarIntPacketNumber(bytes.NewReader(b.Bytes()))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(len).To(Equal(protocol.PacketNumberLen2))
|
||||
Expect(p).To(Equal(protocol.PacketNumber(0x1337)))
|
||||
})
|
||||
|
||||
It("only uses the least significant 14 bits when writing a 2 byte packet number", func() {
|
||||
b := &bytes.Buffer{}
|
||||
err := WriteVarIntPacketNumber(b, 0x1234ff37, protocol.PacketNumberLen2)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(b.Len()).To(Equal(2))
|
||||
p, len, err := ReadVarIntPacketNumber(bytes.NewReader(b.Bytes()))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(len).To(Equal(protocol.PacketNumberLen2))
|
||||
Expect(p).To(Equal(protocol.PacketNumber(0x3f37)))
|
||||
})
|
||||
|
||||
It("writes a small 4 byte packet number", func() {
|
||||
b := &bytes.Buffer{}
|
||||
err := WriteVarIntPacketNumber(b, 0xbeef, protocol.PacketNumberLen4)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(b.Len()).To(Equal(4))
|
||||
p, len, err := ReadVarIntPacketNumber(bytes.NewReader(b.Bytes()))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(len).To(Equal(protocol.PacketNumberLen4))
|
||||
Expect(p).To(Equal(protocol.PacketNumber(0xbeef)))
|
||||
})
|
||||
|
||||
It("writes a 4 byte packet number", func() {
|
||||
b := &bytes.Buffer{}
|
||||
err := WriteVarIntPacketNumber(b, 0x12beef42, protocol.PacketNumberLen4)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(b.Len()).To(Equal(4))
|
||||
p, len, err := ReadVarIntPacketNumber(bytes.NewReader(b.Bytes()))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(len).To(Equal(protocol.PacketNumberLen4))
|
||||
Expect(p).To(Equal(protocol.PacketNumber(0x12beef42)))
|
||||
})
|
||||
|
||||
It("only uses the least significant 30 bits when writing a 4 byte packet number", func() {
|
||||
b := &bytes.Buffer{}
|
||||
err := WriteVarIntPacketNumber(b, 0x1234deadbeef, protocol.PacketNumberLen4)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(b.Len()).To(Equal(4))
|
||||
p, len, err := ReadVarIntPacketNumber(bytes.NewReader(b.Bytes()))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(len).To(Equal(protocol.PacketNumberLen4))
|
||||
Expect(p).To(Equal(protocol.PacketNumber(0x1eadbeef)))
|
||||
})
|
||||
|
||||
It("errors when encountering invalid packet number lengths", func() {
|
||||
b := &bytes.Buffer{}
|
||||
err := WriteVarIntPacketNumber(b, 0x1234deadbeef, 13)
|
||||
Expect(err).To(MatchError("invalid packet number length: 13"))
|
||||
})
|
||||
})
|
||||
})
|
|
@ -4,6 +4,7 @@ import (
|
|||
"bytes"
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
"github.com/lucas-clemente/quic-go/internal/utils"
|
||||
|
@ -13,7 +14,8 @@ import (
|
|||
type ExtendedHeader struct {
|
||||
Header
|
||||
|
||||
Raw []byte
|
||||
typeByte byte
|
||||
Raw []byte
|
||||
|
||||
PacketNumberLen protocol.PacketNumberLen
|
||||
PacketNumber protocol.PacketNumber
|
||||
|
@ -22,6 +24,15 @@ type ExtendedHeader struct {
|
|||
}
|
||||
|
||||
func (h *ExtendedHeader) parse(b *bytes.Reader, v protocol.VersionNumber) (*ExtendedHeader, error) {
|
||||
// read the (now unencrypted) first byte
|
||||
var err error
|
||||
h.typeByte, err = b.ReadByte()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err := b.Seek(int64(h.len)-1, io.SeekCurrent); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if h.IsLongHeader {
|
||||
return h.parseLongHeader(b, v)
|
||||
}
|
||||
|
@ -29,27 +40,31 @@ func (h *ExtendedHeader) parse(b *bytes.Reader, v protocol.VersionNumber) (*Exte
|
|||
}
|
||||
|
||||
func (h *ExtendedHeader) parseLongHeader(b *bytes.Reader, v protocol.VersionNumber) (*ExtendedHeader, error) {
|
||||
pn, pnLen, err := utils.ReadVarIntPacketNumber(b)
|
||||
if err != nil {
|
||||
if err := h.readPacketNumber(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
h.PacketNumber = pn
|
||||
h.PacketNumberLen = pnLen
|
||||
return h, nil
|
||||
}
|
||||
|
||||
func (h *ExtendedHeader) parseShortHeader(b *bytes.Reader, v protocol.VersionNumber) (*ExtendedHeader, error) {
|
||||
h.KeyPhase = int(h.typeByte&0x4) >> 2
|
||||
|
||||
pn, pnLen, err := utils.ReadVarIntPacketNumber(b)
|
||||
if err != nil {
|
||||
if err := h.readPacketNumber(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
h.PacketNumber = pn
|
||||
h.PacketNumberLen = pnLen
|
||||
return h, nil
|
||||
}
|
||||
|
||||
func (h *ExtendedHeader) readPacketNumber(b *bytes.Reader) error {
|
||||
h.PacketNumberLen = protocol.PacketNumberLen(h.typeByte&0x3) + 1
|
||||
pn, err := utils.BigEndian.ReadUintN(b, uint8(h.PacketNumberLen))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
h.PacketNumber = protocol.PacketNumber(pn)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Write writes the Header.
|
||||
func (h *ExtendedHeader) Write(b *bytes.Buffer, ver protocol.VersionNumber) error {
|
||||
if h.IsLongHeader {
|
||||
|
@ -70,7 +85,11 @@ func (h *ExtendedHeader) writeLongHeader(b *bytes.Buffer, v protocol.VersionNumb
|
|||
case protocol.PacketTypeRetry:
|
||||
packetType = 0x3
|
||||
}
|
||||
b.WriteByte(0xc0 | packetType<<4)
|
||||
firstByte := 0xc0 | packetType<<4
|
||||
if h.Type != protocol.PacketTypeRetry { // Retry packets don't have a packet number
|
||||
firstByte |= uint8(h.PacketNumberLen - 1)
|
||||
}
|
||||
b.WriteByte(firstByte)
|
||||
utils.BigEndian.WriteUint32(b, uint32(h.Version))
|
||||
connIDLen, err := encodeConnIDLen(h.DestConnectionID, h.SrcConnectionID)
|
||||
if err != nil {
|
||||
|
@ -101,17 +120,25 @@ func (h *ExtendedHeader) writeLongHeader(b *bytes.Buffer, v protocol.VersionNumb
|
|||
}
|
||||
|
||||
utils.WriteVarInt(b, uint64(h.Length))
|
||||
return utils.WriteVarIntPacketNumber(b, h.PacketNumber, h.PacketNumberLen)
|
||||
return h.writePacketNumber(b)
|
||||
}
|
||||
|
||||
// TODO: add support for the key phase
|
||||
func (h *ExtendedHeader) writeShortHeader(b *bytes.Buffer, v protocol.VersionNumber) error {
|
||||
typeByte := byte(0x40)
|
||||
typeByte := 0x40 | uint8(h.PacketNumberLen-1)
|
||||
typeByte |= byte(h.KeyPhase << 2)
|
||||
|
||||
b.WriteByte(typeByte)
|
||||
b.Write(h.DestConnectionID.Bytes())
|
||||
return utils.WriteVarIntPacketNumber(b, h.PacketNumber, h.PacketNumberLen)
|
||||
return h.writePacketNumber(b)
|
||||
}
|
||||
|
||||
func (h *ExtendedHeader) writePacketNumber(b *bytes.Buffer) error {
|
||||
if h.PacketNumberLen == protocol.PacketNumberLenInvalid || h.PacketNumberLen > protocol.PacketNumberLen4 {
|
||||
return fmt.Errorf("invalid packet number length: %d", h.PacketNumberLen)
|
||||
}
|
||||
utils.BigEndian.WriteUintN(b, uint8(h.PacketNumberLen), uint64(h.PacketNumber))
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetLength determines the length of the Header.
|
||||
|
|
|
@ -21,12 +21,6 @@ var _ = Describe("Header", func() {
|
|||
buf = &bytes.Buffer{}
|
||||
})
|
||||
|
||||
appendPacketNumber := func(data []byte, pn protocol.PacketNumber, pnLen protocol.PacketNumberLen) []byte {
|
||||
buf := &bytes.Buffer{}
|
||||
utils.WriteVarIntPacketNumber(buf, pn, pnLen)
|
||||
return append(data, buf.Bytes()...)
|
||||
}
|
||||
|
||||
Context("Long Header", func() {
|
||||
srcConnID := protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8}
|
||||
|
||||
|
@ -41,17 +35,17 @@ var _ = Describe("Header", func() {
|
|||
Length: 0xcafe,
|
||||
},
|
||||
PacketNumber: 0xdecaf,
|
||||
PacketNumberLen: protocol.PacketNumberLen4,
|
||||
PacketNumberLen: protocol.PacketNumberLen3,
|
||||
}).Write(buf, versionIETFHeader)).To(Succeed())
|
||||
expected := []byte{
|
||||
0xc0 ^ 0x2<<4,
|
||||
0xc0 | 0x2<<4 | 0x2,
|
||||
0x1, 0x2, 0x3, 0x4, // version number
|
||||
0x35, // connection ID lengths
|
||||
0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, // dest connection ID
|
||||
0xde, 0xca, 0xfb, 0xad, 0x0, 0x0, 0x13, 0x37, // source connection ID
|
||||
}
|
||||
expected = append(expected, encodeVarInt(0xcafe)...) // length
|
||||
expected = appendPacketNumber(expected, 0xdecaf, protocol.PacketNumberLen4)
|
||||
expected = append(expected, encodeVarInt(0xcafe)...) // length
|
||||
expected = append(expected, []byte{0xd, 0xec, 0xaf}...) // packet number
|
||||
Expect(buf.Bytes()).To(Equal(expected))
|
||||
})
|
||||
|
||||
|
@ -180,27 +174,27 @@ var _ = Describe("Header", func() {
|
|||
PacketNumberLen: protocol.PacketNumberLen2,
|
||||
PacketNumber: 0x765,
|
||||
}).Write(buf, versionIETFHeader)).To(Succeed())
|
||||
expected := []byte{0x40}
|
||||
expected = appendPacketNumber(expected, 0x765, protocol.PacketNumberLen2)
|
||||
expected := []byte{0x40 | 0x1}
|
||||
expected = append(expected, []byte{0x7, 0x65}...) // packet number
|
||||
Expect(buf.Bytes()).To(Equal(expected))
|
||||
})
|
||||
|
||||
It("writes a header with a 4 byte packet number", func() {
|
||||
Expect((&ExtendedHeader{
|
||||
PacketNumberLen: protocol.PacketNumberLen4,
|
||||
PacketNumber: 0x123456,
|
||||
PacketNumber: 0x12345678,
|
||||
}).Write(buf, versionIETFHeader)).To(Succeed())
|
||||
expected := []byte{0x40}
|
||||
expected = appendPacketNumber(expected, 0x123456, protocol.PacketNumberLen4)
|
||||
expected := []byte{0x40 | 0x3}
|
||||
expected = append(expected, []byte{0x12, 0x34, 0x56, 0x78}...)
|
||||
Expect(buf.Bytes()).To(Equal(expected))
|
||||
})
|
||||
|
||||
It("errors when given an invalid packet number length", func() {
|
||||
err := (&ExtendedHeader{
|
||||
PacketNumberLen: 3,
|
||||
PacketNumberLen: 5,
|
||||
PacketNumber: 0xdecafbad,
|
||||
}).Write(buf, versionIETFHeader)
|
||||
Expect(err).To(MatchError("invalid packet number length: 3"))
|
||||
Expect(err).To(MatchError("invalid packet number length: 5"))
|
||||
})
|
||||
|
||||
It("writes the Key Phase Bit", func() {
|
||||
|
|
|
@ -178,9 +178,6 @@ func (h *Header) IsVersionNegotiation() bool {
|
|||
// 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) {
|
||||
if _, err := b.Seek(int64(h.len), io.SeekCurrent); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return h.toExtendedHeader().parse(b, ver)
|
||||
}
|
||||
|
||||
|
|
|
@ -7,18 +7,11 @@ import (
|
|||
|
||||
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
"github.com/lucas-clemente/quic-go/internal/qerr"
|
||||
"github.com/lucas-clemente/quic-go/internal/utils"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Header Parsing", func() {
|
||||
appendPacketNumber := func(data []byte, pn protocol.PacketNumber, pnLen protocol.PacketNumberLen) []byte {
|
||||
buf := &bytes.Buffer{}
|
||||
utils.WriteVarIntPacketNumber(buf, pn, pnLen)
|
||||
return append(data, buf.Bytes()...)
|
||||
}
|
||||
|
||||
appendVersion := func(data []byte, v protocol.VersionNumber) []byte {
|
||||
offset := len(data)
|
||||
data = append(data, []byte{0, 0, 0, 0}...)
|
||||
|
@ -73,7 +66,7 @@ var _ = Describe("Header Parsing", func() {
|
|||
It("parses a Long Header", func() {
|
||||
destConnID := protocol.ConnectionID{9, 8, 7, 6, 5, 4, 3, 2, 1}
|
||||
srcConnID := protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef}
|
||||
data := []byte{0xc0}
|
||||
data := []byte{0xc0 ^ 0x3}
|
||||
data = appendVersion(data, versionIETFFrames)
|
||||
data = append(data, 0x61) // connection ID lengths
|
||||
data = append(data, destConnID...)
|
||||
|
@ -81,7 +74,7 @@ var _ = Describe("Header Parsing", func() {
|
|||
data = append(data, encodeVarInt(6)...) // token length
|
||||
data = append(data, []byte("foobar")...) // token
|
||||
data = append(data, encodeVarInt(0x1337)...) // length
|
||||
data = appendPacketNumber(data, 0xbeef, protocol.PacketNumberLen4)
|
||||
data = append(data, []byte{0, 0, 0xbe, 0xef}...)
|
||||
|
||||
hdr, err := ParseHeader(bytes.NewReader(data), 0)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -159,12 +152,12 @@ var _ = Describe("Header Parsing", func() {
|
|||
})
|
||||
|
||||
It("parses a Long Header with a 2 byte packet number", func() {
|
||||
data := []byte{0xc0}
|
||||
data := []byte{0xc0 ^ 0x1}
|
||||
data = appendVersion(data, versionIETFFrames) // version number
|
||||
data = append(data, 0x0) // connection ID lengths
|
||||
data = append(data, encodeVarInt(0)...) // token length
|
||||
data = append(data, encodeVarInt(0x42)...) // length
|
||||
data = appendPacketNumber(data, 0x123, protocol.PacketNumberLen2)
|
||||
data = append(data, []byte{0x1, 0x23}...)
|
||||
|
||||
hdr, err := ParseHeader(bytes.NewReader(data), 0)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@ -193,12 +186,12 @@ var _ = Describe("Header Parsing", func() {
|
|||
})
|
||||
|
||||
It("errors if the token length is too large", func() {
|
||||
data := []byte{0xc0}
|
||||
data := []byte{0xc0 ^ 0x1}
|
||||
data = appendVersion(data, versionIETFFrames)
|
||||
data = append(data, 0x0) // connection ID lengths
|
||||
data = append(data, encodeVarInt(4)...) // token length: 4 bytes (1 byte too long)
|
||||
data = append(data, encodeVarInt(0x42)...) // length, 1 byte
|
||||
data = appendPacketNumber(data, 0x123, protocol.PacketNumberLen2) // 2 bytes
|
||||
data = append(data, 0x0) // connection ID lengths
|
||||
data = append(data, encodeVarInt(4)...) // token length: 4 bytes (1 byte too long)
|
||||
data = append(data, encodeVarInt(0x42)...) // length, 1 byte
|
||||
data = append(data, []byte{0x12, 0x34}...) // packet number
|
||||
|
||||
b := bytes.NewReader(data)
|
||||
_, err := ParseHeader(b, 0)
|
||||
|
@ -218,12 +211,12 @@ var _ = Describe("Header Parsing", func() {
|
|||
})
|
||||
|
||||
It("errors on EOF, when parsing the extended header", func() {
|
||||
data := []byte{0xc0 ^ 0x2<<4}
|
||||
data := []byte{0xc0 | 0x2<<4 | 0x3}
|
||||
data = appendVersion(data, versionIETFFrames)
|
||||
data = append(data, 0x0) // connection ID lengths
|
||||
data = append(data, encodeVarInt(0x1337)...)
|
||||
hdrLen := len(data)
|
||||
data = appendPacketNumber(data, 0xdeadbeef, protocol.PacketNumberLen4)
|
||||
data = append(data, []byte{0xde, 0xad, 0xbe, 0xef}...) // packet number
|
||||
for i := hdrLen; i < len(data); i++ {
|
||||
b := bytes.NewReader(data[:i])
|
||||
hdr, err := ParseHeader(b, 0)
|
||||
|
@ -254,7 +247,7 @@ var _ = Describe("Header Parsing", func() {
|
|||
It("reads a Short Header with a 8 byte connection ID", func() {
|
||||
connID := protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37}
|
||||
data := append([]byte{0x40}, connID...)
|
||||
data = appendPacketNumber(data, 0x42, protocol.PacketNumberLen1)
|
||||
data = append(data, 0x42) // packet number
|
||||
hdr, err := ParseHeader(bytes.NewReader(data), 8)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(hdr.IsLongHeader).To(BeFalse())
|
||||
|
@ -280,7 +273,7 @@ var _ = Describe("Header Parsing", func() {
|
|||
It("reads a Short Header with a 5 byte connection ID", func() {
|
||||
connID := protocol.ConnectionID{1, 2, 3, 4, 5}
|
||||
data := append([]byte{0x40}, connID...)
|
||||
data = appendPacketNumber(data, 0x42, protocol.PacketNumberLen1)
|
||||
data = append(data, 0x42) // packet number
|
||||
hdr, err := ParseHeader(bytes.NewReader(data), 5)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(hdr.IsLongHeader).To(BeFalse())
|
||||
|
@ -299,7 +292,7 @@ var _ = Describe("Header Parsing", func() {
|
|||
0x40 ^ 0x4,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, // connection ID
|
||||
}
|
||||
data = appendPacketNumber(data, 11, protocol.PacketNumberLen1)
|
||||
data = append(data, 11) // packet number
|
||||
hdr, err := ParseHeader(bytes.NewReader(data), 6)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(hdr.IsLongHeader).To(BeFalse())
|
||||
|
@ -312,10 +305,10 @@ var _ = Describe("Header Parsing", func() {
|
|||
|
||||
It("reads a header with a 2 byte packet number", func() {
|
||||
data := []byte{
|
||||
0x40,
|
||||
0x40 | 0x1,
|
||||
0xde, 0xad, 0xbe, 0xef, // connection ID
|
||||
}
|
||||
data = appendPacketNumber(data, 0x1337, protocol.PacketNumberLen2)
|
||||
data = append(data, []byte{0x13, 0x37}...) // packet number
|
||||
hdr, err := ParseHeader(bytes.NewReader(data), 4)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
b := bytes.NewReader(data)
|
||||
|
@ -327,12 +320,12 @@ var _ = Describe("Header Parsing", func() {
|
|||
Expect(b.Len()).To(BeZero())
|
||||
})
|
||||
|
||||
It("reads a header with a 4 byte packet number", func() {
|
||||
It("reads a header with a 3 byte packet number", func() {
|
||||
data := []byte{
|
||||
0x40,
|
||||
0x40 | 0x2,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x1, 0x2, 0x3, 0x4, // connection ID
|
||||
}
|
||||
data = appendPacketNumber(data, 0x99beef, protocol.PacketNumberLen4)
|
||||
data = append(data, []byte{0x99, 0xbe, 0xef}...) // packet number
|
||||
hdr, err := ParseHeader(bytes.NewReader(data), 10)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
b := bytes.NewReader(data)
|
||||
|
@ -340,7 +333,7 @@ var _ = Describe("Header Parsing", func() {
|
|||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(extHdr.IsLongHeader).To(BeFalse())
|
||||
Expect(extHdr.PacketNumber).To(Equal(protocol.PacketNumber(0x99beef)))
|
||||
Expect(extHdr.PacketNumberLen).To(Equal(protocol.PacketNumberLen4))
|
||||
Expect(extHdr.PacketNumberLen).To(Equal(protocol.PacketNumberLen3))
|
||||
Expect(b.Len()).To(BeZero())
|
||||
})
|
||||
|
||||
|
@ -357,11 +350,11 @@ var _ = Describe("Header Parsing", func() {
|
|||
|
||||
It("errors on EOF, when parsing the extended header", func() {
|
||||
data := []byte{
|
||||
0x40,
|
||||
0x40 ^ 0x3,
|
||||
0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, // connection ID
|
||||
}
|
||||
hdrLen := len(data)
|
||||
data = appendPacketNumber(data, 0xdeadbeef, protocol.PacketNumberLen4)
|
||||
data = append(data, []byte{0xde, 0xad, 0xbe, 0xef}...) // packet number
|
||||
for i := hdrLen; i < len(data); i++ {
|
||||
b := bytes.NewReader(data[:i])
|
||||
hdr, err := ParseHeader(b, 6)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue