Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

webtransport: make it possible to record qlogs (controlled by QLOGDIR env) #1828

Merged
merged 4 commits into from
Oct 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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