diff --git a/internal/ackhandler/sent_packet_handler.go b/internal/ackhandler/sent_packet_handler.go index 2a8564a0..b3159a9c 100644 --- a/internal/ackhandler/sent_packet_handler.go +++ b/internal/ackhandler/sent_packet_handler.go @@ -76,6 +76,8 @@ type sentPacketHandler struct { // The alarm timeout alarm time.Time + traceCallback func(quictrace.Event) + logger utils.Logger } @@ -83,6 +85,7 @@ type sentPacketHandler struct { func NewSentPacketHandler( initialPacketNumber protocol.PacketNumber, rttStats *congestion.RTTStats, + traceCallback func(quictrace.Event), logger utils.Logger, ) SentPacketHandler { congestion := congestion.NewCubicSender( @@ -99,6 +102,7 @@ func NewSentPacketHandler( oneRTTPackets: newPacketNumberSpace(0), rttStats: rttStats, congestion: congestion, + traceCallback: traceCallback, logger: logger, } } @@ -404,6 +408,17 @@ func (h *sentPacketHandler) detectLostPackets( } } pnSpace.history.Remove(p.PacketNumber) + if h.traceCallback != nil { + h.traceCallback(quictrace.Event{ + Time: now, + EventType: quictrace.PacketLost, + EncryptionLevel: p.EncryptionLevel, + PacketNumber: p.PacketNumber, + PacketSize: p.Length, + Frames: p.Frames, + TransportState: h.GetStats(), + }) + } } return nil } diff --git a/internal/ackhandler/sent_packet_handler_test.go b/internal/ackhandler/sent_packet_handler_test.go index 948c8b4b..e3d894e9 100644 --- a/internal/ackhandler/sent_packet_handler_test.go +++ b/internal/ackhandler/sent_packet_handler_test.go @@ -48,7 +48,7 @@ var _ = Describe("SentPacketHandler", func() { BeforeEach(func() { rttStats := &congestion.RTTStats{} - handler = NewSentPacketHandler(42, rttStats, utils.DefaultLogger).(*sentPacketHandler) + handler = NewSentPacketHandler(42, rttStats, nil, utils.DefaultLogger).(*sentPacketHandler) streamFrame = wire.StreamFrame{ StreamID: 5, Data: []byte{0x13, 0x37}, diff --git a/session.go b/session.go index 347c1597..35a18715 100644 --- a/session.go +++ b/session.go @@ -162,6 +162,8 @@ type session struct { // it is reset as soon as we receive a packet from the peer keepAlivePingSent bool + traceCallback func(quictrace.Event) + logger utils.Logger } @@ -194,7 +196,7 @@ var newSession = func( version: v, } s.preSetup() - s.sentPacketHandler = ackhandler.NewSentPacketHandler(0, s.rttStats, s.logger) + s.sentPacketHandler = ackhandler.NewSentPacketHandler(0, s.rttStats, s.traceCallback, s.logger) s.streamsMap = newStreamsMap( s, s.newFlowController, @@ -276,7 +278,7 @@ var newClientSession = func( version: v, } s.preSetup() - s.sentPacketHandler = ackhandler.NewSentPacketHandler(initialPacketNumber, s.rttStats, s.logger) + s.sentPacketHandler = ackhandler.NewSentPacketHandler(initialPacketNumber, s.rttStats, s.traceCallback, s.logger) initialStream := newCryptoStream() handshakeStream := newCryptoStream() oneRTTStream := newPostHandshakeCryptoStream(s.framer) @@ -339,6 +341,11 @@ func (s *session) preSetup() { s.rttStats, s.logger, ) + if s.config.QuicTracer != nil { + s.traceCallback = func(ev quictrace.Event) { + s.config.QuicTracer.Trace(s.origDestConnID, ev) + } + } } func (s *session) postSetup() error { @@ -683,7 +690,7 @@ func (s *session) handleUnpackedPacket(packet *unpackedPacket, rcvTime time.Time if ackhandler.IsFrameAckEliciting(frame) { isAckEliciting = true } - if s.config.QuicTracer != nil { + if s.traceCallback != nil { frames = append(frames, frame) } if err := s.handleFrame(frame, packet.packetNumber, packet.encryptionLevel); err != nil { @@ -691,8 +698,8 @@ func (s *session) handleUnpackedPacket(packet *unpackedPacket, rcvTime time.Time } } - if s.config.QuicTracer != nil { - s.config.QuicTracer.Trace(s.origDestConnID, quictrace.Event{ + if s.traceCallback != nil { + s.traceCallback(quictrace.Event{ Time: time.Now(), EventType: quictrace.PacketReceived, TransportState: s.sentPacketHandler.GetStats(), @@ -1173,8 +1180,8 @@ func (s *session) sendPackedPacket(packet *packedPacket) error { if s.firstAckElicitingPacketAfterIdleSentTime.IsZero() && packet.IsAckEliciting() { s.firstAckElicitingPacketAfterIdleSentTime = time.Now() } - if s.config.QuicTracer != nil { - s.config.QuicTracer.Trace(s.origDestConnID, quictrace.Event{ + if s.traceCallback != nil { + s.traceCallback(quictrace.Event{ Time: time.Now(), EventType: quictrace.PacketSent, TransportState: s.sentPacketHandler.GetStats(),