Documentation
¶
Overview ¶
Package relaynet holds the QUIC + TLS plumbing shared by the relay command binaries: self-signed dev certificates, the relay's QUIC tuning, and the listener/dialer constructors that bridge quic-go to the transport-agnostic session.Conn the relay operates on.
It exists so more than one relay binary shares one copy of this setup rather than each carrying its own: cmd/relay here, and the out-of-tree relay built on a distributed [relay.DiscoveryStore], which imports this package. The helpers here are aimed at local development and single-operator deployments — SelfSignedCert, InsecureClientTLSConfig and Listen are explicitly not for production: the first two skip real trust, and the third accepts every browser Origin.
Index ¶
- Variables
- func DialQUIC(ctx context.Context, addr string, tlsCfg *tls.Config) (session.Conn, error)
- func DialWebTransport(ctx context.Context, rawURL string, tlsCfg *tls.Config) (session.Conn, error)
- func InsecureClientTLSConfig(alpns []string) *tls.Config
- func SelfSignedCert() (tls.Certificate, error)
- func TLSConfig(certFile, keyFile string, alpns []string) (*tls.Config, error)
- type DualListener
Constants ¶
This section is empty.
Variables ¶
var DualALPNs = slices.Concat(MOQTQUICALPNs, WebTransportALPNs)
DualALPNs lists the ALPNs of both MOQT transport mappings, for a listener that serves them on one socket — see Listen. A TLS config built with these accepts a raw-QUIC client offering "moqt-NN" and an HTTP/3 client offering "h3"; each connection's negotiated ALPN then says which mapping it is.
var MOQTQUICALPNs = []string{"moqt-19"}
MOQTQUICALPNs lists the raw-QUIC MOQT ALPNs the relay accepts. Draft-19 SETUP carries no version field (§3.1), so the "moqt-NN" ALPN is itself the draft-version signal — the negotiated ALPN fixes the draft. We advertise only "moqt-19", the draft this implementation speaks. The older "moqt-18"/"-17"/"-16" and the pre-15 "moq-00" (which expected in-SETUP version negotiation, removed in -19) are deliberately not offered: our -19 wire behavior can't complete a SETUP with a peer that selected any of them, so advertising them would only let such a peer clear TLS and then fail.
var WebTransportALPNs = []string{http3.NextProtoH3}
WebTransportALPNs lists the TLS ALPNs of the MOQT-over-WebTransport mapping. WebTransport rides HTTP/3, whose ALPN is "h3" — the "moqt-NN" identifiers belong to raw QUIC (MOQTQUICALPNs). The draft version is instead negotiated as the WebTransport sub-protocol (§3.1), which Listen offers.
Pass these alone to TLSConfig for a listener that serves *only* WebTransport; DualALPNs serves both mappings.
Functions ¶
func DialQUIC ¶
DialQUIC dials addr over raw QUIC with the relay's default QUIC tuning and returns the established connection as a session.Conn, ready for the relay to drive the client-side MOQT SETUP on. It is the shape a relay Dialer expects.
quicconn.Dial owns the address handling, including the multi-address, RFC 6724-ordered resolution that keeps a dual-stack peer named by hostname from being dialed over the wrong family — see its doc comment.
func DialWebTransport ¶
DialWebTransport dials rawURL — the https URL of a WebTransport endpoint, i.e. the §3.1.4 conversion of a moqt URI — and returns the established session as a session.Conn, ready for the caller to drive the client-side MOQT SETUP on. It is the WebTransport counterpart of DialQUIC and has the shape a relay Dialer expects; tlsCfg must advertise WebTransportALPNs.
func InsecureClientTLSConfig ¶
InsecureClientTLSConfig returns a client TLS config that offers alpns and SKIPS certificate verification. It exists for relay-to-relay dialing in development, where peers present self-signed certs; production deployments MUST supply a config with a real trust store instead.
func SelfSignedCert ¶
func SelfSignedCert() (tls.Certificate, error)
SelfSignedCert generates an ephemeral ECDSA-P256 self-signed certificate for localhost, valid for 10 days (within Chrome's ≤14-day tolerance for serverCertificateHashes pinning). It is for local development only.
func TLSConfig ¶
TLSConfig returns a server TLS config for the chosen MOQT transport. If certFile and keyFile are both non-empty the pair is loaded from disk; otherwise an ephemeral self-signed certificate is generated in memory (see SelfSignedCert). alpns lists the acceptable ALPNs in server-preference order.
Types ¶
type DualListener ¶
type DualListener struct {
// contains filtered or unexported fields
}
DualListener is the Listen listener: one QUIC socket whose connections are split by negotiated ALPN into the raw-QUIC and WebTransport halves, then merged into one Accept queue so the relay cannot tell them apart.
func Listen ¶
Listen serves both MOQT transport mappings on a single UDP socket: raw QUIC for peers and native clients that dial a moqt URI, and WebTransport (HTTP/3) at wtPath for anything dialing the https form of the same URI (§3.1.3, §3.1.4) — browsers included. tlsCfg must advertise DualALPNs.
This is what a relay behind a load balancer wants, and it is why no transport flag is needed: the two mappings differ only in ALPN, so one listener can offer both and decide per connection. Clients choose by URL scheme, peer relays keep dialing raw QUIC, and nothing has to agree deployment-wide.
The returned listener owns the socket; Close releases it along with both halves. A connection whose ALPN is not "h3" is treated as raw QUIC: the ALPN set the handshake selected from is tlsCfg's, so nothing else can get that far.
CheckOrigin accepts every origin, as [ListenWebTransport] does — see the package doc. Serving both mappings means a relay is reachable from a browser by default, so a deployment that cares about which pages may open sessions needs its own policy here.
func (*DualListener) Accept ¶
Accept returns the next connection from either transport. It satisfies the relay's Listener interface.
func (*DualListener) Addr ¶
func (l *DualListener) Addr() net.Addr
Addr returns the UDP address both transports are served on.
func (*DualListener) Close ¶
func (l *DualListener) Close() error
Close stops accepting new connections. Connections already accepted keep working, and the UDP socket stays open until the last of them ends — quic-go releases it once its transport has no connections left.
That is load-bearing, not incidental: [relay.Relay.Stop] closes the listener as an early step and only then broadcasts GOAWAY and waits out the grace period (§10.4, §3.6). A Close that dropped the socket would kill every draining session with it, and no peer would ever see its GOAWAY.
Close is idempotent and joins the failures of every step.