Live links
When both people are at the keyboard, Glitr tries a direct data channel so the next message does not wait on a push and a poll. There are two ways to get that channel: Pair now (out of band) and git signaling (mailbox bulletin board). Onion is a third native path on Tor.
User story: Direct live links. Wiring: Network.
Live WebRTC does not ride Tor. ICE still uses ordinary browser / engine STUN.
Two introductions
| Path | How you meet | Mailbox fallback |
|---|---|---|
| Git-URL contact | Cascaded offer/answer rows on each repo; poll completes ICE | Yes — next text or file send is git again if the channel dies |
| Pair now | Plaintext QR / paste / NFC bundle (wu1:), stored as webrtc:… | No — delivery stops until you pair again or move to a git URL |
While a Pair now panel is open for a contact, git signaling for that id is paused. Logout deletes the git signaling row.
What is plaintext out of band
A wu1: bundle is SDP + ICE for the handshake, exchanged on a channel Glitr does not protect: a screen, a clipboard, a chat you already have, NFC. Anyone who sees the bundle can try to finish the handshake as you.
That is the same class of risk as scanning a QR from the wrong person. Hello + safety number after the channel opens is the TOFU check, not encryption of the invite itself.
Git-brokered signaling is the opposite on this one row: the inner SDP is cascaded to the contact. The host sees that a signaling file exists.
What rides the channel
Chat bodies and file bytes use the same recipient cascade as git outbound — not plaintext over DTLS. A live file is sealed as one cascade blob; frames then carry slices of that ciphertext. Soft cap is 32 MiB of plaintext. Incomplete transfers persist in sealed file-transfers/ so a drop can resume.
Local sent and inbox still update so the thread does not forget what you just said.
Control frames are JSON on the data channel (ChatFrame in webrtc-core). They are not a second cascade wrap:
| Frame | Payload | Content control |
|---|---|---|
chat | Sealed body | Cascade — Mitigated against a path observer who cannot open the session |
fileChunk | Slice of sealed file | Cascade |
fileOffer | Name, mime, size, ciphertext length; optional sealed preview | Metadata is visible to a peer (and to anyone who can read the DTLS stream) |
hello | Public profile, device id, optional git mailbox / onion | Identity material — Documented |
typing, receipt | Boolean / message id | DTLS only — Partial |
callInvite / accept / reject / hangup / share | Session id, voice vs video | DTLS only — Partial |
callSdp | Renegotiation bundle | Treat like other live signaling |
A network observer who cannot break DTLS does not see those JSON frames. The product still does not treat DTLS as the content control. That is why bodies and file bytes are cascaded again.
STUN and ICE
There is no Glitr STUN farm. The web client uses a public Google STUN (stun:stun.l.google.com:19302). ICE candidates can include reflexive IP addresses. A STUN operator and anyone who sees the candidates can learn that two networks are trying to meet, and often where those networks are.
Some networks will not complete ICE. On a git-URL contact, the promise in that case is git delivery, not a VPN. On Pair now, you need ICE or you re-pair later.
Calls (voice / video) use getUserMedia on the same RTCPeerConnection. Call media is a live-path concern of its own: it is not the git mailbox cascade. Desktop Linux often has no webview WebRTC, so calls stay unavailable there even when webrtc-rs carries chat.
Hello and key mismatch
When the channel opens, each side sends HelloProfile. evaluate_hello returns Store, Match, or Mismatch. Mismatch is a UI prompt. A safety number is computed locally from both hello keys.
A malicious peer can send malformed frames to confuse a parser. Failure handling is “no plaintext on decrypt error.” That is a Partial control (validation and fuzzing are not a published audit).
Groups and fallback
Groups never use the live file path. A group send is git fan-out.
If the channel dies and the contact has a git URL, the next text or file send is git again. Pair-now contacts do not get that fallback.
Git, WebRTC, and onion share one protocol session per contact so the ratchet does not fork.
Next: Tor — the native live path that does not wait on ICE.
