package quicreuse

import "github.com/libp2p/go-libp2p/p2p/transport/quicreuse"

Package quicreuse provides `quicreuse.ConnManager`, which provides functionality for reusing QUIC transports for various purposes, like listening & dialing, having multiple QUIC listeners on the same address with different ALPNs, and sharing the same address with non QUIC transports like WebRTC.

Index

Functions

func FromQuicMultiaddr

func FromQuicMultiaddr(addr ma.Multiaddr) (*net.UDPAddr, quic.Version, error)

func ToQuicMultiaddr

func ToQuicMultiaddr(na net.Addr, version quic.Version) (ma.Multiaddr, error)

func WithAssociation

func WithAssociation(ctx context.Context, association any) context.Context

WithAssociation returns a new context with the given association. Used in DialQUIC to prefer a transport that has the given association.

Types

type ConnManager

type ConnManager struct {
	// contains filtered or unexported fields
}

ConnManager enables QUIC and WebTransport transports to listen on the same port, reusing listen addresses for dialing, and provides a PacketConn for sharing the listen address with other protocols like WebRTC. Reusing the listen address for dialing helps with address discovery and hole punching. For details of the reuse logic see `ListenQUICAndAssociate` and `DialQUIC`. If reuseport is disabled using the `DisableReuseport` option, listen addresses are not used for dialing.

func NewConnManager

func NewConnManager(statelessResetKey quic.StatelessResetKey, tokenKey quic.TokenGeneratorKey, opts ...Option) (*ConnManager, error)

NewConnManager returns a new ConnManager

func (*ConnManager) ClientConfig

func (c *ConnManager) ClientConfig() *quic.Config

func (*ConnManager) Close

func (c *ConnManager) Close() error

func (*ConnManager) DialQUIC

func (c *ConnManager) DialQUIC(ctx context.Context, raddr ma.Multiaddr, tlsConf *tls.Config, allowWindowIncrease func(conn quic.Connection, delta uint64) bool) (quic.Connection, error)

DialQUIC dials `raddr`. Use `WithAssociation` to select a specific transport that was previously used for listening. see the documentation for `ListenQUICAndAssociate` for details on associate. The priority order for reusing the transport is as follows: - Listening transport with the same association - Any other listening transport - Any transport previously used for dialing If none of these are available, it'll create a new transport.

func (*ConnManager) LendTransport

func (c *ConnManager) LendTransport(network string, tr QUICTransport, conn net.PacketConn) (<-chan struct{}, error)

LendTransport is an advanced method used to lend an existing QUICTransport to the ConnManager. The ConnManager will close the returned channel when it is done with the transport, so that the owner may safely close the transport.

func (*ConnManager) ListenQUIC

func (c *ConnManager) ListenQUIC(addr ma.Multiaddr, tlsConf *tls.Config, allowWindowIncrease func(conn quic.Connection, delta uint64) bool) (Listener, error)

ListenQUIC listens for quic connections with the provided `tlsConf.NextProtos` ALPNs on `addr`. The same addr can be shared between different ALPNs.

func (*ConnManager) ListenQUICAndAssociate

func (c *ConnManager) ListenQUICAndAssociate(association any, addr ma.Multiaddr, tlsConf *tls.Config, allowWindowIncrease func(conn quic.Connection, delta uint64) bool) (Listener, error)

ListenQUICAndAssociate listens for quic connections with the provided `tlsConf.NextProtos` ALPNs on `addr`. The same addr can be shared between different ALPNs. The QUIC Transport used for listening is tagged with the `association`. Any subsequent `TransportWithAssociationForDial`, 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 (*ConnManager) Protocols

func (c *ConnManager) Protocols() []int

Protocols returns the supported QUIC protocols. The only supported protocol at the moment is /quic-v1.

func (*ConnManager) SharedNonQUICPacketConn

func (c *ConnManager) SharedNonQUICPacketConn(_ string, laddr *net.UDPAddr) (net.PacketConn, error)

SharedNonQUICPacketConn returns a `net.PacketConn` for `laddr` for non QUIC uses.

func (*ConnManager) TransportForDial

func (c *ConnManager) TransportForDial(network string, raddr *net.UDPAddr) (RefCountedQUICTransport, error)

TransportForDial returns a transport for dialing `raddr`. If reuseport is enabled, it attempts to reuse the QUIC Transport used for previous listens or dials.

func (*ConnManager) TransportWithAssociationForDial

func (c *ConnManager) TransportWithAssociationForDial(association any, network string, raddr *net.UDPAddr) (RefCountedQUICTransport, error)

TransportWithAssociationForDial returns a transport for dialing `raddr`. If reuseport is enabled, it attempts to reuse the QUIC Transport previously used for listening with `ListenQuicAndAssociate` with the same `association`. If it fails to do so, it uses any other previously used transport.

type Listener

type Listener interface {
	Accept(context.Context) (quic.Connection, error)
	Addr() net.Addr
	Multiaddrs() []ma.Multiaddr
	io.Closer
}

type Option

type Option func(*ConnManager) error

func ConnContext

func ConnContext(f func(ctx context.Context, clientInfo *quic.ClientInfo) (context.Context, error)) Option

ConnContext sets the context for all connections accepted by listeners. This doesn't affect the context for dialed connections. To reject a connection, return a non nil error.

func DisableReuseport

func DisableReuseport() Option

func EnableMetrics

func EnableMetrics(reg prometheus.Registerer) Option

EnableMetrics enables Prometheus metrics collection. If reg is nil, prometheus.DefaultRegisterer will be used as the registerer.

func OverrideListenUDP

func OverrideListenUDP(f listenUDP) Option

func OverrideSourceIPSelector

func OverrideSourceIPSelector(f func() (SourceIPSelector, error)) Option

func VerifySourceAddress

func VerifySourceAddress(f func(addr net.Addr) bool) Option

VerifySourceAddress returns whether to verify the source address for incoming connection requests. For more details see: `quic.Transport.VerifySourceAddress`

type QUICListener

type QUICListener interface {
	Accept(ctx context.Context) (quic.Connection, error)
	Close() error
	Addr() net.Addr
}

type QUICTransport

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)
	WriteTo(b []byte, addr net.Addr) (int, error)
	ReadNonQUICPacket(ctx context.Context, b []byte) (int, net.Addr, error)
	io.Closer
}

type RefCountedQUICTransport

type RefCountedQUICTransport interface {
	LocalAddr() net.Addr

	// Used to send packets directly around QUIC. Useful for hole punching.
	WriteTo([]byte, net.Addr) (int, error)

	Close() error

	// count transport reference
	DecreaseCount()
	IncreaseCount()

	Dial(ctx context.Context, addr net.Addr, tlsConf *tls.Config, conf *quic.Config) (quic.Connection, error)
	Listen(tlsConf *tls.Config, conf *quic.Config) (QUICListener, error)
}

type SourceIPSelector

type SourceIPSelector interface {
	PreferredSourceIPForDestination(dst *net.UDPAddr) (net.IP, error)
}

Source Files

config.go connmgr.go listener.go nonquic_packetconn.go options.go quic_multiaddr.go reuse.go tracer.go

Version
v0.42.0 (latest)
Published
Jun 18, 2025
Platform
linux/amd64
Imports
25 packages
Last checked
4 weeks ago

Tools for package owners.