qlog: use PathEndpointInfo in connection_started (#5368)

* qlog: use PathEndpointInfo in connection_started

* correctly deal with dual-stack addresses
This commit is contained in:
Marten Seemann
2025-10-11 13:55:38 +08:00
committed by GitHub
parent ae909aeb72
commit 115e8ee5d7
5 changed files with 176 additions and 47 deletions

View File

@@ -3,7 +3,6 @@ package qlog
import (
"errors"
"fmt"
"net"
"net/netip"
"time"
@@ -56,11 +55,33 @@ func (i RawInfo) encode(enc *jsontext.Encoder) error {
return h.err
}
type PathEndpointInfo struct {
IPv4 netip.AddrPort
IPv6 netip.AddrPort
}
func (p PathEndpointInfo) encode(enc *jsontext.Encoder) error {
h := encoderHelper{enc: enc}
h.WriteToken(jsontext.BeginObject)
if p.IPv4.IsValid() {
h.WriteToken(jsontext.String("ip_v4"))
h.WriteToken(jsontext.String(p.IPv4.Addr().String()))
h.WriteToken(jsontext.String("port_v4"))
h.WriteToken(jsontext.Int(int64(p.IPv4.Port())))
}
if p.IPv6.IsValid() {
h.WriteToken(jsontext.String("ip_v6"))
h.WriteToken(jsontext.String(p.IPv6.Addr().String()))
h.WriteToken(jsontext.String("port_v6"))
h.WriteToken(jsontext.Int(int64(p.IPv6.Port())))
}
h.WriteToken(jsontext.EndObject)
return h.err
}
type StartedConnection struct {
SrcAddr *net.UDPAddr
DestAddr *net.UDPAddr
SrcConnectionID ConnectionID
DestConnectionID ConnectionID
Local PathEndpointInfo
Remote PathEndpointInfo
}
func (e StartedConnection) Name() string { return "transport:connection_started" }
@@ -68,25 +89,14 @@ func (e StartedConnection) Name() string { return "transport:connection_started"
func (e StartedConnection) Encode(enc *jsontext.Encoder, _ time.Time) error {
h := encoderHelper{enc: enc}
h.WriteToken(jsontext.BeginObject)
if e.SrcAddr.IP.To4() != nil {
h.WriteToken(jsontext.String("ip_version"))
h.WriteToken(jsontext.String("ipv4"))
} else {
h.WriteToken(jsontext.String("ip_version"))
h.WriteToken(jsontext.String("ipv6"))
h.WriteToken(jsontext.String("local"))
if err := e.Local.encode(enc); err != nil {
return err
}
h.WriteToken(jsontext.String("remote"))
if err := e.Remote.encode(enc); err != nil {
return err
}
h.WriteToken(jsontext.String("src_ip"))
h.WriteToken(jsontext.String(e.SrcAddr.IP.String()))
h.WriteToken(jsontext.String("src_port"))
h.WriteToken(jsontext.Int(int64(e.SrcAddr.Port)))
h.WriteToken(jsontext.String("dst_ip"))
h.WriteToken(jsontext.String(e.DestAddr.IP.String()))
h.WriteToken(jsontext.String("dst_port"))
h.WriteToken(jsontext.Int(int64(e.DestAddr.Port)))
h.WriteToken(jsontext.String("src_cid"))
h.WriteToken(jsontext.String(e.SrcConnectionID.String()))
h.WriteToken(jsontext.String("dst_cid"))
h.WriteToken(jsontext.String(e.DestConnectionID.String()))
h.WriteToken(jsontext.EndObject)
return h.err
}

View File

@@ -3,7 +3,6 @@ package qlog
import (
"bytes"
"encoding/json"
"net"
"net/netip"
"testing"
"time"
@@ -58,21 +57,28 @@ func decode(t *testing.T, data string) (string, map[string]any) {
}
func TestStartedConnection(t *testing.T) {
var localInfo, remoteInfo PathEndpointInfo
localInfo.IPv4 = netip.AddrPortFrom(netip.AddrFrom4([4]byte{192, 168, 13, 37}), 42)
ip, err := netip.ParseAddr("2001:db8::1")
require.NoError(t, err)
remoteInfo.IPv6 = netip.AddrPortFrom(ip, 24)
name, ev := testEventEncoding(t, &StartedConnection{
SrcAddr: &net.UDPAddr{IP: net.IPv4(192, 168, 13, 37), Port: 42},
DestAddr: &net.UDPAddr{IP: net.IPv4(192, 168, 12, 34), Port: 24},
SrcConnectionID: protocol.ParseConnectionID([]byte{1, 2, 3, 4}),
DestConnectionID: protocol.ParseConnectionID([]byte{5, 6, 7, 8}),
Local: localInfo,
Remote: remoteInfo,
})
require.Equal(t, "transport:connection_started", name)
require.Equal(t, "ipv4", ev["ip_version"])
require.Equal(t, "192.168.13.37", ev["src_ip"])
require.Equal(t, float64(42), ev["src_port"])
require.Equal(t, "192.168.12.34", ev["dst_ip"])
require.Equal(t, float64(24), ev["dst_port"])
require.Equal(t, "01020304", ev["src_cid"])
require.Equal(t, "05060708", ev["dst_cid"])
local, ok := ev["local"].(map[string]any)
require.True(t, ok)
require.Equal(t, "192.168.13.37", local["ip_v4"])
require.Equal(t, float64(42), local["port_v4"])
remote, ok := ev["remote"].(map[string]any)
require.True(t, ok)
require.Equal(t, "2001:db8::1", remote["ip_v6"])
require.Equal(t, float64(24), remote["port_v6"])
}
func TestVersionInformation(t *testing.T) {