diff --git a/p2p/transport/quic/tracer.go b/p2p/transport/internal/quicutils/tracer.go similarity index 90% rename from p2p/transport/quic/tracer.go rename to p2p/transport/internal/quicutils/tracer.go index 50f429dcad..272b1be290 100644 --- a/p2p/transport/quic/tracer.go +++ b/p2p/transport/internal/quicutils/tracer.go @@ -1,4 +1,4 @@ -package libp2pquic +package quicutils import ( "bufio" @@ -7,17 +7,21 @@ import ( "os" "time" + golog "github.com/ipfs/go-log/v2" "github.com/klauspost/compress/zstd" - "github.com/lucas-clemente/quic-go/logging" "github.com/lucas-clemente/quic-go/qlog" ) -var qlogTracer logging.Tracer +var log = golog.Logger("quic-utils") + +// QLOGTracer holds a qlog tracer, if qlogging is enabled (enabled using the QLOGDIR environment variable). +// Otherwise it is nil. +var QLOGTracer logging.Tracer func init() { if qlogDir := os.Getenv("QLOGDIR"); len(qlogDir) > 0 { - qlogTracer = initQlogger(qlogDir) + QLOGTracer = initQlogger(qlogDir) } } diff --git a/p2p/transport/quic/tracer_test.go b/p2p/transport/internal/quicutils/tracer_test.go similarity index 99% rename from p2p/transport/quic/tracer_test.go rename to p2p/transport/internal/quicutils/tracer_test.go index c651032d09..0d095d342d 100644 --- a/p2p/transport/quic/tracer_test.go +++ b/p2p/transport/internal/quicutils/tracer_test.go @@ -1,4 +1,4 @@ -package libp2pquic +package quicutils import ( "bytes" diff --git a/p2p/transport/quic/transport.go b/p2p/transport/quic/transport.go index 0b908db43a..4a70d80783 100644 --- a/p2p/transport/quic/transport.go +++ b/p2p/transport/quic/transport.go @@ -19,6 +19,7 @@ import ( "github.com/libp2p/go-libp2p/core/pnet" tpt "github.com/libp2p/go-libp2p/core/transport" p2ptls "github.com/libp2p/go-libp2p/p2p/security/tls" + "github.com/libp2p/go-libp2p/p2p/transport/internal/quicutils" ma "github.com/multiformats/go-multiaddr" mafmt "github.com/multiformats/go-multiaddr-fmt" @@ -201,7 +202,7 @@ func NewTransport(key ic.PrivKey, psk pnet.PSK, gater connmgr.ConnectionGater, r return nil, err } var tracers []quiclogging.Tracer - if qlogTracer != nil { + if qlogTracer := quicutils.QLOGTracer; qlogTracer != nil { tracers = append(tracers, qlogTracer) } if cfg.metrics { diff --git a/p2p/transport/webtransport/listener.go b/p2p/transport/webtransport/listener.go index 317afbe41d..15905a95a6 100644 --- a/p2p/transport/webtransport/listener.go +++ b/p2p/transport/webtransport/listener.go @@ -9,12 +9,10 @@ import ( "net/http" "time" - "github.com/libp2p/go-libp2p/p2p/security/noise/pb" - - "github.com/libp2p/go-libp2p/core/connmgr" "github.com/libp2p/go-libp2p/core/network" tpt "github.com/libp2p/go-libp2p/core/transport" "github.com/libp2p/go-libp2p/p2p/security/noise" + "github.com/libp2p/go-libp2p/p2p/security/noise/pb" "github.com/lucas-clemente/quic-go/http3" "github.com/marten-seemann/webtransport-go" @@ -28,15 +26,10 @@ const queueLen = 16 const handshakeTimeout = 10 * time.Second type listener struct { - transport tpt.Transport - noise *noise.Transport - certManager *certManager + transport *transport tlsConf *tls.Config isStaticTLSConf bool - rcmgr network.ResourceManager - gater connmgr.ConnectionGater - server webtransport.Server ctx context.Context @@ -52,7 +45,7 @@ type listener struct { var _ tpt.Listener = &listener{} -func newListener(laddr ma.Multiaddr, transport tpt.Transport, noise *noise.Transport, certManager *certManager, tlsConf *tls.Config, gater connmgr.ConnectionGater, rcmgr network.ResourceManager) (tpt.Listener, error) { +func newListener(laddr ma.Multiaddr, t *transport, tlsConf *tls.Config) (tpt.Listener, error) { network, addr, err := manet.DialArgs(laddr) if err != nil { return nil, err @@ -72,23 +65,22 @@ func newListener(laddr ma.Multiaddr, transport tpt.Transport, noise *noise.Trans isStaticTLSConf := tlsConf != nil if tlsConf == nil { tlsConf = &tls.Config{GetConfigForClient: func(*tls.ClientHelloInfo) (*tls.Config, error) { - return certManager.GetConfig(), nil + return t.certManager.GetConfig(), nil }} } ln := &listener{ - transport: transport, - noise: noise, - certManager: certManager, + transport: t, tlsConf: tlsConf, isStaticTLSConf: isStaticTLSConf, - rcmgr: rcmgr, - gater: gater, queue: make(chan tpt.CapableConn, queueLen), serverClosed: make(chan struct{}), addr: udpConn.LocalAddr(), multiaddr: localMultiaddr, server: webtransport.Server{ - H3: http3.Server{TLSConfig: tlsConf}, + H3: http3.Server{ + QuicConfig: t.quicConfig, + TLSConfig: tlsConf, + }, CheckOrigin: func(r *http.Request) bool { return true }, }, } @@ -120,12 +112,12 @@ func (l *listener) httpHandler(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusBadRequest) return } - if l.gater != nil && !l.gater.InterceptAccept(&connMultiaddrs{local: l.multiaddr, remote: remoteMultiaddr}) { + if l.transport.gater != nil && !l.transport.gater.InterceptAccept(&connMultiaddrs{local: l.multiaddr, remote: remoteMultiaddr}) { w.WriteHeader(http.StatusForbidden) return } - connScope, err := l.rcmgr.OpenConnection(network.DirInbound, false, remoteMultiaddr) + connScope, err := l.transport.rcmgr.OpenConnection(network.DirInbound, false, remoteMultiaddr) if err != nil { log.Debugw("resource manager blocked incoming connection", "addr", r.RemoteAddr, "error", err) w.WriteHeader(http.StatusServiceUnavailable) @@ -151,7 +143,7 @@ func (l *listener) httpHandler(w http.ResponseWriter, r *http.Request) { } cancel() - if l.gater != nil && !l.gater.InterceptSecured(network.DirInbound, sconn.RemotePeer(), sconn) { + if l.transport.gater != nil && !l.transport.gater.InterceptSecured(network.DirInbound, sconn.RemotePeer(), sconn) { // TODO: can we close with a specific error here? sess.Close() connScope.Done() @@ -199,10 +191,10 @@ func (l *listener) handshake(ctx context.Context, sess *webtransport.Session) (* } var earlyData [][]byte if !l.isStaticTLSConf { - earlyData = l.certManager.SerializedCertHashes() + earlyData = l.transport.certManager.SerializedCertHashes() } - n, err := l.noise.WithSessionOptions(noise.EarlyData( + n, err := l.transport.noise.WithSessionOptions(noise.EarlyData( nil, newEarlyDataSender(&pb.NoiseExtensions{WebtransportCerthashes: earlyData}), )) @@ -225,10 +217,10 @@ func (l *listener) Addr() net.Addr { } func (l *listener) Multiaddr() ma.Multiaddr { - if l.certManager == nil { + if l.transport.certManager == nil { return l.multiaddr } - return l.multiaddr.Encapsulate(l.certManager.AddrComponent()) + return l.multiaddr.Encapsulate(l.transport.certManager.AddrComponent()) } func (l *listener) Close() error { diff --git a/p2p/transport/webtransport/transport.go b/p2p/transport/webtransport/transport.go index 5cd3a88170..a65f723458 100644 --- a/p2p/transport/webtransport/transport.go +++ b/p2p/transport/webtransport/transport.go @@ -11,16 +11,18 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p/p2p/security/noise/pb" - - "github.com/benbjohnson/clock" - logging "github.com/ipfs/go-log/v2" "github.com/libp2p/go-libp2p/core/connmgr" ic "github.com/libp2p/go-libp2p/core/crypto" "github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-libp2p/core/peer" tpt "github.com/libp2p/go-libp2p/core/transport" "github.com/libp2p/go-libp2p/p2p/security/noise" + "github.com/libp2p/go-libp2p/p2p/security/noise/pb" + "github.com/libp2p/go-libp2p/p2p/transport/internal/quicutils" + + "github.com/benbjohnson/clock" + logging "github.com/ipfs/go-log/v2" + "github.com/lucas-clemente/quic-go" "github.com/lucas-clemente/quic-go/http3" "github.com/marten-seemann/webtransport-go" ma "github.com/multiformats/go-multiaddr" @@ -69,8 +71,9 @@ type transport struct { pid peer.ID clock clock.Clock - rcmgr network.ResourceManager - gater connmgr.ConnectionGater + quicConfig *quic.Config + rcmgr network.ResourceManager + gater connmgr.ConnectionGater listenOnce sync.Once listenOnceErr error @@ -91,11 +94,12 @@ func New(key ic.PrivKey, gater connmgr.ConnectionGater, rcmgr network.ResourceMa return nil, err } t := &transport{ - pid: id, - privKey: key, - rcmgr: rcmgr, - gater: gater, - clock: clock.New(), + pid: id, + privKey: key, + rcmgr: rcmgr, + gater: gater, + clock: clock.New(), + quicConfig: &quic.Config{}, } for _, opt := range opts { if err := opt(t); err != nil { @@ -107,6 +111,9 @@ func New(key ic.PrivKey, gater connmgr.ConnectionGater, rcmgr network.ResourceMa return nil, err } t.noise = n + if qlogTracer := quicutils.QLOGTracer; qlogTracer != nil { + t.quicConfig.Tracer = qlogTracer + } return t, nil } @@ -176,7 +183,10 @@ func (t *transport) dial(ctx context.Context, addr string, sni string, certHashe } } dialer := webtransport.Dialer{ - RoundTripper: &http3.RoundTripper{TLSClientConfig: tlsConf}, + RoundTripper: &http3.RoundTripper{ + TLSClientConfig: tlsConf, + QuicConfig: t.quicConfig, + }, } rsp, sess, err := dialer.Dial(ctx, url, nil) if err != nil { @@ -284,7 +294,7 @@ func (t *transport) Listen(laddr ma.Multiaddr) (tpt.Listener, error) { return nil, t.listenOnceErr } } - return newListener(laddr, t, t.noise, t.certManager, t.staticTLSConf, t.gater, t.rcmgr) + return newListener(laddr, t, t.staticTLSConf) } func (t *transport) Protocols() []int {