0036: Pair invites use the host's own tunnel

On this page

Status: accepted

Context

Two copies of Short Leash need to find each other and swap the connection setup (offer, answer, ICE candidates) before they can talk directly. The usual answer is a signaling and presence server, but Short Leash runs no servers and keeps no accounts. Short Leash already shares sites through Cloudflare quick tunnels (ADR 0010), and each tunnel is a public HTTPS address that serves a WebSocket.

Some networks block direct connections. In the spikes, two machines behind the same router couldn't reach each other at their public addresses. Those calls need a TURN relay.

Decision

  • The host is the server for its own session.
    • leashd serves a signaling WebSocket on the share listener, on loopback, and publishes it with a quick tunnel (pair:<id>, like webhook tunnels in ADR 0020).
    • The tunnel only carries setup. Media goes peer to peer (ADR 0035).
  • Invites:
    • An invite is https://<name>.trycloudflare.com/#<token>, with a 128-bit random token after #. Browsers never send the fragment, so the token isn't in any request's address or log.
    • It's valid for up to three joins while the session lasts, and the host can replace it.
    • The guest proves the token in its first WebSocket message, compared in constant time. That message is encrypted to Cloudflare's edge, which can read it; the short code of ADR 0038 protected against Cloudflare, or anyone in its place, sitting in the middle, until 0043 removed it; now nothing does.
    • At most eight people wait at once.
    • Every guest waits for the host to let them in. Guests can't let others in.
  • Publishing:
    • The host shows the invite only once the tunnel's name resolves at Cloudflare's resolver (1.1.1.1). Guests look the name up there too.
    • The system resolver caches an early "no such name" and would break a fresh invite for minutes.
  • Keeping the connection:
    • Signaling sends a heartbeat every 30 seconds, under Cloudflare's idle timeout.
    • Once peers connect, renegotiation moves to the data channel. The tunnel is only needed again for an ICE restart.
    • When a let-in guest's signaling drops without a goodbye, or goes silent for two and a half heartbeats, the host keeps them in the session for 90 seconds (their call keeps running), takes back control if they had it and can't give it again until they're back. The guest's Short Leash tries for a minute to connect again and sends the secret the host gave it when it let them in. A match brings them back as the same person; a secret that doesn't match, or belongs to someone the host removed, is refused without reaching the waiting room.
  • Finding addresses: STUN from stun.cloudflare.com.
  • Relay:
    • TURN is used only when the host has added a Cloudflare TURN key (Key ID and Key token) in Settings › Sharing › Relay for pairing. The key is saved in secrets/sharing.json like the other sharing secrets (ADR 0012).
    • The host mints short-lived relay credentials (at most 48 hours) and sends them to guests over signaling. Guests set up nothing.
    • When a direct connection fails without a key, Pair says so and offers Set up relay.
  • No presence: no contacts, no "who's online", no ringing. Invites are links people send however they like.

Consequences

  • No servers: Short Leash runs none and keeps no accounts or contact lists. The privacy promise stays as it is.
  • Speed: an invite is ready in about 6 seconds, and the guest connects in well under a second after joining.
  • No uptime guarantee: quick tunnels have none, and their names change each session. A host whose Short Leash restarts ends the session; the guests need a new invite.
  • No relay by default: without a TURN key, roughly one call in five on strict or corporate networks won't connect. With a key, relayed traffic counts against the host's Cloudflare allowance (1,000 GB a month free).
  • No calling: people can't "call" a teammate who is online. That's a deliberate trade for having no server. A later presence feature would need its own decision.
  • Guest-side checks: a guest's Short Leash only opens invites with a trycloudflare.com name and a well-formed token, and always asks before joining.