Documentation
¶
Overview ¶
Package quicconn adapts github.com/quic-go/quic-go's *quic.Conn to the transport-neutral session.Conn interface.
This is the sole boundary in the moqt tree where quic-go's concrete types meet the session abstraction. Putting it in a dedicated subpackage lets the rest of pkg/moqt (and its tests) stay independent of quic-go's surface.
quic-go uses typed-uint64 aliases (quic.StreamErrorCode, quic.ApplicationErrorCode) for error codes; session.Conn / SendStream / ReceiveStream use plain uint64. The wrappers below do the lossless conversion at each call site.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Dial ¶
func Dial(ctx context.Context, addr string, tlsCfg *tls.Config, quicCfg *quic.Config) (session.Conn, error)
Dial opens a raw-QUIC connection to addr ("host:port") and returns it as a session.Conn, ready for a client-side MOQT SETUP. It is the client-side counterpart of NewListener, and the one dial path every MOQT client in this repo shares — the relay's cross-relay dialer and the demo/interop CLIs alike.
The name in addr is resolved here rather than left to quic.DialAddr, which resolves via net.ResolveUDPAddr. That helper returns the first *IPv4* address for a bare "host:port" and reaches for IPv6 only when the string carries a bracketed literal — it picks the family by looking for a '[' in the string (net.addrList.forResolve), not by what the resolver ranked first. So a dual-stack peer named by hostname is always dialed over IPv4, even where only the IPv6 path carries traffic: the Initials leave, nothing answers, and the dial fails with "timeout: no recent network activity" while the host is plainly reachable over IPv6.
net.Resolver.LookupIPAddr instead returns every address in RFC 6724 order — the same ranking getaddrinfo / `getent ahosts` report — and each is tried in turn, so a host whose first address is unreachable still connects on the next. Candidates go back to quic.DialAddr as literals via net.JoinHostPort, which brackets IPv6: that pins the family chosen here and costs no second lookup. ctx bounds the whole sequence, so a caller's dial timeout applies across all candidates rather than per candidate.
Types ¶
type Listener ¶
type Listener struct {
// contains filtered or unexported fields
}
Listener adapts a *quic.Listener so it can be handed directly to the relay's accept loop. The relay's listener interface requires Accept(ctx) → session.Conn, Addr() → net.Addr, and Close() → error; this type satisfies it structurally without forcing this package to import pkg/relay.
The caller owns the underlying *quic.Listener — its TLS config, ALPN selection ("moqt-19"), QUIC parameters, and listening socket. Close on the Listener forwards to the underlying *quic.Listener, which is also what the caller would call themselves on shutdown; both paths are equivalent.
func NewListener ¶
NewListener wraps ql so it can be passed to relay.New.
Typical wiring:
ql, err := quic.ListenAddr(":4433", tlsCfg, quicCfg)
if err != nil { … }
r := relay.New(quicconn.NewListener(ql), relay.Config{ … })
go r.Start(ctx)
func (*Listener) Accept ¶
Accept blocks until the next inbound *quic.Conn arrives, then wraps it via New into a session.Conn the relay can hand to session.Server. ctx cancellation propagates to the underlying Accept.