mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-04 12:47:36 +03:00
identify version negotiation packets without parsing the header
This commit is contained in:
parent
14426dfa12
commit
df34e4496e
5 changed files with 35 additions and 12 deletions
|
@ -287,7 +287,7 @@ func (c *client) establishSecureConnection(ctx context.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *client) handlePacket(p *receivedPacket) {
|
func (c *client) handlePacket(p *receivedPacket) {
|
||||||
if p.hdr.IsVersionNegotiation() {
|
if wire.IsVersionNegotiationPacket(p.data) {
|
||||||
go c.handleVersionNegotiationPacket(p.hdr)
|
go c.handleVersionNegotiationPacket(p.hdr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,10 +60,11 @@ var _ = Describe("Client", func() {
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
hdr, _, _, err := wire.ParsePacket(data, 0)
|
hdr, _, _, err := wire.ParsePacket(data, 0)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(hdr.IsVersionNegotiation()).To(BeTrue())
|
Expect(wire.IsVersionNegotiationPacket(data)).To(BeTrue())
|
||||||
return &receivedPacket{
|
return &receivedPacket{
|
||||||
rcvTime: time.Now(),
|
rcvTime: time.Now(),
|
||||||
hdr: hdr,
|
hdr: hdr,
|
||||||
|
data: data,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,14 @@ func ParseConnectionID(data []byte, shortHeaderConnIDLen int) (protocol.Connecti
|
||||||
return protocol.ConnectionID(data[6 : 6+destConnIDLen]), nil
|
return protocol.ConnectionID(data[6 : 6+destConnIDLen]), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsVersionNegotiationPacket says if this is a version negotiation packet
|
||||||
|
func IsVersionNegotiationPacket(b []byte) bool {
|
||||||
|
if len(b) < 5 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return b[0]&0x80 > 0 && b[1] == 0 && b[2] == 0 && b[3] == 0 && b[4] == 0
|
||||||
|
}
|
||||||
|
|
||||||
var errUnsupportedVersion = errors.New("unsupported version")
|
var errUnsupportedVersion = errors.New("unsupported version")
|
||||||
|
|
||||||
// The Header is the version independent part of the header
|
// The Header is the version independent part of the header
|
||||||
|
@ -129,7 +137,7 @@ func (h *Header) parseLongHeader(b *bytes.Reader) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
h.Version = protocol.VersionNumber(v)
|
h.Version = protocol.VersionNumber(v)
|
||||||
if !h.IsVersionNegotiation() && h.typeByte&0x40 == 0 {
|
if h.Version != 0 && h.typeByte&0x40 == 0 {
|
||||||
return errors.New("not a QUIC packet")
|
return errors.New("not a QUIC packet")
|
||||||
}
|
}
|
||||||
connIDLenByte, err := b.ReadByte()
|
connIDLenByte, err := b.ReadByte()
|
||||||
|
@ -214,11 +222,6 @@ func (h *Header) parseVersionNegotiationPacket(b *bytes.Reader) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsVersionNegotiation says if this a version negotiation packet
|
|
||||||
func (h *Header) IsVersionNegotiation() bool {
|
|
||||||
return h.IsLongHeader && h.Version == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParsedLen returns the number of bytes that were consumed when parsing the header
|
// ParsedLen returns the number of bytes that were consumed when parsing the header
|
||||||
func (h *Header) ParsedLen() protocol.ByteCount {
|
func (h *Header) ParsedLen() protocol.ByteCount {
|
||||||
return h.parsedLen
|
return h.parsedLen
|
||||||
|
|
|
@ -94,6 +94,24 @@ var _ = Describe("Header Parsing", func() {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Context("Identifying Version Negotiation Packets", func() {
|
||||||
|
It("identifies version negotiation packets", func() {
|
||||||
|
Expect(IsVersionNegotiationPacket([]byte{0x80 | 0x56, 0, 0, 0, 0})).To(BeTrue())
|
||||||
|
Expect(IsVersionNegotiationPacket([]byte{0x56, 0, 0, 0, 0})).To(BeFalse())
|
||||||
|
Expect(IsVersionNegotiationPacket([]byte{0x80, 1, 0, 0, 0})).To(BeFalse())
|
||||||
|
Expect(IsVersionNegotiationPacket([]byte{0x80, 0, 1, 0, 0})).To(BeFalse())
|
||||||
|
Expect(IsVersionNegotiationPacket([]byte{0x80, 0, 0, 1, 0})).To(BeFalse())
|
||||||
|
Expect(IsVersionNegotiationPacket([]byte{0x80, 0, 0, 0, 1})).To(BeFalse())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("returns false on EOF", func() {
|
||||||
|
vnp := []byte{0x80, 0, 0, 0, 0}
|
||||||
|
for i := range vnp {
|
||||||
|
Expect(IsVersionNegotiationPacket(vnp[:i])).To(BeFalse())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
Context("Version Negotiation Packets", func() {
|
Context("Version Negotiation Packets", func() {
|
||||||
It("parses", func() {
|
It("parses", func() {
|
||||||
srcConnID := protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
|
srcConnID := protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
|
||||||
|
@ -101,12 +119,12 @@ var _ = Describe("Header Parsing", func() {
|
||||||
versions := []protocol.VersionNumber{0x22334455, 0x33445566}
|
versions := []protocol.VersionNumber{0x22334455, 0x33445566}
|
||||||
vnp, err := ComposeVersionNegotiation(destConnID, srcConnID, versions)
|
vnp, err := ComposeVersionNegotiation(destConnID, srcConnID, versions)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(IsVersionNegotiationPacket(vnp)).To(BeTrue())
|
||||||
hdr, _, rest, err := ParsePacket(vnp, 0)
|
hdr, _, rest, err := ParsePacket(vnp, 0)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(hdr.DestConnectionID).To(Equal(destConnID))
|
Expect(hdr.DestConnectionID).To(Equal(destConnID))
|
||||||
Expect(hdr.SrcConnectionID).To(Equal(srcConnID))
|
Expect(hdr.SrcConnectionID).To(Equal(srcConnID))
|
||||||
Expect(hdr.IsLongHeader).To(BeTrue())
|
Expect(hdr.IsLongHeader).To(BeTrue())
|
||||||
Expect(hdr.IsVersionNegotiation()).To(BeTrue())
|
|
||||||
Expect(hdr.Version).To(BeZero())
|
Expect(hdr.Version).To(BeZero())
|
||||||
for _, v := range versions {
|
for _, v := range versions {
|
||||||
Expect(hdr.SupportedVersions).To(ContainElement(v))
|
Expect(hdr.SupportedVersions).To(ContainElement(v))
|
||||||
|
@ -150,12 +168,12 @@ var _ = Describe("Header Parsing", func() {
|
||||||
hdrLen := len(data)
|
hdrLen := len(data)
|
||||||
data = append(data, []byte{0, 0, 0xbe, 0xef}...) // packet number
|
data = append(data, []byte{0, 0, 0xbe, 0xef}...) // packet number
|
||||||
data = append(data, []byte("foobar")...)
|
data = append(data, []byte("foobar")...)
|
||||||
|
Expect(IsVersionNegotiationPacket(data)).To(BeFalse())
|
||||||
|
|
||||||
hdr, pdata, rest, err := ParsePacket(data, 0)
|
hdr, pdata, rest, err := ParsePacket(data, 0)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(pdata).To(Equal(data))
|
Expect(pdata).To(Equal(data))
|
||||||
Expect(hdr.IsLongHeader).To(BeTrue())
|
Expect(hdr.IsLongHeader).To(BeTrue())
|
||||||
Expect(hdr.IsVersionNegotiation()).To(BeFalse())
|
|
||||||
Expect(hdr.DestConnectionID).To(Equal(destConnID))
|
Expect(hdr.DestConnectionID).To(Equal(destConnID))
|
||||||
Expect(hdr.SrcConnectionID).To(Equal(srcConnID))
|
Expect(hdr.SrcConnectionID).To(Equal(srcConnID))
|
||||||
Expect(hdr.Type).To(Equal(protocol.PacketTypeInitial))
|
Expect(hdr.Type).To(Equal(protocol.PacketTypeInitial))
|
||||||
|
@ -399,10 +417,11 @@ var _ = Describe("Header Parsing", func() {
|
||||||
connID := protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37}
|
connID := protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x13, 0x37}
|
||||||
data := append([]byte{0x40}, connID...)
|
data := append([]byte{0x40}, connID...)
|
||||||
data = append(data, 0x42) // packet number
|
data = append(data, 0x42) // packet number
|
||||||
|
Expect(IsVersionNegotiationPacket(data)).To(BeFalse())
|
||||||
|
|
||||||
hdr, pdata, rest, err := ParsePacket(data, 8)
|
hdr, pdata, rest, err := ParsePacket(data, 8)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(hdr.IsLongHeader).To(BeFalse())
|
Expect(hdr.IsLongHeader).To(BeFalse())
|
||||||
Expect(hdr.IsVersionNegotiation()).To(BeFalse())
|
|
||||||
Expect(hdr.DestConnectionID).To(Equal(connID))
|
Expect(hdr.DestConnectionID).To(Equal(connID))
|
||||||
b := bytes.NewReader(data)
|
b := bytes.NewReader(data)
|
||||||
extHdr, err := hdr.ParseExtended(b, versionIETFFrames)
|
extHdr, err := hdr.ParseExtended(b, versionIETFFrames)
|
||||||
|
|
|
@ -239,8 +239,8 @@ var _ = Describe("Server", func() {
|
||||||
var write mockPacketConnWrite
|
var write mockPacketConnWrite
|
||||||
Eventually(conn.dataWritten).Should(Receive(&write))
|
Eventually(conn.dataWritten).Should(Receive(&write))
|
||||||
Expect(write.to.String()).To(Equal("127.0.0.1:1337"))
|
Expect(write.to.String()).To(Equal("127.0.0.1:1337"))
|
||||||
|
Expect(wire.IsVersionNegotiationPacket(write.data)).To(BeTrue())
|
||||||
hdr := parseHeader(write.data)
|
hdr := parseHeader(write.data)
|
||||||
Expect(hdr.IsVersionNegotiation()).To(BeTrue())
|
|
||||||
Expect(hdr.DestConnectionID).To(Equal(srcConnID))
|
Expect(hdr.DestConnectionID).To(Equal(srcConnID))
|
||||||
Expect(hdr.SrcConnectionID).To(Equal(destConnID))
|
Expect(hdr.SrcConnectionID).To(Equal(destConnID))
|
||||||
Expect(hdr.SupportedVersions).ToNot(ContainElement(protocol.VersionNumber(0x42)))
|
Expect(hdr.SupportedVersions).ToNot(ContainElement(protocol.VersionNumber(0x42)))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue