feat(recording): tap meshrelay pump and write .mcrec files (VS-4) #26

Merged
David merged 1 commit from feat/recording-capture-vs-4 into main 2026-05-17 14:32:23 +02:00
Owner

Summary

The Recordings panel already listed + deleted .mcrec files; the producer side was missing. This PR taps the meshrelay pump on the joining side and writes a JSON-LF .mcrec when the SPA opens the relay with record=1 and the server has a configured recording_dir.

Format

One JSON object per line:

  • header: {"time":0,"type":"meta","protocol":"<bits>","nodeid":"<id>"}
  • each chunk: {"time":<ms_from_start>,"type":"input"|"output","data":"<base64>"}

input = bytes from the joining side's WS toward the peer; output = bytes from the peer toward the joining side.

Why the joining side only

Both sides' pumps see the same bytes (one as inbound, one as outbound). Recording on only the joiner avoids double-write while still capturing both directions.

Test plan

  • cargo test -p meshcentral-web --lib meshrelay (2/2 passing).
  • cargo check -p meshcentral-web clean.
  • Reviewer: open a terminal session with record=1, confirm a fresh .mcrec appears under <recording_dir>/<nodeid>/ and that the legacy player can replay it.

Closes VS-4.

## Summary The Recordings panel already listed + deleted `.mcrec` files; the producer side was missing. This PR taps the meshrelay pump on the joining side and writes a JSON-LF `.mcrec` when the SPA opens the relay with `record=1` and the server has a configured `recording_dir`. ## Format One JSON object per line: - header: `{"time":0,"type":"meta","protocol":"<bits>","nodeid":"<id>"}` - each chunk: `{"time":<ms_from_start>,"type":"input"|"output","data":"<base64>"}` `input` = bytes from the joining side's WS toward the peer; `output` = bytes from the peer toward the joining side. ## Why the joining side only Both sides' pumps see the same bytes (one as inbound, one as outbound). Recording on only the joiner avoids double-write while still capturing both directions. ## Test plan - [x] `cargo test -p meshcentral-web --lib meshrelay` (2/2 passing). - [x] `cargo check -p meshcentral-web` clean. - [ ] Reviewer: open a terminal session with `record=1`, confirm a fresh `.mcrec` appears under `<recording_dir>/<nodeid>/` and that the legacy player can replay it. Closes VS-4.
feat(recording): tap meshrelay pump and write .mcrec files (VS-4)
Some checks failed
Check / fmt + clippy + build + tests (pull_request) Failing after 3s
Create release / Create release from merged PR (pull_request) Has been skipped
7f9f836cb0
The Recordings panel already listed and deleted `.mcrec` files under `recording_dir`; the producer side was missing. Adds a recording tap on the meshrelay pump.

When the SPA opens a relay with `record=1` AND the server has a configured `recording_dir`, the joining side allocates a JSON-LF writer at `<recording_dir>/<nodeid_or_"unknown">/<unixms>.mcrec`. Format mirrors the legacy player: a `meta` header carrying the protocol bitmap + nodeid, then one `{time, type:"input"|"output", data:"<base64>"}` per relayed chunk. `input` = bytes from the joining side's WS toward the peer; `output` = bytes from the peer toward the joining side.

Recording opens only on the second-arrival (joining) side so each chunk lands once in the file even though both sides' pumps see the same bytes. Failure to open or write a chunk logs a warning and the session continues without recording rather than dropping the live tunnel.

Wiring:

- `RelayQuery` grows `record: Option<String>`.
- `meshrelay_ws_handler` computes a `RecordingRequest` (`enabled` / `nodeid` / `protocol` / `dir`) before the WS upgrade and threads it through.
- `drive_session` calls `open_recorder` on the joining side and passes the optional `RelayRecorder` to `pump_socket`.
- `pump_socket` writes a chunk on each inbound (WS->peer) and each post-rendezvous outbound (peer->WS).

#VS-4 State Done
David merged commit 9992982e74 into main 2026-05-17 14:32:23 +02:00
David deleted branch feat/recording-capture-vs-4 2026-05-17 14:32:23 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/vervain-server!26
No description provided.