quic: upgrade quic-go to v0.53 (#3323)

This commit is contained in:
sukun
2025-07-02 23:24:16 +02:00
committed by GitHub
parent 000582cf2c
commit 7b7c3ed4ce
16 changed files with 147 additions and 158 deletions

8
go.mod
View File

@@ -53,8 +53,8 @@ require (
github.com/pion/webrtc/v4 v4.1.2
github.com/prometheus/client_golang v1.22.0
github.com/prometheus/client_model v0.6.2
github.com/quic-go/quic-go v0.52.0
github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66
github.com/quic-go/quic-go v0.53.0
github.com/quic-go/webtransport-go v0.9.0
github.com/stretchr/testify v1.10.0
go.uber.org/fx v1.24.0
go.uber.org/goleak v1.3.0
@@ -73,8 +73,6 @@ require (
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/francoispqt/gojay v1.2.13 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
@@ -83,7 +81,6 @@ require (
github.com/minio/sha256-simd v1.0.1 // indirect
github.com/multiformats/go-base36 v0.2.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/onsi/ginkgo/v2 v2.23.4 // indirect
github.com/pion/dtls/v2 v2.2.12 // indirect
github.com/pion/dtls/v3 v3.0.6 // indirect
github.com/pion/interceptor v0.1.40 // indirect
@@ -103,7 +100,6 @@ require (
github.com/quic-go/qpack v0.5.1 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/wlynxg/anet v0.0.5 // indirect
go.uber.org/automaxprocs v1.6.0 // indirect
go.uber.org/dig v1.19.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476 // indirect

22
go.sum
View File

@@ -39,10 +39,6 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
@@ -60,8 +56,6 @@ github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a h1://KbezygeMJZCSHH+HgUZiTeSoiuFspbMg1ge+eFj18=
github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
@@ -178,10 +172,6 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=
github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=
github.com/onsi/gomega v1.36.3 h1:hID7cr8t3Wp26+cYnfcjR6HpJ00fdogN6dqZ1t6IylU=
github.com/onsi/gomega v1.36.3/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0=
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y=
@@ -230,8 +220,6 @@ github.com/pion/webrtc/v4 v4.1.2/go.mod h1:xsCXiNAmMEjIdFxAYU0MbB3RwRieJsegSB2JZ
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
@@ -246,10 +234,10 @@ github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzM
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
github.com/quic-go/quic-go v0.52.0 h1:/SlHrCRElyaU6MaEPKqKr9z83sBg2v4FLLvWM+Z47pA=
github.com/quic-go/quic-go v0.52.0/go.mod h1:MFlGGpcpJqRAfmYi6NC2cptDPSxRWTOGNuP4wqrWmzQ=
github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 h1:4WFk6u3sOT6pLa1kQ50ZVdm8BQFgJNA117cepZxtLIg=
github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66/go.mod h1:Vp72IJajgeOL6ddqrAhmp7IM9zbTcgkQxD/YdxrVwMw=
github.com/quic-go/quic-go v0.53.0 h1:QHX46sISpG2S03dPeZBgVIZp8dGagIaiu2FiVYvpCZI=
github.com/quic-go/quic-go v0.53.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY=
github.com/quic-go/webtransport-go v0.9.0 h1:jgys+7/wm6JarGDrW+lD/r9BGqBAmqY/ssklE09bA70=
github.com/quic-go/webtransport-go v0.9.0/go.mod h1:4FUYIiUc75XSsF6HShcLeXXYZJ9AGwo/xh3L8M/P1ao=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
@@ -298,8 +286,6 @@ github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU=
github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
go.uber.org/dig v1.19.0 h1:BACLhebsYdpQ7IROQ1AGPjrXcP5dF80U3gKoFzbaq/4=
go.uber.org/dig v1.19.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE=
go.uber.org/fx v1.24.0 h1:wE8mruvpg2kiiL1Vqd0CC+tr0/24XIB10Iwp2lLWzkg=

View File

@@ -13,7 +13,7 @@ import (
)
type conn struct {
quicConn quic.Connection
quicConn *quic.Conn
transport *transport
scope network.ConnManagementScope

View File

@@ -83,7 +83,7 @@ func (l *listener) Accept() (tpt.CapableConn, error) {
// wrapConn wraps a QUIC connection into a libp2p [tpt.CapableConn].
// If wrapping fails. The caller is responsible for cleaning up the
// connection.
func (l *listener) wrapConn(qconn quic.Connection) (*conn, error) {
func (l *listener) wrapConn(qconn *quic.Conn) (*conn, error) {
remoteMultiaddr, err := quicreuse.ToQuicMultiaddr(qconn.RemoteAddr(), qconn.ConnectionState().Version)
if err != nil {
return nil, err
@@ -112,7 +112,7 @@ func (l *listener) wrapConn(qconn quic.Connection) (*conn, error) {
return c, nil
}
func (l *listener) wrapConnWithScope(qconn quic.Connection, connScope network.ConnManagementScope, remoteMultiaddr ma.Multiaddr) (*conn, error) {
func (l *listener) wrapConnWithScope(qconn *quic.Conn, connScope network.ConnManagementScope, remoteMultiaddr ma.Multiaddr) (*conn, error) {
// The tls.Config used to establish this connection already verified the certificate chain.
// Since we don't have any way of knowing which tls.Config was used though,
// we have to re-determine the peer's identity here.

View File

@@ -14,10 +14,10 @@ const (
)
type stream struct {
quic.Stream
*quic.Stream
}
var _ network.MuxedStream = &stream{}
var _ network.MuxedStream = stream{}
func parseStreamError(err error) error {
if err == nil {
@@ -54,38 +54,38 @@ func parseStreamError(err error) error {
return err
}
func (s *stream) Read(b []byte) (n int, err error) {
func (s stream) Read(b []byte) (n int, err error) {
n, err = s.Stream.Read(b)
return n, parseStreamError(err)
}
func (s *stream) Write(b []byte) (n int, err error) {
func (s stream) Write(b []byte) (n int, err error) {
n, err = s.Stream.Write(b)
return n, parseStreamError(err)
}
func (s *stream) Reset() error {
func (s stream) Reset() error {
s.Stream.CancelRead(reset)
s.Stream.CancelWrite(reset)
return nil
}
func (s *stream) ResetWithError(errCode network.StreamErrorCode) error {
func (s stream) ResetWithError(errCode network.StreamErrorCode) error {
s.Stream.CancelRead(quic.StreamErrorCode(errCode))
s.Stream.CancelWrite(quic.StreamErrorCode(errCode))
return nil
}
func (s *stream) Close() error {
func (s stream) Close() error {
s.Stream.CancelRead(reset)
return s.Stream.Close()
}
func (s *stream) CloseRead() error {
func (s stream) CloseRead() error {
s.Stream.CancelRead(reset)
return nil
}
func (s *stream) CloseWrite() error {
func (s stream) CloseWrite() error {
return s.Stream.Close()
}

View File

@@ -50,7 +50,7 @@ type transport struct {
rnd rand.Rand
connMx sync.Mutex
conns map[quic.Connection]*conn
conns map[*quic.Conn]*conn
listenersMu sync.Mutex
// map of UDPAddr as string to a virtualListeners
@@ -95,7 +95,7 @@ func NewTransport(key ic.PrivKey, connManager *quicreuse.ConnManager, psk pnet.P
connManager: connManager,
gater: gater,
rcmgr: rcmgr,
conns: make(map[quic.Connection]*conn),
conns: make(map[*quic.Conn]*conn),
holePunching: make(map[holePunchKey]*activeHolePunch),
rnd: *rand.New(rand.NewSource(time.Now().UnixNano())),
@@ -174,13 +174,13 @@ func (t *transport) dialWithScope(ctx context.Context, raddr ma.Multiaddr, p pee
return c, nil
}
func (t *transport) addConn(conn quic.Connection, c *conn) {
func (t *transport) addConn(conn *quic.Conn, c *conn) {
t.connMx.Lock()
t.conns[conn] = c
t.connMx.Unlock()
}
func (t *transport) removeConn(conn quic.Connection) {
func (t *transport) removeConn(conn *quic.Conn) {
t.connMx.Lock()
delete(t.conns, conn)
t.connMx.Unlock()
@@ -344,7 +344,7 @@ func (t *transport) Listen(addr ma.Multiaddr) (tpt.Listener, error) {
return l, nil
}
func (t *transport) allowWindowIncrease(conn quic.Connection, size uint64) bool {
func (t *transport) allowWindowIncrease(conn *quic.Conn, size uint64) bool {
// If the QUIC connection tries to increase the window before we've inserted it
// into our connections map (which we do right after dialing / accepting it),
// we have no way to account for that memory. This should be very rare.

View File

@@ -24,7 +24,7 @@ import (
)
type QUICListener interface {
Accept(ctx context.Context) (quic.Connection, error)
Accept(ctx context.Context) (*quic.Conn, error)
Close() error
Addr() net.Addr
}
@@ -33,7 +33,7 @@ var _ QUICListener = &quic.Listener{}
type QUICTransport interface {
Listen(tlsConf *tls.Config, conf *quic.Config) (QUICListener, error)
Dial(ctx context.Context, addr net.Addr, tlsConf *tls.Config, conf *quic.Config) (quic.Connection, error)
Dial(ctx context.Context, addr net.Addr, tlsConf *tls.Config, conf *quic.Config) (*quic.Conn, error)
WriteTo(b []byte, addr net.Addr) (int, error)
ReadNonQUICPacket(ctx context.Context, b []byte) (int, net.Addr, error)
io.Closer
@@ -198,7 +198,7 @@ func (c *ConnManager) LendTransport(network string, tr QUICTransport, conn net.P
// ListenQUIC listens for quic connections with the provided `tlsConf.NextProtos` ALPNs on `addr`. The same addr can be shared between
// different ALPNs.
func (c *ConnManager) ListenQUIC(addr ma.Multiaddr, tlsConf *tls.Config, allowWindowIncrease func(conn quic.Connection, delta uint64) bool) (Listener, error) {
func (c *ConnManager) ListenQUIC(addr ma.Multiaddr, tlsConf *tls.Config, allowWindowIncrease func(conn *quic.Conn, delta uint64) bool) (Listener, error) {
return c.ListenQUICAndAssociate(nil, addr, tlsConf, allowWindowIncrease)
}
@@ -208,7 +208,7 @@ func (c *ConnManager) ListenQUIC(addr ma.Multiaddr, tlsConf *tls.Config, allowWi
// or `DialQUIC` calls with the same `association` will reuse the QUIC Transport used by this method.
// A common use of associations is to ensure /quic dials use the quic listening address and /webtransport dials use the
// WebTransport listening address.
func (c *ConnManager) ListenQUICAndAssociate(association any, addr ma.Multiaddr, tlsConf *tls.Config, allowWindowIncrease func(conn quic.Connection, delta uint64) bool) (Listener, error) {
func (c *ConnManager) ListenQUICAndAssociate(association any, addr ma.Multiaddr, tlsConf *tls.Config, allowWindowIncrease func(conn *quic.Conn, delta uint64) bool) (Listener, error) {
netw, host, err := manet.DialArgs(addr)
if err != nil {
return nil, err
@@ -332,7 +332,7 @@ func WithAssociation(ctx context.Context, association any) context.Context {
// - Any other listening transport
// - Any transport previously used for dialing
// If none of these are available, it'll create a new transport.
func (c *ConnManager) DialQUIC(ctx context.Context, raddr ma.Multiaddr, tlsConf *tls.Config, allowWindowIncrease func(conn quic.Connection, delta uint64) bool) (quic.Connection, error) {
func (c *ConnManager) DialQUIC(ctx context.Context, raddr ma.Multiaddr, tlsConf *tls.Config, allowWindowIncrease func(conn *quic.Conn, delta uint64) bool) (*quic.Conn, error) {
naddr, v, err := FromQuicMultiaddr(raddr)
if err != nil {
return nil, err

View File

@@ -295,7 +295,7 @@ func TestExternalTransport(t *testing.T) {
"quic",
ma.StringCast(fmt.Sprintf("/ip4/0.0.0.0/udp/%d", port)),
&tls.Config{NextProtos: []string{"libp2p"}},
func(quic.Connection, uint64) bool { return false },
func(*quic.Conn, uint64) bool { return false },
)
require.NoError(t, err)
defer ln.Close()
@@ -316,7 +316,7 @@ func TestExternalTransport(t *testing.T) {
ctx,
ma.StringCast(fmt.Sprintf("/ip4/127.0.0.1/udp/%d/quic-v1", udpLn.LocalAddr().(*net.UDPAddr).Port)),
&tls.Config{NextProtos: []string{"libp2p"}},
func(quic.Connection, uint64) bool { return false },
func(*quic.Conn, uint64) bool { return false },
)
require.ErrorIs(t, err, context.DeadlineExceeded)

View File

@@ -17,7 +17,7 @@ import (
)
type Listener interface {
Accept(context.Context) (quic.Connection, error)
Accept(context.Context) (*quic.Conn, error)
Addr() net.Addr
Multiaddrs() []ma.Multiaddr
io.Closer
@@ -26,7 +26,7 @@ type Listener interface {
type protoConf struct {
ln *listener
tlsConf *tls.Config
allowWindowIncrease func(conn quic.Connection, delta uint64) bool
allowWindowIncrease func(conn *quic.Conn, delta uint64) bool
}
type quicListener struct {
@@ -80,7 +80,7 @@ func newQuicListener(tr RefCountedQUICTransport, quicConfig *quic.Config) (*quic
return cl, nil
}
func (l *quicListener) allowWindowIncrease(conn quic.Connection, delta uint64) bool {
func (l *quicListener) allowWindowIncrease(conn *quic.Conn, delta uint64) bool {
l.protocolsMu.Lock()
defer l.protocolsMu.Unlock()
@@ -91,7 +91,7 @@ func (l *quicListener) allowWindowIncrease(conn quic.Connection, delta uint64) b
return conf.allowWindowIncrease(conn, delta)
}
func (l *quicListener) Add(tlsConf *tls.Config, allowWindowIncrease func(conn quic.Connection, delta uint64) bool, onRemove func()) (Listener, error) {
func (l *quicListener) Add(tlsConf *tls.Config, allowWindowIncrease func(conn *quic.Conn, delta uint64) bool, onRemove func()) (Listener, error) {
l.protocolsMu.Lock()
defer l.protocolsMu.Unlock()
@@ -157,7 +157,7 @@ const queueLen = 16
// A listener for a single ALPN protocol (set).
type listener struct {
queue chan quic.Connection
queue chan *quic.Conn
acceptLoopRunning chan struct{}
addr net.Addr
addrs []ma.Multiaddr
@@ -169,7 +169,7 @@ var _ Listener = &listener{}
func newSingleListener(addr net.Addr, addrs []ma.Multiaddr, remove func(), running chan struct{}) *listener {
return &listener{
queue: make(chan quic.Connection, queueLen),
queue: make(chan *quic.Conn, queueLen),
acceptLoopRunning: running,
remove: remove,
addr: addr,
@@ -177,7 +177,7 @@ func newSingleListener(addr net.Addr, addrs []ma.Multiaddr, remove func(), runni
}
}
func (l *listener) add(c quic.Connection) {
func (l *listener) add(c *quic.Conn) {
select {
case l.queue <- c:
default:
@@ -185,7 +185,7 @@ func (l *listener) add(c quic.Connection) {
}
}
func (l *listener) Accept(ctx context.Context) (quic.Connection, error) {
func (l *listener) Accept(ctx context.Context) (*quic.Conn, error) {
select {
case <-ctx.Done():
return nil, ctx.Err()

View File

@@ -25,7 +25,7 @@ type RefCountedQUICTransport interface {
DecreaseCount()
IncreaseCount()
Dial(ctx context.Context, addr net.Addr, tlsConf *tls.Config, conf *quic.Config) (quic.Connection, error)
Dial(ctx context.Context, addr net.Addr, tlsConf *tls.Config, conf *quic.Config) (*quic.Conn, error)
Listen(tlsConf *tls.Config, conf *quic.Config) (QUICListener, error)
}
@@ -45,7 +45,7 @@ func (c *singleOwnerTransport) LocalAddr() net.Addr {
return c.packetConn.LocalAddr()
}
func (c *singleOwnerTransport) Dial(ctx context.Context, addr net.Addr, tlsConf *tls.Config, conf *quic.Config) (quic.Connection, error) {
func (c *singleOwnerTransport) Dial(ctx context.Context, addr net.Addr, tlsConf *tls.Config, conf *quic.Config) (*quic.Conn, error) {
return c.Transport.Dial(ctx, addr, tlsConf, conf)
}

View File

@@ -32,12 +32,12 @@ type conn struct {
session *webtransport.Session
scope network.ConnManagementScope
qconn quic.Connection
qconn *quic.Conn
}
var _ tpt.CapableConn = &conn{}
func newConn(tr *transport, sess *webtransport.Session, sconn *connSecurityMultiaddrs, scope network.ConnManagementScope, qconn quic.Connection) *conn {
func newConn(tr *transport, sess *webtransport.Session, sconn *connSecurityMultiaddrs, scope network.ConnManagementScope, qconn *quic.Conn) *conn {
return &conn{
connSecurityMultiaddrs: sconn,
transport: tr,

View File

@@ -6,6 +6,7 @@ import (
"fmt"
"net"
"net/http"
"sync"
"time"
"github.com/libp2p/go-libp2p/core/network"
@@ -25,51 +26,6 @@ const handshakeTimeout = 10 * time.Second
type connKey struct{}
// negotiatingConn is a wrapper around a quic.Connection that lets us wrap it in
// our own context for the duration of the upgrade process. Upgrading a quic
// connection to an h3 connection to a webtransport session.
type negotiatingConn struct {
quic.Connection
ctx context.Context
cancel context.CancelFunc
// stopClose is a function that stops the connection from being closed when
// the context is done. Returns true if the connection close function was
// not called.
stopClose func() bool
err error
}
func (c *negotiatingConn) Unwrap() (quic.Connection, error) {
defer c.cancel()
if c.stopClose != nil {
// unwrap the first time
if !c.stopClose() {
c.err = errTimeout
}
c.stopClose = nil
}
if c.err != nil {
return nil, c.err
}
return c.Connection, nil
}
func wrapConn(ctx context.Context, c quic.Connection, handshakeTimeout time.Duration) *negotiatingConn {
ctx, cancel := context.WithTimeout(ctx, handshakeTimeout)
stopClose := context.AfterFunc(ctx, func() {
log.Debugf("failed to handshake on conn: %s", c.RemoteAddr())
c.CloseWithError(1, "")
})
return &negotiatingConn{
Connection: c,
ctx: ctx,
cancel: cancel,
stopClose: stopClose,
}
}
var errTimeout = errors.New("timeout")
type listener struct {
transport *transport
isStaticTLSConf bool
@@ -86,6 +42,9 @@ type listener struct {
multiaddr ma.Multiaddr
queue chan tpt.CapableConn
mx sync.Mutex
pendingConns map[*quic.Conn]*negotiatingConn
}
var _ tpt.Listener = &listener{}
@@ -106,12 +65,13 @@ func newListener(reuseListener quicreuse.Listener, t *transport, isStaticTLSConf
multiaddr: localMultiaddr,
server: webtransport.Server{
H3: http3.Server{
ConnContext: func(ctx context.Context, c quic.Connection) context.Context {
ConnContext: func(ctx context.Context, c *quic.Conn) context.Context {
return context.WithValue(ctx, connKey{}, c)
},
},
CheckOrigin: func(_ *http.Request) bool { return true },
},
pendingConns: make(map[*quic.Conn]*negotiatingConn),
}
ln.ctx, ln.ctxCancel = context.WithCancel(context.Background())
mux := http.NewServeMux()
@@ -125,13 +85,71 @@ func newListener(reuseListener quicreuse.Listener, t *transport, isStaticTLSConf
log.Debugw("serving failed", "addr", ln.Addr(), "error", err)
return
}
wrapped := wrapConn(ln.ctx, conn, t.handshakeTimeout)
go ln.server.ServeQUICConn(wrapped)
err = ln.startHandshake(conn)
if err != nil {
log.Debugf("failed to start handshake: %s", err)
continue
}
go ln.server.ServeQUICConn(conn)
}
}()
return ln, nil
}
func (l *listener) startHandshake(conn *quic.Conn) error {
ctx, cancel := context.WithTimeout(l.ctx, handshakeTimeout)
stopHandshakeTimeout := context.AfterFunc(ctx, func() {
log.Debugf("failed to handshake on conn: %s", conn.RemoteAddr())
conn.CloseWithError(1, "")
l.mx.Lock()
delete(l.pendingConns, conn)
l.mx.Unlock()
})
l.mx.Lock()
defer l.mx.Unlock()
// don't add to map if the context is already cancelled
if ctx.Err() != nil {
cancel()
return ctx.Err()
}
l.pendingConns[conn] = &negotiatingConn{
Conn: conn,
ctx: ctx,
cancel: cancel,
stopHandshakeTimeout: stopHandshakeTimeout,
}
return nil
}
// negotiatingConn is a wrapper around a *quic.Conn that lets us wrap it in
// our own context for the duration of the upgrade process. Upgrading a quic
// connection to an h3 connection to a webtransport session.
type negotiatingConn struct {
*quic.Conn
ctx context.Context
cancel context.CancelFunc
// stopHandshakeTimeout is a function that stops triggering the handshake timeout. Returns true if the handshake timeout was not triggered.
stopHandshakeTimeout func() bool
err error
}
func (c *negotiatingConn) StopHandshakeTimeout() error {
defer c.cancel()
if c.stopHandshakeTimeout != nil {
// cancel the handshake timeout function
if !c.stopHandshakeTimeout() {
c.err = errTimeout
}
c.stopHandshakeTimeout = nil
}
if c.err != nil {
return c.err
}
return nil
}
var errTimeout = errors.New("timeout")
func (l *listener) httpHandler(w http.ResponseWriter, r *http.Request) {
typ, ok := r.URL.Query()["type"]
if !ok || len(typ) != 1 || typ[0] != "noise" {
@@ -207,14 +225,18 @@ func (l *listener) httpHandlerWithConnScope(w http.ResponseWriter, r *http.Reque
sess.CloseWithError(1, "")
return errors.New("invalid context")
}
nconn, ok := connVal.(*negotiatingConn)
qconn := connVal.(*quic.Conn)
l.mx.Lock()
nconn, ok := l.pendingConns[qconn]
delete(l.pendingConns, qconn)
l.mx.Unlock()
if !ok {
log.Errorf("unexpected connection in context. invalid conn type: %T", nconn)
log.Debugf("handshake timed out: %s", r.RemoteAddr)
sess.CloseWithError(1, "")
return errors.New("invalid context")
return errTimeout
}
qconn, err := nconn.Unwrap()
if err != nil {
if err := nconn.StopHandshakeTimeout(); err != nil {
log.Debugf("handshake timed out: %s", r.RemoteAddr)
sess.CloseWithError(1, "")
return err
@@ -268,7 +290,7 @@ func (l *listener) handshake(ctx context.Context, sess *webtransport.Session) (*
if err != nil {
return nil, fmt.Errorf("failed to initialize Noise session: %w", err)
}
c, err := n.SecureInbound(ctx, &webtransportStream{Stream: str, wsess: sess}, "")
c, err := n.SecureInbound(ctx, webtransportStream{Stream: str, wsess: sess}, "")
if err != nil {
return nil, err
}

View File

@@ -14,27 +14,27 @@ const (
)
type webtransportStream struct {
webtransport.Stream
*webtransport.Stream
wsess *webtransport.Session
}
var _ net.Conn = &webtransportStream{}
var _ net.Conn = webtransportStream{}
func (s *webtransportStream) LocalAddr() net.Addr {
func (s webtransportStream) LocalAddr() net.Addr {
return s.wsess.LocalAddr()
}
func (s *webtransportStream) RemoteAddr() net.Addr {
func (s webtransportStream) RemoteAddr() net.Addr {
return s.wsess.RemoteAddr()
}
type stream struct {
webtransport.Stream
*webtransport.Stream
}
var _ network.MuxedStream = &stream{}
var _ network.MuxedStream = stream{}
func (s *stream) Read(b []byte) (n int, err error) {
func (s stream) Read(b []byte) (n int, err error) {
n, err = s.Stream.Read(b)
if err != nil {
var streamErr *webtransport.StreamError
@@ -49,7 +49,7 @@ func (s *stream) Read(b []byte) (n int, err error) {
return n, err
}
func (s *stream) Write(b []byte) (n int, err error) {
func (s stream) Write(b []byte) (n int, err error) {
n, err = s.Stream.Write(b)
if err != nil {
var streamErr *webtransport.StreamError
@@ -64,7 +64,7 @@ func (s *stream) Write(b []byte) (n int, err error) {
return n, err
}
func (s *stream) Reset() error {
func (s stream) Reset() error {
s.Stream.CancelRead(reset)
s.Stream.CancelWrite(reset)
return nil
@@ -75,22 +75,22 @@ func (s *stream) Reset() error {
// browsers(https://www.ietf.org/archive/id/draft-kinnear-webtransport-http2-02.html)
// only supports 1 byte error codes. For more details, see
// https://github.com/libp2p/specs/blob/4eca305185c7aef219e936bef76c48b1ab0a8b43/error-codes/README.md?plain=1#L84
func (s *stream) ResetWithError(_ network.StreamErrorCode) error {
func (s stream) ResetWithError(_ network.StreamErrorCode) error {
s.Stream.CancelRead(reset)
s.Stream.CancelWrite(reset)
return nil
}
func (s *stream) Close() error {
func (s stream) Close() error {
s.Stream.CancelRead(reset)
return s.Stream.Close()
}
func (s *stream) CloseRead() error {
func (s stream) CloseRead() error {
s.Stream.CancelRead(reset)
return nil
}
func (s *stream) CloseWrite() error {
func (s stream) CloseWrite() error {
return s.Stream.Close()
}

View File

@@ -86,7 +86,7 @@ type transport struct {
noise *noise.Transport
connMx sync.Mutex
conns map[quic.Connection]*conn // quic connection -> *conn
conns map[*quic.Conn]*conn // quic connection -> *conn
handshakeTimeout time.Duration
}
@@ -113,7 +113,7 @@ func New(key ic.PrivKey, psk pnet.PSK, connManager *quicreuse.ConnManager, gater
gater: gater,
clock: clock.New(),
connManager: connManager,
conns: map[quic.Connection]*conn{},
conns: map[*quic.Conn]*conn{},
handshakeTimeout: handshakeTimeout,
}
for _, opt := range opts {
@@ -188,7 +188,7 @@ func (t *transport) dialWithScope(ctx context.Context, raddr ma.Multiaddr, p pee
return conn, nil
}
func (t *transport) dial(ctx context.Context, addr ma.Multiaddr, url, sni string, certHashes []multihash.DecodedMultihash) (*webtransport.Session, quic.Connection, error) {
func (t *transport) dial(ctx context.Context, addr ma.Multiaddr, url, sni string, certHashes []multihash.DecodedMultihash) (*webtransport.Session, *quic.Conn, error) {
var tlsConf *tls.Config
if t.tlsClientConf != nil {
tlsConf = t.tlsClientConf.Clone()
@@ -215,8 +215,8 @@ func (t *transport) dial(ctx context.Context, addr ma.Multiaddr, url, sni string
return nil, nil, err
}
dialer := webtransport.Dialer{
DialAddr: func(_ context.Context, _ string, _ *tls.Config, _ *quic.Config) (quic.EarlyConnection, error) {
return conn.(quic.EarlyConnection), nil
DialAddr: func(_ context.Context, _ string, _ *tls.Config, _ *quic.Config) (*quic.Conn, error) {
return conn, nil
},
QUICConfig: t.connManager.ClientConfig().Clone(),
}
@@ -274,7 +274,7 @@ func (t *transport) upgrade(ctx context.Context, sess *webtransport.Session, p p
if err != nil {
return nil, fmt.Errorf("failed to create Noise transport: %w", err)
}
c, err := n.SecureOutbound(ctx, &webtransportStream{Stream: str, wsess: sess}, p)
c, err := n.SecureOutbound(ctx, webtransportStream{Stream: str, wsess: sess}, p)
if err != nil {
return nil, err
}
@@ -357,7 +357,7 @@ func (t *transport) Close() error {
return nil
}
func (t *transport) allowWindowIncrease(conn quic.Connection, size uint64) bool {
func (t *transport) allowWindowIncrease(conn *quic.Conn, size uint64) bool {
t.connMx.Lock()
defer t.connMx.Unlock()
@@ -368,13 +368,13 @@ func (t *transport) allowWindowIncrease(conn quic.Connection, size uint64) bool
return c.allowWindowIncrease(size)
}
func (t *transport) addConn(conn quic.Connection, c *conn) {
func (t *transport) addConn(conn *quic.Conn, c *conn) {
t.connMx.Lock()
t.conns[conn] = c
t.connMx.Unlock()
}
func (t *transport) removeConn(conn quic.Connection) {
func (t *transport) removeConn(conn *quic.Conn) {
t.connMx.Lock()
delete(t.conns, conn)
t.connMx.Unlock()

View File

@@ -17,9 +17,7 @@ require (
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/flynn/noise v1.1.0 // indirect
github.com/francoispqt/gojay v1.2.13 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/google/gopacket v1.1.19 // indirect
github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.5.3 // indirect
github.com/huin/goupnp v1.3.0 // indirect
@@ -54,7 +52,7 @@ require (
github.com/multiformats/go-multistream v0.6.1 // indirect
github.com/multiformats/go-varint v0.0.7 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/onsi/ginkgo/v2 v2.23.4 // indirect
github.com/onsi/gomega v1.36.3 // indirect
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect
github.com/pion/datachannel v1.5.10 // indirect
github.com/pion/dtls/v2 v2.2.12 // indirect
@@ -80,11 +78,10 @@ require (
github.com/prometheus/common v0.64.0 // indirect
github.com/prometheus/procfs v0.16.1 // indirect
github.com/quic-go/qpack v0.5.1 // indirect
github.com/quic-go/quic-go v0.52.0 // indirect
github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 // indirect
github.com/quic-go/quic-go v0.53.0 // indirect
github.com/quic-go/webtransport-go v0.9.0 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/wlynxg/anet v0.0.5 // indirect
go.uber.org/automaxprocs v1.6.0 // indirect
go.uber.org/dig v1.19.0 // indirect
go.uber.org/fx v1.24.0 // indirect
go.uber.org/mock v0.5.2 // indirect

View File

@@ -43,12 +43,8 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
@@ -66,8 +62,6 @@ github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a h1://KbezygeMJZCSHH+HgUZiTeSoiuFspbMg1ge+eFj18=
github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
@@ -177,8 +171,6 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=
github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=
github.com/onsi/gomega v1.36.3 h1:hID7cr8t3Wp26+cYnfcjR6HpJ00fdogN6dqZ1t6IylU=
github.com/onsi/gomega v1.36.3/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
@@ -229,8 +221,6 @@ github.com/pion/webrtc/v4 v4.1.2/go.mod h1:xsCXiNAmMEjIdFxAYU0MbB3RwRieJsegSB2JZ
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
@@ -245,10 +235,10 @@ github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzM
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
github.com/quic-go/quic-go v0.52.0 h1:/SlHrCRElyaU6MaEPKqKr9z83sBg2v4FLLvWM+Z47pA=
github.com/quic-go/quic-go v0.52.0/go.mod h1:MFlGGpcpJqRAfmYi6NC2cptDPSxRWTOGNuP4wqrWmzQ=
github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 h1:4WFk6u3sOT6pLa1kQ50ZVdm8BQFgJNA117cepZxtLIg=
github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66/go.mod h1:Vp72IJajgeOL6ddqrAhmp7IM9zbTcgkQxD/YdxrVwMw=
github.com/quic-go/quic-go v0.53.0 h1:QHX46sISpG2S03dPeZBgVIZp8dGagIaiu2FiVYvpCZI=
github.com/quic-go/quic-go v0.53.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY=
github.com/quic-go/webtransport-go v0.9.0 h1:jgys+7/wm6JarGDrW+lD/r9BGqBAmqY/ssklE09bA70=
github.com/quic-go/webtransport-go v0.9.0/go.mod h1:4FUYIiUc75XSsF6HShcLeXXYZJ9AGwo/xh3L8M/P1ao=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
@@ -297,8 +287,6 @@ github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU=
github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
go.uber.org/dig v1.19.0 h1:BACLhebsYdpQ7IROQ1AGPjrXcP5dF80U3gKoFzbaq/4=
go.uber.org/dig v1.19.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE=
go.uber.org/fx v1.24.0 h1:wE8mruvpg2kiiL1Vqd0CC+tr0/24XIB10Iwp2lLWzkg=