Skip to content

Commit

Permalink
Merge pull request #1828 from libp2p/webtransport-qlogging
Browse files Browse the repository at this point in the history
webtransport: make it possible to record qlogs (controlled by QLOGDIR env)
  • Loading branch information
marten-seemann authored Oct 14, 2022
2 parents a401276 + 28ca6e5 commit 828486e
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 43 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package libp2pquic
package quicutils

import (
"bufio"
Expand All @@ -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)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package libp2pquic
package quicutils

import (
"bytes"
Expand Down
3 changes: 2 additions & 1 deletion p2p/transport/quic/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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 {
Expand Down
40 changes: 16 additions & 24 deletions p2p/transport/webtransport/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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 },
},
}
Expand Down Expand Up @@ -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)
Expand All @@ -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()
Expand Down Expand Up @@ -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}),
))
Expand All @@ -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 {
Expand Down
36 changes: 23 additions & 13 deletions p2p/transport/webtransport/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand All @@ -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 {
Expand All @@ -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
}

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit 828486e

Please sign in to comment.