0037: Pair calls are the loopback exception

On this page

Status: accepted

Context

Short Leash binds everything to 127.0.0.1 (invariant 2): sites, services, mail and the share listener are never reachable from the network. A direct call between two computers can't work that way. WebRTC's ICE gathers addresses on the real network interfaces, so the two peers can reach each other on the same network or through NAT.

Decision

  • Who: only the pairing helper, and only while a session runs, opens UDP sockets on non-loopback interfaces. These are ICE's own sockets on ephemeral ports.
  • How they're protected:
    • Everything on them is authenticated by ICE credentials from the session's signaling, and encrypted with DTLS-SRTP keyed to the peer's certificate.
    • Nothing else listens: no TCP, no fixed port.
  • When: the sockets close when the session ends. They don't exist outside a session.
  • Settings › Pair › Privacy:
    • Hide my local network address uses ICE without host candidates.
    • Relay every call uses ICE relay only, and needs the TURN key from ADR 0036.
  • Everything else is unchanged: leashd's signaling endpoint stays on loopback behind the tunnel, as all sharing does.

Consequences

  • Invariant 2 now reads: "Everything binds to loopback, except the pairing helper's call sockets during a session (ADR 0037)."
  • Address exposure: people in a session can see each other's addresses, local or public, unless the host hides them or relays every call. Pair's privacy section and docs say so.
  • macOS: asks for Local Network access the first time a call reaches a peer on the same network. Short Leash.app declares NSLocalNetworkUsageDescription.
  • Windows: didn't prompt or need a firewall rule to join a call in the spikes. The firewall lets replies to ICE's outgoing checks back in. If a normally launched Short Leash shows otherwise, setup adds a rule for the helper, with its removal in uninstall (invariant 4).