Sessions
trueseal-relay handles two distinct session types. Each uses a different Noise handshake pattern and serves a different purpose. They run on separate TCP listeners.
Push Sessions
A Push Session is short-lived and anonymous. A device opens one to deliver blobs to the relay, then closes it.
Handshake: Noise NK. The device verifies the relay’s static public key — confirming it is talking to the correct relay. The relay never learns the device’s identity. A fresh ephemeral X25519 keypair is generated for each Push Session and discarded immediately after. The relay cannot link a Push Session to any device or Receive Session.
Flow:
- Device opens TCP connection to the push listener (default
:7701). - Noise NK handshake completes — relay authenticated, device anonymous.
- Device sends one or more
Pushframes, one per recipient blob. - For each Push: relay persists to Inbox, sends
Ack. - If a blob is rejected (e.g. oversized), relay sends
Error— device must not retry that blob. - Device closes the connection when done.
Multiple blobs can be sent in a single Push Session. One Ack per blob, in order.
Receive Sessions
A Receive Session is long-lived and authenticated. A device opens one and keeps it open to receive blobs in real time.
Handshake: Noise XX. Mutual authentication — the device and relay verify each other’s static public keys. The relay learns the device’s stable noise public key and registers it as online.
Flow:
- Device opens TCP connection to the receive listener (default
:7700). - Noise XX handshake completes — both sides authenticated.
- Relay flushes any blobs already in the device’s Inbox — delivers them without deleting.
- Relay delivers new blobs as they arrive — immediately, without polling.
- For each Deliver frame received, the client durably persists the blob then sends a DeliverAck with the blob’s ID.
- On receiving a DeliverAck, the relay deletes the blob from the Inbox. If the session drops before a DeliverAck arrives, the blob is re-delivered on the next Receive Session — clients must handle duplicates.
- Either side sends
Heartbeaton idle to prevent NAT/firewall timeout; the other side echoes it. - Session stays open until the device disconnects or the connection drops.
Only one Receive Session per device is expected at a time. The relay allows concurrent sessions for the same key — this can happen briefly during reconnect. Atomic Inbox flushing prevents double-delivery: only one session wins the flush race.
Heartbeat
Idle TCP connections are silently killed by NAT tables and firewalls, typically after 30–300 seconds. trueseal-relay sends Heartbeat frames on idle Receive Sessions to keep the connection alive. The client echoes back a Heartbeat. Either side may initiate.
The heartbeat interval is configurable. If a device stops responding to heartbeats, the relay closes the connection and the device reconnects.