From 3601f06aed8a38090f5c0b2b25d3352f05772d57 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Tue, 12 Jun 2018 16:14:56 +0200 Subject: [PATCH] only accept a single Retry packet for a connection --- client.go | 11 ++++++++++- client_test.go | 17 +++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/client.go b/client.go index f7c1ffad2..f4e8ef9d1 100644 --- a/client.go +++ b/client.go @@ -24,6 +24,8 @@ type client struct { conn connection hostname string + receivedRetry bool + versionNegotiated bool // has the server accepted our version receivedVersionNegotiationPacket bool negotiatedVersions []protocol.VersionNumber // the list of versions from the version negotiation packet @@ -370,7 +372,14 @@ func (c *client) handleIETFQUICPacket(hdr *wire.Header, packetData []byte, remot return fmt.Errorf("received a packet with an unexpected connection ID (%s, expected %s)", hdr.DestConnectionID, c.srcConnID) } if hdr.IsLongHeader { - if hdr.Type != protocol.PacketTypeRetry && hdr.Type != protocol.PacketTypeHandshake { + switch hdr.Type { + case protocol.PacketTypeRetry: + if c.receivedRetry { + return nil + } + c.receivedRetry = true + case protocol.PacketTypeHandshake: + default: return fmt.Errorf("Received unsupported packet type: %s", hdr.Type) } if protocol.ByteCount(len(packetData)) < hdr.PayloadLen { diff --git a/client_test.go b/client_test.go index f402bdfe8..e12f47f6f 100644 --- a/client_test.go +++ b/client_test.go @@ -724,6 +724,23 @@ var _ = Describe("Client", func() { Eventually(done).Should(BeClosed()) }) + It("only accepts one Retry packet", func() { + sess := NewMockPacketHandler(mockCtrl) + cl.session = sess + h := &wire.Header{ + IsLongHeader: true, + Type: protocol.PacketTypeRetry, + SrcConnectionID: connID, + DestConnectionID: connID, + } + // only EXPECT a single call to handlePacket() + sess.EXPECT().handlePacket(gomock.Any()) + err := cl.handleIETFQUICPacket(h, nil, &net.UDPAddr{}, time.Now()) + Expect(err).ToNot(HaveOccurred()) + err = cl.handleIETFQUICPacket(h, nil, &net.UDPAddr{}, time.Now()) + Expect(err).ToNot(HaveOccurred()) + }) + It("closes the session when encountering an error while reading from the connection", func() { testErr := errors.New("test error") sess := NewMockPacketHandler(mockCtrl)