forked from quic-go/quic-go
validate minimum packet size before sending a version negotiation packet
fixes #429
This commit is contained in:
@@ -163,6 +163,10 @@ func (s *server) handlePacket(pconn net.PacketConn, remoteAddr net.Addr, packet
|
|||||||
|
|
||||||
// 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(hdr.VersionNumber) {
|
if hdr.VersionFlag && !protocol.IsSupportedVersion(hdr.VersionNumber) {
|
||||||
|
// drop packets that are too small to be valid first packets
|
||||||
|
if len(packet) < protocol.ClientHelloMinimumSize+len(hdr.Raw) {
|
||||||
|
return errors.New("dropping small packet with unknown version")
|
||||||
|
}
|
||||||
utils.Infof("Client offered version %d, sending VersionNegotiationPacket", hdr.VersionNumber)
|
utils.Infof("Client offered version %d, sending VersionNegotiationPacket", hdr.VersionNumber)
|
||||||
_, err = pconn.WriteTo(composeVersionNegotiation(hdr.ConnectionID), remoteAddr)
|
_, err = pconn.WriteTo(composeVersionNegotiation(hdr.ConnectionID), remoteAddr)
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -260,6 +260,21 @@ var _ = Describe("Server", func() {
|
|||||||
Expect(serv.sessions).To(HaveLen(1))
|
Expect(serv.sessions).To(HaveLen(1))
|
||||||
Expect(serv.sessions[connID].(*mockSession).packetCount).To(Equal(1))
|
Expect(serv.sessions[connID].(*mockSession).packetCount).To(Equal(1))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("doesn't respond with a version negotiation packet if the first packet is too small", func() {
|
||||||
|
b := &bytes.Buffer{}
|
||||||
|
hdr := PublicHeader{
|
||||||
|
VersionFlag: true,
|
||||||
|
ConnectionID: 0x1337,
|
||||||
|
PacketNumber: 1,
|
||||||
|
PacketNumberLen: protocol.PacketNumberLen2,
|
||||||
|
}
|
||||||
|
hdr.Write(b, 13 /* not a valid QUIC version */, protocol.PerspectiveClient)
|
||||||
|
b.Write(bytes.Repeat([]byte{0}, protocol.ClientHelloMinimumSize-1)) // this packet is 1 byte too small
|
||||||
|
err := serv.handlePacket(conn, udpAddr, b.Bytes())
|
||||||
|
Expect(err).To(MatchError("dropping small packet with unknown version"))
|
||||||
|
Expect(conn.dataWritten.Len()).Should(BeZero())
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
It("setups with the right values", func() {
|
It("setups with the right values", func() {
|
||||||
@@ -284,24 +299,34 @@ var _ = Describe("Server", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("setups and responds with version negotiation", func() {
|
It("setups and responds with version negotiation", func() {
|
||||||
conn.dataToRead = []byte{0x09, 0x01, 0, 0, 0, 0, 0, 0, 0, 0x01, 0x01, 'Q', '0', '0', '0', 0x01}
|
b := &bytes.Buffer{}
|
||||||
|
hdr := PublicHeader{
|
||||||
|
VersionFlag: true,
|
||||||
|
ConnectionID: 0x1337,
|
||||||
|
PacketNumber: 1,
|
||||||
|
PacketNumberLen: protocol.PacketNumberLen2,
|
||||||
|
}
|
||||||
|
hdr.Write(b, 13 /* not a valid QUIC version */, protocol.PerspectiveClient)
|
||||||
|
b.Write(bytes.Repeat([]byte{0}, protocol.ClientHelloMinimumSize)) // add a fake CHLO
|
||||||
|
conn.dataToRead = b.Bytes()
|
||||||
conn.dataReadFrom = udpAddr
|
conn.dataReadFrom = udpAddr
|
||||||
ln, err := Listen(conn, config)
|
ln, err := Listen(conn, config)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
var returned bool
|
||||||
go func() {
|
go func() {
|
||||||
defer GinkgoRecover()
|
ln.Serve()
|
||||||
err := ln.Serve()
|
returned = true
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
Eventually(func() int { return conn.dataWritten.Len() }).ShouldNot(BeZero())
|
Eventually(func() int { return conn.dataWritten.Len() }).ShouldNot(BeZero())
|
||||||
Expect(conn.dataWrittenTo).To(Equal(udpAddr))
|
Expect(conn.dataWrittenTo).To(Equal(udpAddr))
|
||||||
expected := append(
|
expected := append(
|
||||||
[]byte{0x9, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
[]byte{0x9, 0x37, 0x13, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
|
||||||
protocol.SupportedVersionsAsTags...,
|
protocol.SupportedVersionsAsTags...,
|
||||||
)
|
)
|
||||||
Expect(conn.dataWritten.Bytes()).To(Equal(expected))
|
Expect(conn.dataWritten.Bytes()).To(Equal(expected))
|
||||||
|
Expect(returned).To(BeFalse())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("sends a PublicReset for new connections that don't have the VersionFlag set", func() {
|
It("sends a PublicReset for new connections that don't have the VersionFlag set", func() {
|
||||||
|
|||||||
Reference in New Issue
Block a user