Two transports carry it. The bare-QUIC request wire (
NativeQuicOpClient, the
inference frontends) is Python only. The MoQT track wire (MoqtClient) carries
it in every native SDK: Python, Go, Rust, Java, Kotlin, .NET, Swift, Flutter and
Unity. The browser SDK stays relay-only: a browser cannot adopt a socket or pin a
leaf certificate.How a connection is made
- The server binds its QUIC port and learns its public address from a STUN reflector on that same socket.
- The server registers a UDP tunnel on a relay PoP in front of the same port.
- The server publishes its addresses, the relay address and the SHA-256 of its certificate to the rendezvous. The rendezvous needs an org API key.
- The client binds a socket, learns its public address and publishes it.
- Both sides send punch probes toward each other. The client dials the server’s public address for 5 seconds with the certificate pinned.
- If the direct dial fails, the client dials the relay address with the same pin.
Environment
The pair id is a string of 6 to 64 characters from
A-Z, a-z, 0-9, _
and -. Share it and the pair token out of band.
Server
serve_path returns the punched socket in path.fd. Pass it as adopt_fd
to the native server. keepalive re-publishes the record every 30 seconds
and punches toward each client that joins the pair.
Client
client_path refuses to return a server record that has no certificate
fingerprint. A dial without a pin is not possible through this API.
Native fields
The C ABI carries the same options for other bindings:What to expect on real networks
Two subscribers of one carrier NAT often cannot reach each other directly, even when both NATs map addresses in the endpoint-independent way. The punch fails and the relay serves the connection. This is a normal case. Design for the relay path first and treat the direct path as the faster option when it is available.MoQT: the same paths for every SDK
A MoQT peer that ACCEPTS a direct connection runs an in-process WebTransport server on its punched socket. It accepts one session whose CONNECT carries the pair token astok=. Any other CONNECT is answered 403. The DIALING peer pins
the accepting peer’s certificate and dials it for 5 seconds, then dials the
relay it always dialed. The MoQT session is the same object on both paths.
The rendezvous call and the dial ladder are in the SDK for Python
(
clutchcall.p2p.moqt_serve / moqt_dial), Go (MoqtP2P), Rust
(clutchcall::p2p::MoqtP2p), Java (MoqtP2P), .NET (MoqtP2P) and Swift
(MoqtP2P). Kotlin, Flutter and Unity expose the primitives; the app makes the
one HTTPS POST to the rendezvous with the HTTP client it already has, then calls
listen or connectEx.
The C ABI behind every wrapper: clutch_moqt_connect_ex, clutch_moqt_listen,
clutch_moqt_local_port, clutch_p2p_punch and clutch_p2p_cert_sha256, all
in the MoQT library. Existing exports are unchanged.