diff --git a/client.go b/client.go index 83c7e4545..5a5cc914b 100644 --- a/client.go +++ b/client.go @@ -29,8 +29,7 @@ type client struct { packetHandlers packetHandlerManager - token []byte - receivedRetry bool + token []byte versionNegotiated bool // has the server accepted our version receivedVersionNegotiationPacket bool @@ -486,15 +485,16 @@ func (c *client) handleVersionNegotiationPacket(hdr *wire.Header) error { func (c *client) handleRetryPacket(hdr *wire.Header) { c.logger.Debugf("<- Received Retry") hdr.Log(c.logger) - if c.receivedRetry { // only accept a single Retry - c.logger.Debugf("Received more than one Retry. Ignoring.") + // A server that performs multiple retries must use a source connection ID of at least 8 bytes. + // Only a server that won't send additional Retries can use shorter connection IDs. + if hdr.OrigDestConnectionID.Len() < protocol.MinConnectionIDLenInitial { + c.logger.Debugf("Received a Retry with a too short Original Destination Connection ID: %d bytes, must have at least %d bytes.", hdr.OrigDestConnectionID.Len(), protocol.MinConnectionIDLenInitial) return } if !hdr.OrigDestConnectionID.Equal(c.destConnID) { c.logger.Debugf("Received spoofed Retry. Original Destination Connection ID: %s, expected: %s", hdr.OrigDestConnectionID, c.destConnID) return } - c.receivedRetry = true c.destConnID = hdr.SrcConnectionID c.token = hdr.Token c.session.destroy(errCloseSessionForRetry)