diff --git a/internal/wire/header.go b/internal/wire/header.go index 5bcabb36..96066cc9 100644 --- a/internal/wire/header.go +++ b/internal/wire/header.go @@ -41,13 +41,14 @@ func ParseHeaderSentByServer(b *bytes.Reader, version protocol.VersionNumber) (* var isPublicHeader bool // As a client, we know the version of the packet that the server sent, except for Version Negotiation Packets. - // Both gQUIC and IETF QUIC Version Negotiation Packets have 0x1 set. - if typeByte&0x1 > 0 { + if typeByte == 0x81 { // IETF draft Version Negotiation Packet + isPublicHeader = false + } else if typeByte&0xcf == 0x9 { // gQUIC Version Negotiation Packet // IETF QUIC Version Negotiation Packets are sent with the Long Header (indicated by the 0x80 bit) // gQUIC always has 0x80 unset - isPublicHeader = typeByte&0x80 == 0 - } else { - // For all packets that are not Version Negotiation Packets, the client knows the version that this packet was sent with + isPublicHeader = true + } else { // not a Version Negotiation Packet + // the client knows the version that this packet was sent with isPublicHeader = !version.UsesTLS() } return parsePacketHeader(b, protocol.PerspectiveServer, isPublicHeader) diff --git a/internal/wire/header_test.go b/internal/wire/header_test.go index 65871eb8..d28c8907 100644 --- a/internal/wire/header_test.go +++ b/internal/wire/header_test.go @@ -19,7 +19,7 @@ var _ = Describe("Header", func() { ) Context("parsing", func() { - It("parses an IETF draft header, when the QUIC version supports TLS", func() { + It("parses an IETF draft Short 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{ @@ -51,6 +51,21 @@ var _ = Describe("Header", func() { Expect(hdr.isPublicHeader).To(BeFalse()) }) + It("doens't mistake packets with a Short Header for Version Negotiation Packets", func() { + // make sure this packet could be mistaken for a Version Negotiation Packet, if we only look at the 0x1 bit + buf := &bytes.Buffer{} + err := (&Header{ + IsLongHeader: false, + PacketNumberLen: protocol.PacketNumberLen1, + PacketNumber: 0x42, + }).writeHeader(buf) + Expect(err).ToNot(HaveOccurred()) + Expect(buf.Bytes()[0] & 0x1).To(BeEquivalentTo(0x1)) + hdr, err := ParseHeaderSentByServer(bytes.NewReader(buf.Bytes()), versionIETFHeader) + Expect(err).ToNot(HaveOccurred()) + Expect(hdr.isPublicHeader).To(BeFalse()) + }) + It("parses a gQUIC Public Header, when the version is not known", func() { buf := &bytes.Buffer{} err := (&Header{