Stand up the friends control plane: a persistent-identity iroh endpoint that's online for the whole GUI session, separate from the ephemeral video sessions, ready to carry friend requests and pushed share-codes. Identity split by plane (common/endpoint.rs): the video plane (host/ viewer) goes back to ephemeral per-session keypairs, while the new bind_control() binds with the machine's persistent identity. They must differ — the GUI's control endpoint and a host's video endpoint can be live at once, and iroh routes by EndpointId, so a shared id would make relay delivery ambiguous. Bonus: a screen-share now leaks no stable id. common/control.rs — the protocol: a ControlMsg enum (Hello / Friend Request / FriendAccept / FriendDecline / ShareCode) with one-message- per-connection framing (EOF-delimited JSON) and a one-byte ACK the receiver returns only after a successful parse, so send() gets a real delivered/failed signal (the basis for the later code-push queue). The sender id is taken from the connection's verified remote key, never the payload. send() takes impl Into<EndpointAddr> so production dials a bare EndpointId (discovery resolves it) while tests use a full addr. gui/presence.rs — the service: a dedicated thread + current-thread tokio runtime (mirroring the tray) binds the control endpoint and runs the accept loop, bridging inbound messages to a std mpsc the UI drains each tick and pinging the Waker so they land even while hidden to the tray. The whole friends stack (identity, control, CONTROL_ALPN, bind_control) is gated behind the `gui` feature — a headless CLI host runs no presence service — keeping the headless build lean and warning-free. Verified: loopback test delivers a FriendRequest across two real iroh endpoints with the correct authenticated sender id; the live GUI binds its control endpoint on launch under the persistent identity. fmt + clippy clean on both feature sets; headless and gui test suites pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
15 lines
777 B
Rust
15 lines
777 B
Rust
/// ALPN identifying the pixelpass video wire protocol on the iroh tunnel.
|
|
///
|
|
/// Bump the version suffix whenever the wire format changes. Today the wire is
|
|
/// "raw MPEG-TS bytes copied bidirectionally," so bumps will be rare.
|
|
pub const ALPN: &[u8] = b"pixelpass/0";
|
|
|
|
/// ALPN for the friends control plane — the always-on presence endpoint that
|
|
/// carries friend requests and shared codes between peers' GUIs. Separate from
|
|
/// [`ALPN`] so the same machine can run a control endpoint and a video endpoint
|
|
/// without their accept loops colliding, and so a control dial never lands on a
|
|
/// bare video host (which doesn't speak this protocol). GUI-only, like the rest
|
|
/// of the friends stack.
|
|
#[cfg(feature = "gui")]
|
|
pub const CONTROL_ALPN: &[u8] = b"pixelpass/ctrl/0";
|