Commit Graph
5 Commits
Author SHA1 Message Date
ddidderr 37420e26ed fix(peer): coalesce full UI view publications
Keep one queued and one replaceable pending snapshot for remote-library and Call-to-Play views while preserving lifecycle-event FIFO delivery. Generation barriers and fenced drains prevent stale nonempty views from crossing disable or acknowledgement boundaries.

Test Plan:
- just test
- just clippy
- focused burst, lifecycle ordering, fence, repeated-barrier, and stale-view tests
- independent ordering review
- git diff --check
2026-09-12 13:06:10 +02:00
ddidderr ff962801ae fix(peer): cap public control and extractor concurrency
Limit server-wide decoded control requests to 16 and gate Stream Install providers behind a separate two-slot semaphore. The provider permit remains held through producer cleanup, bounding concurrent unrar work while ordinary bulk transfers retain their own capacity.

Test Plan:
- just test (passed after rerunning one transient ETXTBSY failure)
- just fmt (Rust formatting passed; repository's generated security report still triggers pre-existing rumdl violations)
- git diff --check
2026-09-12 12:32:12 +02:00
ddidderr 63aa4bc77c fix(peer): serve manifests from the validated cache only
Follow-up to the scanner finding #2 fix ("rejected bulk requests can
populate the persistent manifest cache"). The previous commit reordered
admission so the compact content index and local readiness are checked
before any manifest body is loaded. That relied on ordering alone: the
loader still called `CatalogBundle::manifest`, which reads and parses
the artifact from disk on a cache miss, and nothing in the test suite
proved that a rejected request leaves the cache untouched.

Switch the outbound admission loader to `cached_manifest`, which never
performs filesystem I/O. This is safe because every game that can pass
`can_serve_game` is catalog-eligible and its manifest was primed by
`prime_library_manifests` before the library revision that advertises it
became visible (server startup in `services/server.rs`, every library
scan publication in `handlers.rs`). A cache miss therefore means a
publication-ordering bug rather than a legitimate serve, and failing the
request closed with a logged error is the right outcome.

The admission tests now assert that a request with the wrong content
identity leaves `cached_manifest("game")` erroring, for both catalog
chunks and Stream Install, and prime the manifest explicitly before the
accepted-request assertions, mirroring what the server does. The
architecture document describes the cache-only serving path.

Behaviour visible to peers is unchanged for valid requests. Rejected
requests no longer cause a disk read under the admission lock.

This layers the `cached_manifest` switch and no-load assertions from the
parallel security branch (lanspread2 commit 4e0419a) onto the identity
gate introduced in 55fa494.

Test plan:
- `cargo test -p lanspread-peer --lib`: 488 passed.
- `just test`, `just clippy`, `cargo +nightly fmt --check` at the end of
  the series.

Claude-Session: https://claude.ai/code/session_01QRkCv4a4GqkajyamxmbSuA
2026-09-12 11:12:14 +02:00
ddidderr 55fa4941bc fix(peer): gate bulk requests on the compact index before loading manifests
Security audit finding Codex #2 ("rejected bulk requests can populate
the persistent manifest cache"). `admit_outbound_transfer` loaded the
full catalog manifest for the requested game ID first and only then
compared the content ID and checked whether the game is locally
serveable. Because manifests are cached for the life of the process,
one anonymous LAN client could make a node parse and retain the entire
catalog's manifest corpus with requests for games it does not even
have, and every such request paid a disk read under the admission lock.

The catalog already exposes a compact content index that answers
identity and streamed-install support without I/O. Admission now
checks that index and in-memory local readiness first; only requests
that pass both load the manifest. Accepted requests behave exactly as
before, including the streamed-install support check.

Test plan: `just test`. Manual: with two peer-cli containers, chunk
downloads and Stream Install still complete; a request naming an
unknown game ID or wrong content ID is declined with the same log
message as before.

Claude-Session: https://claude.ai/code/session_017C3Nbgwpdm3YNwZhhFLHwg
2026-09-02 22:37:40 +02:00
ddidderr 60fd7ba0c2 feat(peer)!: cut over to authenticated catalog sharing
Replace address-only trust and pushed peer state with installation identities,
SPKI-pinned QUIC, candidate-only discovery, and bounded responder-owned
protocol-8 pulls. The runtime now owns each network generation and all admitted
work through shutdown.

Add exact bundled content identities, reproducible manifest publishing,
capability-confined downloads, streaming BLAKE3 verification, quarantine and
retry, and crash-recoverable download and install transactions. Ship generated
fixture catalogs and fail closed when production manifests are absent.

The Tauri backend exposes durable sharing policy, redacted identity state, and
attempt-keyed transfer snapshots. Frontend consumption follows in the next
commit. Repository-wide test certificates and protocol-7 paths are removed.

BREAKING CHANGE: peers must use protocol 8 and exact catalog content artifacts;
protocol-7 frames and shared-certificate identities are no longer accepted.

Test Plan:
- `just test` -- passed on the completed stack (708 workspace tests)
- `just clippy` -- passed on the completed stack
- `just build` -- passed with fixture catalogs on the completed stack
- `just catalog-check-production` -- failed closed because the external
  production manifest corpus is absent
- `git diff --cached --check` -- passed
2026-08-10 13:59:18 +02:00