Skip to main content

Module pending_pair

Module pending_pair 

Source
Expand description

Daemon-orchestrated detached pair sessions.

Problem: wire pair-host and wire pair-join block for the full pair timeout (300s default) waiting for the peer to show up. If the operator’s terminal closes or the process is killed, the handshake dies — and on the relay side leaves a stuck slot that needs wire pair-abandon to clean.

Solution: pair-host/-join write a “pending pair” descriptor file and exit in milliseconds. The wire daemon (already running for inbox sync) picks up pending files each tick, runs the handshake, and transitions state through the file. Operator confirms SAS via wire pair-confirm <code> <digits> from any process; daemon finalizes on the next tick.

State flow (status field on the file): request_host / request_guest ↓ daemon registers on relay, stores PakeSide in memory polling ↓ daemon polls for peer’s SPAKE2 message; on arrival computes SAS sas_ready (file now has sas field set; operator sees it via pair-list) ↓ wire pair-confirm validates typed digits, sets status=confirmed confirmed ↓ daemon finalizes (peer card exchange, trust pin); deletes file (gone)

Terminal failure states: aborted (any error or user cancel), aborted_restart (daemon restarted mid-handshake; PakeSide lost from memory; operator must re-issue).

In-memory PakeSide is the single point of fragility: it’s not persisted, so daemon restart drops live sessions. cleanup_on_startup releases the relay slot and marks the file aborted_restart so the operator knows. Daemon restarts are rare; this is an acceptable tradeoff vs. forking the spake2 crate to expose its internal scalar.

Structs§

PendingPair

Functions§

cleanup_on_startup
Run on daemon startup. Only marks pending files aborted_restart if the previous daemon (according to PID file) is no longer alive. Idempotent for the same daemon process (writes its own PID, then re-running this function on subsequent calls is a no-op).
delete_pending
list_pending
pending_dir
read_pending
tick
One daemon tick. Walks every pending file and advances it one step in the state machine. Each file’s failures are isolated — a single broken file doesn’t stop processing of the rest. Also GCs old terminal-state files.
write_pending