forked from quic-go/quic-go
Merge pull request #2480 from lucas-clemente/qlog-dropped-retry
qlog dropped Retry packets
This commit is contained in:
@@ -242,20 +242,26 @@ func (t keyUpdateTrigger) String() string {
|
||||
type PacketDropReason uint8
|
||||
|
||||
const (
|
||||
// PacketDropKeyUnavailable: when a packet is dropped because keys are unavailable
|
||||
// PacketDropKeyUnavailable is used when a packet is dropped because keys are unavailable
|
||||
PacketDropKeyUnavailable PacketDropReason = iota
|
||||
// PacketDropUnknownConnectionID: when a packet is dropped because the connection ID is unknown
|
||||
// PacketDropUnknownConnectionID is used when a packet is dropped because the connection ID is unknown
|
||||
PacketDropUnknownConnectionID
|
||||
// PacketDropHeaderParseError: when a packet is dropped because header parsing failed
|
||||
// PacketDropHeaderParseError is used when a packet is dropped because header parsing failed
|
||||
PacketDropHeaderParseError
|
||||
// PacketDropPayloadDecryptError: when a packet is dropped because decrypting the payload failed
|
||||
// PacketDropPayloadDecryptError is used when a packet is dropped because decrypting the payload failed
|
||||
PacketDropPayloadDecryptError
|
||||
// PacketDropProtocolViolation: when a packet is dropped due to a protocol violation
|
||||
// PacketDropProtocolViolation is used when a packet is dropped due to a protocol violation
|
||||
PacketDropProtocolViolation
|
||||
// PacketDropDOSPrevention: when a packet is dropped to mitigate a DoS attack
|
||||
// PacketDropDOSPrevention is used when a packet is dropped to mitigate a DoS attack
|
||||
PacketDropDOSPrevention
|
||||
// PacketDropUnsupportedVersion: when a packet is dropped because the version is not supported
|
||||
// PacketDropUnsupportedVersion is used when a packet is dropped because the version is not supported
|
||||
PacketDropUnsupportedVersion
|
||||
// PacketDropUnexpectedPacket is used when an unexpected packet is received
|
||||
PacketDropUnexpectedPacket
|
||||
// PacketDropUnexpectedSourceConnectionID is used when a packet with an unexpected source connection ID is received
|
||||
PacketDropUnexpectedSourceConnectionID
|
||||
// PacketDropUnexpectedVersion is used when a packet with an unexpected version is received
|
||||
PacketDropUnexpectedVersion
|
||||
)
|
||||
|
||||
func (r PacketDropReason) String() string {
|
||||
@@ -274,6 +280,12 @@ func (r PacketDropReason) String() string {
|
||||
return "dos_prevention"
|
||||
case PacketDropUnsupportedVersion:
|
||||
return "unsupported_version"
|
||||
case PacketDropUnexpectedPacket:
|
||||
return "unexpected_packet"
|
||||
case PacketDropUnexpectedSourceConnectionID:
|
||||
return "unexpected_source_connection_id"
|
||||
case PacketDropUnexpectedVersion:
|
||||
return "unexpected_version"
|
||||
default:
|
||||
panic("unknown packet drop reason")
|
||||
}
|
||||
|
||||
@@ -71,6 +71,9 @@ var _ = Describe("Types", func() {
|
||||
Expect(PacketDropProtocolViolation.String()).To(Equal("protocol_violation"))
|
||||
Expect(PacketDropDOSPrevention.String()).To(Equal("dos_prevention"))
|
||||
Expect(PacketDropUnsupportedVersion.String()).To(Equal("unsupported_version"))
|
||||
Expect(PacketDropUnexpectedPacket.String()).To(Equal("unexpected_packet"))
|
||||
Expect(PacketDropUnexpectedSourceConnectionID.String()).To(Equal("unexpected_source_connection_id"))
|
||||
Expect(PacketDropUnexpectedVersion.String()).To(Equal("unexpected_version"))
|
||||
})
|
||||
|
||||
Context("transport errors", func() {
|
||||
|
||||
26
session.go
26
session.go
@@ -807,31 +807,45 @@ func (s *session) handleSinglePacket(p *receivedPacket, hdr *wire.Header) bool /
|
||||
}
|
||||
|
||||
func (s *session) handleRetryPacket(hdr *wire.Header, data []byte) bool /* was this a valid Retry */ {
|
||||
(&wire.ExtendedHeader{Header: *hdr}).Log(s.logger)
|
||||
if s.perspective == protocol.PerspectiveServer {
|
||||
if s.qlogger != nil {
|
||||
s.qlogger.DroppedPacket(qlog.PacketTypeRetry, protocol.ByteCount(len(data)), qlog.PacketDropUnexpectedPacket)
|
||||
}
|
||||
s.logger.Debugf("Ignoring Retry.")
|
||||
return false
|
||||
}
|
||||
if s.receivedFirstPacket {
|
||||
if s.qlogger != nil {
|
||||
s.qlogger.DroppedPacket(qlog.PacketTypeRetry, protocol.ByteCount(len(data)), qlog.PacketDropUnexpectedPacket)
|
||||
}
|
||||
s.logger.Debugf("Ignoring Retry, since we already received a packet.")
|
||||
return false
|
||||
}
|
||||
(&wire.ExtendedHeader{Header: *hdr}).Log(s.logger)
|
||||
destConnID := s.connIDManager.Get()
|
||||
if hdr.SrcConnectionID.Equal(destConnID) {
|
||||
if s.qlogger != nil {
|
||||
s.qlogger.DroppedPacket(qlog.PacketTypeRetry, protocol.ByteCount(len(data)), qlog.PacketDropUnexpectedPacket)
|
||||
}
|
||||
s.logger.Debugf("Ignoring Retry, since the server didn't change the Source Connection ID.")
|
||||
return false
|
||||
}
|
||||
tag := handshake.GetRetryIntegrityTag(data[:len(data)-16], destConnID)
|
||||
if !bytes.Equal(data[len(data)-16:], tag[:]) {
|
||||
s.logger.Debugf("Ignoring spoofed Retry. Integrity Tag doesn't match.")
|
||||
return false
|
||||
}
|
||||
// If a token is already set, this means that we already received a Retry from the server.
|
||||
// Ignore this Retry packet.
|
||||
if s.receivedRetry {
|
||||
s.logger.Debugf("Ignoring Retry, since a Retry was already received.")
|
||||
return false
|
||||
}
|
||||
|
||||
tag := handshake.GetRetryIntegrityTag(data[:len(data)-16], destConnID)
|
||||
if !bytes.Equal(data[len(data)-16:], tag[:]) {
|
||||
if s.qlogger != nil {
|
||||
s.qlogger.DroppedPacket(qlog.PacketTypeRetry, protocol.ByteCount(len(data)), qlog.PacketDropPayloadDecryptError)
|
||||
}
|
||||
s.logger.Debugf("Ignoring spoofed Retry. Integrity Tag doesn't match.")
|
||||
return false
|
||||
}
|
||||
|
||||
s.logger.Debugf("<- Received Retry")
|
||||
s.logger.Debugf("Switching destination connection ID to: %s", hdr.SrcConnectionID)
|
||||
if s.qlogger != nil {
|
||||
|
||||
@@ -578,10 +578,14 @@ var _ = Describe("Session", func() {
|
||||
|
||||
It("drops Retry packets", func() {
|
||||
p := getPacket(&wire.ExtendedHeader{Header: wire.Header{
|
||||
IsLongHeader: true,
|
||||
Type: protocol.PacketTypeRetry,
|
||||
}}, nil)
|
||||
qlogger.EXPECT().DroppedPacket(qlog.PacketTypeNotDetermined, protocol.ByteCount(len(p.data)), gomock.Any())
|
||||
IsLongHeader: true,
|
||||
Type: protocol.PacketTypeRetry,
|
||||
DestConnectionID: destConnID,
|
||||
SrcConnectionID: srcConnID,
|
||||
Version: sess.version,
|
||||
Token: []byte("foobar"),
|
||||
}}, make([]byte, 16) /* Retry integrity tag */)
|
||||
qlogger.EXPECT().DroppedPacket(qlog.PacketTypeRetry, protocol.ByteCount(len(p.data)), qlog.PacketDropUnexpectedPacket)
|
||||
Expect(sess.handlePacketImpl(p)).To(BeFalse())
|
||||
})
|
||||
|
||||
@@ -2054,18 +2058,24 @@ var _ = Describe("Client Session", func() {
|
||||
|
||||
It("ignores Retry packets after receiving a regular packet", func() {
|
||||
sess.receivedFirstPacket = true
|
||||
Expect(sess.handlePacketImpl(getPacket(retryHdr, getRetryTag(retryHdr)))).To(BeFalse())
|
||||
p := getPacket(retryHdr, getRetryTag(retryHdr))
|
||||
qlogger.EXPECT().DroppedPacket(qlog.PacketTypeRetry, protocol.ByteCount(len(p.data)), qlog.PacketDropUnexpectedPacket)
|
||||
Expect(sess.handlePacketImpl(p)).To(BeFalse())
|
||||
})
|
||||
|
||||
It("ignores Retry packets if the server didn't change the connection ID", func() {
|
||||
retryHdr.SrcConnectionID = destConnID
|
||||
Expect(sess.handlePacketImpl(getPacket(retryHdr, getRetryTag(retryHdr)))).To(BeFalse())
|
||||
p := getPacket(retryHdr, getRetryTag(retryHdr))
|
||||
qlogger.EXPECT().DroppedPacket(qlog.PacketTypeRetry, protocol.ByteCount(len(p.data)), qlog.PacketDropUnexpectedPacket)
|
||||
Expect(sess.handlePacketImpl(p)).To(BeFalse())
|
||||
})
|
||||
|
||||
It("ignores Retry packets with the a wrong Integrity tag", func() {
|
||||
tag := getRetryTag(retryHdr)
|
||||
tag[0]++
|
||||
Expect(sess.handlePacketImpl(getPacket(retryHdr, tag))).To(BeFalse())
|
||||
p := getPacket(retryHdr, tag)
|
||||
qlogger.EXPECT().DroppedPacket(qlog.PacketTypeRetry, protocol.ByteCount(len(p.data)), qlog.PacketDropPayloadDecryptError)
|
||||
Expect(sess.handlePacketImpl(p)).To(BeFalse())
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user