From 3a359027b51064d633d6f0faf530833fa4d788c6 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sun, 27 Jun 2021 15:29:29 -0700 Subject: [PATCH] add a config option to disable sending of Version Negotiation packets --- config.go | 35 ++++++++++++++++++----------------- config_test.go | 3 +++ interface.go | 4 ++++ server.go | 4 +++- server_test.go | 19 +++++++++++++++++++ 5 files changed, 47 insertions(+), 18 deletions(-) diff --git a/config.go b/config.go index 61ee7a21..8e439c26 100644 --- a/config.go +++ b/config.go @@ -101,22 +101,23 @@ func populateConfig(config *Config) *Config { } return &Config{ - Versions: versions, - HandshakeIdleTimeout: handshakeIdleTimeout, - MaxIdleTimeout: idleTimeout, - AcceptToken: config.AcceptToken, - KeepAlive: config.KeepAlive, - InitialStreamReceiveWindow: initialStreamReceiveWindow, - MaxStreamReceiveWindow: maxStreamReceiveWindow, - InitialConnectionReceiveWindow: initialConnectionReceiveWindow, - MaxConnectionReceiveWindow: maxConnectionReceiveWindow, - MaxIncomingStreams: maxIncomingStreams, - MaxIncomingUniStreams: maxIncomingUniStreams, - ConnectionIDLength: config.ConnectionIDLength, - StatelessResetKey: config.StatelessResetKey, - TokenStore: config.TokenStore, - EnableDatagrams: config.EnableDatagrams, - DisablePathMTUDiscovery: config.DisablePathMTUDiscovery, - Tracer: config.Tracer, + Versions: versions, + HandshakeIdleTimeout: handshakeIdleTimeout, + MaxIdleTimeout: idleTimeout, + AcceptToken: config.AcceptToken, + KeepAlive: config.KeepAlive, + InitialStreamReceiveWindow: initialStreamReceiveWindow, + MaxStreamReceiveWindow: maxStreamReceiveWindow, + InitialConnectionReceiveWindow: initialConnectionReceiveWindow, + MaxConnectionReceiveWindow: maxConnectionReceiveWindow, + MaxIncomingStreams: maxIncomingStreams, + MaxIncomingUniStreams: maxIncomingUniStreams, + ConnectionIDLength: config.ConnectionIDLength, + StatelessResetKey: config.StatelessResetKey, + TokenStore: config.TokenStore, + EnableDatagrams: config.EnableDatagrams, + DisablePathMTUDiscovery: config.DisablePathMTUDiscovery, + DisableVersionNegotiationPackets: config.DisableVersionNegotiationPackets, + Tracer: config.Tracer, } } diff --git a/config_test.go b/config_test.go index 6cb2ce91..b8454b10 100644 --- a/config_test.go +++ b/config_test.go @@ -75,6 +75,8 @@ var _ = Describe("Config", func() { f.Set(reflect.ValueOf(true)) case "EnableDatagrams": f.Set(reflect.ValueOf(true)) + case "DisableVersionNegotiationPackets": + f.Set(reflect.ValueOf(true)) case "DisablePathMTUDiscovery": f.Set(reflect.ValueOf(true)) case "Tracer": @@ -152,6 +154,7 @@ var _ = Describe("Config", func() { Expect(c.MaxConnectionReceiveWindow).To(BeEquivalentTo(protocol.DefaultMaxReceiveConnectionFlowControlWindow)) Expect(c.MaxIncomingStreams).To(BeEquivalentTo(protocol.DefaultMaxIncomingStreams)) Expect(c.MaxIncomingUniStreams).To(BeEquivalentTo(protocol.DefaultMaxIncomingUniStreams)) + Expect(c.DisableVersionNegotiationPackets).To(BeFalse()) Expect(c.DisablePathMTUDiscovery).To(BeFalse()) }) diff --git a/interface.go b/interface.go index 0b1a1891..df8a95d9 100644 --- a/interface.go +++ b/interface.go @@ -298,6 +298,10 @@ type Config struct { // DisablePathMTUDiscovery disables Path MTU Discovery (RFC 8899). // Packets will then be at most 1252 (IPv4) / 1232 (IPv6) bytes in size. DisablePathMTUDiscovery bool + // DisableVersionNegotiationPackets disables the sending of Version Negotiation packets. + // This can be useful if version information is exchanged out-of-band. + // It has no effect for a client. + DisableVersionNegotiationPackets bool // See https://datatracker.ietf.org/doc/draft-ietf-quic-datagram/. // Datagrams will only be available when both peers enable datagram support. EnableDatagrams bool diff --git a/server.go b/server.go index f2b94c42..6ab869c0 100644 --- a/server.go +++ b/server.go @@ -366,7 +366,9 @@ func (s *baseServer) handlePacketImpl(p *receivedPacket) bool /* is the buffer s } return false } - go s.sendVersionNegotiationPacket(p, hdr) + if !s.config.DisableVersionNegotiationPackets { + go s.sendVersionNegotiationPacket(p, hdr) + } return false } if hdr.IsLongHeader && hdr.Type != protocol.PacketTypeInitial { diff --git a/server_test.go b/server_test.go index 3abb5341..80f199c1 100644 --- a/server_test.go +++ b/server_test.go @@ -406,6 +406,25 @@ var _ = Describe("Server", func() { Eventually(done).Should(BeClosed()) }) + It("doesn't send a Version Negotiation packets if sending them is disabled", func() { + serv.config.DisableVersionNegotiationPackets = true + srcConnID := protocol.ConnectionID{1, 2, 3, 4, 5} + destConnID := protocol.ConnectionID{1, 2, 3, 4, 5, 6} + packet := getPacket(&wire.Header{ + IsLongHeader: true, + Type: protocol.PacketTypeHandshake, + SrcConnectionID: srcConnID, + DestConnectionID: destConnID, + Version: 0x42, + }, make([]byte, protocol.MinUnknownVersionPacketSize)) + raddr := &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 1337} + packet.remoteAddr = raddr + done := make(chan struct{}) + conn.EXPECT().WriteTo(gomock.Any(), raddr).Do(func() { close(done) }).Times(0) + serv.handlePacket(packet) + Consistently(done, 50*time.Millisecond).ShouldNot(BeClosed()) + }) + It("ignores Version Negotiation packets", func() { data, err := wire.ComposeVersionNegotiation( protocol.ConnectionID{1, 2, 3, 4},