From 0bd7e744ffc8c11b16c594ae6cd8ca03e683687d Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sun, 1 Jul 2018 12:15:15 +0700 Subject: [PATCH] implement parsing of headers with different connection ID lengths --- client.go | 2 +- client_multiplexer.go | 2 +- client_test.go | 2 +- internal/protocol/connection_id.go | 2 +- internal/protocol/protocol.go | 6 ++ internal/protocol/server_parameters.go | 9 -- internal/wire/header.go | 5 +- internal/wire/header_parser.go | 13 ++- internal/wire/header_parser_test.go | 113 +++++++++++++--------- internal/wire/header_test.go | 17 +--- internal/wire/version_negotiation_test.go | 4 +- packet_packer_test.go | 2 +- server.go | 2 +- server_test.go | 4 +- server_tls_test.go | 2 +- session_test.go | 2 +- 16 files changed, 97 insertions(+), 90 deletions(-) diff --git a/client.go b/client.go index e8e92ddf..6937b344 100644 --- a/client.go +++ b/client.go @@ -364,7 +364,7 @@ func (c *client) handleRead(remoteAddr net.Addr, packet []byte) { rcvTime := time.Now() r := bytes.NewReader(packet) - iHdr, err := wire.ParseInvariantHeader(r) + iHdr, err := wire.ParseInvariantHeader(r, protocol.ConnectionIDLenGQUIC) // drop the packet if we can't parse the header if err != nil { c.logger.Errorf("error parsing invariant header: %s", err) diff --git a/client_multiplexer.go b/client_multiplexer.go index e2b1f717..1b9a2882 100644 --- a/client_multiplexer.go +++ b/client_multiplexer.go @@ -87,7 +87,7 @@ func (m *clientMultiplexer) listen(c net.PacketConn, sessions packetHandlerManag rcvTime := time.Now() r := bytes.NewReader(data) - iHdr, err := wire.ParseInvariantHeader(r) + iHdr, err := wire.ParseInvariantHeader(r, protocol.ConnectionIDLenGQUIC) // drop the packet if we can't parse the header if err != nil { m.logger.Debugf("error parsing invariant header from %s: %s", addr, err) diff --git a/client_test.go b/client_test.go index 39284af2..30d2bb5c 100644 --- a/client_test.go +++ b/client_test.go @@ -866,7 +866,7 @@ var _ = Describe("Client", func() { pr = wire.WritePublicReset(cl.destConnID, 1, 0) r := bytes.NewReader(pr) - iHdr, err := wire.ParseInvariantHeader(r) + iHdr, err := wire.ParseInvariantHeader(r, 0) Expect(err).ToNot(HaveOccurred()) hdr, err = iHdr.Parse(r, protocol.PerspectiveServer, versionGQUICFrames) Expect(err).ToNot(HaveOccurred()) diff --git a/internal/protocol/connection_id.go b/internal/protocol/connection_id.go index dca4bcd6..cf2f480d 100644 --- a/internal/protocol/connection_id.go +++ b/internal/protocol/connection_id.go @@ -12,7 +12,7 @@ type ConnectionID []byte // GenerateConnectionID generates a connection ID using cryptographic random func GenerateConnectionID() (ConnectionID, error) { - b := make([]byte, ConnectionIDLen) + b := make([]byte, ConnectionIDLenGQUIC) if _, err := rand.Read(b); err != nil { return nil, err } diff --git a/internal/protocol/protocol.go b/internal/protocol/protocol.go index e89b2227..2a52f895 100644 --- a/internal/protocol/protocol.go +++ b/internal/protocol/protocol.go @@ -82,3 +82,9 @@ const MinInitialPacketSize = 1200 // * one failure due to an incorrect or missing source-address token // * one failure due the server's certificate chain being unavailable and the server being unwilling to send it without a valid source-address token const MaxClientHellos = 3 + +// ConnectionIDLenGQUIC is the length of the source Connection ID used on gQUIC QUIC packets. +const ConnectionIDLenGQUIC = 8 + +// MinConnectionIDLenInitial is the minimum length of the destination connection ID on an Initial packet. +const MinConnectionIDLenInitial = 8 diff --git a/internal/protocol/server_parameters.go b/internal/protocol/server_parameters.go index 92fb0dd2..c8696fdf 100644 --- a/internal/protocol/server_parameters.go +++ b/internal/protocol/server_parameters.go @@ -145,12 +145,3 @@ const MaxAckFrameSize ByteCount = 1000 // If the packet packing frequency is higher, multiple packets might be sent at once. // Example: For a packet pacing delay of 20 microseconds, we would send 5 packets at once, wait for 100 microseconds, and so forth. const MinPacingDelay time.Duration = 100 * time.Microsecond - -// ConnectionIDLen is the length of the source Connection ID used on IETF QUIC packets. -// The Short Header contains the connection ID, but not the length, -// so we need to know this value in advance (or encode it into the connection ID). -// TODO: make this configurable -const ConnectionIDLen = 8 - -// MinConnectionIDLenInitial is the minimum length of the destination connection ID on an Initial packet. -const MinConnectionIDLenInitial = 8 diff --git a/internal/wire/header.go b/internal/wire/header.go index d53a9872..99efab75 100644 --- a/internal/wire/header.go +++ b/internal/wire/header.go @@ -56,9 +56,6 @@ func (h *Header) Write(b *bytes.Buffer, pers protocol.Perspective, version proto // TODO: add support for the key phase func (h *Header) writeLongHeader(b *bytes.Buffer) error { - if h.SrcConnectionID.Len() != protocol.ConnectionIDLen { - return fmt.Errorf("Header: source connection ID must be %d bytes, is %d", protocol.ConnectionIDLen, h.SrcConnectionID.Len()) - } b.WriteByte(byte(0x80 | h.Type)) utils.BigEndian.WriteUint32(b, uint32(h.Version)) connIDLen, err := encodeConnIDLen(h.DestConnectionID, h.SrcConnectionID) @@ -174,7 +171,7 @@ func (h *Header) getPublicHeaderLength() (protocol.ByteCount, error) { return 0, errPacketNumberLenNotSet } length += protocol.ByteCount(h.PacketNumberLen) - length += protocol.ByteCount(h.DestConnectionID.Len()) // if set, always 8 bytes + length += protocol.ByteCount(h.DestConnectionID.Len()) // Version Number in packets sent by the client if h.VersionFlag { length += 4 diff --git a/internal/wire/header_parser.go b/internal/wire/header_parser.go index 523c24fe..e712f76a 100644 --- a/internal/wire/header_parser.go +++ b/internal/wire/header_parser.go @@ -21,7 +21,7 @@ type InvariantHeader struct { } // ParseInvariantHeader parses the version independent part of the header -func ParseInvariantHeader(b *bytes.Reader) (*InvariantHeader, error) { +func ParseInvariantHeader(b *bytes.Reader, shortHeaderConnIDLen int) (*InvariantHeader, error) { typeByte, err := b.ReadByte() if err != nil { return nil, err @@ -36,8 +36,15 @@ func ParseInvariantHeader(b *bytes.Reader) (*InvariantHeader, error) { // In the IETF Short Header: // * 0x8 it is the gQUIC Demultiplexing bit, and always 0. // * 0x20 and 0x10 are always 1. - if typeByte&0x8 > 0 || typeByte&0x38 == 0x30 { - h.DestConnectionID, err = protocol.ReadConnectionID(b, 8) + var connIDLen int + if typeByte&0x8 > 0 { // Public Header containing a connection ID + connIDLen = 8 + } + if typeByte&0x38 == 0x30 { // Short Header + connIDLen = shortHeaderConnIDLen + } + if connIDLen > 0 { + h.DestConnectionID, err = protocol.ReadConnectionID(b, connIDLen) if err != nil { return nil, err } diff --git a/internal/wire/header_parser_test.go b/internal/wire/header_parser_test.go index c7d62776..769abf1f 100644 --- a/internal/wire/header_parser_test.go +++ b/internal/wire/header_parser_test.go @@ -22,13 +22,13 @@ var _ = Describe("Header Parsing", func() { Context("Version Negotiation Packets", func() { It("parses", func() { - srcConnID := protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8} - destConnID := protocol.ConnectionID{8, 7, 6, 5, 4, 3, 2, 1} + srcConnID := protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12} + destConnID := protocol.ConnectionID{9, 8, 7, 6, 5, 4, 3, 2, 1} versions := []protocol.VersionNumber{0x22334455, 0x33445566} data, err := ComposeVersionNegotiation(destConnID, srcConnID, versions) Expect(err).ToNot(HaveOccurred()) b := bytes.NewReader(data) - iHdr, err := ParseInvariantHeader(b) + iHdr, err := ParseInvariantHeader(b, 0) Expect(err).ToNot(HaveOccurred()) Expect(iHdr.DestConnectionID).To(Equal(destConnID)) Expect(iHdr.SrcConnectionID).To(Equal(srcConnID)) @@ -50,7 +50,7 @@ var _ = Describe("Header Parsing", func() { data, err := ComposeVersionNegotiation(connID, connID, versions) Expect(err).ToNot(HaveOccurred()) b := bytes.NewReader(data[:len(data)-2]) - iHdr, err := ParseInvariantHeader(b) + iHdr, err := ParseInvariantHeader(b, 0) Expect(err).ToNot(HaveOccurred()) _, err = iHdr.Parse(b, protocol.PerspectiveServer, versionIETFFrames) Expect(err).To(MatchError(qerr.InvalidVersionNegotiationPacket)) @@ -63,7 +63,7 @@ var _ = Describe("Header Parsing", func() { Expect(err).ToNot(HaveOccurred()) // remove 8 bytes (two versions), since ComposeVersionNegotiation also added a reserved version number b := bytes.NewReader(data[:len(data)-8]) - iHdr, err := ParseInvariantHeader(b) + iHdr, err := ParseInvariantHeader(b, 0) Expect(err).ToNot(HaveOccurred()) _, err = iHdr.Parse(b, protocol.PerspectiveServer, versionIETFFrames) Expect(err).To(MatchError("InvalidVersionNegotiationPacket: empty version list")) @@ -71,13 +71,13 @@ var _ = Describe("Header Parsing", func() { }) Context("Long Headers", func() { - It("parses a long header", func() { - destConnID := protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37} - srcConnID := protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x42, 0x42} + It("parses a Long Header", func() { + destConnID := protocol.ConnectionID{9, 8, 7, 6, 5, 4, 3, 2, 1} + srcConnID := protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef} data := []byte{ 0x80 ^ uint8(protocol.PacketTypeInitial), 0x1, 0x2, 0x3, 0x4, // version number - 0x55, // connection ID lengths + 0x61, // connection ID lengths } data = append(data, destConnID...) data = append(data, srcConnID...) @@ -86,7 +86,7 @@ var _ = Describe("Header Parsing", func() { data = appendPacketNumber(data, 0xbeef, protocol.PacketNumberLen4) b := bytes.NewReader(data) - iHdr, err := ParseInvariantHeader(b) + iHdr, err := ParseInvariantHeader(b, 0) Expect(err).ToNot(HaveOccurred()) Expect(iHdr.IsLongHeader).To(BeTrue()) Expect(iHdr.DestConnectionID).To(Equal(destConnID)) @@ -105,7 +105,7 @@ var _ = Describe("Header Parsing", func() { Expect(b.Len()).To(BeZero()) }) - It("parses a long header without a destination connection ID", func() { + It("parses a Long Header without a destination connection ID", func() { data := []byte{ 0x80 ^ uint8(protocol.PacketTypeInitial), 0x1, 0x2, 0x3, 0x4, // version number @@ -115,13 +115,13 @@ var _ = Describe("Header Parsing", func() { data = append(data, encodeVarInt(0x42)...) // payload length data = append(data, []byte{0xde, 0xca, 0xfb, 0xad}...) b := bytes.NewReader(data) - iHdr, err := ParseInvariantHeader(b) + iHdr, err := ParseInvariantHeader(b, 0) Expect(err).ToNot(HaveOccurred()) Expect(iHdr.SrcConnectionID).To(Equal(protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef})) Expect(iHdr.DestConnectionID).To(BeEmpty()) }) - It("parses a long header without a source connection ID", func() { + It("parses a Long Header without a source connection ID", func() { data := []byte{ 0x80 ^ uint8(protocol.PacketTypeInitial), 0x1, 0x2, 0x3, 0x4, // version number @@ -131,13 +131,13 @@ var _ = Describe("Header Parsing", func() { data = append(data, encodeVarInt(0x42)...) // payload length data = append(data, []byte{0xde, 0xca, 0xfb, 0xad}...) b := bytes.NewReader(data) - iHdr, err := ParseInvariantHeader(b) + iHdr, err := ParseInvariantHeader(b, 0) Expect(err).ToNot(HaveOccurred()) Expect(iHdr.SrcConnectionID).To(BeEmpty()) Expect(iHdr.DestConnectionID).To(Equal(protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})) }) - It("parses a long header with a 2 byte packet number", func() { + It("parses a Long Header with a 2 byte packet number", func() { data := []byte{ 0x80 ^ uint8(protocol.PacketTypeInitial), 0x1, 0x2, 0x3, 0x4, // version number @@ -146,7 +146,7 @@ var _ = Describe("Header Parsing", func() { data = append(data, encodeVarInt(0x42)...) // payload length data = appendPacketNumber(data, 0x123, protocol.PacketNumberLen2) b := bytes.NewReader(data) - iHdr, err := ParseInvariantHeader(b) + iHdr, err := ParseInvariantHeader(b, 0) Expect(err).ToNot(HaveOccurred()) hdr, err := iHdr.Parse(b, protocol.PerspectiveServer, versionIETFHeader) Expect(err).ToNot(HaveOccurred()) @@ -167,7 +167,7 @@ var _ = Describe("Header Parsing", func() { }).Write(buf, protocol.PerspectiveClient, protocol.VersionTLS) Expect(err).ToNot(HaveOccurred()) b := bytes.NewReader(buf.Bytes()) - iHdr, err := ParseInvariantHeader(b) + iHdr, err := ParseInvariantHeader(b, 0) Expect(err).ToNot(HaveOccurred()) _, err = iHdr.Parse(b, protocol.PerspectiveClient, versionIETFHeader) Expect(err).To(MatchError("InvalidPacketHeader: Received packet with invalid packet type: 42")) @@ -182,7 +182,7 @@ var _ = Describe("Header Parsing", func() { 0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37, // source connection ID } for i := 0; i < len(data); i++ { - _, err := ParseInvariantHeader(bytes.NewReader(data[:i])) + _, err := ParseInvariantHeader(bytes.NewReader(data[:i]), 0) Expect(err).To(Equal(io.EOF)) } }) @@ -198,7 +198,7 @@ var _ = Describe("Header Parsing", func() { data = appendPacketNumber(data, 0xdeadbeef, protocol.PacketNumberLen4) for i := iHdrLen; i < len(data); i++ { b := bytes.NewReader(data[:i]) - iHdr, err := ParseInvariantHeader(b) + iHdr, err := ParseInvariantHeader(b, 0) Expect(err).ToNot(HaveOccurred()) _, err = iHdr.Parse(b, protocol.PerspectiveServer, versionIETFHeader) Expect(err).To(Equal(io.EOF)) @@ -207,12 +207,12 @@ var _ = Describe("Header Parsing", func() { }) Context("Short Headers", func() { - It("reads a short header with a connection ID", func() { + It("reads a Short Header with a 8 byte connection ID", func() { connID := protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37} data := append([]byte{0x30}, connID...) data = appendPacketNumber(data, 0x42, protocol.PacketNumberLen1) b := bytes.NewReader(data) - iHdr, err := ParseInvariantHeader(b) + iHdr, err := ParseInvariantHeader(b, 8) Expect(err).ToNot(HaveOccurred()) Expect(iHdr.IsLongHeader).To(BeFalse()) Expect(iHdr.DestConnectionID).To(Equal(connID)) @@ -226,14 +226,31 @@ var _ = Describe("Header Parsing", func() { Expect(b.Len()).To(BeZero()) }) + It("reads a Short Header with a 5 byte connection ID", func() { + connID := protocol.ConnectionID{1, 2, 3, 4, 5} + data := append([]byte{0x30}, connID...) + data = appendPacketNumber(data, 0x42, protocol.PacketNumberLen1) + b := bytes.NewReader(data) + iHdr, err := ParseInvariantHeader(b, 5) + Expect(err).ToNot(HaveOccurred()) + Expect(iHdr.IsLongHeader).To(BeFalse()) + Expect(iHdr.DestConnectionID).To(Equal(connID)) + hdr, err := iHdr.Parse(b, protocol.PerspectiveClient, versionIETFHeader) + Expect(err).ToNot(HaveOccurred()) + Expect(hdr.KeyPhase).To(Equal(0)) + Expect(hdr.DestConnectionID).To(Equal(connID)) + Expect(hdr.SrcConnectionID).To(BeEmpty()) + Expect(b.Len()).To(BeZero()) + }) + It("reads the Key Phase Bit", func() { data := []byte{ 0x30 ^ 0x40, - 0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37, // connection ID + 0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, // connection ID } data = appendPacketNumber(data, 11, protocol.PacketNumberLen1) b := bytes.NewReader(data) - iHdr, err := ParseInvariantHeader(b) + iHdr, err := ParseInvariantHeader(b, 6) Expect(err).ToNot(HaveOccurred()) hdr, err := iHdr.Parse(b, protocol.PerspectiveServer, versionIETFHeader) Expect(err).ToNot(HaveOccurred()) @@ -245,11 +262,11 @@ var _ = Describe("Header Parsing", func() { It("reads a header with a 2 byte packet number", func() { data := []byte{ 0x30 ^ 0x40 ^ 0x1, - 0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37, // connection ID + 0xde, 0xad, 0xbe, 0xef, // connection ID } data = appendPacketNumber(data, 0x1337, protocol.PacketNumberLen2) b := bytes.NewReader(data) - iHdr, err := ParseInvariantHeader(b) + iHdr, err := ParseInvariantHeader(b, 4) Expect(err).ToNot(HaveOccurred()) hdr, err := iHdr.Parse(b, protocol.PerspectiveClient, versionIETFHeader) Expect(err).ToNot(HaveOccurred()) @@ -262,11 +279,11 @@ var _ = Describe("Header Parsing", func() { It("reads a header with a 4 byte packet number", func() { data := []byte{ 0x30 ^ 0x40 ^ 0x2, - 0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37, // connection ID + 0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x1, 0x2, 0x3, 0x4, // connection ID } data = appendPacketNumber(data, 0x99beef, protocol.PacketNumberLen4) b := bytes.NewReader(data) - iHdr, err := ParseInvariantHeader(b) + iHdr, err := ParseInvariantHeader(b, 10) Expect(err).ToNot(HaveOccurred()) hdr, err := iHdr.Parse(b, protocol.PerspectiveServer, versionIETFHeader) Expect(err).ToNot(HaveOccurred()) @@ -282,7 +299,7 @@ var _ = Describe("Header Parsing", func() { 0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37, // connection ID } for i := 0; i < len(data); i++ { - _, err := ParseInvariantHeader(bytes.NewReader(data[:i])) + _, err := ParseInvariantHeader(bytes.NewReader(data[:i]), 8) Expect(err).To(Equal(io.EOF)) } }) @@ -290,13 +307,13 @@ var _ = Describe("Header Parsing", func() { It("errors on EOF, when parsing the invariant header", func() { data := []byte{ 0x30 ^ 0x2, - 0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37, // connection ID + 0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, // connection ID } iHdrLen := len(data) data = appendPacketNumber(data, 0xdeadbeef, protocol.PacketNumberLen4) for i := iHdrLen; i < len(data); i++ { b := bytes.NewReader(data[:i]) - iHdr, err := ParseInvariantHeader(b) + iHdr, err := ParseInvariantHeader(b, 6) Expect(err).ToNot(HaveOccurred()) _, err = iHdr.Parse(b, protocol.PerspectiveClient, versionIETFHeader) Expect(err).To(Equal(io.EOF)) @@ -307,10 +324,14 @@ var _ = Describe("Header Parsing", func() { Context("Public Header", func() { It("accepts a sample client header", func() { - ver := make([]byte, 4) - binary.BigEndian.PutUint32(ver, uint32(protocol.SupportedVersions[0])) - b := bytes.NewReader(append(append([]byte{0x09, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6}, ver...), 0x01)) - iHdr, err := ParseInvariantHeader(b) + data := []byte{ + 0x9, + 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, + } + data = append(data, []byte{0xde, 0xad, 0xbe, 0xef}...) + data = append(data, 0x1) // packet number + b := bytes.NewReader(data) + iHdr, err := ParseInvariantHeader(b, 0) Expect(err).ToNot(HaveOccurred()) Expect(iHdr.IsLongHeader).To(BeFalse()) hdr, err := iHdr.Parse(b, protocol.PerspectiveClient, versionPublicHeader) @@ -321,7 +342,7 @@ var _ = Describe("Header Parsing", func() { connID := protocol.ConnectionID{0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6} Expect(hdr.DestConnectionID).To(Equal(connID)) Expect(hdr.SrcConnectionID).To(BeEmpty()) - Expect(hdr.Version).To(Equal(protocol.SupportedVersions[0])) + Expect(hdr.Version).To(Equal(protocol.VersionNumber(0xdeadbeef))) Expect(hdr.SupportedVersions).To(BeEmpty()) Expect(hdr.PacketNumber).To(Equal(protocol.PacketNumber(1))) Expect(b.Len()).To(BeZero()) @@ -329,7 +350,7 @@ var _ = Describe("Header Parsing", func() { It("accepts an omitted connection ID", func() { b := bytes.NewReader([]byte{0x0, 0x1}) - iHdr, err := ParseInvariantHeader(b) + iHdr, err := ParseInvariantHeader(b, 8) Expect(err).ToNot(HaveOccurred()) Expect(iHdr.IsLongHeader).To(BeFalse()) Expect(iHdr.DestConnectionID).To(BeEmpty()) @@ -342,7 +363,7 @@ var _ = Describe("Header Parsing", func() { It("parses a PUBLIC_RESET packet", func() { b := bytes.NewReader([]byte{0xa, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8}) - iHdr, err := ParseInvariantHeader(b) + iHdr, err := ParseInvariantHeader(b, 4) Expect(err).ToNot(HaveOccurred()) Expect(iHdr.IsLongHeader).To(BeFalse()) hdr, err := iHdr.Parse(b, protocol.PerspectiveServer, versionPublicHeader) @@ -359,7 +380,7 @@ var _ = Describe("Header Parsing", 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} Expect(divNonce).To(HaveLen(32)) b := bytes.NewReader(append(append([]byte{0x0c, 0xf6, 0x19, 0x86, 0x66, 0x9b, 0x9f, 0xfa, 0x4c}, divNonce...), 0x37)) - iHdr, err := ParseInvariantHeader(b) + iHdr, err := ParseInvariantHeader(b, 7) Expect(err).ToNot(HaveOccurred()) Expect(iHdr.IsLongHeader).To(BeFalse()) hdr, err := iHdr.Parse(b, protocol.PerspectiveServer, versionPublicHeader) @@ -380,7 +401,7 @@ var _ = Describe("Header Parsing", func() { data = append(data, []byte{0x13, 37}...) // packet number for i := iHdrLen; i < len(data); i++ { b := bytes.NewReader(data[:i]) - iHdr, err := ParseInvariantHeader(b) + iHdr, err := ParseInvariantHeader(b, 5) Expect(err).ToNot(HaveOccurred()) _, err = iHdr.Parse(b, protocol.PerspectiveServer, versionPublicHeader) Expect(err).To(Equal(io.EOF)) @@ -398,7 +419,7 @@ var _ = Describe("Header Parsing", func() { connID := protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8} versions := []protocol.VersionNumber{0x13, 0x37} b := bytes.NewReader(ComposeGQUICVersionNegotiation(connID, versions)) - iHdr, err := ParseInvariantHeader(b) + iHdr, err := ParseInvariantHeader(b, 6) Expect(err).ToNot(HaveOccurred()) hdr, err := iHdr.Parse(b, protocol.PerspectiveServer, versionPublicHeader) Expect(err).ToNot(HaveOccurred()) @@ -416,7 +437,7 @@ var _ = Describe("Header Parsing", func() { It("errors if it doesn't contain any versions", func() { b := bytes.NewReader([]byte{0x9, 0xf6, 0x19, 0x86, 0x66, 0x9b, 0x9f, 0xfa, 0x4c}) - iHdr, err := ParseInvariantHeader(b) + iHdr, err := ParseInvariantHeader(b, 4) Expect(err).ToNot(HaveOccurred()) _, err = iHdr.Parse(b, protocol.PerspectiveServer, versionPublicHeader) Expect(err).To(MatchError("InvalidVersionNegotiationPacket: empty version list")) @@ -428,7 +449,7 @@ var _ = Describe("Header Parsing", func() { data = appendVersion(data, protocol.SupportedVersions[0]) data = appendVersion(data, 99) // unsupported version b := bytes.NewReader(data) - iHdr, err := ParseInvariantHeader(b) + iHdr, err := ParseInvariantHeader(b, 0) Expect(err).ToNot(HaveOccurred()) hdr, err := iHdr.Parse(b, protocol.PerspectiveServer, versionPublicHeader) Expect(err).ToNot(HaveOccurred()) @@ -442,7 +463,7 @@ var _ = Describe("Header Parsing", func() { data := ComposeGQUICVersionNegotiation(protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8}, protocol.SupportedVersions) data = append(data, []byte{0x13, 0x37}...) b := bytes.NewReader(data) - iHdr, err := ParseInvariantHeader(b) + iHdr, err := ParseInvariantHeader(b, 0) Expect(err).ToNot(HaveOccurred()) _, err = iHdr.Parse(b, protocol.PerspectiveServer, versionPublicHeader) Expect(err).To(MatchError(qerr.InvalidVersionNegotiationPacket)) @@ -452,7 +473,7 @@ var _ = Describe("Header Parsing", func() { Context("Packet Number lengths", func() { It("accepts 1-byte packet numbers", func() { b := bytes.NewReader([]byte{0x08, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0xde}) - iHdr, err := ParseInvariantHeader(b) + iHdr, err := ParseInvariantHeader(b, 0) Expect(err).ToNot(HaveOccurred()) hdr, err := iHdr.Parse(b, protocol.PerspectiveServer, versionPublicHeader) Expect(err).ToNot(HaveOccurred()) @@ -463,7 +484,7 @@ var _ = Describe("Header Parsing", func() { It("accepts 2-byte packet numbers", func() { b := bytes.NewReader([]byte{0x18, 0x4c, 0xfa, 0x9f, 0x9b, 0x66, 0x86, 0x19, 0xf6, 0xde, 0xca}) - iHdr, err := ParseInvariantHeader(b) + iHdr, err := ParseInvariantHeader(b, 0) Expect(err).ToNot(HaveOccurred()) hdr, err := iHdr.Parse(b, protocol.PerspectiveServer, versionPublicHeader) Expect(err).ToNot(HaveOccurred()) @@ -474,7 +495,7 @@ var _ = Describe("Header Parsing", 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}) - iHdr, err := ParseInvariantHeader(b) + iHdr, err := ParseInvariantHeader(b, 0) Expect(err).ToNot(HaveOccurred()) hdr, err := iHdr.Parse(b, protocol.PerspectiveServer, versionPublicHeader) Expect(err).ToNot(HaveOccurred()) diff --git a/internal/wire/header_test.go b/internal/wire/header_test.go index eeaa0547..0ac2987c 100644 --- a/internal/wire/header_test.go +++ b/internal/wire/header_test.go @@ -84,21 +84,6 @@ var _ = Describe("Header", func() { Expect(err).To(MatchError("invalid connection ID length: 19 bytes")) }) - It("refuses to write a Long Header with the wrong connection ID length", func() { - srcConnID := protocol.ConnectionID{1, 2, 3, 4, 5, 6} - Expect(srcConnID).ToNot(Equal(protocol.ConnectionIDLen)) - err := (&Header{ - IsLongHeader: true, - Type: 0x5, - SrcConnectionID: srcConnID, - DestConnectionID: protocol.ConnectionID{1, 2, 3, 4, 5}, // connection IDs must be at most 18 bytes long - PacketNumber: 0xdecafbad, - PacketNumberLen: protocol.PacketNumberLen4, - Version: 0x1020304, - }).Write(buf, protocol.PerspectiveServer, versionIETFHeader) - Expect(err).To(MatchError("Header: source connection ID must be 8 bytes, is 6")) - }) - It("writes a header with an 18 byte connection ID", func() { err := (&Header{ IsLongHeader: true, @@ -537,7 +522,7 @@ var _ = Describe("Header", func() { data, err := ComposeVersionNegotiation(destConnID, srcConnID, []protocol.VersionNumber{0x12345678, 0x87654321}) Expect(err).ToNot(HaveOccurred()) b := bytes.NewReader(data) - iHdr, err := ParseInvariantHeader(b) + iHdr, err := ParseInvariantHeader(b, 4) Expect(err).ToNot(HaveOccurred()) hdr, err := iHdr.Parse(b, protocol.PerspectiveServer, versionIETFHeader) Expect(err).ToNot(HaveOccurred()) diff --git a/internal/wire/version_negotiation_test.go b/internal/wire/version_negotiation_test.go index b8194fd5..0d53142a 100644 --- a/internal/wire/version_negotiation_test.go +++ b/internal/wire/version_negotiation_test.go @@ -14,7 +14,7 @@ var _ = Describe("Version Negotiation Packets", func() { versions := []protocol.VersionNumber{1001, 1003} data := ComposeGQUICVersionNegotiation(connID, versions) b := bytes.NewReader(data) - iHdr, err := ParseInvariantHeader(b) + iHdr, err := ParseInvariantHeader(b, 4) Expect(err).ToNot(HaveOccurred()) hdr, err := iHdr.Parse(b, protocol.PerspectiveServer, versionPublicHeader) Expect(err).ToNot(HaveOccurred()) @@ -32,7 +32,7 @@ var _ = Describe("Version Negotiation Packets", func() { Expect(err).ToNot(HaveOccurred()) Expect(data[0] & 0x80).ToNot(BeZero()) b := bytes.NewReader(data) - iHdr, err := ParseInvariantHeader(b) + iHdr, err := ParseInvariantHeader(b, 4) Expect(err).ToNot(HaveOccurred()) hdr, err := iHdr.Parse(b, protocol.PerspectiveServer, versionIETFHeader) Expect(err).ToNot(HaveOccurred()) diff --git a/packet_packer_test.go b/packet_packer_test.go index 7cd66feb..81fa8708 100644 --- a/packet_packer_test.go +++ b/packet_packer_test.go @@ -65,7 +65,7 @@ var _ = Describe("Packet packer", func() { checkPayloadLen := func(data []byte) { r := bytes.NewReader(data) - iHdr, err := wire.ParseInvariantHeader(r) + iHdr, err := wire.ParseInvariantHeader(r, 0) Expect(err).ToNot(HaveOccurred()) hdr, err := iHdr.Parse(r, protocol.PerspectiveServer, versionIETFFrames) Expect(err).ToNot(HaveOccurred()) diff --git a/server.go b/server.go index da791ab6..fe6158fb 100644 --- a/server.go +++ b/server.go @@ -304,7 +304,7 @@ func (s *server) handlePacket(remoteAddr net.Addr, packet []byte) error { rcvTime := time.Now() r := bytes.NewReader(packet) - iHdr, err := wire.ParseInvariantHeader(r) + iHdr, err := wire.ParseInvariantHeader(r, protocol.ConnectionIDLenGQUIC) if err != nil { return qerr.Error(qerr.InvalidPacketHeader, err.Error()) } diff --git a/server_test.go b/server_test.go index 140648ff..2e10e7d7 100644 --- a/server_test.go +++ b/server_test.go @@ -500,7 +500,7 @@ var _ = Describe("Server", func() { Eventually(func() int { return conn.dataWritten.Len() }).ShouldNot(BeZero()) Expect(conn.dataWrittenTo).To(Equal(udpAddr)) r := bytes.NewReader(conn.dataWritten.Bytes()) - iHdr, err := wire.ParseInvariantHeader(r) + iHdr, err := wire.ParseInvariantHeader(r, 0) Expect(err).ToNot(HaveOccurred()) Expect(iHdr.IsLongHeader).To(BeFalse()) replyHdr, err := iHdr.Parse(r, protocol.PerspectiveServer, versionIETFFrames) @@ -546,7 +546,7 @@ var _ = Describe("Server", func() { Eventually(func() int { return conn.dataWritten.Len() }).ShouldNot(BeZero()) Expect(conn.dataWrittenTo).To(Equal(udpAddr)) r := bytes.NewReader(conn.dataWritten.Bytes()) - iHdr, err := wire.ParseInvariantHeader(r) + iHdr, err := wire.ParseInvariantHeader(r, 0) Expect(err).ToNot(HaveOccurred()) replyHdr, err := iHdr.Parse(r, protocol.PerspectiveServer, versionIETFFrames) Expect(err).ToNot(HaveOccurred()) diff --git a/server_tls_test.go b/server_tls_test.go index 2f1f32de..b0e5af1a 100644 --- a/server_tls_test.go +++ b/server_tls_test.go @@ -73,7 +73,7 @@ var _ = Describe("Stateless TLS handling", func() { unpackPacket := func(data []byte) (*wire.Header, []byte) { r := bytes.NewReader(conn.dataWritten.Bytes()) - iHdr, err := wire.ParseInvariantHeader(r) + iHdr, err := wire.ParseInvariantHeader(r, 0) Expect(err).ToNot(HaveOccurred()) hdr, err := iHdr.Parse(r, protocol.PerspectiveServer, versionIETFFrames) Expect(err).ToNot(HaveOccurred()) diff --git a/session_test.go b/session_test.go index 2926f18e..12ad17ea 100644 --- a/session_test.go +++ b/session_test.go @@ -1823,7 +1823,7 @@ var _ = Describe("Client Session", func() { sess.queueControlFrame(&wire.PingFrame{}) var packet []byte Eventually(mconn.written).Should(Receive(&packet)) - hdr, err := wire.ParseInvariantHeader(bytes.NewReader(packet)) + hdr, err := wire.ParseInvariantHeader(bytes.NewReader(packet), 0) Expect(err).ToNot(HaveOccurred()) Expect(hdr.DestConnectionID).To(Equal(protocol.ConnectionID{1, 3, 3, 7, 1, 3, 3, 7})) // make sure the go routine returns