First slice of in-chat file/photo sharing (dedicated file plane, images inline + file chips, session-only). This stage adds the wire types and the pure, unit-tested logic; no transport or UI yet. - protocol: new FILES_ALPN / FILES_PROTO (peerspeak/files/1) for the dedicated file-transfer plane. Bump GOSSIP_PROTO 1->2 + sig domain v2 (Chat gained an attachment field, so cross-version peers fail fast rather than half-work) and Cargo 0.2.0 -> 0.3.0 per VERSIONING.md. BREAKING wire change: all peers must run >= 0.3.0. - new src/files.rs: ChatAttachment descriptor (name/size/kind/id; bytes travel off-gossip), AttachmentKind, plus pure seams — sanitize_filename (path-traversal/control-char/length-safe), size_within_cap, image magic-byte sniffing + defensive limited decode (decode-bomb guard), 32-byte request parsing, human_size. 13 unit tests. - GossipMessage::Chat and RoomEvent::ChatMessage carry an optional ChatAttachment; send_chat takes Option<ChatAttachment>. Untrusted inbound descriptors are filename-sanitized + size-validated on ingest. serde(default) keeps the field forward-compatible at the JSON layer; +round-trip and pre-v2 back-compat tests. The attachment id is a random 32-byte handle (rand, already a dep), not a content hash — the fetch is authenticated + encrypted + member-gated, so no crypto-hash dep is needed. 349 lib tests pass, clippy clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1.8 KiB
1.8 KiB
PeerSpeak Codebase Layout and Architecture Rules
When working in the PeerSpeak repository, adhere to the following architectural boundaries and layout:
Code Layout
src/main.rs: The application entry point (initializes Tokio and the Iced GUI).src/app/: The UI layer (Iced). Handles themes, views (Home, Room, Settings), and visual state. Must communicate with the core via message passing (UiEvent/CoreCommand), not direct function calls.src/core/: The central orchestrator.mod.rs: Manages the session lifecycle, ties together network and UI, and manages the async mixer tasks.jitter.rs: Houses the adaptive playout delay JitterBuffer and Packet Loss Concealment (PLC) logic.
src/network/: The "Dual-Plane" transport layer.gossip.rs(Control Plane): Built oniroh-gossip. Manages room rosters, verified membership, presence, and chat via cryptographically signed envelopes.iroh_impl.rs(Data Plane): Manages raw QUIC endpoints and peer connections. Forwards UDP voice datagrams directly to peers for minimum latency.
src/audio/: Hardware audio backends.- Interfaces heavily with
cpal_impl.rs(Windows/WASAPI) andpipewire_impl.rs(Linux). - CRITICAL RULE: The RT audio callbacks are strictly lock-free. They communicate with the async core exclusively via Single-Producer Single-Consumer (SPSC) ring buffers (
HeapRb). Never allocate memory, log to stdout, or lock Mutexes on the RT threads.
- Interfaces heavily with
src/codec/: Audio compression abstractions, standardizing on Opus at 48kHz mono (opus_impl.rs).
General Directives
- Security: Audio admission is strictly derived from the verified gossip roster (S8). Never trust raw UDP sender IDs without validating against gossip.
- Latency: Preserve the deterministic dialer vs acceptor logic in the QUIC layer to prevent connection loops.