Merge pull request #2818 from lucas-clemente/server-drop-version-negotiation-packets

don't send a version negotiation packet in response to a version negotiation packet
This commit is contained in:
Marten Seemann
2020-10-08 16:19:24 +07:00
committed by GitHub
2 changed files with 31 additions and 2 deletions

View File

@@ -225,7 +225,7 @@ func (s *baseServer) run() {
case <-s.errorChan:
return
case p := <-s.receivedPackets:
if shouldReleaseBuffer := s.handlePacketImpl(p); !shouldReleaseBuffer {
if bufferStillInUse := s.handlePacketImpl(p); !bufferStillInUse {
p.buffer.Release()
}
}
@@ -320,7 +320,14 @@ func (s *baseServer) handlePacket(p *receivedPacket) {
}
}
func (s *baseServer) handlePacketImpl(p *receivedPacket) bool /* should the buffer be released */ {
func (s *baseServer) handlePacketImpl(p *receivedPacket) bool /* is the buffer still in use? */ {
if wire.IsVersionNegotiationPacket(p.data) {
s.logger.Debugf("Dropping Version Negotiation packet.")
if s.config.Tracer != nil {
s.config.Tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeVersionNegotiation, p.Size(), logging.PacketDropUnexpectedPacket)
}
return false
}
// If we're creating a new session, the packet will be passed to the session.
// The header will then be parsed again.
hdr, _, _, err := wire.ParsePacket(p.data, s.config.ConnectionIDLength)

View File

@@ -409,6 +409,28 @@ var _ = Describe("Server", func() {
Eventually(done).Should(BeClosed())
})
It("ignores Version Negotiation packets", func() {
data, err := wire.ComposeVersionNegotiation(
protocol.ConnectionID{1, 2, 3, 4},
protocol.ConnectionID{4, 3, 2, 1},
[]protocol.VersionNumber{1, 2, 3},
)
Expect(err).ToNot(HaveOccurred())
raddr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 1337}
done := make(chan struct{})
tracer.EXPECT().DroppedPacket(raddr, logging.PacketTypeVersionNegotiation, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedPacket).Do(func(net.Addr, logging.PacketType, protocol.ByteCount, logging.PacketDropReason) {
close(done)
})
serv.handlePacket(&receivedPacket{
remoteAddr: raddr,
data: data,
buffer: getPacketBuffer(),
})
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{