forked from quic-go/quic-go
only accept authenticated Retry packets
This commit is contained in:
@@ -261,6 +261,9 @@ func (c *client) dialTLS(ctx context.Context) error {
|
||||
return err
|
||||
}
|
||||
c.logger.Infof("Received a Retry packet. Recreating session.")
|
||||
c.mutex.Lock()
|
||||
c.receivedRetry = true
|
||||
c.mutex.Unlock()
|
||||
if err := c.createNewTLSSession(extHandler.GetPeerParams(), c.version); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -377,7 +380,6 @@ func (c *client) handleIETFQUICPacket(hdr *wire.Header, packetData []byte, remot
|
||||
if c.receivedRetry {
|
||||
return nil
|
||||
}
|
||||
c.receivedRetry = true
|
||||
case protocol.PacketTypeHandshake:
|
||||
default:
|
||||
return fmt.Errorf("Received unsupported packet type: %s", hdr.Type)
|
||||
|
||||
@@ -693,6 +693,60 @@ var _ = Describe("Client", func() {
|
||||
Expect(sessions).To(BeEmpty())
|
||||
})
|
||||
|
||||
It("only accepts one Retry packet", func() {
|
||||
config := &Config{Versions: []protocol.VersionNumber{protocol.VersionTLS}}
|
||||
sess1 := NewMockPacketHandler(mockCtrl)
|
||||
sess1.EXPECT().run().Return(handshake.ErrCloseSessionForRetry)
|
||||
// don't EXPECT any call to handlePacket()
|
||||
sess2 := NewMockPacketHandler(mockCtrl)
|
||||
run := make(chan struct{})
|
||||
sess2.EXPECT().run().Do(func() { <-run })
|
||||
sessions := make(chan *MockPacketHandler, 2)
|
||||
sessions <- sess1
|
||||
sessions <- sess2
|
||||
newTLSClientSession = func(
|
||||
connP connection,
|
||||
_ sessionRunner,
|
||||
hostnameP string,
|
||||
versionP protocol.VersionNumber,
|
||||
_ protocol.ConnectionID,
|
||||
_ protocol.ConnectionID,
|
||||
configP *Config,
|
||||
tls handshake.MintTLS,
|
||||
paramsChan <-chan handshake.TransportParameters,
|
||||
_ protocol.PacketNumber,
|
||||
_ utils.Logger,
|
||||
) (packetHandler, error) {
|
||||
return <-sessions, nil
|
||||
}
|
||||
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
defer GinkgoRecover()
|
||||
_, err := Dial(packetConn, addr, "quic.clemente.io:1337", nil, config)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
close(done)
|
||||
}()
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
h := &wire.Header{
|
||||
IsLongHeader: true,
|
||||
Type: protocol.PacketTypeRetry,
|
||||
SrcConnectionID: connID,
|
||||
DestConnectionID: connID,
|
||||
PacketNumberLen: protocol.PacketNumberLen1,
|
||||
}
|
||||
err := h.Write(buf, protocol.PerspectiveServer, protocol.VersionTLS)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Eventually(sessions).Should(BeEmpty())
|
||||
packetConn.dataToRead <- buf.Bytes()
|
||||
time.Sleep(50 * time.Millisecond) // make sure the packet is read and discarded
|
||||
|
||||
// make the go routine return
|
||||
close(run)
|
||||
Eventually(done).Should(BeClosed())
|
||||
})
|
||||
|
||||
Context("handling packets", func() {
|
||||
It("handles packets", func() {
|
||||
sess := NewMockPacketHandler(mockCtrl)
|
||||
@@ -724,23 +778,6 @@ 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)
|
||||
|
||||
Reference in New Issue
Block a user