Skip to content

Commit

Permalink
only send Version Negotiation packets for packets larger than 1200 bytes
Browse files Browse the repository at this point in the history
  • Loading branch information
marten-seemann committed Oct 8, 2020
1 parent f95b133 commit 36a7b1a
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 3 deletions.
4 changes: 4 additions & 0 deletions internal/protocol/protocol.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ const MaxReceivePacketSize ByteCount = 1452
// MinInitialPacketSize is the minimum size an Initial packet is required to have.
const MinInitialPacketSize = 1200

// MinUnknownVersionPacketSize is the minimum size a packet with an unknown version
// needs to have in order to trigger a Version Negotiation packet.
const MinUnknownVersionPacketSize = MinInitialPacketSize

// MinStatelessResetSize is the minimum size of a stateless reset packet that we send
const MinStatelessResetSize = 1 /* first byte */ + 20 /* max. conn ID length */ + 4 /* max. packet number length */ + 1 /* min. payload length */ + 16 /* token */

Expand Down
7 changes: 7 additions & 0 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,13 @@ func (s *baseServer) handlePacketImpl(p *receivedPacket) bool /* is the buffer s
}
// send a Version Negotiation Packet if the client is speaking a different protocol version
if !protocol.IsSupportedVersion(s.config.Versions, hdr.Version) {
if p.Size() < protocol.MinUnknownVersionPacketSize {
s.logger.Debugf("Dropping a packet with an unknown version that is too small (%d bytes)", p.Size())
if s.config.Tracer != nil {
s.config.Tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropUnexpectedPacket)
}
return false
}
go s.sendVersionNegotiationPacket(p, hdr)
return false
}
Expand Down
30 changes: 27 additions & 3 deletions server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,9 +379,10 @@ var _ = Describe("Server", func() {
SrcConnectionID: srcConnID,
DestConnectionID: destConnID,
Version: 0x42,
}, make([]byte, protocol.MinInitialPacketSize))
packet.remoteAddr = &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 1337}
tracer.EXPECT().SentPacket(packet.remoteAddr, gomock.Any(), gomock.Any(), nil).Do(func(_ net.Addr, replyHdr *logging.Header, _ logging.ByteCount, _ []logging.Frame) {
}, make([]byte, protocol.MinUnknownVersionPacketSize))
raddr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 1337}
packet.remoteAddr = raddr
tracer.EXPECT().SentPacket(raddr, gomock.Any(), gomock.Any(), nil).Do(func(_ net.Addr, replyHdr *logging.Header, _ logging.ByteCount, _ []logging.Frame) {
Expect(replyHdr.IsLongHeader).To(BeTrue())
Expect(replyHdr.Version).To(BeZero())
Expect(replyHdr.SrcConnectionID).To(Equal(destConnID))
Expand Down Expand Up @@ -421,6 +422,29 @@ var _ = Describe("Server", func() {
time.Sleep(scaleDuration(20 * time.Millisecond))
})

It("doesn't send a Version Negotiation Packet for unsupported versions, if the packet is too small", func() {
srcConnID := protocol.ConnectionID{1, 2, 3, 4, 5}
destConnID := protocol.ConnectionID{1, 2, 3, 4, 5, 6}
p := getPacket(&wire.Header{
IsLongHeader: true,
Type: protocol.PacketTypeHandshake,
SrcConnectionID: srcConnID,
DestConnectionID: destConnID,
Version: 0x42,
}, make([]byte, protocol.MinUnknownVersionPacketSize-50))
Expect(p.Size()).To(BeNumerically("<", protocol.MinUnknownVersionPacketSize))
raddr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 1337}
p.remoteAddr = raddr
done := make(chan struct{})
tracer.EXPECT().DroppedPacket(raddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropUnexpectedPacket).Do(func(net.Addr, logging.PacketType, protocol.ByteCount, logging.PacketDropReason) {
close(done)
})
serv.handlePacket(p)
Eventually(done).Should(BeClosed())
// make sure no other packet is sent
time.Sleep(scaleDuration(20 * time.Millisecond))
})

It("replies with a Retry packet, if a Token is required", func() {
serv.config.AcceptToken = func(_ net.Addr, _ *Token) bool { return false }
hdr := &wire.Header{
Expand Down

0 comments on commit 36a7b1a

Please sign in to comment.