From ced65c0ddcf5b24b0e1f04b07bb18e968a77b05a Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 21 Aug 2023 09:55:57 +0700 Subject: [PATCH] wire: always set the QUIC bit for Version Negotiation packets (#3991) * wire: always set the QUIC bit for Version Negotiation packets * Update internal/wire/version_negotiation_test.go --- internal/wire/version_negotiation.go | 5 ++++- internal/wire/version_negotiation_test.go | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/internal/wire/version_negotiation.go b/internal/wire/version_negotiation.go index 3dc62113..afde70fa 100644 --- a/internal/wire/version_negotiation.go +++ b/internal/wire/version_negotiation.go @@ -40,7 +40,10 @@ func ComposeVersionNegotiation(destConnID, srcConnID protocol.ArbitraryLenConnec buf := bytes.NewBuffer(make([]byte, 0, expectedLen)) r := make([]byte, 1) _, _ = rand.Read(r) // ignore the error here. It is not critical to have perfect random here. - buf.WriteByte(r[0] | 0x80) + // Setting the "QUIC bit" (0x40) is not required by the RFC, + // but it allows clients to demultiplex QUIC with a long list of other protocols. + // See RFC 9443 and https://mailarchive.ietf.org/arch/msg/quic/oR4kxGKY6mjtPC1CZegY1ED4beg/ for details. + buf.WriteByte(r[0] | 0xc0) utils.BigEndian.WriteUint32(buf, 0) // version 0 buf.WriteByte(uint8(destConnID.Len())) buf.Write(destConnID.Bytes()) diff --git a/internal/wire/version_negotiation_test.go b/internal/wire/version_negotiation_test.go index 65d0ba91..acd6d7ce 100644 --- a/internal/wire/version_negotiation_test.go +++ b/internal/wire/version_negotiation_test.go @@ -64,6 +64,7 @@ var _ = Describe("Version Negotiation Packets", func() { versions := []protocol.VersionNumber{1001, 1003} data := ComposeVersionNegotiation(destConnID, srcConnID, versions) Expect(IsLongHeaderPacket(data[0])).To(BeTrue()) + Expect(data[0] & 0x40).ToNot(BeZero()) v, err := ParseVersion(data) Expect(err).ToNot(HaveOccurred()) Expect(v).To(BeZero())