logging: pass the packet number to ConnectionTracer.DroppedPacket (#4171)

In most cases the packet number is not known when a packet is dropped,
but it's useful to log the packet number when dropping a duplicate
packet.
This commit is contained in:
Marten Seemann 2023-11-17 13:11:16 +01:00 committed by GitHub
parent 96ab48eb7d
commit 3bf2e19d0d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 95 additions and 70 deletions

View file

@ -804,14 +804,14 @@ func (s *connection) handlePacketImpl(rp receivedPacket) bool {
destConnID, err = wire.ParseConnectionID(p.data, s.srcConnIDLen)
if err != nil {
if s.tracer != nil && s.tracer.DroppedPacket != nil {
s.tracer.DroppedPacket(logging.PacketTypeNotDetermined, protocol.ByteCount(len(data)), logging.PacketDropHeaderParseError)
s.tracer.DroppedPacket(logging.PacketTypeNotDetermined, protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), logging.PacketDropHeaderParseError)
}
s.logger.Debugf("error parsing packet, couldn't parse connection ID: %s", err)
break
}
if destConnID != lastConnID {
if s.tracer != nil && s.tracer.DroppedPacket != nil {
s.tracer.DroppedPacket(logging.PacketTypeNotDetermined, protocol.ByteCount(len(data)), logging.PacketDropUnknownConnectionID)
s.tracer.DroppedPacket(logging.PacketTypeNotDetermined, protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), logging.PacketDropUnknownConnectionID)
}
s.logger.Debugf("coalesced packet has different destination connection ID: %s, expected %s", destConnID, lastConnID)
break
@ -826,7 +826,7 @@ func (s *connection) handlePacketImpl(rp receivedPacket) bool {
if err == wire.ErrUnsupportedVersion {
dropReason = logging.PacketDropUnsupportedVersion
}
s.tracer.DroppedPacket(logging.PacketTypeNotDetermined, protocol.ByteCount(len(data)), dropReason)
s.tracer.DroppedPacket(logging.PacketTypeNotDetermined, protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), dropReason)
}
s.logger.Debugf("error parsing packet: %s", err)
break
@ -835,7 +835,7 @@ func (s *connection) handlePacketImpl(rp receivedPacket) bool {
if hdr.Version != s.version {
if s.tracer != nil && s.tracer.DroppedPacket != nil {
s.tracer.DroppedPacket(logging.PacketTypeFromHeader(hdr), protocol.ByteCount(len(data)), logging.PacketDropUnexpectedVersion)
s.tracer.DroppedPacket(logging.PacketTypeFromHeader(hdr), protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedVersion)
}
s.logger.Debugf("Dropping packet with version %x. Expected %x.", hdr.Version, s.version)
break
@ -894,7 +894,7 @@ func (s *connection) handleShortHeaderPacket(p receivedPacket, destConnID protoc
if s.receivedPacketHandler.IsPotentiallyDuplicate(pn, protocol.Encryption1RTT) {
s.logger.Debugf("Dropping (potentially) duplicate packet.")
if s.tracer != nil && s.tracer.DroppedPacket != nil {
s.tracer.DroppedPacket(logging.PacketType1RTT, p.Size(), logging.PacketDropDuplicate)
s.tracer.DroppedPacket(logging.PacketType1RTT, pn, p.Size(), logging.PacketDropDuplicate)
}
return false
}
@ -940,7 +940,7 @@ func (s *connection) handleLongHeaderPacket(p receivedPacket, hdr *wire.Header)
// After this, all packets with a different source connection have to be ignored.
if s.receivedFirstPacket && hdr.Type == protocol.PacketTypeInitial && hdr.SrcConnectionID != s.handshakeDestConnID {
if s.tracer != nil && s.tracer.DroppedPacket != nil {
s.tracer.DroppedPacket(logging.PacketTypeInitial, p.Size(), logging.PacketDropUnknownConnectionID)
s.tracer.DroppedPacket(logging.PacketTypeInitial, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnknownConnectionID)
}
s.logger.Debugf("Dropping Initial packet (%d bytes) with unexpected source connection ID: %s (expected %s)", p.Size(), hdr.SrcConnectionID, s.handshakeDestConnID)
return false
@ -948,7 +948,7 @@ func (s *connection) handleLongHeaderPacket(p receivedPacket, hdr *wire.Header)
// drop 0-RTT packets, if we are a client
if s.perspective == protocol.PerspectiveClient && hdr.Type == protocol.PacketType0RTT {
if s.tracer != nil && s.tracer.DroppedPacket != nil {
s.tracer.DroppedPacket(logging.PacketType0RTT, p.Size(), logging.PacketDropKeyUnavailable)
s.tracer.DroppedPacket(logging.PacketType0RTT, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropKeyUnavailable)
}
return false
}
@ -964,10 +964,10 @@ func (s *connection) handleLongHeaderPacket(p receivedPacket, hdr *wire.Header)
packet.hdr.Log(s.logger)
}
if s.receivedPacketHandler.IsPotentiallyDuplicate(packet.hdr.PacketNumber, packet.encryptionLevel) {
if pn := packet.hdr.PacketNumber; s.receivedPacketHandler.IsPotentiallyDuplicate(pn, packet.encryptionLevel) {
s.logger.Debugf("Dropping (potentially) duplicate packet.")
if s.tracer != nil && s.tracer.DroppedPacket != nil {
s.tracer.DroppedPacket(logging.PacketTypeFromHeader(hdr), p.Size(), logging.PacketDropDuplicate)
s.tracer.DroppedPacket(logging.PacketTypeFromHeader(hdr), pn, p.Size(), logging.PacketDropDuplicate)
}
return false
}
@ -983,7 +983,7 @@ func (s *connection) handleUnpackError(err error, p receivedPacket, pt logging.P
switch err {
case handshake.ErrKeysDropped:
if s.tracer != nil && s.tracer.DroppedPacket != nil {
s.tracer.DroppedPacket(pt, p.Size(), logging.PacketDropKeyUnavailable)
s.tracer.DroppedPacket(pt, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropKeyUnavailable)
}
s.logger.Debugf("Dropping %s packet (%d bytes) because we already dropped the keys.", pt, p.Size())
case handshake.ErrKeysNotYetAvailable:
@ -999,7 +999,7 @@ func (s *connection) handleUnpackError(err error, p receivedPacket, pt logging.P
case handshake.ErrDecryptionFailed:
// This might be a packet injected by an attacker. Drop it.
if s.tracer != nil && s.tracer.DroppedPacket != nil {
s.tracer.DroppedPacket(pt, p.Size(), logging.PacketDropPayloadDecryptError)
s.tracer.DroppedPacket(pt, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropPayloadDecryptError)
}
s.logger.Debugf("Dropping %s packet (%d bytes) that could not be unpacked. Error: %s", pt, p.Size(), err)
default:
@ -1007,7 +1007,7 @@ func (s *connection) handleUnpackError(err error, p receivedPacket, pt logging.P
if errors.As(err, &headerErr) {
// This might be a packet injected by an attacker. Drop it.
if s.tracer != nil && s.tracer.DroppedPacket != nil {
s.tracer.DroppedPacket(pt, p.Size(), logging.PacketDropHeaderParseError)
s.tracer.DroppedPacket(pt, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropHeaderParseError)
}
s.logger.Debugf("Dropping %s packet (%d bytes) for which we couldn't unpack the header. Error: %s", pt, p.Size(), err)
} else {
@ -1022,14 +1022,14 @@ func (s *connection) handleUnpackError(err error, p receivedPacket, pt logging.P
func (s *connection) handleRetryPacket(hdr *wire.Header, data []byte, rcvTime time.Time) bool /* was this a valid Retry */ {
if s.perspective == protocol.PerspectiveServer {
if s.tracer != nil && s.tracer.DroppedPacket != nil {
s.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedPacket)
s.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedPacket)
}
s.logger.Debugf("Ignoring Retry.")
return false
}
if s.receivedFirstPacket {
if s.tracer != nil && s.tracer.DroppedPacket != nil {
s.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedPacket)
s.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedPacket)
}
s.logger.Debugf("Ignoring Retry, since we already received a packet.")
return false
@ -1037,7 +1037,7 @@ func (s *connection) handleRetryPacket(hdr *wire.Header, data []byte, rcvTime ti
destConnID := s.connIDManager.Get()
if hdr.SrcConnectionID == destConnID {
if s.tracer != nil && s.tracer.DroppedPacket != nil {
s.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedPacket)
s.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedPacket)
}
s.logger.Debugf("Ignoring Retry, since the server didn't change the Source Connection ID.")
return false
@ -1052,7 +1052,7 @@ func (s *connection) handleRetryPacket(hdr *wire.Header, data []byte, rcvTime ti
tag := handshake.GetRetryIntegrityTag(data[:len(data)-16], destConnID, hdr.Version)
if !bytes.Equal(data[len(data)-16:], tag[:]) {
if s.tracer != nil && s.tracer.DroppedPacket != nil {
s.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.ByteCount(len(data)), logging.PacketDropPayloadDecryptError)
s.tracer.DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, protocol.ByteCount(len(data)), logging.PacketDropPayloadDecryptError)
}
s.logger.Debugf("Ignoring spoofed Retry. Integrity Tag doesn't match.")
return false
@ -1085,7 +1085,7 @@ func (s *connection) handleVersionNegotiationPacket(p receivedPacket) {
if s.perspective == protocol.PerspectiveServer || // servers never receive version negotiation packets
s.receivedFirstPacket || s.versionNegotiated { // ignore delayed / duplicated version negotiation packets
if s.tracer != nil && s.tracer.DroppedPacket != nil {
s.tracer.DroppedPacket(logging.PacketTypeVersionNegotiation, p.Size(), logging.PacketDropUnexpectedPacket)
s.tracer.DroppedPacket(logging.PacketTypeVersionNegotiation, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnexpectedPacket)
}
return
}
@ -1093,7 +1093,7 @@ func (s *connection) handleVersionNegotiationPacket(p receivedPacket) {
src, dest, supportedVersions, err := wire.ParseVersionNegotiationPacket(p.data)
if err != nil {
if s.tracer != nil && s.tracer.DroppedPacket != nil {
s.tracer.DroppedPacket(logging.PacketTypeVersionNegotiation, p.Size(), logging.PacketDropHeaderParseError)
s.tracer.DroppedPacket(logging.PacketTypeVersionNegotiation, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropHeaderParseError)
}
s.logger.Debugf("Error parsing Version Negotiation packet: %s", err)
return
@ -1102,7 +1102,7 @@ func (s *connection) handleVersionNegotiationPacket(p receivedPacket) {
for _, v := range supportedVersions {
if v == s.version {
if s.tracer != nil && s.tracer.DroppedPacket != nil {
s.tracer.DroppedPacket(logging.PacketTypeVersionNegotiation, p.Size(), logging.PacketDropUnexpectedVersion)
s.tracer.DroppedPacket(logging.PacketTypeVersionNegotiation, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnexpectedVersion)
}
// The Version Negotiation packet contains the version that we offered.
// This might be a packet sent by an attacker, or it was corrupted.
@ -1343,7 +1343,7 @@ func (s *connection) handlePacket(p receivedPacket) {
case s.receivedPackets <- p:
default:
if s.tracer != nil && s.tracer.DroppedPacket != nil {
s.tracer.DroppedPacket(logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropDOSPrevention)
s.tracer.DroppedPacket(logging.PacketTypeNotDetermined, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropDOSPrevention)
}
}
}
@ -2305,7 +2305,7 @@ func (s *connection) tryQueueingUndecryptablePacket(p receivedPacket, pt logging
}
if len(s.undecryptablePackets)+1 > protocol.MaxUndecryptablePackets {
if s.tracer != nil && s.tracer.DroppedPacket != nil {
s.tracer.DroppedPacket(pt, p.Size(), logging.PacketDropDOSPrevention)
s.tracer.DroppedPacket(pt, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropDOSPrevention)
}
s.logger.Infof("Dropping undecryptable packet (%d bytes). Undecryptable packet queue full.", p.Size())
return

View file

@ -686,7 +686,7 @@ var _ = Describe("Connection", func() {
Version: conn.version,
Token: []byte("foobar"),
}}, make([]byte, 16) /* Retry integrity tag */)
tracer.EXPECT().DroppedPacket(logging.PacketTypeRetry, p.Size(), logging.PacketDropUnexpectedPacket)
tracer.EXPECT().DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnexpectedPacket)
Expect(conn.handlePacketImpl(p)).To(BeFalse())
})
@ -696,7 +696,7 @@ var _ = Describe("Connection", func() {
protocol.ArbitraryLenConnectionID(destConnID.Bytes()),
conn.config.Versions,
)
tracer.EXPECT().DroppedPacket(logging.PacketTypeVersionNegotiation, protocol.ByteCount(len(b)), logging.PacketDropUnexpectedPacket)
tracer.EXPECT().DroppedPacket(logging.PacketTypeVersionNegotiation, protocol.InvalidPacketNumber, protocol.ByteCount(len(b)), logging.PacketDropUnexpectedPacket)
Expect(conn.handlePacketImpl(receivedPacket{
data: b,
buffer: getPacketBuffer(),
@ -712,7 +712,7 @@ var _ = Describe("Connection", func() {
PacketNumberLen: protocol.PacketNumberLen2,
}, nil)
p.data[0] ^= 0x40 // unset the QUIC bit
tracer.EXPECT().DroppedPacket(logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropHeaderParseError)
tracer.EXPECT().DroppedPacket(logging.PacketTypeNotDetermined, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropHeaderParseError)
Expect(conn.handlePacketImpl(p)).To(BeFalse())
})
@ -724,7 +724,7 @@ var _ = Describe("Connection", func() {
},
PacketNumberLen: protocol.PacketNumberLen2,
}, nil)
tracer.EXPECT().DroppedPacket(logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropUnsupportedVersion)
tracer.EXPECT().DroppedPacket(logging.PacketTypeNotDetermined, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnsupportedVersion)
Expect(conn.handlePacketImpl(p)).To(BeFalse())
})
@ -745,7 +745,7 @@ var _ = Describe("Connection", func() {
},
PacketNumberLen: protocol.PacketNumberLen2,
}, nil)
tracer.EXPECT().DroppedPacket(logging.PacketTypeHandshake, p.Size(), logging.PacketDropUnexpectedVersion)
tracer.EXPECT().DroppedPacket(logging.PacketTypeHandshake, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnexpectedVersion)
Expect(conn.handlePacketImpl(p)).To(BeFalse())
})
@ -811,7 +811,7 @@ var _ = Describe("Connection", func() {
rph := mockackhandler.NewMockReceivedPacketHandler(mockCtrl)
rph.EXPECT().IsPotentiallyDuplicate(protocol.PacketNumber(0x1337), protocol.Encryption1RTT).Return(true)
conn.receivedPacketHandler = rph
tracer.EXPECT().DroppedPacket(logging.PacketType1RTT, protocol.ByteCount(len(packet.data)), logging.PacketDropDuplicate)
tracer.EXPECT().DroppedPacket(logging.PacketType1RTT, protocol.PacketNumber(0x1337), protocol.ByteCount(len(packet.data)), logging.PacketDropDuplicate)
Expect(conn.handlePacketImpl(packet)).To(BeFalse())
})
@ -837,7 +837,7 @@ var _ = Describe("Connection", func() {
PacketNumber: 0x1337,
PacketNumberLen: protocol.PacketNumberLen2,
}, []byte("foobar"))
tracer.EXPECT().DroppedPacket(logging.PacketTypeHandshake, p.Size(), logging.PacketDropPayloadDecryptError)
tracer.EXPECT().DroppedPacket(logging.PacketTypeHandshake, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropPayloadDecryptError)
conn.handlePacket(p)
Consistently(conn.Context().Done()).ShouldNot(BeClosed())
// make the go routine return
@ -955,7 +955,7 @@ var _ = Describe("Connection", func() {
runErr <- conn.run()
}()
expectReplaceWithClosed()
tracer.EXPECT().DroppedPacket(logging.PacketType1RTT, gomock.Any(), logging.PacketDropHeaderParseError)
tracer.EXPECT().DroppedPacket(logging.PacketType1RTT, protocol.InvalidPacketNumber, gomock.Any(), logging.PacketDropHeaderParseError)
conn.handlePacket(getShortHeaderPacket(srcConnID, 0x42, nil))
Consistently(runErr).ShouldNot(Receive())
// make the go routine return
@ -1028,7 +1028,7 @@ var _ = Describe("Connection", func() {
Expect(conn.handlePacketImpl(p1)).To(BeTrue())
// The next packet has to be ignored, since the source connection ID doesn't match.
p2 := getLongHeaderPacket(hdr2, nil)
tracer.EXPECT().DroppedPacket(logging.PacketTypeInitial, protocol.ByteCount(len(p2.data)), logging.PacketDropUnknownConnectionID)
tracer.EXPECT().DroppedPacket(logging.PacketTypeInitial, protocol.InvalidPacketNumber, protocol.ByteCount(len(p2.data)), logging.PacketDropUnknownConnectionID)
Expect(conn.handlePacketImpl(p2)).To(BeFalse())
})
@ -1183,7 +1183,7 @@ var _ = Describe("Connection", func() {
// don't EXPECT any more calls to unpacker.UnpackLongHeader()
gomock.InOrder(
tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), protocol.ByteCount(len(packet1.data)), gomock.Any(), gomock.Any()),
tracer.EXPECT().DroppedPacket(gomock.Any(), protocol.ByteCount(len(packet2.data)), logging.PacketDropUnknownConnectionID),
tracer.EXPECT().DroppedPacket(gomock.Any(), protocol.InvalidPacketNumber, protocol.ByteCount(len(packet2.data)), logging.PacketDropUnknownConnectionID),
)
packet1.data = append(packet1.data, packet2.data...)
Expect(conn.handlePacketImpl(packet1)).To(BeTrue())
@ -2430,7 +2430,7 @@ var _ = Describe("Connection", func() {
It("stores up to MaxConnUnprocessedPackets packets", func() {
done := make(chan struct{})
tracer.EXPECT().DroppedPacket(logging.PacketTypeNotDetermined, logging.ByteCount(6), logging.PacketDropDOSPrevention).Do(func(logging.PacketType, logging.ByteCount, logging.PacketDropReason) {
tracer.EXPECT().DroppedPacket(logging.PacketTypeNotDetermined, protocol.InvalidPacketNumber, logging.ByteCount(6), logging.PacketDropDOSPrevention).Do(func(logging.PacketType, logging.PacketNumber, logging.ByteCount, logging.PacketDropReason) {
close(done)
})
// Nothing here should block
@ -2790,14 +2790,14 @@ var _ = Describe("Client Connection", func() {
It("ignores Version Negotiation packets that offer the current version", func() {
p := getVNP(conn.version)
tracer.EXPECT().DroppedPacket(logging.PacketTypeVersionNegotiation, p.Size(), logging.PacketDropUnexpectedVersion)
tracer.EXPECT().DroppedPacket(logging.PacketTypeVersionNegotiation, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnexpectedVersion)
Expect(conn.handlePacketImpl(p)).To(BeFalse())
})
It("ignores unparseable Version Negotiation packets", func() {
p := getVNP(conn.version)
p.data = p.data[:len(p.data)-2]
tracer.EXPECT().DroppedPacket(logging.PacketTypeVersionNegotiation, p.Size(), logging.PacketDropHeaderParseError)
tracer.EXPECT().DroppedPacket(logging.PacketTypeVersionNegotiation, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropHeaderParseError)
Expect(conn.handlePacketImpl(p)).To(BeFalse())
})
})
@ -2846,14 +2846,14 @@ var _ = Describe("Client Connection", func() {
It("ignores Retry packets after receiving a regular packet", func() {
conn.receivedFirstPacket = true
p := getPacket(retryHdr, getRetryTag(retryHdr))
tracer.EXPECT().DroppedPacket(logging.PacketTypeRetry, p.Size(), logging.PacketDropUnexpectedPacket)
tracer.EXPECT().DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnexpectedPacket)
Expect(conn.handlePacketImpl(p)).To(BeFalse())
})
It("ignores Retry packets if the server didn't change the connection ID", func() {
retryHdr.SrcConnectionID = destConnID
p := getPacket(retryHdr, getRetryTag(retryHdr))
tracer.EXPECT().DroppedPacket(logging.PacketTypeRetry, p.Size(), logging.PacketDropUnexpectedPacket)
tracer.EXPECT().DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropUnexpectedPacket)
Expect(conn.handlePacketImpl(p)).To(BeFalse())
})
@ -2861,7 +2861,7 @@ var _ = Describe("Client Connection", func() {
tag := getRetryTag(retryHdr)
tag[0]++
p := getPacket(retryHdr, tag)
tracer.EXPECT().DroppedPacket(logging.PacketTypeRetry, p.Size(), logging.PacketDropPayloadDecryptError)
tracer.EXPECT().DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, p.Size(), logging.PacketDropPayloadDecryptError)
Expect(conn.handlePacketImpl(p)).To(BeFalse())
})
})
@ -3159,7 +3159,7 @@ var _ = Describe("Client Connection", func() {
tracer.EXPECT().ReceivedLongHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any())
Expect(conn.handlePacketImpl(getPacket(hdr1, nil))).To(BeTrue())
// The next packet has to be ignored, since the source connection ID doesn't match.
tracer.EXPECT().DroppedPacket(gomock.Any(), gomock.Any(), gomock.Any())
tracer.EXPECT().DroppedPacket(gomock.Any(), protocol.InvalidPacketNumber, gomock.Any(), gomock.Any())
Expect(conn.handlePacketImpl(getPacket(hdr2, nil))).To(BeFalse())
})
@ -3174,7 +3174,7 @@ var _ = Describe("Client Connection", func() {
PacketNumber: 0x42,
PacketNumberLen: protocol.PacketNumberLen2,
}, []byte("foobar"))
tracer.EXPECT().DroppedPacket(logging.PacketType0RTT, p.Size(), gomock.Any())
tracer.EXPECT().DroppedPacket(logging.PacketType0RTT, protocol.InvalidPacketNumber, p.Size(), gomock.Any())
Expect(conn.handlePacketImpl(p)).To(BeFalse())
})
@ -3213,7 +3213,7 @@ var _ = Describe("Client Connection", func() {
tracer.EXPECT().ReceivedRetry(gomock.Any())
conn.handlePacketImpl(wrapPacket(testutils.ComposeRetryPacket(newSrcConnID, destConnID, destConnID, []byte("foobar"), conn.version)))
initialPacket := testutils.ComposeInitialPacket(conn.connIDManager.Get(), srcConnID, conn.version, conn.connIDManager.Get(), nil)
tracer.EXPECT().DroppedPacket(gomock.Any(), gomock.Any(), gomock.Any())
tracer.EXPECT().DroppedPacket(gomock.Any(), protocol.InvalidPacketNumber, gomock.Any(), gomock.Any())
Expect(conn.handlePacketImpl(wrapPacket(initialPacket))).To(BeFalse())
})
})

View file

@ -56,8 +56,8 @@ func NewMockConnectionTracer(ctrl *gomock.Controller) (*logging.ConnectionTracer
BufferedPacket: func(typ logging.PacketType, size logging.ByteCount) {
t.BufferedPacket(typ, size)
},
DroppedPacket: func(typ logging.PacketType, size logging.ByteCount, reason logging.PacketDropReason) {
t.DroppedPacket(typ, size, reason)
DroppedPacket: func(typ logging.PacketType, pn logging.PacketNumber, size logging.ByteCount, reason logging.PacketDropReason) {
t.DroppedPacket(typ, pn, size, reason)
},
UpdatedMetrics: func(rttStats *logging.RTTStats, cwnd, bytesInFlight logging.ByteCount, packetsInFlight int) {
t.UpdatedMetrics(rttStats, cwnd, bytesInFlight, packetsInFlight)

View file

@ -296,15 +296,15 @@ func (c *ConnectionTracerDroppedKeyCall) DoAndReturn(f func(protocol.KeyPhase))
}
// DroppedPacket mocks base method.
func (m *MockConnectionTracer) DroppedPacket(arg0 logging.PacketType, arg1 protocol.ByteCount, arg2 logging.PacketDropReason) {
func (m *MockConnectionTracer) DroppedPacket(arg0 logging.PacketType, arg1 protocol.PacketNumber, arg2 protocol.ByteCount, arg3 logging.PacketDropReason) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "DroppedPacket", arg0, arg1, arg2)
m.ctrl.Call(m, "DroppedPacket", arg0, arg1, arg2, arg3)
}
// DroppedPacket indicates an expected call of DroppedPacket.
func (mr *MockConnectionTracerMockRecorder) DroppedPacket(arg0, arg1, arg2 any) *ConnectionTracerDroppedPacketCall {
func (mr *MockConnectionTracerMockRecorder) DroppedPacket(arg0, arg1, arg2, arg3 any) *ConnectionTracerDroppedPacketCall {
mr.mock.ctrl.T.Helper()
call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DroppedPacket", reflect.TypeOf((*MockConnectionTracer)(nil).DroppedPacket), arg0, arg1, arg2)
call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DroppedPacket", reflect.TypeOf((*MockConnectionTracer)(nil).DroppedPacket), arg0, arg1, arg2, arg3)
return &ConnectionTracerDroppedPacketCall{Call: call}
}
@ -320,13 +320,13 @@ func (c *ConnectionTracerDroppedPacketCall) Return() *ConnectionTracerDroppedPac
}
// Do rewrite *gomock.Call.Do
func (c *ConnectionTracerDroppedPacketCall) Do(f func(logging.PacketType, protocol.ByteCount, logging.PacketDropReason)) *ConnectionTracerDroppedPacketCall {
func (c *ConnectionTracerDroppedPacketCall) Do(f func(logging.PacketType, protocol.PacketNumber, protocol.ByteCount, logging.PacketDropReason)) *ConnectionTracerDroppedPacketCall {
c.Call = c.Call.Do(f)
return c
}
// DoAndReturn rewrite *gomock.Call.DoAndReturn
func (c *ConnectionTracerDroppedPacketCall) DoAndReturn(f func(logging.PacketType, protocol.ByteCount, logging.PacketDropReason)) *ConnectionTracerDroppedPacketCall {
func (c *ConnectionTracerDroppedPacketCall) DoAndReturn(f func(logging.PacketType, protocol.PacketNumber, protocol.ByteCount, logging.PacketDropReason)) *ConnectionTracerDroppedPacketCall {
c.Call = c.Call.DoAndReturn(f)
return c
}

View file

@ -31,7 +31,7 @@ type ConnectionTracer interface {
ReceivedLongHeaderPacket(*logging.ExtendedHeader, logging.ByteCount, logging.ECN, []logging.Frame)
ReceivedShortHeaderPacket(*logging.ShortHeader, logging.ByteCount, logging.ECN, []logging.Frame)
BufferedPacket(logging.PacketType, logging.ByteCount)
DroppedPacket(logging.PacketType, logging.ByteCount, logging.PacketDropReason)
DroppedPacket(logging.PacketType, logging.PacketNumber, logging.ByteCount, logging.PacketDropReason)
UpdatedMetrics(rttStats *logging.RTTStats, cwnd, bytesInFlight logging.ByteCount, packetsInFlight int)
AcknowledgedPacket(logging.EncryptionLevel, logging.PacketNumber)
LostPacket(logging.EncryptionLevel, logging.PacketNumber, logging.PacketLossReason)

View file

@ -20,7 +20,7 @@ type ConnectionTracer struct {
ReceivedLongHeaderPacket func(*ExtendedHeader, ByteCount, ECN, []Frame)
ReceivedShortHeaderPacket func(*ShortHeader, ByteCount, ECN, []Frame)
BufferedPacket func(PacketType, ByteCount)
DroppedPacket func(PacketType, ByteCount, PacketDropReason)
DroppedPacket func(PacketType, PacketNumber, ByteCount, PacketDropReason)
UpdatedMetrics func(rttStats *RTTStats, cwnd, bytesInFlight ByteCount, packetsInFlight int)
AcknowledgedPacket func(EncryptionLevel, PacketNumber)
LostPacket func(EncryptionLevel, PacketNumber, PacketLossReason)
@ -139,10 +139,10 @@ func NewMultiplexedConnectionTracer(tracers ...*ConnectionTracer) *ConnectionTra
}
}
},
DroppedPacket: func(typ PacketType, size ByteCount, reason PacketDropReason) {
DroppedPacket: func(typ PacketType, pn PacketNumber, size ByteCount, reason PacketDropReason) {
for _, t := range tracers {
if t.DroppedPacket != nil {
t.DroppedPacket(typ, size, reason)
t.DroppedPacket(typ, pn, size, reason)
}
}
},

View file

@ -184,9 +184,9 @@ var _ = Describe("Tracing", func() {
})
It("traces the DroppedPacket event", func() {
tr1.EXPECT().DroppedPacket(PacketTypeInitial, ByteCount(1337), PacketDropHeaderParseError)
tr2.EXPECT().DroppedPacket(PacketTypeInitial, ByteCount(1337), PacketDropHeaderParseError)
tracer.DroppedPacket(PacketTypeInitial, 1337, PacketDropHeaderParseError)
tr1.EXPECT().DroppedPacket(PacketTypeInitial, PacketNumber(42), ByteCount(1337), PacketDropHeaderParseError)
tr2.EXPECT().DroppedPacket(PacketTypeInitial, PacketNumber(42), ByteCount(1337), PacketDropHeaderParseError)
tracer.DroppedPacket(PacketTypeInitial, 42, 1337, PacketDropHeaderParseError)
})
It("traces the UpdatedCongestionState event", func() {

View file

@ -243,15 +243,16 @@ func (e eventPacketBuffered) IsNil() bool { return false }
func (e eventPacketBuffered) MarshalJSONObject(enc *gojay.Encoder) {
//nolint:gosimple
enc.ObjectKey("header", packetHeaderWithType{PacketType: e.PacketType})
enc.ObjectKey("header", packetHeaderWithType{PacketType: e.PacketType, PacketNumber: protocol.InvalidPacketNumber})
enc.ObjectKey("raw", rawInfo{Length: e.PacketSize})
enc.StringKey("trigger", "keys_unavailable")
}
type eventPacketDropped struct {
PacketType logging.PacketType
PacketSize protocol.ByteCount
Trigger packetDropReason
PacketType logging.PacketType
PacketSize protocol.ByteCount
PacketNumber logging.PacketNumber
Trigger packetDropReason
}
func (e eventPacketDropped) Category() category { return categoryTransport }
@ -259,7 +260,10 @@ func (e eventPacketDropped) Name() string { return "packet_dropped" }
func (e eventPacketDropped) IsNil() bool { return false }
func (e eventPacketDropped) MarshalJSONObject(enc *gojay.Encoder) {
enc.ObjectKey("header", packetHeaderWithType{PacketType: e.PacketType})
enc.ObjectKey("header", packetHeaderWithType{
PacketType: e.PacketType,
PacketNumber: e.PacketNumber,
})
enc.ObjectKey("raw", rawInfo{Length: e.PacketSize})
enc.StringKey("trigger", e.Trigger.String())
}

View file

@ -110,14 +110,18 @@ func (h packetHeaderVersionNegotiation) MarshalJSONObject(enc *gojay.Encoder) {
enc.StringKey("dcid", h.DestConnectionID.String())
}
// a minimal header that only outputs the packet type
// a minimal header that only outputs the packet type, and potentially a packet number
type packetHeaderWithType struct {
PacketType logging.PacketType
PacketType logging.PacketType
PacketNumber logging.PacketNumber
}
func (h packetHeaderWithType) IsNil() bool { return false }
func (h packetHeaderWithType) MarshalJSONObject(enc *gojay.Encoder) {
enc.StringKey("packet_type", packetType(h.PacketType).String())
if h.PacketNumber != protocol.InvalidPacketNumber {
enc.Int64Key("packet_number", int64(h.PacketNumber))
}
}
// a minimal header that only outputs the packet type

View file

@ -106,8 +106,8 @@ func NewConnectionTracer(w io.WriteCloser, p protocol.Perspective, odcid protoco
BufferedPacket: func(pt logging.PacketType, size protocol.ByteCount) {
t.BufferedPacket(pt, size)
},
DroppedPacket: func(pt logging.PacketType, size protocol.ByteCount, reason logging.PacketDropReason) {
t.DroppedPacket(pt, size, reason)
DroppedPacket: func(pt logging.PacketType, pn logging.PacketNumber, size logging.ByteCount, reason logging.PacketDropReason) {
t.DroppedPacket(pt, pn, size, reason)
},
UpdatedMetrics: func(rttStats *utils.RTTStats, cwnd, bytesInFlight protocol.ByteCount, packetsInFlight int) {
t.UpdatedMetrics(rttStats, cwnd, bytesInFlight, packetsInFlight)
@ -444,12 +444,13 @@ func (t *connectionTracer) BufferedPacket(pt logging.PacketType, size protocol.B
t.mutex.Unlock()
}
func (t *connectionTracer) DroppedPacket(pt logging.PacketType, size protocol.ByteCount, reason logging.PacketDropReason) {
func (t *connectionTracer) DroppedPacket(pt logging.PacketType, pn logging.PacketNumber, size protocol.ByteCount, reason logging.PacketDropReason) {
t.mutex.Lock()
t.recordEvent(time.Now(), &eventPacketDropped{
PacketType: pt,
PacketSize: size,
Trigger: packetDropReason(reason),
PacketType: pt,
PacketNumber: pn,
PacketSize: size,
Trigger: packetDropReason(reason),
})
t.mutex.Unlock()
}

View file

@ -616,7 +616,7 @@ var _ = Describe("Tracing", func() {
})
It("records dropped packets", func() {
tracer.DroppedPacket(logging.PacketTypeHandshake, 1337, logging.PacketDropPayloadDecryptError)
tracer.DroppedPacket(logging.PacketTypeRetry, protocol.InvalidPacketNumber, 1337, logging.PacketDropPayloadDecryptError)
entry := exportAndParseSingle()
Expect(entry.Time).To(BeTemporally("~", time.Now(), scaleDuration(10*time.Millisecond)))
Expect(entry.Name).To(Equal("transport:packet_dropped"))
@ -626,10 +626,26 @@ var _ = Describe("Tracing", func() {
Expect(ev).To(HaveKey("header"))
hdr := ev["header"].(map[string]interface{})
Expect(hdr).To(HaveLen(1))
Expect(hdr).To(HaveKeyWithValue("packet_type", "handshake"))
Expect(hdr).To(HaveKeyWithValue("packet_type", "retry"))
Expect(ev).To(HaveKeyWithValue("trigger", "payload_decrypt_error"))
})
It("records dropped packets with a packet number", func() {
tracer.DroppedPacket(logging.PacketTypeHandshake, 42, 1337, logging.PacketDropDuplicate)
entry := exportAndParseSingle()
Expect(entry.Time).To(BeTemporally("~", time.Now(), scaleDuration(10*time.Millisecond)))
Expect(entry.Name).To(Equal("transport:packet_dropped"))
ev := entry.Event
Expect(ev).To(HaveKey("raw"))
Expect(ev["raw"].(map[string]interface{})).To(HaveKeyWithValue("length", float64(1337)))
Expect(ev).To(HaveKey("header"))
hdr := ev["header"].(map[string]interface{})
Expect(hdr).To(HaveLen(2))
Expect(hdr).To(HaveKeyWithValue("packet_type", "handshake"))
Expect(hdr).To(HaveKeyWithValue("packet_number", float64(42)))
Expect(ev).To(HaveKeyWithValue("trigger", "duplicate"))
})
It("records metrics updates", func() {
now := time.Now()
rttStats := utils.NewRTTStats()