mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-05 05:07:36 +03:00
use the new packet header for connections using TLS
This commit is contained in:
parent
6c394acde7
commit
4556ad01e5
18 changed files with 631 additions and 421 deletions
|
@ -249,10 +249,10 @@ func (c *client) handlePacket(remoteAddr net.Addr, packet []byte) {
|
||||||
rcvTime := time.Now()
|
rcvTime := time.Now()
|
||||||
|
|
||||||
r := bytes.NewReader(packet)
|
r := bytes.NewReader(packet)
|
||||||
hdr, err := wire.ParsePublicHeader(r, protocol.PerspectiveServer, c.version)
|
hdr, err := wire.ParseHeader(r, protocol.PerspectiveServer, c.version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Errorf("error parsing packet from %s: %s", remoteAddr.String(), err.Error())
|
utils.Errorf("error parsing packet from %s: %s", remoteAddr.String(), err.Error())
|
||||||
// drop this packet if we can't parse the Public Header
|
// drop this packet if we can't parse the header
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// reject packets with truncated connection id if we didn't request truncation
|
// reject packets with truncated connection id if we didn't request truncation
|
||||||
|
@ -308,13 +308,13 @@ func (c *client) handlePacket(remoteAddr net.Addr, packet []byte) {
|
||||||
|
|
||||||
c.session.handlePacket(&receivedPacket{
|
c.session.handlePacket(&receivedPacket{
|
||||||
remoteAddr: remoteAddr,
|
remoteAddr: remoteAddr,
|
||||||
publicHeader: hdr,
|
header: hdr,
|
||||||
data: packet[len(packet)-r.Len():],
|
data: packet[len(packet)-r.Len():],
|
||||||
rcvTime: rcvTime,
|
rcvTime: rcvTime,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *client) handlePacketWithVersionFlag(hdr *wire.PublicHeader) error {
|
func (c *client) handlePacketWithVersionFlag(hdr *wire.Header) error {
|
||||||
for _, v := range hdr.SupportedVersions {
|
for _, v := range hdr.SupportedVersions {
|
||||||
if v == c.version {
|
if v == c.version {
|
||||||
// the version negotiation packet contains the version that we offered
|
// the version negotiation packet contains the version that we offered
|
||||||
|
|
|
@ -30,11 +30,11 @@ var _ = Describe("Client", func() {
|
||||||
// generate a packet sent by the server that accepts the QUIC version suggested by the client
|
// generate a packet sent by the server that accepts the QUIC version suggested by the client
|
||||||
acceptClientVersionPacket := func(connID protocol.ConnectionID) []byte {
|
acceptClientVersionPacket := func(connID protocol.ConnectionID) []byte {
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
err := (&wire.PublicHeader{
|
err := (&wire.Header{
|
||||||
ConnectionID: connID,
|
ConnectionID: connID,
|
||||||
PacketNumber: 1,
|
PacketNumber: 1,
|
||||||
PacketNumberLen: 1,
|
PacketNumberLen: 1,
|
||||||
}).Write(b, protocol.VersionWhatever, protocol.PerspectiveServer)
|
}).Write(b, protocol.PerspectiveServer, protocol.VersionWhatever)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
return b.Bytes()
|
return b.Bytes()
|
||||||
}
|
}
|
||||||
|
@ -302,13 +302,13 @@ var _ = Describe("Client", func() {
|
||||||
|
|
||||||
Context("version negotiation", func() {
|
Context("version negotiation", func() {
|
||||||
It("recognizes that a packet without VersionFlag means that the server accepted the suggested version", func() {
|
It("recognizes that a packet without VersionFlag means that the server accepted the suggested version", func() {
|
||||||
ph := wire.PublicHeader{
|
ph := wire.Header{
|
||||||
PacketNumber: 1,
|
PacketNumber: 1,
|
||||||
PacketNumberLen: protocol.PacketNumberLen2,
|
PacketNumberLen: protocol.PacketNumberLen2,
|
||||||
ConnectionID: 0x1337,
|
ConnectionID: 0x1337,
|
||||||
}
|
}
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
err := ph.Write(b, protocol.VersionWhatever, protocol.PerspectiveServer)
|
err := ph.Write(b, protocol.PerspectiveServer, protocol.VersionWhatever)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
cl.handlePacket(nil, b.Bytes())
|
cl.handlePacket(nil, b.Bytes())
|
||||||
Expect(cl.versionNegotiated).To(BeTrue())
|
Expect(cl.versionNegotiated).To(BeTrue())
|
||||||
|
@ -450,11 +450,11 @@ var _ = Describe("Client", func() {
|
||||||
It("ignores packets without connection id, if it didn't request connection id trunctation", func() {
|
It("ignores packets without connection id, if it didn't request connection id trunctation", func() {
|
||||||
cl.config.RequestConnectionIDOmission = false
|
cl.config.RequestConnectionIDOmission = false
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
(&wire.PublicHeader{
|
(&wire.Header{
|
||||||
OmitConnectionID: true,
|
OmitConnectionID: true,
|
||||||
PacketNumber: 1,
|
PacketNumber: 1,
|
||||||
PacketNumberLen: 1,
|
PacketNumberLen: 1,
|
||||||
}).Write(buf, protocol.VersionWhatever, protocol.PerspectiveServer)
|
}).Write(buf, protocol.PerspectiveServer, protocol.VersionWhatever)
|
||||||
cl.handlePacket(addr, buf.Bytes())
|
cl.handlePacket(addr, buf.Bytes())
|
||||||
Expect(sess.packetCount).To(BeZero())
|
Expect(sess.packetCount).To(BeZero())
|
||||||
Expect(sess.closed).To(BeFalse())
|
Expect(sess.closed).To(BeFalse())
|
||||||
|
@ -462,11 +462,11 @@ var _ = Describe("Client", func() {
|
||||||
|
|
||||||
It("ignores packets with the wrong connection ID", func() {
|
It("ignores packets with the wrong connection ID", func() {
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
(&wire.PublicHeader{
|
(&wire.Header{
|
||||||
ConnectionID: cl.connectionID + 1,
|
ConnectionID: cl.connectionID + 1,
|
||||||
PacketNumber: 1,
|
PacketNumber: 1,
|
||||||
PacketNumberLen: 1,
|
PacketNumberLen: 1,
|
||||||
}).Write(buf, protocol.VersionWhatever, protocol.PerspectiveServer)
|
}).Write(buf, protocol.PerspectiveServer, protocol.VersionWhatever)
|
||||||
cl.handlePacket(addr, buf.Bytes())
|
cl.handlePacket(addr, buf.Bytes())
|
||||||
Expect(sess.packetCount).To(BeZero())
|
Expect(sess.packetCount).To(BeZero())
|
||||||
Expect(sess.closed).To(BeFalse())
|
Expect(sess.closed).To(BeFalse())
|
||||||
|
@ -513,13 +513,13 @@ var _ = Describe("Client", func() {
|
||||||
|
|
||||||
Context("handling packets", func() {
|
Context("handling packets", func() {
|
||||||
It("handles packets", func() {
|
It("handles packets", func() {
|
||||||
ph := wire.PublicHeader{
|
ph := wire.Header{
|
||||||
PacketNumber: 1,
|
PacketNumber: 1,
|
||||||
PacketNumberLen: protocol.PacketNumberLen2,
|
PacketNumberLen: protocol.PacketNumberLen2,
|
||||||
ConnectionID: 0x1337,
|
ConnectionID: 0x1337,
|
||||||
}
|
}
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
err := ph.Write(b, cl.version, protocol.PerspectiveServer)
|
err := ph.Write(b, protocol.PerspectiveServer, cl.version)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
packetConn.dataToRead = b.Bytes()
|
packetConn.dataToRead = b.Bytes()
|
||||||
|
|
||||||
|
|
|
@ -20,13 +20,13 @@ type packetData []byte
|
||||||
var _ = Describe("QUIC Proxy", func() {
|
var _ = Describe("QUIC Proxy", func() {
|
||||||
makePacket := func(p protocol.PacketNumber, payload []byte) []byte {
|
makePacket := func(p protocol.PacketNumber, payload []byte) []byte {
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
hdr := wire.PublicHeader{
|
hdr := wire.Header{
|
||||||
PacketNumber: p,
|
PacketNumber: p,
|
||||||
PacketNumberLen: protocol.PacketNumberLen6,
|
PacketNumberLen: protocol.PacketNumberLen6,
|
||||||
ConnectionID: 1337,
|
ConnectionID: 1337,
|
||||||
OmitConnectionID: false,
|
OmitConnectionID: false,
|
||||||
}
|
}
|
||||||
hdr.Write(b, protocol.VersionWhatever, protocol.PerspectiveServer)
|
hdr.Write(b, protocol.PerspectiveServer, protocol.VersionWhatever)
|
||||||
raw := b.Bytes()
|
raw := b.Bytes()
|
||||||
raw = append(raw, payload...)
|
raw = append(raw, payload...)
|
||||||
return raw
|
return raw
|
||||||
|
|
96
internal/wire/header.go
Normal file
96
internal/wire/header.go
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
package wire
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
|
||||||
|
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||||
|
"github.com/lucas-clemente/quic-go/internal/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Header is the header of a QUIC packet.
|
||||||
|
// It contains fields that are only needed for the gQUIC Public Header and the IETF draft Header.
|
||||||
|
type Header struct {
|
||||||
|
Raw []byte
|
||||||
|
ConnectionID protocol.ConnectionID
|
||||||
|
OmitConnectionID bool
|
||||||
|
PacketNumberLen protocol.PacketNumberLen
|
||||||
|
PacketNumber protocol.PacketNumber
|
||||||
|
Version protocol.VersionNumber // VersionNumber sent by the client
|
||||||
|
SupportedVersions []protocol.VersionNumber // Version Number sent in a Version Negotiation Packet by the server
|
||||||
|
|
||||||
|
// only needed for the gQUIC Public Header
|
||||||
|
VersionFlag bool
|
||||||
|
ResetFlag bool
|
||||||
|
DiversificationNonce []byte
|
||||||
|
|
||||||
|
// only needed for the IETF Header
|
||||||
|
Type uint8
|
||||||
|
IsLongHeader bool
|
||||||
|
KeyPhase int
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseHeader parses the header.
|
||||||
|
func ParseHeader(b *bytes.Reader, sentBy protocol.Perspective, version protocol.VersionNumber) (*Header, error) {
|
||||||
|
var typeByte uint8
|
||||||
|
if version == protocol.VersionUnknown {
|
||||||
|
var err error
|
||||||
|
typeByte, err = b.ReadByte()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
_ = b.UnreadByte() // unread the type byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// There are two conditions this is a header in the IETF Header format:
|
||||||
|
// 1. We already know the version (because this is a packet that belongs to an exisitng session).
|
||||||
|
// 2. If this is a new packet, it must have the Long Format, which has the 0x80 bit set (which is always 0 in gQUIC).
|
||||||
|
// There's a third option: This could be a packet with Short Format that arrives after a server lost state.
|
||||||
|
// In that case, we'll try parsing the header as a gQUIC Public Header.
|
||||||
|
if version.UsesTLS() || (version == protocol.VersionUnknown && typeByte&0x80 > 0) {
|
||||||
|
return parseHeader(b, sentBy)
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a gQUIC Public Header.
|
||||||
|
return parsePublicHeader(b, sentBy, version)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PeekConnectionID parses the connection ID from a QUIC packet's public header, sent by the client.
|
||||||
|
// This function should not be called for packets sent by the server, since on these packets the Connection ID could be omitted.
|
||||||
|
// If no error occurs, it restores the read position in the bytes.Reader.
|
||||||
|
func PeekConnectionID(b *bytes.Reader) (protocol.ConnectionID, error) {
|
||||||
|
var connectionID protocol.ConnectionID
|
||||||
|
if _, err := b.ReadByte(); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
// unread the public flag byte
|
||||||
|
defer b.UnreadByte()
|
||||||
|
|
||||||
|
// Assume that the packet contains the Connection ID.
|
||||||
|
// This is a valid assumption for all packets sent by the client, because the server doesn't allow the ommision of the Connection ID.
|
||||||
|
connID, err := utils.BigEndian.ReadUint64(b)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
connectionID = protocol.ConnectionID(connID)
|
||||||
|
// unread the connection ID
|
||||||
|
for i := 0; i < 8; i++ {
|
||||||
|
b.UnreadByte()
|
||||||
|
}
|
||||||
|
return connectionID, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write writes the Header.
|
||||||
|
func (h *Header) Write(b *bytes.Buffer, pers protocol.Perspective, version protocol.VersionNumber) error {
|
||||||
|
if !version.UsesTLS() {
|
||||||
|
return h.writePublicHeader(b, pers, version)
|
||||||
|
}
|
||||||
|
return h.writeHeader(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetLength determines the length of the Header.
|
||||||
|
func (h *Header) GetLength(pers protocol.Perspective, version protocol.VersionNumber) (protocol.ByteCount, error) {
|
||||||
|
if !version.UsesTLS() {
|
||||||
|
return h.getPublicHeaderLength(pers)
|
||||||
|
}
|
||||||
|
return h.getHeaderLength()
|
||||||
|
}
|
178
internal/wire/header_test.go
Normal file
178
internal/wire/header_test.go
Normal file
|
@ -0,0 +1,178 @@
|
||||||
|
package wire
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("Header", func() {
|
||||||
|
const (
|
||||||
|
versionPublicHeader = protocol.Version39 // a QUIC version that uses the Public Header format
|
||||||
|
versionIETFHeader = protocol.VersionTLS // a QUIC version taht uses the IETF Header format
|
||||||
|
)
|
||||||
|
|
||||||
|
Context("peeking the connection ID", func() {
|
||||||
|
It("gets the connection ID", func() {
|
||||||
|
b := bytes.NewReader([]byte{0x09, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0x51, 0x30, 0x33, 0x34, 0x01})
|
||||||
|
len := b.Len()
|
||||||
|
connID, err := PeekConnectionID(b)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(connID).To(Equal(protocol.ConnectionID(0x4cfa9f9b668619f6)))
|
||||||
|
Expect(b.Len()).To(Equal(len))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("errors if the header is too short", func() {
|
||||||
|
b := bytes.NewReader([]byte{0x09, 0xf6, 0x19, 0x86, 0x66, 0x9b})
|
||||||
|
_, err := PeekConnectionID(b)
|
||||||
|
Expect(err).To(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("errors if the header is empty", func() {
|
||||||
|
b := bytes.NewReader([]byte{})
|
||||||
|
_, err := PeekConnectionID(b)
|
||||||
|
Expect(err).To(HaveOccurred())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("parsing", func() {
|
||||||
|
It("parses an IETF draft header, when the QUIC version supports TLS", func() {
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
// use a short header, which isn't distinguishable from the gQUIC Public Header when looking at the type byte
|
||||||
|
err := (&Header{
|
||||||
|
IsLongHeader: false,
|
||||||
|
KeyPhase: 1,
|
||||||
|
PacketNumber: 0x42,
|
||||||
|
PacketNumberLen: protocol.PacketNumberLen2,
|
||||||
|
}).writeHeader(buf)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
hdr, err := ParseHeader(bytes.NewReader(buf.Bytes()), protocol.PerspectiveClient, versionIETFHeader)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(hdr.KeyPhase).To(BeEquivalentTo(1))
|
||||||
|
Expect(hdr.PacketNumber).To(Equal(protocol.PacketNumber(0x42)))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("parses an IETF draft header, when the version is not known, but it has Long Header format", func() {
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
err := (&Header{
|
||||||
|
IsLongHeader: true,
|
||||||
|
Type: 3,
|
||||||
|
PacketNumber: 0x42,
|
||||||
|
}).writeHeader(buf)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
hdr, err := ParseHeader(bytes.NewReader(buf.Bytes()), protocol.PerspectiveClient, protocol.VersionUnknown)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(hdr.Type).To(BeEquivalentTo(3))
|
||||||
|
Expect(hdr.PacketNumber).To(Equal(protocol.PacketNumber(0x42)))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("parses a gQUIC Public Header, when the version is not known", func() {
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
err := (&Header{
|
||||||
|
VersionFlag: true,
|
||||||
|
Version: versionPublicHeader,
|
||||||
|
ConnectionID: 0x42,
|
||||||
|
PacketNumber: 0x1337,
|
||||||
|
PacketNumberLen: protocol.PacketNumberLen6,
|
||||||
|
}).writePublicHeader(buf, protocol.PerspectiveClient, versionPublicHeader)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
hdr, err := ParseHeader(bytes.NewReader(buf.Bytes()), protocol.PerspectiveClient, protocol.VersionUnknown)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(hdr.PacketNumber).To(Equal(protocol.PacketNumber(0x1337)))
|
||||||
|
Expect(hdr.Version).To(Equal(versionPublicHeader))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("parses a gQUIC Public Header, when the version is known", func() {
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
err := (&Header{
|
||||||
|
ConnectionID: 0x42,
|
||||||
|
PacketNumber: 0x1337,
|
||||||
|
PacketNumberLen: protocol.PacketNumberLen6,
|
||||||
|
DiversificationNonce: bytes.Repeat([]byte{'f'}, 32),
|
||||||
|
}).writePublicHeader(buf, protocol.PerspectiveServer, versionPublicHeader)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
hdr, err := ParseHeader(bytes.NewReader(buf.Bytes()), protocol.PerspectiveServer, versionPublicHeader)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(hdr.PacketNumber).To(Equal(protocol.PacketNumber(0x1337)))
|
||||||
|
Expect(hdr.DiversificationNonce).To(HaveLen(32))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("errors when given no data", func() {
|
||||||
|
_, err := ParseHeader(bytes.NewReader([]byte{}), protocol.PerspectiveClient, protocol.VersionUnknown)
|
||||||
|
Expect(err).To(MatchError(io.EOF))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("writing", func() {
|
||||||
|
It("writes a gQUIC Public Header", func() {
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
err := (&Header{
|
||||||
|
ConnectionID: 0x1337,
|
||||||
|
PacketNumber: 0x42,
|
||||||
|
PacketNumberLen: protocol.PacketNumberLen2,
|
||||||
|
}).Write(buf, protocol.PerspectiveServer, versionPublicHeader)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
_, err = parsePublicHeader(bytes.NewReader(buf.Bytes()), protocol.PerspectiveServer, versionPublicHeader)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("writes a IETF draft header", func() {
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
err := (&Header{
|
||||||
|
ConnectionID: 0x1337,
|
||||||
|
PacketNumber: 0x42,
|
||||||
|
PacketNumberLen: protocol.PacketNumberLen2,
|
||||||
|
KeyPhase: 1,
|
||||||
|
}).Write(buf, protocol.PerspectiveServer, versionIETFHeader)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
_, err = parseHeader(bytes.NewReader(buf.Bytes()), protocol.PerspectiveServer)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("getting the length", func() {
|
||||||
|
It("get the length of a gQUIC Public Header", func() {
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
hdr := &Header{
|
||||||
|
ConnectionID: 0x1337,
|
||||||
|
PacketNumber: 0x42,
|
||||||
|
PacketNumberLen: protocol.PacketNumberLen2,
|
||||||
|
DiversificationNonce: bytes.Repeat([]byte{'f'}, 32),
|
||||||
|
}
|
||||||
|
err := hdr.Write(buf, protocol.PerspectiveServer, versionPublicHeader)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
publicHeaderLen, err := hdr.getPublicHeaderLength(protocol.PerspectiveServer)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
ietfHeaderLen, err := hdr.getHeaderLength()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(publicHeaderLen).ToNot(Equal(ietfHeaderLen)) // make sure we can distinguish between the two header types
|
||||||
|
len, err := hdr.GetLength(protocol.PerspectiveServer, versionPublicHeader)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(len).To(Equal(publicHeaderLen))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("get the length of a a IETF draft header", func() {
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
hdr := &Header{
|
||||||
|
IsLongHeader: true,
|
||||||
|
ConnectionID: 0x1337,
|
||||||
|
PacketNumber: 0x42,
|
||||||
|
PacketNumberLen: protocol.PacketNumberLen2,
|
||||||
|
KeyPhase: 1,
|
||||||
|
}
|
||||||
|
err := hdr.Write(buf, protocol.PerspectiveServer, versionIETFHeader)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
publicHeaderLen, err := hdr.getPublicHeaderLength(protocol.PerspectiveServer)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
ietfHeaderLen, err := hdr.getHeaderLength()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(publicHeaderLen).ToNot(Equal(ietfHeaderLen)) // make sure we can distinguish between the two header types
|
||||||
|
len, err := hdr.GetLength(protocol.PerspectiveServer, versionIETFHeader)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(len).To(Equal(ietfHeaderLen))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
|
@ -9,22 +9,8 @@ import (
|
||||||
"github.com/lucas-clemente/quic-go/qerr"
|
"github.com/lucas-clemente/quic-go/qerr"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The Header is the header of a QUIC Packet.
|
// parseHeader parses the header.
|
||||||
// TODO: add support for the key phase
|
func parseHeader(b *bytes.Reader, packetSentBy protocol.Perspective) (*Header, error) {
|
||||||
type Header struct {
|
|
||||||
Type uint8
|
|
||||||
IsLongHeader bool
|
|
||||||
KeyPhase int
|
|
||||||
OmitConnectionID bool
|
|
||||||
ConnectionID protocol.ConnectionID
|
|
||||||
PacketNumber protocol.PacketNumber
|
|
||||||
PacketNumberLen protocol.PacketNumberLen
|
|
||||||
Version protocol.VersionNumber
|
|
||||||
SupportedVersions []protocol.VersionNumber // version number sent in a Version Negotiation Packet by the server
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseHeader parses a header
|
|
||||||
func ParseHeader(b *bytes.Reader, packetSentBy protocol.Perspective) (*Header, error) {
|
|
||||||
typeByte, err := b.ReadByte()
|
typeByte, err := b.ReadByte()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -99,13 +85,15 @@ func parseShortHeader(b *bytes.Reader, typeByte byte) (*Header, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Header) Write(b *bytes.Buffer) error {
|
// writeHeader writes the Header.
|
||||||
|
func (h *Header) writeHeader(b *bytes.Buffer) error {
|
||||||
if h.IsLongHeader {
|
if h.IsLongHeader {
|
||||||
return h.writeLongHeader(b)
|
return h.writeLongHeader(b)
|
||||||
}
|
}
|
||||||
return h.writeShortHeader(b)
|
return h.writeShortHeader(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: add support for the key phase
|
||||||
func (h *Header) writeLongHeader(b *bytes.Buffer) error {
|
func (h *Header) writeLongHeader(b *bytes.Buffer) error {
|
||||||
b.WriteByte(byte(0x80 ^ h.Type))
|
b.WriteByte(byte(0x80 ^ h.Type))
|
||||||
utils.BigEndian.WriteUint64(b, uint64(h.ConnectionID))
|
utils.BigEndian.WriteUint64(b, uint64(h.ConnectionID))
|
||||||
|
@ -129,8 +117,8 @@ func (h *Header) writeShortHeader(b *bytes.Buffer) error {
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("invalid packet number length: %d", h.PacketNumberLen)
|
return fmt.Errorf("invalid packet number length: %d", h.PacketNumberLen)
|
||||||
}
|
}
|
||||||
|
|
||||||
b.WriteByte(typeByte)
|
b.WriteByte(typeByte)
|
||||||
|
|
||||||
if !h.OmitConnectionID {
|
if !h.OmitConnectionID {
|
||||||
utils.BigEndian.WriteUint64(b, uint64(h.ConnectionID))
|
utils.BigEndian.WriteUint64(b, uint64(h.ConnectionID))
|
||||||
}
|
}
|
||||||
|
@ -145,8 +133,8 @@ func (h *Header) writeShortHeader(b *bytes.Buffer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLength gets the length of the Header in bytes.
|
// getHeaderLength gets the length of the Header in bytes.
|
||||||
func (h *Header) GetLength() (protocol.ByteCount, error) {
|
func (h *Header) getHeaderLength() (protocol.ByteCount, error) {
|
||||||
if h.IsLongHeader {
|
if h.IsLongHeader {
|
||||||
return 1 + 8 + 4 + 4, nil
|
return 1 + 8 + 4 + 4, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("Header", func() {
|
var _ = Describe("IETF draft Header", func() {
|
||||||
Context("parsing", func() {
|
Context("parsing", func() {
|
||||||
Context("long headers", func() {
|
Context("long headers", func() {
|
||||||
var data []byte
|
var data []byte
|
||||||
|
@ -27,7 +27,7 @@ var _ = Describe("Header", func() {
|
||||||
|
|
||||||
It("parses a long header", func() {
|
It("parses a long header", func() {
|
||||||
b := bytes.NewReader(data)
|
b := bytes.NewReader(data)
|
||||||
h, err := ParseHeader(b, protocol.PerspectiveClient)
|
h, err := parseHeader(b, protocol.PerspectiveClient)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(h.Type).To(BeEquivalentTo(3))
|
Expect(h.Type).To(BeEquivalentTo(3))
|
||||||
Expect(h.IsLongHeader).To(BeTrue())
|
Expect(h.IsLongHeader).To(BeTrue())
|
||||||
|
@ -41,7 +41,7 @@ var _ = Describe("Header", func() {
|
||||||
|
|
||||||
It("errors on EOF", func() {
|
It("errors on EOF", func() {
|
||||||
for i := 0; i < len(data); i++ {
|
for i := 0; i < len(data); i++ {
|
||||||
_, err := ParseHeader(bytes.NewReader(data[:i]), protocol.PerspectiveClient)
|
_, err := parseHeader(bytes.NewReader(data[:i]), protocol.PerspectiveClient)
|
||||||
Expect(err).To(Equal(io.EOF))
|
Expect(err).To(Equal(io.EOF))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -57,7 +57,7 @@ var _ = Describe("Header", func() {
|
||||||
0x33, 0x44, 0x55, 0x66}...,
|
0x33, 0x44, 0x55, 0x66}...,
|
||||||
)
|
)
|
||||||
b := bytes.NewReader(data)
|
b := bytes.NewReader(data)
|
||||||
h, err := ParseHeader(b, protocol.PerspectiveServer)
|
h, err := parseHeader(b, protocol.PerspectiveServer)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(h.SupportedVersions).To(Equal([]protocol.VersionNumber{
|
Expect(h.SupportedVersions).To(Equal([]protocol.VersionNumber{
|
||||||
0x22334455,
|
0x22334455,
|
||||||
|
@ -68,20 +68,20 @@ var _ = Describe("Header", func() {
|
||||||
It("errors if it contains versions of the wrong length", func() {
|
It("errors if it contains versions of the wrong length", func() {
|
||||||
data = append(data, []byte{0x22, 0x33}...) // too short. Should be 4 bytes.
|
data = append(data, []byte{0x22, 0x33}...) // too short. Should be 4 bytes.
|
||||||
b := bytes.NewReader(data)
|
b := bytes.NewReader(data)
|
||||||
_, err := ParseHeader(b, protocol.PerspectiveServer)
|
_, err := parseHeader(b, protocol.PerspectiveServer)
|
||||||
Expect(err).To(MatchError(qerr.InvalidVersionNegotiationPacket))
|
Expect(err).To(MatchError(qerr.InvalidVersionNegotiationPacket))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("errors if it was sent by the client", func() {
|
It("errors if it was sent by the client", func() {
|
||||||
data = append(data, []byte{0x22, 0x33, 0x44, 0x55}...)
|
data = append(data, []byte{0x22, 0x33, 0x44, 0x55}...)
|
||||||
b := bytes.NewReader(data)
|
b := bytes.NewReader(data)
|
||||||
_, err := ParseHeader(b, protocol.PerspectiveClient)
|
_, err := parseHeader(b, protocol.PerspectiveClient)
|
||||||
Expect(err).To(MatchError("InvalidVersionNegotiationPacket: sent by the client"))
|
Expect(err).To(MatchError("InvalidVersionNegotiationPacket: sent by the client"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("errors if the version list is emtpy", func() {
|
It("errors if the version list is emtpy", func() {
|
||||||
b := bytes.NewReader(data)
|
b := bytes.NewReader(data)
|
||||||
_, err := ParseHeader(b, protocol.PerspectiveServer)
|
_, err := parseHeader(b, protocol.PerspectiveServer)
|
||||||
Expect(err).To(MatchError("InvalidVersionNegotiationPacket: empty version list"))
|
Expect(err).To(MatchError("InvalidVersionNegotiationPacket: empty version list"))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -95,7 +95,7 @@ var _ = Describe("Header", func() {
|
||||||
0x42, // packet number
|
0x42, // packet number
|
||||||
}
|
}
|
||||||
b := bytes.NewReader(data)
|
b := bytes.NewReader(data)
|
||||||
h, err := ParseHeader(b, protocol.PerspectiveClient)
|
h, err := parseHeader(b, protocol.PerspectiveClient)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(h.IsLongHeader).To(BeFalse())
|
Expect(h.IsLongHeader).To(BeFalse())
|
||||||
Expect(h.KeyPhase).To(Equal(0))
|
Expect(h.KeyPhase).To(Equal(0))
|
||||||
|
@ -111,7 +111,7 @@ var _ = Describe("Header", func() {
|
||||||
0x11,
|
0x11,
|
||||||
}
|
}
|
||||||
b := bytes.NewReader(data)
|
b := bytes.NewReader(data)
|
||||||
h, err := ParseHeader(b, protocol.PerspectiveClient)
|
h, err := parseHeader(b, protocol.PerspectiveClient)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(h.IsLongHeader).To(BeFalse())
|
Expect(h.IsLongHeader).To(BeFalse())
|
||||||
Expect(h.KeyPhase).To(Equal(1))
|
Expect(h.KeyPhase).To(Equal(1))
|
||||||
|
@ -124,7 +124,7 @@ var _ = Describe("Header", func() {
|
||||||
0x21, // packet number
|
0x21, // packet number
|
||||||
}
|
}
|
||||||
b := bytes.NewReader(data)
|
b := bytes.NewReader(data)
|
||||||
h, err := ParseHeader(b, protocol.PerspectiveClient)
|
h, err := parseHeader(b, protocol.PerspectiveClient)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(h.IsLongHeader).To(BeFalse())
|
Expect(h.IsLongHeader).To(BeFalse())
|
||||||
Expect(h.OmitConnectionID).To(BeTrue())
|
Expect(h.OmitConnectionID).To(BeTrue())
|
||||||
|
@ -139,7 +139,7 @@ var _ = Describe("Header", func() {
|
||||||
0x13, 0x37, // packet number
|
0x13, 0x37, // packet number
|
||||||
}
|
}
|
||||||
b := bytes.NewReader(data)
|
b := bytes.NewReader(data)
|
||||||
h, err := ParseHeader(b, protocol.PerspectiveClient)
|
h, err := parseHeader(b, protocol.PerspectiveClient)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(h.IsLongHeader).To(BeFalse())
|
Expect(h.IsLongHeader).To(BeFalse())
|
||||||
Expect(h.PacketNumber).To(Equal(protocol.PacketNumber(0x1337)))
|
Expect(h.PacketNumber).To(Equal(protocol.PacketNumber(0x1337)))
|
||||||
|
@ -153,7 +153,7 @@ var _ = Describe("Header", func() {
|
||||||
0xde, 0xad, 0xbe, 0xef, // packet number
|
0xde, 0xad, 0xbe, 0xef, // packet number
|
||||||
}
|
}
|
||||||
b := bytes.NewReader(data)
|
b := bytes.NewReader(data)
|
||||||
h, err := ParseHeader(b, protocol.PerspectiveClient)
|
h, err := parseHeader(b, protocol.PerspectiveClient)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(h.IsLongHeader).To(BeFalse())
|
Expect(h.IsLongHeader).To(BeFalse())
|
||||||
Expect(h.PacketNumber).To(Equal(protocol.PacketNumber(0xdeadbeef)))
|
Expect(h.PacketNumber).To(Equal(protocol.PacketNumber(0xdeadbeef)))
|
||||||
|
@ -168,7 +168,7 @@ var _ = Describe("Header", func() {
|
||||||
0xde, 0xca, 0xfb, 0xad, // packet number
|
0xde, 0xca, 0xfb, 0xad, // packet number
|
||||||
}
|
}
|
||||||
for i := 0; i < len(data); i++ {
|
for i := 0; i < len(data); i++ {
|
||||||
_, err := ParseHeader(bytes.NewReader(data[:i]), protocol.PerspectiveClient)
|
_, err := parseHeader(bytes.NewReader(data[:i]), protocol.PerspectiveClient)
|
||||||
Expect(err).To(Equal(io.EOF))
|
Expect(err).To(Equal(io.EOF))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -190,7 +190,7 @@ var _ = Describe("Header", func() {
|
||||||
ConnectionID: 0xdeadbeefcafe1337,
|
ConnectionID: 0xdeadbeefcafe1337,
|
||||||
PacketNumber: 0xdecafbad,
|
PacketNumber: 0xdecafbad,
|
||||||
Version: 0x1020304,
|
Version: 0x1020304,
|
||||||
}).Write(buf)
|
}).writeHeader(buf)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(buf.Bytes()).To(Equal([]byte{
|
Expect(buf.Bytes()).To(Equal([]byte{
|
||||||
0x80 ^ 0x5,
|
0x80 ^ 0x5,
|
||||||
|
@ -207,7 +207,7 @@ var _ = Describe("Header", func() {
|
||||||
ConnectionID: 0xdeadbeefcafe1337,
|
ConnectionID: 0xdeadbeefcafe1337,
|
||||||
PacketNumberLen: protocol.PacketNumberLen1,
|
PacketNumberLen: protocol.PacketNumberLen1,
|
||||||
PacketNumber: 0x42,
|
PacketNumber: 0x42,
|
||||||
}).Write(buf)
|
}).writeHeader(buf)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(buf.Bytes()).To(Equal([]byte{
|
Expect(buf.Bytes()).To(Equal([]byte{
|
||||||
0x40 ^ 0x1,
|
0x40 ^ 0x1,
|
||||||
|
@ -221,7 +221,7 @@ var _ = Describe("Header", func() {
|
||||||
OmitConnectionID: true,
|
OmitConnectionID: true,
|
||||||
PacketNumberLen: protocol.PacketNumberLen1,
|
PacketNumberLen: protocol.PacketNumberLen1,
|
||||||
PacketNumber: 0x42,
|
PacketNumber: 0x42,
|
||||||
}).Write(buf)
|
}).writeHeader(buf)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(buf.Bytes()).To(Equal([]byte{
|
Expect(buf.Bytes()).To(Equal([]byte{
|
||||||
0x1,
|
0x1,
|
||||||
|
@ -234,7 +234,7 @@ var _ = Describe("Header", func() {
|
||||||
OmitConnectionID: true,
|
OmitConnectionID: true,
|
||||||
PacketNumberLen: protocol.PacketNumberLen2,
|
PacketNumberLen: protocol.PacketNumberLen2,
|
||||||
PacketNumber: 0x1337,
|
PacketNumber: 0x1337,
|
||||||
}).Write(buf)
|
}).writeHeader(buf)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(buf.Bytes()).To(Equal([]byte{
|
Expect(buf.Bytes()).To(Equal([]byte{
|
||||||
0x2,
|
0x2,
|
||||||
|
@ -247,7 +247,7 @@ var _ = Describe("Header", func() {
|
||||||
OmitConnectionID: true,
|
OmitConnectionID: true,
|
||||||
PacketNumberLen: protocol.PacketNumberLen4,
|
PacketNumberLen: protocol.PacketNumberLen4,
|
||||||
PacketNumber: 0xdecafbad,
|
PacketNumber: 0xdecafbad,
|
||||||
}).Write(buf)
|
}).writeHeader(buf)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(buf.Bytes()).To(Equal([]byte{
|
Expect(buf.Bytes()).To(Equal([]byte{
|
||||||
0x3,
|
0x3,
|
||||||
|
@ -260,7 +260,7 @@ var _ = Describe("Header", func() {
|
||||||
OmitConnectionID: true,
|
OmitConnectionID: true,
|
||||||
PacketNumberLen: 3,
|
PacketNumberLen: 3,
|
||||||
PacketNumber: 0xdecafbad,
|
PacketNumber: 0xdecafbad,
|
||||||
}).Write(buf)
|
}).writeHeader(buf)
|
||||||
Expect(err).To(MatchError("invalid packet number length: 3"))
|
Expect(err).To(MatchError("invalid packet number length: 3"))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -270,7 +270,7 @@ var _ = Describe("Header", func() {
|
||||||
OmitConnectionID: true,
|
OmitConnectionID: true,
|
||||||
PacketNumberLen: protocol.PacketNumberLen1,
|
PacketNumberLen: protocol.PacketNumberLen1,
|
||||||
PacketNumber: 0x42,
|
PacketNumber: 0x42,
|
||||||
}).Write(buf)
|
}).writeHeader(buf)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(buf.Bytes()).To(Equal([]byte{
|
Expect(buf.Bytes()).To(Equal([]byte{
|
||||||
0x20 ^ 0x1,
|
0x20 ^ 0x1,
|
||||||
|
@ -289,8 +289,8 @@ var _ = Describe("Header", func() {
|
||||||
|
|
||||||
It("has the right length for the long header", func() {
|
It("has the right length for the long header", func() {
|
||||||
h := &Header{IsLongHeader: true}
|
h := &Header{IsLongHeader: true}
|
||||||
Expect(h.GetLength()).To(Equal(protocol.ByteCount(17)))
|
Expect(h.getHeaderLength()).To(Equal(protocol.ByteCount(17)))
|
||||||
err := h.Write(buf)
|
err := h.writeHeader(buf)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(buf.Len()).To(Equal(17))
|
Expect(buf.Len()).To(Equal(17))
|
||||||
})
|
})
|
||||||
|
@ -299,8 +299,8 @@ var _ = Describe("Header", func() {
|
||||||
h := &Header{
|
h := &Header{
|
||||||
PacketNumberLen: protocol.PacketNumberLen1,
|
PacketNumberLen: protocol.PacketNumberLen1,
|
||||||
}
|
}
|
||||||
Expect(h.GetLength()).To(Equal(protocol.ByteCount(1 + 8 + 1)))
|
Expect(h.getHeaderLength()).To(Equal(protocol.ByteCount(1 + 8 + 1)))
|
||||||
err := h.Write(buf)
|
err := h.writeHeader(buf)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(buf.Len()).To(Equal(10))
|
Expect(buf.Len()).To(Equal(10))
|
||||||
})
|
})
|
||||||
|
@ -310,8 +310,8 @@ var _ = Describe("Header", func() {
|
||||||
OmitConnectionID: true,
|
OmitConnectionID: true,
|
||||||
PacketNumberLen: protocol.PacketNumberLen1,
|
PacketNumberLen: protocol.PacketNumberLen1,
|
||||||
}
|
}
|
||||||
Expect(h.GetLength()).To(Equal(protocol.ByteCount(1 + 1)))
|
Expect(h.getHeaderLength()).To(Equal(protocol.ByteCount(1 + 1)))
|
||||||
err := h.Write(buf)
|
err := h.writeHeader(buf)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(buf.Len()).To(Equal(2))
|
Expect(buf.Len()).To(Equal(2))
|
||||||
})
|
})
|
||||||
|
@ -321,8 +321,8 @@ var _ = Describe("Header", func() {
|
||||||
OmitConnectionID: true,
|
OmitConnectionID: true,
|
||||||
PacketNumberLen: protocol.PacketNumberLen2,
|
PacketNumberLen: protocol.PacketNumberLen2,
|
||||||
}
|
}
|
||||||
Expect(h.GetLength()).To(Equal(protocol.ByteCount(1 + 2)))
|
Expect(h.getHeaderLength()).To(Equal(protocol.ByteCount(1 + 2)))
|
||||||
err := h.Write(buf)
|
err := h.writeHeader(buf)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(buf.Len()).To(Equal(3))
|
Expect(buf.Len()).To(Equal(3))
|
||||||
})
|
})
|
||||||
|
@ -332,15 +332,15 @@ var _ = Describe("Header", func() {
|
||||||
OmitConnectionID: true,
|
OmitConnectionID: true,
|
||||||
PacketNumberLen: protocol.PacketNumberLen4,
|
PacketNumberLen: protocol.PacketNumberLen4,
|
||||||
}
|
}
|
||||||
Expect(h.GetLength()).To(Equal(protocol.ByteCount(1 + 4)))
|
Expect(h.getHeaderLength()).To(Equal(protocol.ByteCount(1 + 4)))
|
||||||
err := h.Write(buf)
|
err := h.writeHeader(buf)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(buf.Len()).To(Equal(5))
|
Expect(buf.Len()).To(Equal(5))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("errors when given an invalid packet number length", func() {
|
It("errors when given an invalid packet number length", func() {
|
||||||
h := &Header{PacketNumberLen: 5}
|
h := &Header{PacketNumberLen: 5}
|
||||||
_, err := h.GetLength()
|
_, err := h.getHeaderLength()
|
||||||
Expect(err).To(MatchError("invalid packet number length: 5"))
|
Expect(err).To(MatchError("invalid packet number length: 5"))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -20,28 +20,13 @@ var (
|
||||||
errGetLengthNotForVersionNegotiation = errors.New("PublicHeader: GetLength cannot be called for VersionNegotiation packets")
|
errGetLengthNotForVersionNegotiation = errors.New("PublicHeader: GetLength cannot be called for VersionNegotiation packets")
|
||||||
)
|
)
|
||||||
|
|
||||||
// The PublicHeader is the header of a gQUIC packet.
|
// writePublicHeader writes a Public Header.
|
||||||
type PublicHeader struct {
|
func (h *Header) writePublicHeader(b *bytes.Buffer, pers protocol.Perspective, version protocol.VersionNumber) error {
|
||||||
Raw []byte
|
|
||||||
ConnectionID protocol.ConnectionID
|
|
||||||
VersionFlag bool
|
|
||||||
ResetFlag bool
|
|
||||||
OmitConnectionID bool
|
|
||||||
PacketNumberLen protocol.PacketNumberLen
|
|
||||||
PacketNumber protocol.PacketNumber
|
|
||||||
VersionNumber protocol.VersionNumber // VersionNumber sent by the client
|
|
||||||
SupportedVersions []protocol.VersionNumber // VersionNumbers sent by the server
|
|
||||||
DiversificationNonce []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write writes a Public Header.
|
|
||||||
func (h *PublicHeader) Write(b *bytes.Buffer, version protocol.VersionNumber, pers protocol.Perspective) error {
|
|
||||||
publicFlagByte := uint8(0x00)
|
|
||||||
|
|
||||||
if h.VersionFlag && h.ResetFlag {
|
if h.VersionFlag && h.ResetFlag {
|
||||||
return errResetAndVersionFlagSet
|
return errResetAndVersionFlagSet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
publicFlagByte := uint8(0x00)
|
||||||
if h.VersionFlag {
|
if h.VersionFlag {
|
||||||
publicFlagByte |= 0x01
|
publicFlagByte |= 0x01
|
||||||
}
|
}
|
||||||
|
@ -51,14 +36,12 @@ func (h *PublicHeader) Write(b *bytes.Buffer, version protocol.VersionNumber, pe
|
||||||
if !h.OmitConnectionID {
|
if !h.OmitConnectionID {
|
||||||
publicFlagByte |= 0x08
|
publicFlagByte |= 0x08
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(h.DiversificationNonce) > 0 {
|
if len(h.DiversificationNonce) > 0 {
|
||||||
if len(h.DiversificationNonce) != 32 {
|
if len(h.DiversificationNonce) != 32 {
|
||||||
return errors.New("invalid diversification nonce length")
|
return errors.New("invalid diversification nonce length")
|
||||||
}
|
}
|
||||||
publicFlagByte |= 0x04
|
publicFlagByte |= 0x04
|
||||||
}
|
}
|
||||||
|
|
||||||
// only set PacketNumberLen bits if a packet number will be written
|
// only set PacketNumberLen bits if a packet number will be written
|
||||||
if h.hasPacketNumber(pers) {
|
if h.hasPacketNumber(pers) {
|
||||||
switch h.PacketNumberLen {
|
switch h.PacketNumberLen {
|
||||||
|
@ -72,21 +55,17 @@ func (h *PublicHeader) Write(b *bytes.Buffer, version protocol.VersionNumber, pe
|
||||||
publicFlagByte |= 0x30
|
publicFlagByte |= 0x30
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
b.WriteByte(publicFlagByte)
|
b.WriteByte(publicFlagByte)
|
||||||
|
|
||||||
if !h.OmitConnectionID {
|
if !h.OmitConnectionID {
|
||||||
utils.BigEndian.WriteUint64(b, uint64(h.ConnectionID))
|
utils.BigEndian.WriteUint64(b, uint64(h.ConnectionID))
|
||||||
}
|
}
|
||||||
|
|
||||||
if h.VersionFlag && pers == protocol.PerspectiveClient {
|
if h.VersionFlag && pers == protocol.PerspectiveClient {
|
||||||
utils.LittleEndian.WriteUint32(b, protocol.VersionNumberToTag(h.VersionNumber))
|
utils.LittleEndian.WriteUint32(b, protocol.VersionNumberToTag(h.Version))
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(h.DiversificationNonce) > 0 {
|
if len(h.DiversificationNonce) > 0 {
|
||||||
b.Write(h.DiversificationNonce)
|
b.Write(h.DiversificationNonce)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we're a server, and the VersionFlag is set, we must not include anything else in the packet
|
// if we're a server, and the VersionFlag is set, we must not include anything else in the packet
|
||||||
if !h.hasPacketNumber(pers) {
|
if !h.hasPacketNumber(pers) {
|
||||||
return nil
|
return nil
|
||||||
|
@ -108,39 +87,10 @@ func (h *PublicHeader) Write(b *bytes.Buffer, version protocol.VersionNumber, pe
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PeekConnectionID parses the connection ID from a QUIC packet's public header.
|
// parsePublicHeader parses a QUIC packet's Public Header.
|
||||||
// If no error occurs, it restores the read position in the bytes.Reader.
|
|
||||||
func PeekConnectionID(b *bytes.Reader, packetSentBy protocol.Perspective) (protocol.ConnectionID, error) {
|
|
||||||
var connectionID protocol.ConnectionID
|
|
||||||
publicFlagByte, err := b.ReadByte()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
// unread the public flag byte
|
|
||||||
defer b.UnreadByte()
|
|
||||||
|
|
||||||
omitConnectionID := publicFlagByte&0x08 == 0
|
|
||||||
if omitConnectionID && packetSentBy == protocol.PerspectiveClient {
|
|
||||||
return 0, errReceivedOmittedConnectionID
|
|
||||||
}
|
|
||||||
if !omitConnectionID {
|
|
||||||
connID, err := utils.BigEndian.ReadUint64(b)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
connectionID = protocol.ConnectionID(connID)
|
|
||||||
// unread the connection ID
|
|
||||||
for i := 0; i < 8; i++ {
|
|
||||||
b.UnreadByte()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return connectionID, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParsePublicHeader parses a QUIC packet's Public Header.
|
|
||||||
// The packetSentBy is the perspective of the peer that sent this PublicHeader, i.e. if we're the server, packetSentBy should be PerspectiveClient.
|
// The packetSentBy is the perspective of the peer that sent this PublicHeader, i.e. if we're the server, packetSentBy should be PerspectiveClient.
|
||||||
func ParsePublicHeader(b *bytes.Reader, packetSentBy protocol.Perspective, version protocol.VersionNumber) (*PublicHeader, error) {
|
func parsePublicHeader(b *bytes.Reader, packetSentBy protocol.Perspective, version protocol.VersionNumber) (*Header, error) {
|
||||||
header := &PublicHeader{}
|
header := &Header{}
|
||||||
|
|
||||||
// First byte
|
// First byte
|
||||||
publicFlagByte, err := b.ReadByte()
|
publicFlagByte, err := b.ReadByte()
|
||||||
|
@ -163,7 +113,6 @@ func ParsePublicHeader(b *bytes.Reader, packetSentBy protocol.Perspective, versi
|
||||||
if header.OmitConnectionID && packetSentBy == protocol.PerspectiveClient {
|
if header.OmitConnectionID && packetSentBy == protocol.PerspectiveClient {
|
||||||
return nil, errReceivedOmittedConnectionID
|
return nil, errReceivedOmittedConnectionID
|
||||||
}
|
}
|
||||||
|
|
||||||
if header.hasPacketNumber(packetSentBy) {
|
if header.hasPacketNumber(packetSentBy) {
|
||||||
switch publicFlagByte & 0x30 {
|
switch publicFlagByte & 0x30 {
|
||||||
case 0x30:
|
case 0x30:
|
||||||
|
@ -230,8 +179,8 @@ func ParsePublicHeader(b *bytes.Reader, packetSentBy protocol.Perspective, versi
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
header.VersionNumber = protocol.VersionTagToNumber(versionTag)
|
header.Version = protocol.VersionTagToNumber(versionTag)
|
||||||
version = header.VersionNumber
|
version = header.Version
|
||||||
}
|
}
|
||||||
|
|
||||||
// Packet number
|
// Packet number
|
||||||
|
@ -242,47 +191,40 @@ func ParsePublicHeader(b *bytes.Reader, packetSentBy protocol.Perspective, versi
|
||||||
}
|
}
|
||||||
header.PacketNumber = protocol.PacketNumber(packetNumber)
|
header.PacketNumber = protocol.PacketNumber(packetNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
return header, nil
|
return header, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLength gets the length of the publicHeader in bytes.
|
// getPublicHeaderLength gets the length of the publicHeader in bytes.
|
||||||
// It can only be called for regular packets.
|
// It can only be called for regular packets.
|
||||||
func (h *PublicHeader) GetLength(pers protocol.Perspective) (protocol.ByteCount, error) {
|
func (h *Header) getPublicHeaderLength(pers protocol.Perspective) (protocol.ByteCount, error) {
|
||||||
if h.VersionFlag && h.ResetFlag {
|
if h.VersionFlag && h.ResetFlag {
|
||||||
return 0, errResetAndVersionFlagSet
|
return 0, errResetAndVersionFlagSet
|
||||||
}
|
}
|
||||||
|
|
||||||
if h.VersionFlag && pers == protocol.PerspectiveServer {
|
if h.VersionFlag && pers == protocol.PerspectiveServer {
|
||||||
return 0, errGetLengthNotForVersionNegotiation
|
return 0, errGetLengthNotForVersionNegotiation
|
||||||
}
|
}
|
||||||
|
|
||||||
length := protocol.ByteCount(1) // 1 byte for public flags
|
length := protocol.ByteCount(1) // 1 byte for public flags
|
||||||
|
|
||||||
if h.hasPacketNumber(pers) {
|
if h.hasPacketNumber(pers) {
|
||||||
if h.PacketNumberLen != protocol.PacketNumberLen1 && h.PacketNumberLen != protocol.PacketNumberLen2 && h.PacketNumberLen != protocol.PacketNumberLen4 && h.PacketNumberLen != protocol.PacketNumberLen6 {
|
if h.PacketNumberLen != protocol.PacketNumberLen1 && h.PacketNumberLen != protocol.PacketNumberLen2 && h.PacketNumberLen != protocol.PacketNumberLen4 && h.PacketNumberLen != protocol.PacketNumberLen6 {
|
||||||
return 0, errPacketNumberLenNotSet
|
return 0, errPacketNumberLenNotSet
|
||||||
}
|
}
|
||||||
length += protocol.ByteCount(h.PacketNumberLen)
|
length += protocol.ByteCount(h.PacketNumberLen)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !h.OmitConnectionID {
|
if !h.OmitConnectionID {
|
||||||
length += 8 // 8 bytes for the connection ID
|
length += 8 // 8 bytes for the connection ID
|
||||||
}
|
}
|
||||||
|
|
||||||
// Version Number in packets sent by the client
|
// Version Number in packets sent by the client
|
||||||
if h.VersionFlag {
|
if h.VersionFlag {
|
||||||
length += 4
|
length += 4
|
||||||
}
|
}
|
||||||
|
|
||||||
length += protocol.ByteCount(len(h.DiversificationNonce))
|
length += protocol.ByteCount(len(h.DiversificationNonce))
|
||||||
|
|
||||||
return length, nil
|
return length, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// hasPacketNumber determines if this Public Header will contain a packet number
|
// hasPacketNumber determines if this Public Header will contain a packet number
|
||||||
// this depends on the ResetFlag, the VersionFlag and who sent the packet
|
// this depends on the ResetFlag, the VersionFlag and who sent the packet
|
||||||
func (h *PublicHeader) hasPacketNumber(packetSentBy protocol.Perspective) bool {
|
func (h *Header) hasPacketNumber(packetSentBy protocol.Perspective) bool {
|
||||||
if h.ResetFlag {
|
if h.ResetFlag {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,53 +12,15 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("Public Header", func() {
|
var _ = Describe("Public Header", func() {
|
||||||
Context("parsing the connection ID", func() {
|
|
||||||
It("does not accept an omitted connection ID as a server", func() {
|
|
||||||
b := bytes.NewReader([]byte{0x00, 0x01})
|
|
||||||
_, err := PeekConnectionID(b, protocol.PerspectiveClient)
|
|
||||||
Expect(err).To(MatchError(errReceivedOmittedConnectionID))
|
|
||||||
})
|
|
||||||
|
|
||||||
It("gets the connection ID", func() {
|
|
||||||
b := bytes.NewReader([]byte{0x09, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0x51, 0x30, 0x33, 0x34, 0x01})
|
|
||||||
len := b.Len()
|
|
||||||
connID, err := PeekConnectionID(b, protocol.PerspectiveClient)
|
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
Expect(connID).To(Equal(protocol.ConnectionID(0x4cfa9f9b668619f6)))
|
|
||||||
Expect(b.Len()).To(Equal(len))
|
|
||||||
})
|
|
||||||
|
|
||||||
It("errors if the Public Header is too short", func() {
|
|
||||||
b := bytes.NewReader([]byte{0x09, 0xf6, 0x19, 0x86, 0x66, 0x9b})
|
|
||||||
_, err := PeekConnectionID(b, protocol.PerspectiveClient)
|
|
||||||
Expect(err).To(HaveOccurred())
|
|
||||||
})
|
|
||||||
|
|
||||||
It("errors if the Public Header is empty", func() {
|
|
||||||
b := bytes.NewReader([]byte{})
|
|
||||||
_, err := PeekConnectionID(b, protocol.PerspectiveClient)
|
|
||||||
Expect(err).To(HaveOccurred())
|
|
||||||
})
|
|
||||||
|
|
||||||
It("accepts an ommitted connection ID as a client", func() {
|
|
||||||
b := bytes.NewReader([]byte{0x00, 0x01})
|
|
||||||
len := b.Len()
|
|
||||||
connID, err := PeekConnectionID(b, protocol.PerspectiveServer)
|
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
Expect(connID).To(BeZero())
|
|
||||||
Expect(b.Len()).To(Equal(len))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
Context("when parsing", func() {
|
Context("when parsing", func() {
|
||||||
It("accepts a sample client header", func() {
|
It("accepts a sample client header", func() {
|
||||||
b := bytes.NewReader([]byte{0x09, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0x51, 0x30, 0x33, 0x34, 0x01})
|
b := bytes.NewReader([]byte{0x09, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0x51, 0x30, 0x33, 0x34, 0x01})
|
||||||
hdr, err := ParsePublicHeader(b, protocol.PerspectiveClient, protocol.VersionUnknown)
|
hdr, err := parsePublicHeader(b, protocol.PerspectiveClient, protocol.VersionUnknown)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(hdr.VersionFlag).To(BeTrue())
|
Expect(hdr.VersionFlag).To(BeTrue())
|
||||||
Expect(hdr.ResetFlag).To(BeFalse())
|
Expect(hdr.ResetFlag).To(BeFalse())
|
||||||
Expect(hdr.ConnectionID).To(Equal(protocol.ConnectionID(0x4cfa9f9b668619f6)))
|
Expect(hdr.ConnectionID).To(Equal(protocol.ConnectionID(0x4cfa9f9b668619f6)))
|
||||||
Expect(hdr.VersionNumber).To(Equal(protocol.VersionNumber(34)))
|
Expect(hdr.Version).To(Equal(protocol.VersionNumber(34)))
|
||||||
Expect(hdr.SupportedVersions).To(BeEmpty())
|
Expect(hdr.SupportedVersions).To(BeEmpty())
|
||||||
Expect(hdr.PacketNumber).To(Equal(protocol.PacketNumber(1)))
|
Expect(hdr.PacketNumber).To(Equal(protocol.PacketNumber(1)))
|
||||||
Expect(b.Len()).To(BeZero())
|
Expect(b.Len()).To(BeZero())
|
||||||
|
@ -66,13 +28,13 @@ var _ = Describe("Public Header", func() {
|
||||||
|
|
||||||
It("does not accept an omittedd connection ID as a server", func() {
|
It("does not accept an omittedd connection ID as a server", func() {
|
||||||
b := bytes.NewReader([]byte{0x00, 0x01})
|
b := bytes.NewReader([]byte{0x00, 0x01})
|
||||||
_, err := ParsePublicHeader(b, protocol.PerspectiveClient, protocol.VersionWhatever)
|
_, err := parsePublicHeader(b, protocol.PerspectiveClient, protocol.VersionWhatever)
|
||||||
Expect(err).To(MatchError(errReceivedOmittedConnectionID))
|
Expect(err).To(MatchError(errReceivedOmittedConnectionID))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("accepts aan d connection ID as a client", func() {
|
It("accepts aan d connection ID as a client", func() {
|
||||||
b := bytes.NewReader([]byte{0x00, 0x01})
|
b := bytes.NewReader([]byte{0x00, 0x01})
|
||||||
hdr, err := ParsePublicHeader(b, protocol.PerspectiveServer, protocol.VersionWhatever)
|
hdr, err := parsePublicHeader(b, protocol.PerspectiveServer, protocol.VersionWhatever)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(hdr.OmitConnectionID).To(BeTrue())
|
Expect(hdr.OmitConnectionID).To(BeTrue())
|
||||||
Expect(hdr.ConnectionID).To(BeZero())
|
Expect(hdr.ConnectionID).To(BeZero())
|
||||||
|
@ -81,13 +43,13 @@ var _ = Describe("Public Header", func() {
|
||||||
|
|
||||||
It("rejects 0 as a connection ID", func() {
|
It("rejects 0 as a connection ID", func() {
|
||||||
b := bytes.NewReader([]byte{0x09, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x51, 0x30, 0x33, 0x30, 0x01})
|
b := bytes.NewReader([]byte{0x09, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x51, 0x30, 0x33, 0x30, 0x01})
|
||||||
_, err := ParsePublicHeader(b, protocol.PerspectiveClient, protocol.VersionUnknown)
|
_, err := parsePublicHeader(b, protocol.PerspectiveClient, protocol.VersionUnknown)
|
||||||
Expect(err).To(MatchError(errInvalidConnectionID))
|
Expect(err).To(MatchError(errInvalidConnectionID))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("reads a PublicReset packet", func() {
|
It("reads a PublicReset packet", func() {
|
||||||
b := bytes.NewReader([]byte{0xa, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8})
|
b := bytes.NewReader([]byte{0xa, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8})
|
||||||
hdr, err := ParsePublicHeader(b, protocol.PerspectiveServer, protocol.VersionUnknown)
|
hdr, err := parsePublicHeader(b, protocol.PerspectiveServer, protocol.VersionUnknown)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(hdr.ResetFlag).To(BeTrue())
|
Expect(hdr.ResetFlag).To(BeTrue())
|
||||||
Expect(hdr.ConnectionID).ToNot(BeZero())
|
Expect(hdr.ConnectionID).ToNot(BeZero())
|
||||||
|
@ -95,7 +57,7 @@ var _ = Describe("Public Header", func() {
|
||||||
|
|
||||||
It("parses a public reset packet", func() {
|
It("parses a public reset packet", func() {
|
||||||
b := bytes.NewReader([]byte{0xa, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08})
|
b := bytes.NewReader([]byte{0xa, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08})
|
||||||
hdr, err := ParsePublicHeader(b, protocol.PerspectiveServer, protocol.VersionUnknown)
|
hdr, err := parsePublicHeader(b, protocol.PerspectiveServer, protocol.VersionUnknown)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(hdr.ResetFlag).To(BeTrue())
|
Expect(hdr.ResetFlag).To(BeTrue())
|
||||||
Expect(hdr.VersionFlag).To(BeFalse())
|
Expect(hdr.VersionFlag).To(BeFalse())
|
||||||
|
@ -106,7 +68,7 @@ var _ = Describe("Public Header", func() {
|
||||||
divNonce := []byte{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f}
|
divNonce := []byte{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f}
|
||||||
Expect(divNonce).To(HaveLen(32))
|
Expect(divNonce).To(HaveLen(32))
|
||||||
b := bytes.NewReader(append(append([]byte{0x0c, 0xf6, 0x19, 0x86, 0x66, 0x9b, 0x9f, 0xfa, 0x4c}, divNonce...), 0x37))
|
b := bytes.NewReader(append(append([]byte{0x0c, 0xf6, 0x19, 0x86, 0x66, 0x9b, 0x9f, 0xfa, 0x4c}, divNonce...), 0x37))
|
||||||
hdr, err := ParsePublicHeader(b, protocol.PerspectiveServer, protocol.VersionWhatever)
|
hdr, err := parsePublicHeader(b, protocol.PerspectiveServer, protocol.VersionWhatever)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(hdr.ConnectionID).To(Not(BeZero()))
|
Expect(hdr.ConnectionID).To(Not(BeZero()))
|
||||||
Expect(hdr.DiversificationNonce).To(Equal(divNonce))
|
Expect(hdr.DiversificationNonce).To(Equal(divNonce))
|
||||||
|
@ -115,7 +77,7 @@ var _ = Describe("Public Header", func() {
|
||||||
|
|
||||||
It("returns an unknown version error when receiving a packet without a version for which the version is not given", func() {
|
It("returns an unknown version error when receiving a packet without a version for which the version is not given", func() {
|
||||||
b := bytes.NewReader([]byte{0x10, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0xef})
|
b := bytes.NewReader([]byte{0x10, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0xef})
|
||||||
_, err := ParsePublicHeader(b, protocol.PerspectiveServer, protocol.VersionUnknown)
|
_, err := parsePublicHeader(b, protocol.PerspectiveServer, protocol.VersionUnknown)
|
||||||
Expect(err).To(MatchError(ErrPacketWithUnknownVersion))
|
Expect(err).To(MatchError(ErrPacketWithUnknownVersion))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -124,7 +86,7 @@ var _ = Describe("Public Header", func() {
|
||||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1,
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1,
|
||||||
0x01,
|
0x01,
|
||||||
})
|
})
|
||||||
_, err := ParsePublicHeader(b, protocol.PerspectiveClient, protocol.VersionWhatever)
|
_, err := parsePublicHeader(b, protocol.PerspectiveClient, protocol.VersionWhatever)
|
||||||
Expect(err).To(MatchError("diversification nonces should only be sent by servers"))
|
Expect(err).To(MatchError("diversification nonces should only be sent by servers"))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -137,17 +99,17 @@ var _ = Describe("Public Header", func() {
|
||||||
|
|
||||||
It("parses version negotiation packets sent by the server", func() {
|
It("parses version negotiation packets sent by the server", func() {
|
||||||
b := bytes.NewReader(ComposeVersionNegotiation(0x1337, protocol.SupportedVersions))
|
b := bytes.NewReader(ComposeVersionNegotiation(0x1337, protocol.SupportedVersions))
|
||||||
hdr, err := ParsePublicHeader(b, protocol.PerspectiveServer, protocol.VersionUnknown)
|
hdr, err := parsePublicHeader(b, protocol.PerspectiveServer, protocol.VersionUnknown)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(hdr.VersionFlag).To(BeTrue())
|
Expect(hdr.VersionFlag).To(BeTrue())
|
||||||
Expect(hdr.VersionNumber).To(BeZero()) // unitialized
|
Expect(hdr.Version).To(BeZero()) // unitialized
|
||||||
Expect(hdr.SupportedVersions).To(Equal(protocol.SupportedVersions))
|
Expect(hdr.SupportedVersions).To(Equal(protocol.SupportedVersions))
|
||||||
Expect(b.Len()).To(BeZero())
|
Expect(b.Len()).To(BeZero())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("errors if it doesn't contain any versions", func() {
|
It("errors if it doesn't contain any versions", func() {
|
||||||
b := bytes.NewReader([]byte{0x9, 0xf6, 0x19, 0x86, 0x66, 0x9b, 0x9f, 0xfa, 0x4c})
|
b := bytes.NewReader([]byte{0x9, 0xf6, 0x19, 0x86, 0x66, 0x9b, 0x9f, 0xfa, 0x4c})
|
||||||
_, err := ParsePublicHeader(b, protocol.PerspectiveServer, protocol.VersionUnknown)
|
_, err := parsePublicHeader(b, protocol.PerspectiveServer, protocol.VersionUnknown)
|
||||||
Expect(err).To(MatchError("InvalidVersionNegotiationPacket: empty version list"))
|
Expect(err).To(MatchError("InvalidVersionNegotiationPacket: empty version list"))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -157,7 +119,7 @@ var _ = Describe("Public Header", func() {
|
||||||
data = appendVersion(data, protocol.SupportedVersions[0])
|
data = appendVersion(data, protocol.SupportedVersions[0])
|
||||||
data = appendVersion(data, 99) // unsupported version
|
data = appendVersion(data, 99) // unsupported version
|
||||||
b := bytes.NewReader(data)
|
b := bytes.NewReader(data)
|
||||||
hdr, err := ParsePublicHeader(b, protocol.PerspectiveServer, protocol.VersionUnknown)
|
hdr, err := parsePublicHeader(b, protocol.PerspectiveServer, protocol.VersionUnknown)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(hdr.VersionFlag).To(BeTrue())
|
Expect(hdr.VersionFlag).To(BeTrue())
|
||||||
Expect(hdr.SupportedVersions).To(Equal([]protocol.VersionNumber{1, protocol.SupportedVersions[0], 99}))
|
Expect(hdr.SupportedVersions).To(Equal([]protocol.VersionNumber{1, protocol.SupportedVersions[0], 99}))
|
||||||
|
@ -168,7 +130,7 @@ var _ = Describe("Public Header", func() {
|
||||||
data := ComposeVersionNegotiation(0x1337, protocol.SupportedVersions)
|
data := ComposeVersionNegotiation(0x1337, protocol.SupportedVersions)
|
||||||
data = append(data, []byte{0x13, 0x37}...)
|
data = append(data, []byte{0x13, 0x37}...)
|
||||||
b := bytes.NewReader(data)
|
b := bytes.NewReader(data)
|
||||||
_, err := ParsePublicHeader(b, protocol.PerspectiveServer, protocol.VersionUnknown)
|
_, err := parsePublicHeader(b, protocol.PerspectiveServer, protocol.VersionUnknown)
|
||||||
Expect(err).To(MatchError(qerr.InvalidVersionNegotiationPacket))
|
Expect(err).To(MatchError(qerr.InvalidVersionNegotiationPacket))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -183,7 +145,7 @@ var _ = Describe("Public Header", func() {
|
||||||
|
|
||||||
It("accepts 1-byte packet numbers", func() {
|
It("accepts 1-byte packet numbers", func() {
|
||||||
b := bytes.NewReader([]byte{0x08, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0xde})
|
b := bytes.NewReader([]byte{0x08, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0xde})
|
||||||
hdr, err := ParsePublicHeader(b, protocol.PerspectiveClient, version)
|
hdr, err := parsePublicHeader(b, protocol.PerspectiveClient, version)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(hdr.PacketNumber).To(Equal(protocol.PacketNumber(0xde)))
|
Expect(hdr.PacketNumber).To(Equal(protocol.PacketNumber(0xde)))
|
||||||
Expect(hdr.PacketNumberLen).To(Equal(protocol.PacketNumberLen1))
|
Expect(hdr.PacketNumberLen).To(Equal(protocol.PacketNumberLen1))
|
||||||
|
@ -192,7 +154,7 @@ var _ = Describe("Public Header", func() {
|
||||||
|
|
||||||
It("accepts 2-byte packet numbers", func() {
|
It("accepts 2-byte packet numbers", func() {
|
||||||
b := bytes.NewReader([]byte{0x18, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0xde, 0xca})
|
b := bytes.NewReader([]byte{0x18, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0xde, 0xca})
|
||||||
hdr, err := ParsePublicHeader(b, protocol.PerspectiveClient, version)
|
hdr, err := parsePublicHeader(b, protocol.PerspectiveClient, version)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(hdr.PacketNumber).To(Equal(protocol.PacketNumber(0xcade)))
|
Expect(hdr.PacketNumber).To(Equal(protocol.PacketNumber(0xcade)))
|
||||||
Expect(hdr.PacketNumberLen).To(Equal(protocol.PacketNumberLen2))
|
Expect(hdr.PacketNumberLen).To(Equal(protocol.PacketNumberLen2))
|
||||||
|
@ -201,7 +163,7 @@ var _ = Describe("Public Header", func() {
|
||||||
|
|
||||||
It("accepts 4-byte packet numbers", func() {
|
It("accepts 4-byte packet numbers", func() {
|
||||||
b := bytes.NewReader([]byte{0x28, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0xad, 0xfb, 0xca, 0xde})
|
b := bytes.NewReader([]byte{0x28, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0xad, 0xfb, 0xca, 0xde})
|
||||||
hdr, err := ParsePublicHeader(b, protocol.PerspectiveClient, version)
|
hdr, err := parsePublicHeader(b, protocol.PerspectiveClient, version)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(hdr.PacketNumber).To(Equal(protocol.PacketNumber(0xdecafbad)))
|
Expect(hdr.PacketNumber).To(Equal(protocol.PacketNumber(0xdecafbad)))
|
||||||
Expect(hdr.PacketNumberLen).To(Equal(protocol.PacketNumberLen4))
|
Expect(hdr.PacketNumberLen).To(Equal(protocol.PacketNumberLen4))
|
||||||
|
@ -210,7 +172,7 @@ var _ = Describe("Public Header", func() {
|
||||||
|
|
||||||
It("accepts 6-byte packet numbers", func() {
|
It("accepts 6-byte packet numbers", func() {
|
||||||
b := bytes.NewReader([]byte{0x38, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0x23, 0x42, 0xad, 0xfb, 0xca, 0xde})
|
b := bytes.NewReader([]byte{0x38, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0x23, 0x42, 0xad, 0xfb, 0xca, 0xde})
|
||||||
hdr, err := ParsePublicHeader(b, protocol.PerspectiveClient, version)
|
hdr, err := parsePublicHeader(b, protocol.PerspectiveClient, version)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(hdr.PacketNumber).To(Equal(protocol.PacketNumber(0xdecafbad4223)))
|
Expect(hdr.PacketNumber).To(Equal(protocol.PacketNumber(0xdecafbad4223)))
|
||||||
Expect(hdr.PacketNumberLen).To(Equal(protocol.PacketNumberLen6))
|
Expect(hdr.PacketNumberLen).To(Equal(protocol.PacketNumberLen6))
|
||||||
|
@ -227,7 +189,7 @@ var _ = Describe("Public Header", func() {
|
||||||
|
|
||||||
It("accepts 1-byte packet numbers", func() {
|
It("accepts 1-byte packet numbers", func() {
|
||||||
b := bytes.NewReader([]byte{0x08, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0xde})
|
b := bytes.NewReader([]byte{0x08, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0xde})
|
||||||
hdr, err := ParsePublicHeader(b, protocol.PerspectiveClient, version)
|
hdr, err := parsePublicHeader(b, protocol.PerspectiveClient, version)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(hdr.PacketNumber).To(Equal(protocol.PacketNumber(0xde)))
|
Expect(hdr.PacketNumber).To(Equal(protocol.PacketNumber(0xde)))
|
||||||
Expect(hdr.PacketNumberLen).To(Equal(protocol.PacketNumberLen1))
|
Expect(hdr.PacketNumberLen).To(Equal(protocol.PacketNumberLen1))
|
||||||
|
@ -236,7 +198,7 @@ var _ = Describe("Public Header", func() {
|
||||||
|
|
||||||
It("accepts 2-byte packet numbers", func() {
|
It("accepts 2-byte packet numbers", func() {
|
||||||
b := bytes.NewReader([]byte{0x18, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0xde, 0xca})
|
b := bytes.NewReader([]byte{0x18, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0xde, 0xca})
|
||||||
hdr, err := ParsePublicHeader(b, protocol.PerspectiveClient, version)
|
hdr, err := parsePublicHeader(b, protocol.PerspectiveClient, version)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(hdr.PacketNumber).To(Equal(protocol.PacketNumber(0xdeca)))
|
Expect(hdr.PacketNumber).To(Equal(protocol.PacketNumber(0xdeca)))
|
||||||
Expect(hdr.PacketNumberLen).To(Equal(protocol.PacketNumberLen2))
|
Expect(hdr.PacketNumberLen).To(Equal(protocol.PacketNumberLen2))
|
||||||
|
@ -245,7 +207,7 @@ var _ = Describe("Public Header", func() {
|
||||||
|
|
||||||
It("accepts 4-byte packet numbers", func() {
|
It("accepts 4-byte packet numbers", func() {
|
||||||
b := bytes.NewReader([]byte{0x28, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0xad, 0xfb, 0xca, 0xde})
|
b := bytes.NewReader([]byte{0x28, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0xad, 0xfb, 0xca, 0xde})
|
||||||
hdr, err := ParsePublicHeader(b, protocol.PerspectiveClient, version)
|
hdr, err := parsePublicHeader(b, protocol.PerspectiveClient, version)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(hdr.PacketNumber).To(Equal(protocol.PacketNumber(0xadfbcade)))
|
Expect(hdr.PacketNumber).To(Equal(protocol.PacketNumber(0xadfbcade)))
|
||||||
Expect(hdr.PacketNumberLen).To(Equal(protocol.PacketNumberLen4))
|
Expect(hdr.PacketNumberLen).To(Equal(protocol.PacketNumberLen4))
|
||||||
|
@ -254,7 +216,7 @@ var _ = Describe("Public Header", func() {
|
||||||
|
|
||||||
It("accepts 6-byte packet numbers", func() {
|
It("accepts 6-byte packet numbers", func() {
|
||||||
b := bytes.NewReader([]byte{0x38, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0x23, 0x42, 0xad, 0xfb, 0xca, 0xde})
|
b := bytes.NewReader([]byte{0x38, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0x23, 0x42, 0xad, 0xfb, 0xca, 0xde})
|
||||||
hdr, err := ParsePublicHeader(b, protocol.PerspectiveClient, version)
|
hdr, err := parsePublicHeader(b, protocol.PerspectiveClient, version)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(hdr.PacketNumber).To(Equal(protocol.PacketNumber(0x2342adfbcade)))
|
Expect(hdr.PacketNumber).To(Equal(protocol.PacketNumber(0x2342adfbcade)))
|
||||||
Expect(hdr.PacketNumberLen).To(Equal(protocol.PacketNumberLen6))
|
Expect(hdr.PacketNumberLen).To(Equal(protocol.PacketNumberLen6))
|
||||||
|
@ -267,60 +229,60 @@ var _ = Describe("Public Header", func() {
|
||||||
Context("when writing", func() {
|
Context("when writing", func() {
|
||||||
It("writes a sample header as a server", func() {
|
It("writes a sample header as a server", func() {
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
hdr := PublicHeader{
|
hdr := Header{
|
||||||
ConnectionID: 0x4cfa9f9b668619f6,
|
ConnectionID: 0x4cfa9f9b668619f6,
|
||||||
PacketNumber: 2,
|
PacketNumber: 2,
|
||||||
PacketNumberLen: protocol.PacketNumberLen6,
|
PacketNumberLen: protocol.PacketNumberLen6,
|
||||||
}
|
}
|
||||||
err := hdr.Write(b, versionLittleEndian, protocol.PerspectiveServer)
|
err := hdr.writePublicHeader(b, protocol.PerspectiveServer, versionLittleEndian)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(b.Bytes()).To(Equal([]byte{0x38, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 2, 0, 0, 0, 0, 0}))
|
Expect(b.Bytes()).To(Equal([]byte{0x38, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 2, 0, 0, 0, 0, 0}))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("writes a sample header as a client", func() {
|
It("writes a sample header as a client", func() {
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
hdr := PublicHeader{
|
hdr := Header{
|
||||||
ConnectionID: 0x4cfa9f9b668619f6,
|
ConnectionID: 0x4cfa9f9b668619f6,
|
||||||
PacketNumber: 0x1337,
|
PacketNumber: 0x1337,
|
||||||
PacketNumberLen: protocol.PacketNumberLen6,
|
PacketNumberLen: protocol.PacketNumberLen6,
|
||||||
}
|
}
|
||||||
err := hdr.Write(b, versionLittleEndian, protocol.PerspectiveClient)
|
err := hdr.writePublicHeader(b, protocol.PerspectiveClient, versionLittleEndian)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(b.Bytes()).To(Equal([]byte{0x38, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0x37, 0x13, 0, 0, 0, 0}))
|
Expect(b.Bytes()).To(Equal([]byte{0x38, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0x37, 0x13, 0, 0, 0, 0}))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("refuses to write a Public Header if the PacketNumberLen is not set", func() {
|
It("refuses to write a Public Header if the PacketNumberLen is not set", func() {
|
||||||
hdr := PublicHeader{
|
hdr := Header{
|
||||||
ConnectionID: 1,
|
ConnectionID: 1,
|
||||||
PacketNumber: 2,
|
PacketNumber: 2,
|
||||||
}
|
}
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
err := hdr.Write(b, protocol.VersionWhatever, protocol.PerspectiveServer)
|
err := hdr.writePublicHeader(b, protocol.PerspectiveServer, protocol.VersionWhatever)
|
||||||
Expect(err).To(MatchError("PublicHeader: PacketNumberLen not set"))
|
Expect(err).To(MatchError("PublicHeader: PacketNumberLen not set"))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("omits the connection ID", func() {
|
It("omits the connection ID", func() {
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
hdr := PublicHeader{
|
hdr := Header{
|
||||||
ConnectionID: 0x4cfa9f9b668619f6,
|
ConnectionID: 0x4cfa9f9b668619f6,
|
||||||
OmitConnectionID: true,
|
OmitConnectionID: true,
|
||||||
PacketNumberLen: protocol.PacketNumberLen6,
|
PacketNumberLen: protocol.PacketNumberLen6,
|
||||||
PacketNumber: 1,
|
PacketNumber: 1,
|
||||||
}
|
}
|
||||||
err := hdr.Write(b, protocol.VersionWhatever, protocol.PerspectiveServer)
|
err := hdr.writePublicHeader(b, protocol.PerspectiveServer, protocol.VersionWhatever)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(b.Bytes()).To(Equal([]byte{0x30, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0}))
|
Expect(b.Bytes()).To(Equal([]byte{0x30, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0}))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("writes diversification nonces", func() {
|
It("writes diversification nonces", func() {
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
hdr := PublicHeader{
|
hdr := Header{
|
||||||
ConnectionID: 0x4cfa9f9b668619f6,
|
ConnectionID: 0x4cfa9f9b668619f6,
|
||||||
PacketNumber: 1,
|
PacketNumber: 1,
|
||||||
PacketNumberLen: protocol.PacketNumberLen1,
|
PacketNumberLen: protocol.PacketNumberLen1,
|
||||||
DiversificationNonce: bytes.Repeat([]byte{1}, 32),
|
DiversificationNonce: bytes.Repeat([]byte{1}, 32),
|
||||||
}
|
}
|
||||||
err := hdr.Write(b, versionLittleEndian, protocol.PerspectiveServer)
|
err := hdr.writePublicHeader(b, protocol.PerspectiveServer, versionLittleEndian)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(b.Bytes()).To(Equal([]byte{
|
Expect(b.Bytes()).To(Equal([]byte{
|
||||||
0x0c, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6,
|
0x0c, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6,
|
||||||
|
@ -331,24 +293,24 @@ var _ = Describe("Public Header", func() {
|
||||||
|
|
||||||
It("throws an error if both Reset Flag and Version Flag are set", func() {
|
It("throws an error if both Reset Flag and Version Flag are set", func() {
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
hdr := PublicHeader{
|
hdr := Header{
|
||||||
VersionFlag: true,
|
VersionFlag: true,
|
||||||
ResetFlag: true,
|
ResetFlag: true,
|
||||||
}
|
}
|
||||||
err := hdr.Write(b, protocol.VersionWhatever, protocol.PerspectiveServer)
|
err := hdr.writePublicHeader(b, protocol.PerspectiveServer, protocol.VersionWhatever)
|
||||||
Expect(err).To(MatchError(errResetAndVersionFlagSet))
|
Expect(err).To(MatchError(errResetAndVersionFlagSet))
|
||||||
})
|
})
|
||||||
|
|
||||||
Context("Version Negotiation packets", func() {
|
Context("Version Negotiation packets", func() {
|
||||||
It("sets the Version Flag for packets sent as a server", func() {
|
It("sets the Version Flag for packets sent as a server", func() {
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
hdr := PublicHeader{
|
hdr := Header{
|
||||||
VersionFlag: true,
|
VersionFlag: true,
|
||||||
ConnectionID: 0x4cfa9f9b668619f6,
|
ConnectionID: 0x4cfa9f9b668619f6,
|
||||||
PacketNumber: 2,
|
PacketNumber: 2,
|
||||||
PacketNumberLen: protocol.PacketNumberLen6,
|
PacketNumberLen: protocol.PacketNumberLen6,
|
||||||
}
|
}
|
||||||
err := hdr.Write(b, protocol.VersionWhatever, protocol.PerspectiveServer)
|
err := hdr.writePublicHeader(b, protocol.PerspectiveServer, protocol.VersionWhatever)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
// must be the first assertion
|
// must be the first assertion
|
||||||
Expect(b.Len()).To(Equal(1 + 8)) // 1 FlagByte + 8 ConnectionID
|
Expect(b.Len()).To(Equal(1 + 8)) // 1 FlagByte + 8 ConnectionID
|
||||||
|
@ -359,14 +321,14 @@ var _ = Describe("Public Header", func() {
|
||||||
|
|
||||||
It("sets the Version Flag for packets sent as a client, and adds a packet number", func() {
|
It("sets the Version Flag for packets sent as a client, and adds a packet number", func() {
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
hdr := PublicHeader{
|
hdr := Header{
|
||||||
VersionFlag: true,
|
VersionFlag: true,
|
||||||
VersionNumber: protocol.Version38,
|
Version: protocol.Version38,
|
||||||
ConnectionID: 0x4cfa9f9b668619f6,
|
ConnectionID: 0x4cfa9f9b668619f6,
|
||||||
PacketNumber: 0x1337,
|
PacketNumber: 0x1337,
|
||||||
PacketNumberLen: protocol.PacketNumberLen6,
|
PacketNumberLen: protocol.PacketNumberLen6,
|
||||||
}
|
}
|
||||||
err := hdr.Write(b, protocol.VersionWhatever, protocol.PerspectiveClient)
|
err := hdr.writePublicHeader(b, protocol.PerspectiveClient, protocol.VersionWhatever)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
// must be the first assertion
|
// must be the first assertion
|
||||||
Expect(b.Len()).To(Equal(1 + 8 + 4 + 6)) // 1 FlagByte + 8 ConnectionID + 4 version number + 6 PacketNumber
|
Expect(b.Len()).To(Equal(1 + 8 + 4 + 6)) // 1 FlagByte + 8 ConnectionID + 4 version number + 6 PacketNumber
|
||||||
|
@ -381,11 +343,11 @@ var _ = Describe("Public Header", func() {
|
||||||
Context("PublicReset packets", func() {
|
Context("PublicReset packets", func() {
|
||||||
It("sets the Reset Flag", func() {
|
It("sets the Reset Flag", func() {
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
hdr := PublicHeader{
|
hdr := Header{
|
||||||
ResetFlag: true,
|
ResetFlag: true,
|
||||||
ConnectionID: 0x4cfa9f9b668619f6,
|
ConnectionID: 0x4cfa9f9b668619f6,
|
||||||
}
|
}
|
||||||
err := hdr.Write(b, protocol.VersionWhatever, protocol.PerspectiveServer)
|
err := hdr.writePublicHeader(b, protocol.PerspectiveServer, protocol.VersionWhatever)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
// must be the first assertion
|
// must be the first assertion
|
||||||
Expect(b.Len()).To(Equal(1 + 8)) // 1 FlagByte + 8 ConnectionID
|
Expect(b.Len()).To(Equal(1 + 8)) // 1 FlagByte + 8 ConnectionID
|
||||||
|
@ -395,108 +357,108 @@ var _ = Describe("Public Header", func() {
|
||||||
|
|
||||||
It("doesn't add a packet number for headers with Reset Flag sent as a client", func() {
|
It("doesn't add a packet number for headers with Reset Flag sent as a client", func() {
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
hdr := PublicHeader{
|
hdr := Header{
|
||||||
ResetFlag: true,
|
ResetFlag: true,
|
||||||
ConnectionID: 0x4cfa9f9b668619f6,
|
ConnectionID: 0x4cfa9f9b668619f6,
|
||||||
PacketNumber: 2,
|
PacketNumber: 2,
|
||||||
PacketNumberLen: protocol.PacketNumberLen6,
|
PacketNumberLen: protocol.PacketNumberLen6,
|
||||||
}
|
}
|
||||||
err := hdr.Write(b, protocol.VersionWhatever, protocol.PerspectiveClient)
|
err := hdr.writePublicHeader(b, protocol.PerspectiveClient, protocol.VersionWhatever)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
// must be the first assertion
|
// must be the first assertion
|
||||||
Expect(b.Len()).To(Equal(1 + 8)) // 1 FlagByte + 8 ConnectionID
|
Expect(b.Len()).To(Equal(1 + 8)) // 1 FlagByte + 8 ConnectionID
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
Context("GetLength", func() {
|
Context("getting the length", func() {
|
||||||
It("errors when calling GetLength for Version Negotiation packets", func() {
|
It("errors when calling getPublicHeaderLength for Version Negotiation packets", func() {
|
||||||
hdr := PublicHeader{VersionFlag: true}
|
hdr := Header{VersionFlag: true}
|
||||||
_, err := hdr.GetLength(protocol.PerspectiveServer)
|
_, err := hdr.getPublicHeaderLength(protocol.PerspectiveServer)
|
||||||
Expect(err).To(MatchError(errGetLengthNotForVersionNegotiation))
|
Expect(err).To(MatchError(errGetLengthNotForVersionNegotiation))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("errors when calling GetLength for packets that have the VersionFlag and the ResetFlag set", func() {
|
It("errors when calling getPublicHeaderLength for packets that have the VersionFlag and the ResetFlag set", func() {
|
||||||
hdr := PublicHeader{
|
hdr := Header{
|
||||||
ResetFlag: true,
|
ResetFlag: true,
|
||||||
VersionFlag: true,
|
VersionFlag: true,
|
||||||
}
|
}
|
||||||
_, err := hdr.GetLength(protocol.PerspectiveServer)
|
_, err := hdr.getPublicHeaderLength(protocol.PerspectiveServer)
|
||||||
Expect(err).To(MatchError(errResetAndVersionFlagSet))
|
Expect(err).To(MatchError(errResetAndVersionFlagSet))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("errors when PacketNumberLen is not set", func() {
|
It("errors when PacketNumberLen is not set", func() {
|
||||||
hdr := PublicHeader{
|
hdr := Header{
|
||||||
ConnectionID: 0x4cfa9f9b668619f6,
|
ConnectionID: 0x4cfa9f9b668619f6,
|
||||||
PacketNumber: 0xDECAFBAD,
|
PacketNumber: 0xDECAFBAD,
|
||||||
}
|
}
|
||||||
_, err := hdr.GetLength(protocol.PerspectiveServer)
|
_, err := hdr.getPublicHeaderLength(protocol.PerspectiveServer)
|
||||||
Expect(err).To(MatchError(errPacketNumberLenNotSet))
|
Expect(err).To(MatchError(errPacketNumberLenNotSet))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("gets the length of a packet with longest packet number length and connectionID", func() {
|
It("gets the length of a packet with longest packet number length and connectionID", func() {
|
||||||
hdr := PublicHeader{
|
hdr := Header{
|
||||||
ConnectionID: 0x4cfa9f9b668619f6,
|
ConnectionID: 0x4cfa9f9b668619f6,
|
||||||
PacketNumber: 0xDECAFBAD,
|
PacketNumber: 0xDECAFBAD,
|
||||||
PacketNumberLen: protocol.PacketNumberLen6,
|
PacketNumberLen: protocol.PacketNumberLen6,
|
||||||
}
|
}
|
||||||
length, err := hdr.GetLength(protocol.PerspectiveServer)
|
length, err := hdr.getPublicHeaderLength(protocol.PerspectiveServer)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(length).To(Equal(protocol.ByteCount(1 + 8 + 6))) // 1 byte public flag, 8 bytes connectionID, and packet number
|
Expect(length).To(Equal(protocol.ByteCount(1 + 8 + 6))) // 1 byte public flag, 8 bytes connectionID, and packet number
|
||||||
})
|
})
|
||||||
|
|
||||||
It("gets the lengths of a packet sent by the client with the VersionFlag set", func() {
|
It("gets the lengths of a packet sent by the client with the VersionFlag set", func() {
|
||||||
hdr := PublicHeader{
|
hdr := Header{
|
||||||
ConnectionID: 0x4cfa9f9b668619f6,
|
ConnectionID: 0x4cfa9f9b668619f6,
|
||||||
OmitConnectionID: true,
|
OmitConnectionID: true,
|
||||||
PacketNumber: 0xDECAFBAD,
|
PacketNumber: 0xDECAFBAD,
|
||||||
PacketNumberLen: protocol.PacketNumberLen6,
|
PacketNumberLen: protocol.PacketNumberLen6,
|
||||||
VersionFlag: true,
|
VersionFlag: true,
|
||||||
VersionNumber: versionLittleEndian,
|
Version: versionLittleEndian,
|
||||||
}
|
}
|
||||||
length, err := hdr.GetLength(protocol.PerspectiveClient)
|
length, err := hdr.getPublicHeaderLength(protocol.PerspectiveClient)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(length).To(Equal(protocol.ByteCount(1 + 4 + 6))) // 1 byte public flag, 4 version number, and packet number
|
Expect(length).To(Equal(protocol.ByteCount(1 + 4 + 6))) // 1 byte public flag, 4 version number, and packet number
|
||||||
})
|
})
|
||||||
|
|
||||||
It("gets the length of a packet with longest packet number length and omitted connectionID", func() {
|
It("gets the length of a packet with longest packet number length and omitted connectionID", func() {
|
||||||
hdr := PublicHeader{
|
hdr := Header{
|
||||||
ConnectionID: 0x4cfa9f9b668619f6,
|
ConnectionID: 0x4cfa9f9b668619f6,
|
||||||
OmitConnectionID: true,
|
OmitConnectionID: true,
|
||||||
PacketNumber: 0xDECAFBAD,
|
PacketNumber: 0xDECAFBAD,
|
||||||
PacketNumberLen: protocol.PacketNumberLen6,
|
PacketNumberLen: protocol.PacketNumberLen6,
|
||||||
}
|
}
|
||||||
length, err := hdr.GetLength(protocol.PerspectiveServer)
|
length, err := hdr.getPublicHeaderLength(protocol.PerspectiveServer)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(length).To(Equal(protocol.ByteCount(1 + 6))) // 1 byte public flag, and packet number
|
Expect(length).To(Equal(protocol.ByteCount(1 + 6))) // 1 byte public flag, and packet number
|
||||||
})
|
})
|
||||||
|
|
||||||
It("gets the length of a packet 2 byte packet number length ", func() {
|
It("gets the length of a packet 2 byte packet number length ", func() {
|
||||||
hdr := PublicHeader{
|
hdr := Header{
|
||||||
ConnectionID: 0x4cfa9f9b668619f6,
|
ConnectionID: 0x4cfa9f9b668619f6,
|
||||||
PacketNumber: 0xDECAFBAD,
|
PacketNumber: 0xDECAFBAD,
|
||||||
PacketNumberLen: protocol.PacketNumberLen2,
|
PacketNumberLen: protocol.PacketNumberLen2,
|
||||||
}
|
}
|
||||||
length, err := hdr.GetLength(protocol.PerspectiveServer)
|
length, err := hdr.getPublicHeaderLength(protocol.PerspectiveServer)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(length).To(Equal(protocol.ByteCount(1 + 8 + 2))) // 1 byte public flag, 8 byte connectionID, and packet number
|
Expect(length).To(Equal(protocol.ByteCount(1 + 8 + 2))) // 1 byte public flag, 8 byte connectionID, and packet number
|
||||||
})
|
})
|
||||||
|
|
||||||
It("works with diversification nonce", func() {
|
It("works with diversification nonce", func() {
|
||||||
hdr := PublicHeader{
|
hdr := Header{
|
||||||
DiversificationNonce: []byte("foo"),
|
DiversificationNonce: []byte("foo"),
|
||||||
PacketNumberLen: protocol.PacketNumberLen1,
|
PacketNumberLen: protocol.PacketNumberLen1,
|
||||||
}
|
}
|
||||||
length, err := hdr.GetLength(protocol.PerspectiveServer)
|
length, err := hdr.getPublicHeaderLength(protocol.PerspectiveServer)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(length).To(Equal(protocol.ByteCount(1 + 8 + 3 + 1))) // 1 byte public flag, 8 byte connectionID, 3 byte DiversificationNonce, 1 byte PacketNumber
|
Expect(length).To(Equal(protocol.ByteCount(1 + 8 + 3 + 1))) // 1 byte public flag, 8 byte connectionID, 3 byte DiversificationNonce, 1 byte PacketNumber
|
||||||
})
|
})
|
||||||
|
|
||||||
It("gets the length of a PublicReset", func() {
|
It("gets the length of a PublicReset", func() {
|
||||||
hdr := PublicHeader{
|
hdr := Header{
|
||||||
ResetFlag: true,
|
ResetFlag: true,
|
||||||
ConnectionID: 0x4cfa9f9b668619f6,
|
ConnectionID: 0x4cfa9f9b668619f6,
|
||||||
}
|
}
|
||||||
length, err := hdr.GetLength(protocol.PerspectiveServer)
|
length, err := hdr.getPublicHeaderLength(protocol.PerspectiveServer)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(length).To(Equal(protocol.ByteCount(1 + 8))) // 1 byte public flag, 8 byte connectionID
|
Expect(length).To(Equal(protocol.ByteCount(1 + 8))) // 1 byte public flag, 8 byte connectionID
|
||||||
})
|
})
|
||||||
|
@ -505,11 +467,11 @@ var _ = Describe("Public Header", func() {
|
||||||
Context("packet number length", func() {
|
Context("packet number length", func() {
|
||||||
It("doesn't write a header if the packet number length is not set", func() {
|
It("doesn't write a header if the packet number length is not set", func() {
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
hdr := PublicHeader{
|
hdr := Header{
|
||||||
ConnectionID: 0x4cfa9f9b668619f6,
|
ConnectionID: 0x4cfa9f9b668619f6,
|
||||||
PacketNumber: 0xDECAFBAD,
|
PacketNumber: 0xDECAFBAD,
|
||||||
}
|
}
|
||||||
err := hdr.Write(b, protocol.VersionWhatever, protocol.PerspectiveServer)
|
err := hdr.writePublicHeader(b, protocol.PerspectiveServer, protocol.VersionWhatever)
|
||||||
Expect(err).To(MatchError("PublicHeader: PacketNumberLen not set"))
|
Expect(err).To(MatchError("PublicHeader: PacketNumberLen not set"))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -522,48 +484,48 @@ var _ = Describe("Public Header", func() {
|
||||||
|
|
||||||
It("writes a header with a 1-byte packet number", func() {
|
It("writes a header with a 1-byte packet number", func() {
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
hdr := PublicHeader{
|
hdr := Header{
|
||||||
ConnectionID: 0x4cfa9f9b668619f6,
|
ConnectionID: 0x4cfa9f9b668619f6,
|
||||||
PacketNumber: 0xDECAFBAD,
|
PacketNumber: 0xDECAFBAD,
|
||||||
PacketNumberLen: protocol.PacketNumberLen1,
|
PacketNumberLen: protocol.PacketNumberLen1,
|
||||||
}
|
}
|
||||||
err := hdr.Write(b, version, protocol.PerspectiveServer)
|
err := hdr.writePublicHeader(b, protocol.PerspectiveServer, version)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(b.Bytes()).To(Equal([]byte{0x08, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0xAD}))
|
Expect(b.Bytes()).To(Equal([]byte{0x08, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0xAD}))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("writes a header with a 2-byte packet number", func() {
|
It("writes a header with a 2-byte packet number", func() {
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
hdr := PublicHeader{
|
hdr := Header{
|
||||||
ConnectionID: 0x4cfa9f9b668619f6,
|
ConnectionID: 0x4cfa9f9b668619f6,
|
||||||
PacketNumber: 0xDECAFBAD,
|
PacketNumber: 0xDECAFBAD,
|
||||||
PacketNumberLen: protocol.PacketNumberLen2,
|
PacketNumberLen: protocol.PacketNumberLen2,
|
||||||
}
|
}
|
||||||
err := hdr.Write(b, version, protocol.PerspectiveServer)
|
err := hdr.writePublicHeader(b, protocol.PerspectiveServer, version)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(b.Bytes()).To(Equal([]byte{0x18, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0xad, 0xfb}))
|
Expect(b.Bytes()).To(Equal([]byte{0x18, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0xad, 0xfb}))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("writes a header with a 4-byte packet number", func() {
|
It("writes a header with a 4-byte packet number", func() {
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
hdr := PublicHeader{
|
hdr := Header{
|
||||||
ConnectionID: 0x4cfa9f9b668619f6,
|
ConnectionID: 0x4cfa9f9b668619f6,
|
||||||
PacketNumber: 0x13DECAFBAD,
|
PacketNumber: 0x13DECAFBAD,
|
||||||
PacketNumberLen: protocol.PacketNumberLen4,
|
PacketNumberLen: protocol.PacketNumberLen4,
|
||||||
}
|
}
|
||||||
err := hdr.Write(b, version, protocol.PerspectiveServer)
|
err := hdr.writePublicHeader(b, protocol.PerspectiveServer, version)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(b.Bytes()).To(Equal([]byte{0x28, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0xAD, 0xfb, 0xca, 0xde}))
|
Expect(b.Bytes()).To(Equal([]byte{0x28, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0xAD, 0xfb, 0xca, 0xde}))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("writes a header with a 6-byte packet number", func() {
|
It("writes a header with a 6-byte packet number", func() {
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
hdr := PublicHeader{
|
hdr := Header{
|
||||||
ConnectionID: 0x4cfa9f9b668619f6,
|
ConnectionID: 0x4cfa9f9b668619f6,
|
||||||
PacketNumber: 0xBE1337DECAFBAD,
|
PacketNumber: 0xBE1337DECAFBAD,
|
||||||
PacketNumberLen: protocol.PacketNumberLen6,
|
PacketNumberLen: protocol.PacketNumberLen6,
|
||||||
}
|
}
|
||||||
err := hdr.Write(b, version, protocol.PerspectiveServer)
|
err := hdr.writePublicHeader(b, protocol.PerspectiveServer, version)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(b.Bytes()).To(Equal([]byte{0x38, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0xad, 0xfb, 0xca, 0xde, 0x37, 0x13}))
|
Expect(b.Bytes()).To(Equal([]byte{0x38, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0xad, 0xfb, 0xca, 0xde, 0x37, 0x13}))
|
||||||
})
|
})
|
||||||
|
@ -578,48 +540,48 @@ var _ = Describe("Public Header", func() {
|
||||||
|
|
||||||
It("writes a header with a 1-byte packet number", func() {
|
It("writes a header with a 1-byte packet number", func() {
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
hdr := PublicHeader{
|
hdr := Header{
|
||||||
ConnectionID: 0x4cfa9f9b668619f6,
|
ConnectionID: 0x4cfa9f9b668619f6,
|
||||||
PacketNumber: 0xdecafbad,
|
PacketNumber: 0xdecafbad,
|
||||||
PacketNumberLen: protocol.PacketNumberLen1,
|
PacketNumberLen: protocol.PacketNumberLen1,
|
||||||
}
|
}
|
||||||
err := hdr.Write(b, version, protocol.PerspectiveServer)
|
err := hdr.writePublicHeader(b, protocol.PerspectiveServer, version)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(b.Bytes()).To(Equal([]byte{0x08, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0xad}))
|
Expect(b.Bytes()).To(Equal([]byte{0x08, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0xad}))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("writes a header with a 2-byte packet number", func() {
|
It("writes a header with a 2-byte packet number", func() {
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
hdr := PublicHeader{
|
hdr := Header{
|
||||||
ConnectionID: 0x4cfa9f9b668619f6,
|
ConnectionID: 0x4cfa9f9b668619f6,
|
||||||
PacketNumber: 0xdecafbad,
|
PacketNumber: 0xdecafbad,
|
||||||
PacketNumberLen: protocol.PacketNumberLen2,
|
PacketNumberLen: protocol.PacketNumberLen2,
|
||||||
}
|
}
|
||||||
err := hdr.Write(b, version, protocol.PerspectiveServer)
|
err := hdr.writePublicHeader(b, protocol.PerspectiveServer, version)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(b.Bytes()).To(Equal([]byte{0x18, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0xfb, 0xad}))
|
Expect(b.Bytes()).To(Equal([]byte{0x18, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0xfb, 0xad}))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("writes a header with a 4-byte packet number", func() {
|
It("writes a header with a 4-byte packet number", func() {
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
hdr := PublicHeader{
|
hdr := Header{
|
||||||
ConnectionID: 0x4cfa9f9b668619f6,
|
ConnectionID: 0x4cfa9f9b668619f6,
|
||||||
PacketNumber: 0x13decafbad,
|
PacketNumber: 0x13decafbad,
|
||||||
PacketNumberLen: protocol.PacketNumberLen4,
|
PacketNumberLen: protocol.PacketNumberLen4,
|
||||||
}
|
}
|
||||||
err := hdr.Write(b, version, protocol.PerspectiveServer)
|
err := hdr.writePublicHeader(b, protocol.PerspectiveServer, version)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(b.Bytes()).To(Equal([]byte{0x28, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0xde, 0xca, 0xfb, 0xad}))
|
Expect(b.Bytes()).To(Equal([]byte{0x28, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0xde, 0xca, 0xfb, 0xad}))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("writes a header with a 6-byte packet number", func() {
|
It("writes a header with a 6-byte packet number", func() {
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
hdr := PublicHeader{
|
hdr := Header{
|
||||||
ConnectionID: 0x4cfa9f9b668619f6,
|
ConnectionID: 0x4cfa9f9b668619f6,
|
||||||
PacketNumber: 0xbe1337decafbad,
|
PacketNumber: 0xbe1337decafbad,
|
||||||
PacketNumberLen: protocol.PacketNumberLen6,
|
PacketNumberLen: protocol.PacketNumberLen6,
|
||||||
}
|
}
|
||||||
err := hdr.Write(b, version, protocol.PerspectiveServer)
|
err := hdr.writePublicHeader(b, protocol.PerspectiveServer, version)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(b.Bytes()).To(Equal([]byte{0x38, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0x13, 0x37, 0xde, 0xca, 0xfb, 0xad}))
|
Expect(b.Bytes()).To(Equal([]byte{0x38, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0x13, 0x37, 0xde, 0xca, 0xfb, 0xad}))
|
||||||
})
|
})
|
||||||
|
|
|
@ -8,14 +8,15 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// ComposeVersionNegotiation composes a Version Negotiation Packet
|
// ComposeVersionNegotiation composes a Version Negotiation Packet
|
||||||
|
// TODO(894): implement the IETF draft format of Version Negotiation Packets
|
||||||
func ComposeVersionNegotiation(connectionID protocol.ConnectionID, versions []protocol.VersionNumber) []byte {
|
func ComposeVersionNegotiation(connectionID protocol.ConnectionID, versions []protocol.VersionNumber) []byte {
|
||||||
fullReply := &bytes.Buffer{}
|
fullReply := &bytes.Buffer{}
|
||||||
responsePublicHeader := PublicHeader{
|
ph := Header{
|
||||||
ConnectionID: connectionID,
|
ConnectionID: connectionID,
|
||||||
PacketNumber: 1,
|
PacketNumber: 1,
|
||||||
VersionFlag: true,
|
VersionFlag: true,
|
||||||
}
|
}
|
||||||
err := responsePublicHeader.Write(fullReply, protocol.VersionWhatever, protocol.PerspectiveServer)
|
err := ph.writePublicHeader(fullReply, protocol.PerspectiveServer, protocol.VersionWhatever)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Errorf("error composing version negotiation packet: %s", err.Error())
|
utils.Errorf("error composing version negotiation packet: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,10 +54,10 @@ func newPacketPacker(connectionID protocol.ConnectionID,
|
||||||
func (p *packetPacker) PackConnectionClose(ccf *wire.ConnectionCloseFrame) (*packedPacket, error) {
|
func (p *packetPacker) PackConnectionClose(ccf *wire.ConnectionCloseFrame) (*packedPacket, error) {
|
||||||
frames := []wire.Frame{ccf}
|
frames := []wire.Frame{ccf}
|
||||||
encLevel, sealer := p.cryptoSetup.GetSealer()
|
encLevel, sealer := p.cryptoSetup.GetSealer()
|
||||||
ph := p.getPublicHeader(encLevel)
|
header := p.getHeader(encLevel)
|
||||||
raw, err := p.writeAndSealPacket(ph, frames, sealer)
|
raw, err := p.writeAndSealPacket(header, frames, sealer)
|
||||||
return &packedPacket{
|
return &packedPacket{
|
||||||
number: ph.PacketNumber,
|
number: header.PacketNumber,
|
||||||
raw: raw,
|
raw: raw,
|
||||||
frames: frames,
|
frames: frames,
|
||||||
encryptionLevel: encLevel,
|
encryptionLevel: encLevel,
|
||||||
|
@ -69,18 +69,18 @@ func (p *packetPacker) PackAckPacket() (*packedPacket, error) {
|
||||||
return nil, errors.New("packet packer BUG: no ack frame queued")
|
return nil, errors.New("packet packer BUG: no ack frame queued")
|
||||||
}
|
}
|
||||||
encLevel, sealer := p.cryptoSetup.GetSealer()
|
encLevel, sealer := p.cryptoSetup.GetSealer()
|
||||||
ph := p.getPublicHeader(encLevel)
|
header := p.getHeader(encLevel)
|
||||||
frames := []wire.Frame{p.ackFrame}
|
frames := []wire.Frame{p.ackFrame}
|
||||||
if p.stopWaiting != nil {
|
if p.stopWaiting != nil {
|
||||||
p.stopWaiting.PacketNumber = ph.PacketNumber
|
p.stopWaiting.PacketNumber = header.PacketNumber
|
||||||
p.stopWaiting.PacketNumberLen = ph.PacketNumberLen
|
p.stopWaiting.PacketNumberLen = header.PacketNumberLen
|
||||||
frames = append(frames, p.stopWaiting)
|
frames = append(frames, p.stopWaiting)
|
||||||
p.stopWaiting = nil
|
p.stopWaiting = nil
|
||||||
}
|
}
|
||||||
p.ackFrame = nil
|
p.ackFrame = nil
|
||||||
raw, err := p.writeAndSealPacket(ph, frames, sealer)
|
raw, err := p.writeAndSealPacket(header, frames, sealer)
|
||||||
return &packedPacket{
|
return &packedPacket{
|
||||||
number: ph.PacketNumber,
|
number: header.PacketNumber,
|
||||||
raw: raw,
|
raw: raw,
|
||||||
frames: frames,
|
frames: frames,
|
||||||
encryptionLevel: encLevel,
|
encryptionLevel: encLevel,
|
||||||
|
@ -99,14 +99,14 @@ func (p *packetPacker) PackHandshakeRetransmission(packet *ackhandler.Packet) (*
|
||||||
if p.stopWaiting == nil {
|
if p.stopWaiting == nil {
|
||||||
return nil, errors.New("PacketPacker BUG: Handshake retransmissions must contain a StopWaitingFrame")
|
return nil, errors.New("PacketPacker BUG: Handshake retransmissions must contain a StopWaitingFrame")
|
||||||
}
|
}
|
||||||
ph := p.getPublicHeader(packet.EncryptionLevel)
|
header := p.getHeader(packet.EncryptionLevel)
|
||||||
p.stopWaiting.PacketNumber = ph.PacketNumber
|
p.stopWaiting.PacketNumber = header.PacketNumber
|
||||||
p.stopWaiting.PacketNumberLen = ph.PacketNumberLen
|
p.stopWaiting.PacketNumberLen = header.PacketNumberLen
|
||||||
frames := append([]wire.Frame{p.stopWaiting}, packet.Frames...)
|
frames := append([]wire.Frame{p.stopWaiting}, packet.Frames...)
|
||||||
p.stopWaiting = nil
|
p.stopWaiting = nil
|
||||||
raw, err := p.writeAndSealPacket(ph, frames, sealer)
|
raw, err := p.writeAndSealPacket(header, frames, sealer)
|
||||||
return &packedPacket{
|
return &packedPacket{
|
||||||
number: ph.PacketNumber,
|
number: header.PacketNumber,
|
||||||
raw: raw,
|
raw: raw,
|
||||||
frames: frames,
|
frames: frames,
|
||||||
encryptionLevel: packet.EncryptionLevel,
|
encryptionLevel: packet.EncryptionLevel,
|
||||||
|
@ -122,17 +122,17 @@ func (p *packetPacker) PackPacket() (*packedPacket, error) {
|
||||||
|
|
||||||
encLevel, sealer := p.cryptoSetup.GetSealer()
|
encLevel, sealer := p.cryptoSetup.GetSealer()
|
||||||
|
|
||||||
publicHeader := p.getPublicHeader(encLevel)
|
header := p.getHeader(encLevel)
|
||||||
publicHeaderLength, err := publicHeader.GetLength(p.perspective)
|
headerLength, err := header.GetLength(p.perspective, p.version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if p.stopWaiting != nil {
|
if p.stopWaiting != nil {
|
||||||
p.stopWaiting.PacketNumber = publicHeader.PacketNumber
|
p.stopWaiting.PacketNumber = header.PacketNumber
|
||||||
p.stopWaiting.PacketNumberLen = publicHeader.PacketNumberLen
|
p.stopWaiting.PacketNumberLen = header.PacketNumberLen
|
||||||
}
|
}
|
||||||
|
|
||||||
maxSize := protocol.MaxPacketSize - protocol.ByteCount(sealer.Overhead()) - publicHeaderLength
|
maxSize := protocol.MaxPacketSize - protocol.ByteCount(sealer.Overhead()) - headerLength
|
||||||
payloadFrames, err := p.composeNextPacket(maxSize, p.canSendData(encLevel))
|
payloadFrames, err := p.composeNextPacket(maxSize, p.canSendData(encLevel))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -149,12 +149,12 @@ func (p *packetPacker) PackPacket() (*packedPacket, error) {
|
||||||
p.stopWaiting = nil
|
p.stopWaiting = nil
|
||||||
p.ackFrame = nil
|
p.ackFrame = nil
|
||||||
|
|
||||||
raw, err := p.writeAndSealPacket(publicHeader, payloadFrames, sealer)
|
raw, err := p.writeAndSealPacket(header, payloadFrames, sealer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &packedPacket{
|
return &packedPacket{
|
||||||
number: publicHeader.PacketNumber,
|
number: header.PacketNumber,
|
||||||
raw: raw,
|
raw: raw,
|
||||||
frames: payloadFrames,
|
frames: payloadFrames,
|
||||||
encryptionLevel: encLevel,
|
encryptionLevel: encLevel,
|
||||||
|
@ -163,19 +163,19 @@ func (p *packetPacker) PackPacket() (*packedPacket, error) {
|
||||||
|
|
||||||
func (p *packetPacker) packCryptoPacket() (*packedPacket, error) {
|
func (p *packetPacker) packCryptoPacket() (*packedPacket, error) {
|
||||||
encLevel, sealer := p.cryptoSetup.GetSealerForCryptoStream()
|
encLevel, sealer := p.cryptoSetup.GetSealerForCryptoStream()
|
||||||
publicHeader := p.getPublicHeader(encLevel)
|
header := p.getHeader(encLevel)
|
||||||
publicHeaderLength, err := publicHeader.GetLength(p.perspective)
|
headerLength, err := header.GetLength(p.perspective, p.version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
maxLen := protocol.MaxPacketSize - protocol.ByteCount(sealer.Overhead()) - protocol.NonForwardSecurePacketSizeReduction - publicHeaderLength
|
maxLen := protocol.MaxPacketSize - protocol.ByteCount(sealer.Overhead()) - protocol.NonForwardSecurePacketSizeReduction - headerLength
|
||||||
frames := []wire.Frame{p.streamFramer.PopCryptoStreamFrame(maxLen)}
|
frames := []wire.Frame{p.streamFramer.PopCryptoStreamFrame(maxLen)}
|
||||||
raw, err := p.writeAndSealPacket(publicHeader, frames, sealer)
|
raw, err := p.writeAndSealPacket(header, frames, sealer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &packedPacket{
|
return &packedPacket{
|
||||||
number: publicHeader.PacketNumber,
|
number: header.PacketNumber,
|
||||||
raw: raw,
|
raw: raw,
|
||||||
frames: frames,
|
frames: frames,
|
||||||
encryptionLevel: encLevel,
|
encryptionLevel: encLevel,
|
||||||
|
@ -262,38 +262,50 @@ func (p *packetPacker) QueueControlFrame(frame wire.Frame) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *packetPacker) getPublicHeader(encLevel protocol.EncryptionLevel) *wire.PublicHeader {
|
func (p *packetPacker) getHeader(encLevel protocol.EncryptionLevel) *wire.Header {
|
||||||
pnum := p.packetNumberGenerator.Peek()
|
pnum := p.packetNumberGenerator.Peek()
|
||||||
packetNumberLen := protocol.GetPacketNumberLengthForHeader(pnum, p.leastUnacked)
|
packetNumberLen := protocol.GetPacketNumberLengthForHeader(pnum, p.leastUnacked)
|
||||||
publicHeader := &wire.PublicHeader{
|
|
||||||
|
var isLongHeader bool
|
||||||
|
if p.version.UsesTLS() && encLevel != protocol.EncryptionForwardSecure {
|
||||||
|
// TODO: set the Long Header type
|
||||||
|
packetNumberLen = protocol.PacketNumberLen4
|
||||||
|
isLongHeader = true
|
||||||
|
}
|
||||||
|
|
||||||
|
header := &wire.Header{
|
||||||
ConnectionID: p.connectionID,
|
ConnectionID: p.connectionID,
|
||||||
PacketNumber: pnum,
|
PacketNumber: pnum,
|
||||||
PacketNumberLen: packetNumberLen,
|
PacketNumberLen: packetNumberLen,
|
||||||
|
IsLongHeader: isLongHeader,
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.omitConnectionID && encLevel == protocol.EncryptionForwardSecure {
|
if p.omitConnectionID && encLevel == protocol.EncryptionForwardSecure {
|
||||||
publicHeader.OmitConnectionID = true
|
header.OmitConnectionID = true
|
||||||
}
|
}
|
||||||
|
if !p.version.UsesTLS() {
|
||||||
if p.perspective == protocol.PerspectiveServer && encLevel == protocol.EncryptionSecure {
|
if p.perspective == protocol.PerspectiveServer && encLevel == protocol.EncryptionSecure {
|
||||||
publicHeader.DiversificationNonce = p.cryptoSetup.DiversificationNonce()
|
header.DiversificationNonce = p.cryptoSetup.DiversificationNonce()
|
||||||
}
|
}
|
||||||
if p.perspective == protocol.PerspectiveClient && encLevel != protocol.EncryptionForwardSecure {
|
if p.perspective == protocol.PerspectiveClient && encLevel != protocol.EncryptionForwardSecure {
|
||||||
publicHeader.VersionFlag = true
|
header.VersionFlag = true
|
||||||
publicHeader.VersionNumber = p.version
|
header.Version = p.version
|
||||||
}
|
}
|
||||||
|
} else if encLevel != protocol.EncryptionForwardSecure {
|
||||||
return publicHeader
|
header.Version = p.version
|
||||||
|
}
|
||||||
|
return header
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *packetPacker) writeAndSealPacket(
|
func (p *packetPacker) writeAndSealPacket(
|
||||||
publicHeader *wire.PublicHeader,
|
header *wire.Header,
|
||||||
payloadFrames []wire.Frame,
|
payloadFrames []wire.Frame,
|
||||||
sealer handshake.Sealer,
|
sealer handshake.Sealer,
|
||||||
) ([]byte, error) {
|
) ([]byte, error) {
|
||||||
raw := getPacketBuffer()
|
raw := getPacketBuffer()
|
||||||
buffer := bytes.NewBuffer(raw)
|
buffer := bytes.NewBuffer(raw)
|
||||||
|
|
||||||
if err := publicHeader.Write(buffer, p.version, p.perspective); err != nil {
|
if err := header.Write(buffer, p.perspective, p.version); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
payloadStartIndex := buffer.Len()
|
payloadStartIndex := buffer.Len()
|
||||||
|
@ -308,11 +320,11 @@ func (p *packetPacker) writeAndSealPacket(
|
||||||
}
|
}
|
||||||
|
|
||||||
raw = raw[0:buffer.Len()]
|
raw = raw[0:buffer.Len()]
|
||||||
_ = sealer.Seal(raw[payloadStartIndex:payloadStartIndex], raw[payloadStartIndex:], publicHeader.PacketNumber, raw[:payloadStartIndex])
|
_ = sealer.Seal(raw[payloadStartIndex:payloadStartIndex], raw[payloadStartIndex:], header.PacketNumber, raw[:payloadStartIndex])
|
||||||
raw = raw[0 : buffer.Len()+sealer.Overhead()]
|
raw = raw[0 : buffer.Len()+sealer.Overhead()]
|
||||||
|
|
||||||
num := p.packetNumberGenerator.Pop()
|
num := p.packetNumberGenerator.Pop()
|
||||||
if num != publicHeader.PacketNumber {
|
if num != header.PacketNumber {
|
||||||
return nil, errors.New("packetPacker BUG: Peeked and Popped packet numbers do not match")
|
return nil, errors.New("packetPacker BUG: Peeked and Popped packet numbers do not match")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,43 @@ var _ = Describe("Packet packer", func() {
|
||||||
Expect(p.encryptionLevel).To(Equal(protocol.EncryptionForwardSecure))
|
Expect(p.encryptionLevel).To(Equal(protocol.EncryptionForwardSecure))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Context("generating a packet header", func() {
|
||||||
|
const (
|
||||||
|
versionPublicHeader = protocol.Version39 // a QUIC version that uses the Public Header format
|
||||||
|
versionIETFHeader = protocol.VersionTLS // a QUIC version taht uses the IETF Header format
|
||||||
|
)
|
||||||
|
|
||||||
|
Context("Public Header (for gQUIC)", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
packer.version = versionPublicHeader
|
||||||
|
})
|
||||||
|
|
||||||
|
It("it omits the connection ID for forward-secure packets", func() {
|
||||||
|
ph := packer.getHeader(protocol.EncryptionForwardSecure)
|
||||||
|
Expect(ph.OmitConnectionID).To(BeFalse())
|
||||||
|
packer.SetOmitConnectionID()
|
||||||
|
ph = packer.getHeader(protocol.EncryptionForwardSecure)
|
||||||
|
Expect(ph.OmitConnectionID).To(BeTrue())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("doesn't omit the connection ID for non-forward-secure packets", func() {
|
||||||
|
packer.SetOmitConnectionID()
|
||||||
|
ph := packer.getHeader(protocol.EncryptionSecure)
|
||||||
|
Expect(ph.OmitConnectionID).To(BeFalse())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("adds the Version Flag to the Public Header before the crypto handshake is finished", func() {
|
||||||
|
packer.perspective = protocol.PerspectiveClient
|
||||||
|
ph := packer.getHeader(protocol.EncryptionSecure)
|
||||||
|
Expect(ph.VersionFlag).To(BeTrue())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("doesn't add the Version Flag to the Public Header for forward-secure packets", func() {
|
||||||
|
packer.perspective = protocol.PerspectiveClient
|
||||||
|
ph := packer.getHeader(protocol.EncryptionForwardSecure)
|
||||||
|
Expect(ph.VersionFlag).To(BeFalse())
|
||||||
|
})
|
||||||
|
|
||||||
Context("diversificaton nonces", func() {
|
Context("diversificaton nonces", func() {
|
||||||
var nonce []byte
|
var nonce []byte
|
||||||
|
|
||||||
|
@ -118,26 +155,61 @@ var _ = Describe("Packet packer", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
It("doesn't include a div nonce, when sending a packet with initial encryption", func() {
|
It("doesn't include a div nonce, when sending a packet with initial encryption", func() {
|
||||||
ph := packer.getPublicHeader(protocol.EncryptionUnencrypted)
|
ph := packer.getHeader(protocol.EncryptionUnencrypted)
|
||||||
Expect(ph.DiversificationNonce).To(BeEmpty())
|
Expect(ph.DiversificationNonce).To(BeEmpty())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("includes a div nonce, when sending a packet with secure encryption", func() {
|
It("includes a div nonce, when sending a packet with secure encryption", func() {
|
||||||
ph := packer.getPublicHeader(protocol.EncryptionSecure)
|
ph := packer.getHeader(protocol.EncryptionSecure)
|
||||||
Expect(ph.DiversificationNonce).To(Equal(nonce))
|
Expect(ph.DiversificationNonce).To(Equal(nonce))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("doesn't include a div nonce, when sending a packet with forward-secure encryption", func() {
|
It("doesn't include a div nonce, when sending a packet with forward-secure encryption", func() {
|
||||||
ph := packer.getPublicHeader(protocol.EncryptionForwardSecure)
|
ph := packer.getHeader(protocol.EncryptionForwardSecure)
|
||||||
Expect(ph.DiversificationNonce).To(BeEmpty())
|
Expect(ph.DiversificationNonce).To(BeEmpty())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("doesn't send a div nonce as a client", func() {
|
It("doesn't send a div nonce as a client", func() {
|
||||||
packer.perspective = protocol.PerspectiveClient
|
packer.perspective = protocol.PerspectiveClient
|
||||||
ph := packer.getPublicHeader(protocol.EncryptionSecure)
|
ph := packer.getHeader(protocol.EncryptionSecure)
|
||||||
Expect(ph.DiversificationNonce).To(BeEmpty())
|
Expect(ph.DiversificationNonce).To(BeEmpty())
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("Header (for IETF draft QUIC)", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
packer.version = versionIETFHeader
|
||||||
|
})
|
||||||
|
|
||||||
|
It("uses the Long Header format for non-forward-secure packets", func() {
|
||||||
|
h := packer.getHeader(protocol.EncryptionSecure)
|
||||||
|
Expect(h.IsLongHeader).To(BeTrue())
|
||||||
|
Expect(h.PacketNumberLen).To(Equal(protocol.PacketNumberLen4))
|
||||||
|
Expect(h.Version).To(Equal(versionIETFHeader))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("uses the Short Header format for forward-secure packets", func() {
|
||||||
|
h := packer.getHeader(protocol.EncryptionForwardSecure)
|
||||||
|
Expect(h.IsLongHeader).To(BeFalse())
|
||||||
|
Expect(h.PacketNumberLen).To(BeNumerically(">", 0))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("it omits the connection ID for forward-secure packets", func() {
|
||||||
|
h := packer.getHeader(protocol.EncryptionForwardSecure)
|
||||||
|
Expect(h.OmitConnectionID).To(BeFalse())
|
||||||
|
packer.SetOmitConnectionID()
|
||||||
|
h = packer.getHeader(protocol.EncryptionForwardSecure)
|
||||||
|
Expect(h.OmitConnectionID).To(BeTrue())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("doesn't omit the connection ID for non-forward-secure packets", func() {
|
||||||
|
packer.SetOmitConnectionID()
|
||||||
|
h := packer.getHeader(protocol.EncryptionSecure)
|
||||||
|
Expect(h.OmitConnectionID).To(BeFalse())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
It("packs a ConnectionClose", func() {
|
It("packs a ConnectionClose", func() {
|
||||||
ccf := wire.ConnectionCloseFrame{
|
ccf := wire.ConnectionCloseFrame{
|
||||||
|
@ -226,48 +298,6 @@ var _ = Describe("Packet packer", func() {
|
||||||
Expect(p).ToNot(BeNil())
|
Expect(p).ToNot(BeNil())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("it omits the connection ID for forward-secure packets", func() {
|
|
||||||
ph := packer.getPublicHeader(protocol.EncryptionForwardSecure)
|
|
||||||
Expect(ph.OmitConnectionID).To(BeFalse())
|
|
||||||
packer.SetOmitConnectionID()
|
|
||||||
ph = packer.getPublicHeader(protocol.EncryptionForwardSecure)
|
|
||||||
Expect(ph.OmitConnectionID).To(BeTrue())
|
|
||||||
})
|
|
||||||
|
|
||||||
It("doesn't omit the connection ID for non-forware-secure packets", func() {
|
|
||||||
packer.SetOmitConnectionID()
|
|
||||||
ph := packer.getPublicHeader(protocol.EncryptionSecure)
|
|
||||||
Expect(ph.OmitConnectionID).To(BeFalse())
|
|
||||||
})
|
|
||||||
|
|
||||||
It("adds the version flag to the public header before the crypto handshake is finished", func() {
|
|
||||||
packer.perspective = protocol.PerspectiveClient
|
|
||||||
packer.cryptoSetup.(*mockCryptoSetup).encLevelSeal = protocol.EncryptionSecure
|
|
||||||
packer.controlFrames = []wire.Frame{&wire.BlockedFrame{StreamID: 0}}
|
|
||||||
packer.connectionID = 0x1337
|
|
||||||
packer.version = 123
|
|
||||||
p, err := packer.PackPacket()
|
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
Expect(p).ToNot(BeNil())
|
|
||||||
hdr, err := wire.ParsePublicHeader(bytes.NewReader(p.raw), protocol.PerspectiveClient, packer.version)
|
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
Expect(hdr.VersionFlag).To(BeTrue())
|
|
||||||
Expect(hdr.VersionNumber).To(Equal(packer.version))
|
|
||||||
})
|
|
||||||
|
|
||||||
It("doesn't add the version flag to the public header for forward-secure packets", func() {
|
|
||||||
packer.perspective = protocol.PerspectiveClient
|
|
||||||
packer.cryptoSetup.(*mockCryptoSetup).encLevelSeal = protocol.EncryptionForwardSecure
|
|
||||||
packer.controlFrames = []wire.Frame{&wire.BlockedFrame{StreamID: 0}}
|
|
||||||
packer.connectionID = 0x1337
|
|
||||||
p, err := packer.PackPacket()
|
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
Expect(p).ToNot(BeNil())
|
|
||||||
hdr, err := wire.ParsePublicHeader(bytes.NewReader(p.raw), protocol.PerspectiveClient, packer.version)
|
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
Expect(hdr.VersionFlag).To(BeFalse())
|
|
||||||
})
|
|
||||||
|
|
||||||
It("packs many control frames into 1 packets", func() {
|
It("packs many control frames into 1 packets", func() {
|
||||||
f := &wire.AckFrame{LargestAcked: 1}
|
f := &wire.AckFrame{LargestAcked: 1}
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
|
|
|
@ -24,10 +24,10 @@ type packetUnpacker struct {
|
||||||
aead quicAEAD
|
aead quicAEAD
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *packetUnpacker) Unpack(publicHeaderBinary []byte, hdr *wire.PublicHeader, data []byte) (*unpackedPacket, error) {
|
func (u *packetUnpacker) Unpack(headerBinary []byte, hdr *wire.Header, data []byte) (*unpackedPacket, error) {
|
||||||
buf := getPacketBuffer()
|
buf := getPacketBuffer()
|
||||||
defer putPacketBuffer(buf)
|
defer putPacketBuffer(buf)
|
||||||
decrypted, encryptionLevel, err := u.aead.Open(buf, data, hdr.PacketNumber, publicHeaderBinary)
|
decrypted, encryptionLevel, err := u.aead.Open(buf, data, hdr.PacketNumber, headerBinary)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Wrap err in quicError so that public reset is sent by session
|
// Wrap err in quicError so that public reset is sent by session
|
||||||
return nil, qerr.Error(qerr.DecryptionFailure, err.Error())
|
return nil, qerr.Error(qerr.DecryptionFailure, err.Error())
|
||||||
|
|
|
@ -31,14 +31,14 @@ var _ quicAEAD = &mockAEAD{}
|
||||||
var _ = Describe("Packet unpacker", func() {
|
var _ = Describe("Packet unpacker", func() {
|
||||||
var (
|
var (
|
||||||
unpacker *packetUnpacker
|
unpacker *packetUnpacker
|
||||||
hdr *wire.PublicHeader
|
hdr *wire.Header
|
||||||
hdrBin []byte
|
hdrBin []byte
|
||||||
data []byte
|
data []byte
|
||||||
buf *bytes.Buffer
|
buf *bytes.Buffer
|
||||||
)
|
)
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
hdr = &wire.PublicHeader{
|
hdr = &wire.Header{
|
||||||
PacketNumber: 10,
|
PacketNumber: 10,
|
||||||
PacketNumberLen: 1,
|
PacketNumberLen: 1,
|
||||||
}
|
}
|
||||||
|
|
15
server.go
15
server.go
|
@ -214,7 +214,7 @@ func (s *server) handlePacket(pconn net.PacketConn, remoteAddr net.Addr, packet
|
||||||
rcvTime := time.Now()
|
rcvTime := time.Now()
|
||||||
|
|
||||||
r := bytes.NewReader(packet)
|
r := bytes.NewReader(packet)
|
||||||
connID, err := wire.PeekConnectionID(r, protocol.PerspectiveClient)
|
connID, err := wire.PeekConnectionID(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return qerr.Error(qerr.InvalidPacketHeader, err.Error())
|
return qerr.Error(qerr.InvalidPacketHeader, err.Error())
|
||||||
}
|
}
|
||||||
|
@ -233,7 +233,7 @@ func (s *server) handlePacket(pconn net.PacketConn, remoteAddr net.Addr, packet
|
||||||
version = session.GetVersion()
|
version = session.GetVersion()
|
||||||
}
|
}
|
||||||
|
|
||||||
hdr, err := wire.ParsePublicHeader(r, protocol.PerspectiveClient, version)
|
hdr, err := wire.ParseHeader(r, protocol.PerspectiveClient, version)
|
||||||
if err == wire.ErrPacketWithUnknownVersion {
|
if err == wire.ErrPacketWithUnknownVersion {
|
||||||
_, err = pconn.WriteTo(wire.WritePublicReset(connID, 0, 0), remoteAddr)
|
_, err = pconn.WriteTo(wire.WritePublicReset(connID, 0, 0), remoteAddr)
|
||||||
return err
|
return err
|
||||||
|
@ -262,23 +262,24 @@ func (s *server) handlePacket(pconn net.PacketConn, remoteAddr net.Addr, packet
|
||||||
// a session is only created once the client sent a supported version
|
// a session is only created once the client sent a supported version
|
||||||
// if we receive a packet for a connection that already has session, it's probably an old packet that was sent by the client before the version was negotiated
|
// if we receive a packet for a connection that already has session, it's probably an old packet that was sent by the client before the version was negotiated
|
||||||
// it is safe to drop it
|
// it is safe to drop it
|
||||||
if ok && hdr.VersionFlag && !protocol.IsSupportedVersion(s.config.Versions, hdr.VersionNumber) {
|
if ok && hdr.VersionFlag && !protocol.IsSupportedVersion(s.config.Versions, hdr.Version) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send Version Negotiation Packet if the client is speaking a different protocol version
|
// Send Version Negotiation Packet if the client is speaking a different protocol version
|
||||||
if hdr.VersionFlag && !protocol.IsSupportedVersion(s.config.Versions, hdr.VersionNumber) {
|
if hdr.VersionFlag && !protocol.IsSupportedVersion(s.config.Versions, hdr.Version) {
|
||||||
// drop packets that are too small to be valid first packets
|
// drop packets that are too small to be valid first packets
|
||||||
if len(packet) < protocol.ClientHelloMinimumSize+len(hdr.Raw) {
|
if len(packet) < protocol.ClientHelloMinimumSize+len(hdr.Raw) {
|
||||||
return errors.New("dropping small packet with unknown version")
|
return errors.New("dropping small packet with unknown version")
|
||||||
}
|
}
|
||||||
utils.Infof("Client offered version %s, sending VersionNegotiationPacket", hdr.VersionNumber)
|
// TODO(894): send a IETF draft style Version Negotiation Packets
|
||||||
|
utils.Infof("Client offered version %s, sending VersionNegotiationPacket", hdr.Version)
|
||||||
_, err = pconn.WriteTo(wire.ComposeVersionNegotiation(hdr.ConnectionID, s.config.Versions), remoteAddr)
|
_, err = pconn.WriteTo(wire.ComposeVersionNegotiation(hdr.ConnectionID, s.config.Versions), remoteAddr)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
version := hdr.VersionNumber
|
version := hdr.Version
|
||||||
if !protocol.IsSupportedVersion(s.config.Versions, version) {
|
if !protocol.IsSupportedVersion(s.config.Versions, version) {
|
||||||
return errors.New("Server BUG: negotiated version not supported")
|
return errors.New("Server BUG: negotiated version not supported")
|
||||||
}
|
}
|
||||||
|
@ -321,7 +322,7 @@ func (s *server) handlePacket(pconn net.PacketConn, remoteAddr net.Addr, packet
|
||||||
}
|
}
|
||||||
session.handlePacket(&receivedPacket{
|
session.handlePacket(&receivedPacket{
|
||||||
remoteAddr: remoteAddr,
|
remoteAddr: remoteAddr,
|
||||||
publicHeader: hdr,
|
header: hdr,
|
||||||
data: packet[len(packet)-r.Len():],
|
data: packet[len(packet)-r.Len():],
|
||||||
rcvTime: rcvTime,
|
rcvTime: rcvTime,
|
||||||
})
|
})
|
||||||
|
|
|
@ -327,13 +327,13 @@ var _ = Describe("Server", func() {
|
||||||
|
|
||||||
It("doesn't respond with a version negotiation packet if the first packet is too small", func() {
|
It("doesn't respond with a version negotiation packet if the first packet is too small", func() {
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
hdr := wire.PublicHeader{
|
hdr := wire.Header{
|
||||||
VersionFlag: true,
|
VersionFlag: true,
|
||||||
ConnectionID: 0x1337,
|
ConnectionID: 0x1337,
|
||||||
PacketNumber: 1,
|
PacketNumber: 1,
|
||||||
PacketNumberLen: protocol.PacketNumberLen2,
|
PacketNumberLen: protocol.PacketNumberLen2,
|
||||||
}
|
}
|
||||||
hdr.Write(b, 13 /* not a valid QUIC version */, protocol.PerspectiveClient)
|
hdr.Write(b, protocol.PerspectiveClient, 13 /* not a valid QUIC version */)
|
||||||
b.Write(bytes.Repeat([]byte{0}, protocol.ClientHelloMinimumSize-1)) // this packet is 1 byte too small
|
b.Write(bytes.Repeat([]byte{0}, protocol.ClientHelloMinimumSize-1)) // this packet is 1 byte too small
|
||||||
err := serv.handlePacket(conn, udpAddr, b.Bytes())
|
err := serv.handlePacket(conn, udpAddr, b.Bytes())
|
||||||
Expect(err).To(MatchError("dropping small packet with unknown version"))
|
Expect(err).To(MatchError("dropping small packet with unknown version"))
|
||||||
|
@ -398,13 +398,13 @@ var _ = Describe("Server", func() {
|
||||||
It("setups and responds with version negotiation", func() {
|
It("setups and responds with version negotiation", func() {
|
||||||
config.Versions = []protocol.VersionNumber{99}
|
config.Versions = []protocol.VersionNumber{99}
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
hdr := wire.PublicHeader{
|
hdr := wire.Header{
|
||||||
VersionFlag: true,
|
VersionFlag: true,
|
||||||
ConnectionID: 0x1337,
|
ConnectionID: 0x1337,
|
||||||
PacketNumber: 1,
|
PacketNumber: 1,
|
||||||
PacketNumberLen: protocol.PacketNumberLen2,
|
PacketNumberLen: protocol.PacketNumberLen2,
|
||||||
}
|
}
|
||||||
hdr.Write(b, 13 /* not a valid QUIC version */, protocol.PerspectiveClient)
|
hdr.Write(b, protocol.PerspectiveClient, 13 /* not a valid QUIC version */)
|
||||||
b.Write(bytes.Repeat([]byte{0}, protocol.ClientHelloMinimumSize)) // add a fake CHLO
|
b.Write(bytes.Repeat([]byte{0}, protocol.ClientHelloMinimumSize)) // add a fake CHLO
|
||||||
conn.dataToRead = b.Bytes()
|
conn.dataToRead = b.Bytes()
|
||||||
conn.dataReadFrom = udpAddr
|
conn.dataReadFrom = udpAddr
|
||||||
|
|
16
session.go
16
session.go
|
@ -20,12 +20,12 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type unpacker interface {
|
type unpacker interface {
|
||||||
Unpack(publicHeaderBinary []byte, hdr *wire.PublicHeader, data []byte) (*unpackedPacket, error)
|
Unpack(headerBinary []byte, hdr *wire.Header, data []byte) (*unpackedPacket, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type receivedPacket struct {
|
type receivedPacket struct {
|
||||||
remoteAddr net.Addr
|
remoteAddr net.Addr
|
||||||
publicHeader *wire.PublicHeader
|
header *wire.Header
|
||||||
data []byte
|
data []byte
|
||||||
rcvTime time.Time
|
rcvTime time.Time
|
||||||
}
|
}
|
||||||
|
@ -322,7 +322,7 @@ runLoop:
|
||||||
}
|
}
|
||||||
// This is a bit unclean, but works properly, since the packet always
|
// This is a bit unclean, but works properly, since the packet always
|
||||||
// begins with the public header and we never copy it.
|
// begins with the public header and we never copy it.
|
||||||
putPacketBuffer(p.publicHeader.Raw)
|
putPacketBuffer(p.header.Raw)
|
||||||
case p := <-s.paramsChan:
|
case p := <-s.paramsChan:
|
||||||
s.processTransportParameters(&p)
|
s.processTransportParameters(&p)
|
||||||
case l, ok := <-aeadChanged:
|
case l, ok := <-aeadChanged:
|
||||||
|
@ -410,7 +410,7 @@ func (s *session) maybeResetTimer() {
|
||||||
|
|
||||||
func (s *session) handlePacketImpl(p *receivedPacket) error {
|
func (s *session) handlePacketImpl(p *receivedPacket) error {
|
||||||
if s.perspective == protocol.PerspectiveClient {
|
if s.perspective == protocol.PerspectiveClient {
|
||||||
diversificationNonce := p.publicHeader.DiversificationNonce
|
diversificationNonce := p.header.DiversificationNonce
|
||||||
if len(diversificationNonce) > 0 {
|
if len(diversificationNonce) > 0 {
|
||||||
s.cryptoSetup.SetDiversificationNonce(diversificationNonce)
|
s.cryptoSetup.SetDiversificationNonce(diversificationNonce)
|
||||||
}
|
}
|
||||||
|
@ -423,7 +423,7 @@ func (s *session) handlePacketImpl(p *receivedPacket) error {
|
||||||
|
|
||||||
s.lastNetworkActivityTime = p.rcvTime
|
s.lastNetworkActivityTime = p.rcvTime
|
||||||
s.keepAlivePingSent = false
|
s.keepAlivePingSent = false
|
||||||
hdr := p.publicHeader
|
hdr := p.header
|
||||||
data := p.data
|
data := p.data
|
||||||
|
|
||||||
// Calculate packet number
|
// Calculate packet number
|
||||||
|
@ -847,7 +847,7 @@ func (s *session) scheduleSending() {
|
||||||
|
|
||||||
func (s *session) tryQueueingUndecryptablePacket(p *receivedPacket) {
|
func (s *session) tryQueueingUndecryptablePacket(p *receivedPacket) {
|
||||||
if s.handshakeComplete {
|
if s.handshakeComplete {
|
||||||
utils.Debugf("Received undecryptable packet from %s after the handshake: %#v, %d bytes data", p.remoteAddr.String(), p.publicHeader, len(p.data))
|
utils.Debugf("Received undecryptable packet from %s after the handshake: %#v, %d bytes data", p.remoteAddr.String(), p.header, len(p.data))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(s.undecryptablePackets)+1 > protocol.MaxUndecryptablePackets {
|
if len(s.undecryptablePackets)+1 > protocol.MaxUndecryptablePackets {
|
||||||
|
@ -856,10 +856,10 @@ func (s *session) tryQueueingUndecryptablePacket(p *receivedPacket) {
|
||||||
s.receivedTooManyUndecrytablePacketsTime = time.Now()
|
s.receivedTooManyUndecrytablePacketsTime = time.Now()
|
||||||
s.maybeResetTimer()
|
s.maybeResetTimer()
|
||||||
}
|
}
|
||||||
utils.Infof("Dropping undecrytable packet 0x%x (undecryptable packet queue full)", p.publicHeader.PacketNumber)
|
utils.Infof("Dropping undecrytable packet 0x%x (undecryptable packet queue full)", p.header.PacketNumber)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
utils.Infof("Queueing packet 0x%x for later decryption", p.publicHeader.PacketNumber)
|
utils.Infof("Queueing packet 0x%x for later decryption", p.header.PacketNumber)
|
||||||
s.undecryptablePackets = append(s.undecryptablePackets, p)
|
s.undecryptablePackets = append(s.undecryptablePackets, p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ type mockUnpacker struct {
|
||||||
unpackErr error
|
unpackErr error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockUnpacker) Unpack(publicHeaderBinary []byte, hdr *wire.PublicHeader, data []byte) (*unpackedPacket, error) {
|
func (m *mockUnpacker) Unpack(headerBinary []byte, hdr *wire.Header, data []byte) (*unpackedPacket, error) {
|
||||||
if m.unpackErr != nil {
|
if m.unpackErr != nil {
|
||||||
return nil, m.unpackErr
|
return nil, m.unpackErr
|
||||||
}
|
}
|
||||||
|
@ -688,16 +688,16 @@ var _ = Describe("Session", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
Context("receiving packets", func() {
|
Context("receiving packets", func() {
|
||||||
var hdr *wire.PublicHeader
|
var hdr *wire.Header
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
sess.unpacker = &mockUnpacker{}
|
sess.unpacker = &mockUnpacker{}
|
||||||
hdr = &wire.PublicHeader{PacketNumberLen: protocol.PacketNumberLen6}
|
hdr = &wire.Header{PacketNumberLen: protocol.PacketNumberLen6}
|
||||||
})
|
})
|
||||||
|
|
||||||
It("sets the {last,largest}RcvdPacketNumber", func() {
|
It("sets the {last,largest}RcvdPacketNumber", func() {
|
||||||
hdr.PacketNumber = 5
|
hdr.PacketNumber = 5
|
||||||
err := sess.handlePacketImpl(&receivedPacket{publicHeader: hdr})
|
err := sess.handlePacketImpl(&receivedPacket{header: hdr})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(sess.lastRcvdPacketNumber).To(Equal(protocol.PacketNumber(5)))
|
Expect(sess.lastRcvdPacketNumber).To(Equal(protocol.PacketNumber(5)))
|
||||||
Expect(sess.largestRcvdPacketNumber).To(Equal(protocol.PacketNumber(5)))
|
Expect(sess.largestRcvdPacketNumber).To(Equal(protocol.PacketNumber(5)))
|
||||||
|
@ -711,7 +711,7 @@ var _ = Describe("Session", func() {
|
||||||
runErr = sess.run()
|
runErr = sess.run()
|
||||||
}()
|
}()
|
||||||
sess.unpacker.(*mockUnpacker).unpackErr = testErr
|
sess.unpacker.(*mockUnpacker).unpackErr = testErr
|
||||||
sess.handlePacket(&receivedPacket{publicHeader: hdr})
|
sess.handlePacket(&receivedPacket{header: hdr})
|
||||||
Eventually(func() error { return runErr }).Should(MatchError(testErr))
|
Eventually(func() error { return runErr }).Should(MatchError(testErr))
|
||||||
Expect(sess.Context().Done()).To(BeClosed())
|
Expect(sess.Context().Done()).To(BeClosed())
|
||||||
close(done)
|
close(done)
|
||||||
|
@ -719,12 +719,12 @@ var _ = Describe("Session", func() {
|
||||||
|
|
||||||
It("sets the {last,largest}RcvdPacketNumber, for an out-of-order packet", func() {
|
It("sets the {last,largest}RcvdPacketNumber, for an out-of-order packet", func() {
|
||||||
hdr.PacketNumber = 5
|
hdr.PacketNumber = 5
|
||||||
err := sess.handlePacketImpl(&receivedPacket{publicHeader: hdr})
|
err := sess.handlePacketImpl(&receivedPacket{header: hdr})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(sess.lastRcvdPacketNumber).To(Equal(protocol.PacketNumber(5)))
|
Expect(sess.lastRcvdPacketNumber).To(Equal(protocol.PacketNumber(5)))
|
||||||
Expect(sess.largestRcvdPacketNumber).To(Equal(protocol.PacketNumber(5)))
|
Expect(sess.largestRcvdPacketNumber).To(Equal(protocol.PacketNumber(5)))
|
||||||
hdr.PacketNumber = 3
|
hdr.PacketNumber = 3
|
||||||
err = sess.handlePacketImpl(&receivedPacket{publicHeader: hdr})
|
err = sess.handlePacketImpl(&receivedPacket{header: hdr})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(sess.lastRcvdPacketNumber).To(Equal(protocol.PacketNumber(3)))
|
Expect(sess.lastRcvdPacketNumber).To(Equal(protocol.PacketNumber(3)))
|
||||||
Expect(sess.largestRcvdPacketNumber).To(Equal(protocol.PacketNumber(5)))
|
Expect(sess.largestRcvdPacketNumber).To(Equal(protocol.PacketNumber(5)))
|
||||||
|
@ -732,9 +732,9 @@ var _ = Describe("Session", func() {
|
||||||
|
|
||||||
It("handles duplicate packets", func() {
|
It("handles duplicate packets", func() {
|
||||||
hdr.PacketNumber = 5
|
hdr.PacketNumber = 5
|
||||||
err := sess.handlePacketImpl(&receivedPacket{publicHeader: hdr})
|
err := sess.handlePacketImpl(&receivedPacket{header: hdr})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
err = sess.handlePacketImpl(&receivedPacket{publicHeader: hdr})
|
err = sess.handlePacketImpl(&receivedPacket{header: hdr})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -744,7 +744,7 @@ var _ = Describe("Session", func() {
|
||||||
Expect(sess.conn.(*mockConnection).remoteAddr).ToNot(Equal(remoteIP))
|
Expect(sess.conn.(*mockConnection).remoteAddr).ToNot(Equal(remoteIP))
|
||||||
p := receivedPacket{
|
p := receivedPacket{
|
||||||
remoteAddr: remoteIP,
|
remoteAddr: remoteIP,
|
||||||
publicHeader: &wire.PublicHeader{PacketNumber: 1337},
|
header: &wire.Header{PacketNumber: 1337},
|
||||||
}
|
}
|
||||||
err := sess.handlePacketImpl(&p)
|
err := sess.handlePacketImpl(&p)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
@ -760,7 +760,7 @@ var _ = Describe("Session", func() {
|
||||||
sess.unpacker.(*packetUnpacker).aead = &mockAEAD{}
|
sess.unpacker.(*packetUnpacker).aead = &mockAEAD{}
|
||||||
p := receivedPacket{
|
p := receivedPacket{
|
||||||
remoteAddr: attackerIP,
|
remoteAddr: attackerIP,
|
||||||
publicHeader: &wire.PublicHeader{PacketNumber: 1337},
|
header: &wire.Header{PacketNumber: 1337},
|
||||||
}
|
}
|
||||||
err := sess.handlePacketImpl(&p)
|
err := sess.handlePacketImpl(&p)
|
||||||
quicErr := err.(*qerr.QuicError)
|
quicErr := err.(*qerr.QuicError)
|
||||||
|
@ -774,7 +774,7 @@ var _ = Describe("Session", func() {
|
||||||
Expect(sess.conn.(*mockConnection).remoteAddr).ToNot(Equal(remoteIP))
|
Expect(sess.conn.(*mockConnection).remoteAddr).ToNot(Equal(remoteIP))
|
||||||
p := receivedPacket{
|
p := receivedPacket{
|
||||||
remoteAddr: remoteIP,
|
remoteAddr: remoteIP,
|
||||||
publicHeader: &wire.PublicHeader{PacketNumber: 1337},
|
header: &wire.Header{PacketNumber: 1337},
|
||||||
}
|
}
|
||||||
sess.unpacker.(*mockUnpacker).unpackErr = testErr
|
sess.unpacker.(*mockUnpacker).unpackErr = testErr
|
||||||
err := sess.handlePacketImpl(&p)
|
err := sess.handlePacketImpl(&p)
|
||||||
|
@ -1140,11 +1140,11 @@ var _ = Describe("Session", func() {
|
||||||
// this completely fills up the undecryptable packets queue and triggers the public reset timer
|
// this completely fills up the undecryptable packets queue and triggers the public reset timer
|
||||||
sendUndecryptablePackets := func() {
|
sendUndecryptablePackets := func() {
|
||||||
for i := 0; i < protocol.MaxUndecryptablePackets+1; i++ {
|
for i := 0; i < protocol.MaxUndecryptablePackets+1; i++ {
|
||||||
hdr := &wire.PublicHeader{
|
hdr := &wire.Header{
|
||||||
PacketNumber: protocol.PacketNumber(i + 1),
|
PacketNumber: protocol.PacketNumber(i + 1),
|
||||||
}
|
}
|
||||||
sess.handlePacket(&receivedPacket{
|
sess.handlePacket(&receivedPacket{
|
||||||
publicHeader: hdr,
|
header: hdr,
|
||||||
remoteAddr: &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 1234},
|
remoteAddr: &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 1234},
|
||||||
data: []byte("foobar"),
|
data: []byte("foobar"),
|
||||||
})
|
})
|
||||||
|
@ -1175,7 +1175,7 @@ var _ = Describe("Session", func() {
|
||||||
sendUndecryptablePackets()
|
sendUndecryptablePackets()
|
||||||
Eventually(func() []*receivedPacket { return sess.undecryptablePackets }).Should(HaveLen(protocol.MaxUndecryptablePackets))
|
Eventually(func() []*receivedPacket { return sess.undecryptablePackets }).Should(HaveLen(protocol.MaxUndecryptablePackets))
|
||||||
// check that old packets are kept, and the new packets are dropped
|
// check that old packets are kept, and the new packets are dropped
|
||||||
Expect(sess.undecryptablePackets[0].publicHeader.PacketNumber).To(Equal(protocol.PacketNumber(1)))
|
Expect(sess.undecryptablePackets[0].header.PacketNumber).To(Equal(protocol.PacketNumber(1)))
|
||||||
sess.Close(nil)
|
sess.Close(nil)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1213,7 +1213,7 @@ var _ = Describe("Session", func() {
|
||||||
|
|
||||||
It("unqueues undecryptable packets for later decryption", func() {
|
It("unqueues undecryptable packets for later decryption", func() {
|
||||||
sess.undecryptablePackets = []*receivedPacket{{
|
sess.undecryptablePackets = []*receivedPacket{{
|
||||||
publicHeader: &wire.PublicHeader{PacketNumber: protocol.PacketNumber(42)},
|
header: &wire.Header{PacketNumber: protocol.PacketNumber(42)},
|
||||||
}}
|
}}
|
||||||
Expect(sess.receivedPackets).NotTo(Receive())
|
Expect(sess.receivedPackets).NotTo(Receive())
|
||||||
sess.tryDecryptingQueuedPackets()
|
sess.tryDecryptingQueuedPackets()
|
||||||
|
@ -1549,10 +1549,10 @@ var _ = Describe("Client Session", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
Context("receiving packets", func() {
|
Context("receiving packets", func() {
|
||||||
var hdr *wire.PublicHeader
|
var hdr *wire.Header
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
hdr = &wire.PublicHeader{PacketNumberLen: protocol.PacketNumberLen6}
|
hdr = &wire.Header{PacketNumberLen: protocol.PacketNumberLen6}
|
||||||
sess.unpacker = &mockUnpacker{}
|
sess.unpacker = &mockUnpacker{}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1560,7 +1560,7 @@ var _ = Describe("Client Session", func() {
|
||||||
go sess.run()
|
go sess.run()
|
||||||
hdr.PacketNumber = 5
|
hdr.PacketNumber = 5
|
||||||
hdr.DiversificationNonce = []byte("foobar")
|
hdr.DiversificationNonce = []byte("foobar")
|
||||||
err := sess.handlePacketImpl(&receivedPacket{publicHeader: hdr})
|
err := sess.handlePacketImpl(&receivedPacket{header: hdr})
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Eventually(func() []byte { return cryptoSetup.divNonce }).Should(Equal(hdr.DiversificationNonce))
|
Eventually(func() []byte { return cryptoSetup.divNonce }).Should(Equal(hdr.DiversificationNonce))
|
||||||
Expect(sess.Close(nil)).To(Succeed())
|
Expect(sess.Close(nil)).To(Succeed())
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue