diff --git a/qlog/event.go b/qlog/event.go index d3d26601..c70ee548 100644 --- a/qlog/event.go +++ b/qlog/event.go @@ -233,6 +233,20 @@ func (e eventVersionNegotiationReceived) MarshalJSONObject(enc *gojay.Encoder) { enc.ArrayKey("supported_versions", versions(e.SupportedVersions)) } +type eventVersionNegotiationSent struct { + Header packetHeaderVersionNegotiation + SupportedVersions []versionNumber +} + +func (e eventVersionNegotiationSent) Category() category { return categoryTransport } +func (e eventVersionNegotiationSent) Name() string { return "packet_sent" } +func (e eventVersionNegotiationSent) IsNil() bool { return false } + +func (e eventVersionNegotiationSent) MarshalJSONObject(enc *gojay.Encoder) { + enc.ObjectKey("header", e.Header) + enc.ArrayKey("supported_versions", versions(e.SupportedVersions)) +} + type eventPacketBuffered struct { PacketType logging.PacketType PacketSize protocol.ByteCount diff --git a/qlog/tracer.go b/qlog/tracer.go index 85398f9f..708e80ab 100644 --- a/qlog/tracer.go +++ b/qlog/tracer.go @@ -17,8 +17,20 @@ func NewTracer(w io.WriteCloser) *logging.Tracer { wr := *newWriter(w, tr) go wr.Run() return &logging.Tracer{ - SentPacket: nil, - SentVersionNegotiationPacket: nil, + SentPacket: nil, + SentVersionNegotiationPacket: func(_ net.Addr, dest, src logging.ArbitraryLenConnectionID, versions []logging.VersionNumber) { + ver := make([]versionNumber, len(versions)) + for i, v := range versions { + ver[i] = versionNumber(v) + } + wr.RecordEvent(time.Now(), &eventVersionNegotiationSent{ + Header: packetHeaderVersionNegotiation{ + SrcConnectionID: src, + DestConnectionID: dest, + }, + SupportedVersions: ver, + }) + }, DroppedPacket: func(addr net.Addr, p logging.PacketType, count logging.ByteCount, reason logging.PacketDropReason) { wr.RecordEvent(time.Now(), eventPacketDropped{ PacketType: p, diff --git a/qlog/tracer_test.go b/qlog/tracer_test.go index 990e4165..75d97059 100644 --- a/qlog/tracer_test.go +++ b/qlog/tracer_test.go @@ -6,6 +6,7 @@ import ( "net" "time" + "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/logging" . "github.com/onsi/ginkgo/v2" @@ -46,6 +47,30 @@ var _ = Describe("Tracing", func() { }) Context("Events", func() { + It("records sending of a Version Negotiation packet", func() { + tracer.SentVersionNegotiationPacket( + nil, + protocol.ArbitraryLenConnectionID{1, 2, 3, 4, 5, 6, 7, 8}, + protocol.ArbitraryLenConnectionID{4, 3, 2, 1}, + []protocol.Version{0xdeadbeef, 0xdecafbad}, + ) + tracer.Close() + entry := exportAndParseSingle(buf) + Expect(entry.Time).To(BeTemporally("~", time.Now(), scaleDuration(10*time.Millisecond))) + Expect(entry.Name).To(Equal("transport:packet_sent")) + ev := entry.Event + Expect(ev).To(HaveKey("header")) + Expect(ev).ToNot(HaveKey("frames")) + Expect(ev).To(HaveKey("supported_versions")) + Expect(ev["supported_versions"].([]interface{})).To(Equal([]interface{}{"deadbeef", "decafbad"})) + header := ev["header"] + Expect(header).To(HaveKeyWithValue("packet_type", "version_negotiation")) + Expect(header).ToNot(HaveKey("packet_number")) + Expect(header).ToNot(HaveKey("version")) + Expect(header).To(HaveKeyWithValue("dcid", "0102030405060708")) + Expect(header).To(HaveKeyWithValue("scid", "04030201")) + }) + It("records dropped packets", func() { addr := net.UDPAddr{IP: net.IPv4(1, 2, 3, 4), Port: 1234} tracer.DroppedPacket(&addr, logging.PacketTypeInitial, 1337, logging.PacketDropPayloadDecryptError)