Skip to content

Desktop multiplexer: recordings the OpenFrame uploader accepts, orphan multiplexers disposed - #218

Merged
mikhailm-coder merged 2 commits into
masterfrom
hotfix/mesh-desktop-multiplex
Oct 8, 2026
Merged

mikhailm-coder merged 2 commits into
masterfrom
hotfix/mesh-desktop-multiplex

Conversation

@mikhailm-coder

@mikhailm-coder mikhailm-coder commented Oct 8, 2026 •

Copy link
Copy Markdown

Makes the desktop multiplexer's recordings first-class OpenFrame recordings, so settings.desktopMultiplex: true can be rolled out: one agent stream and one recording per device however many browsers join a session (Phase 3 live watching builds on it).

CU-17tkuw5v5zv
Change-Set: hotfix-mesh-desktop-multiplex

What changes

  • Recording header and file name. The multiplexer wrote desktopSession-<domain>-<ts>-<nodeHash>.mcrec with no sessionid/userid, so plugins/openframe.js skipped every file and registration (which lists by request id) never saw them: with the flag alone nothing uploads. It now writes relaysession-<domain>-<UTC stamp>-<user>-<device>-<relayId>.mcrec and a header with sessionid (the relay id of the peer that created the multiplexer, i.e. the technician's <requestId>.2.<nonce>), userid and username, exactly like meshrelay.js. The upload key <domain>/recordings/<nodeHash>/<relayId>/<file>, the backend's <requestId>. prefix listing, saas-lib's filename timestamp parser and the player's stitching work unchanged.
  • cmd 82 (display positions) request. Upstream sent the cached positions back to the agent instead of to the browser that asked, so a multiplexed technician could lose monitor geometry. The cached frame now goes to the requesting viewer.
  • cmd 11 (display list) request from a viewer was "un-handled" and dropped; it is forwarded to the agent as on a plain relay (the agent answers with 82 then 11).
  • Orphan multiplexers. A multiplexer is keyed by device and upstream only disposed it when the agent left or when the last viewer left with an agent present. A browser that never got its agent (device offline, gate refused the agent leg) or an agent tunnel whose browser went away left a viewer-less multiplexer behind, header-only recording open, and the next session on that device joined it and was recorded under the stale relay id and user. Harmless before, because such files never uploaded; with a valid header they would have landed in the wrong request folder. Now the last viewer leaving disposes the multiplexer even without an agent, a viewer-less multiplexer whose session never started is replaced when a relay under another id reaches the device, and a header-only recording of a session that never started is deleted instead of published (a plain relay never writes one for a session that never connected, so the backend's never-connected handling is unchanged).
  • Duplicate agent tunnel. addPeer refuses a second agent but performRelay ignored the result and left that socket attached to nothing; it is closed instead. Reachable when a browser redials while its previous socket is still half-open on the server.

Flag off: unchanged, webserver.js only routes p=2 relays here when settings.desktopmultiplex (or the domain flag) is true.

Verified

  • node --check, plus a smoke test against the patched module with a stubbed webserver and the real plugins/openframe.js helpers: one file relaysession-tenant-uuid-2026-10-08-09-56-03-gateway-svc-DESKTOP-ABC1-01ARZ3NDEKTSV4RRFFQ69G5FAV.2.k7x9q1.mcrec; header sessionid/userid/username/protocol: 2; recordingObjectKey → tenant-uuid/recordings/HASH123/<relayId>/<file>; saas-lib MeshFilenameTimestamp regex matches the stamp; a viewer's cmd 82 request is answered to that viewer only; cmd 11 reaches the agent; a second agent is refused; the last viewer leaving closes the agent and fires the recording event with the file name; a viewer-only multiplexer is disposed when the viewer leaves and its header-only file deleted with no event; an agent-only one is abandoned the same way; a traversal-shaped relay id stays inside the recordings directory and is skipped by the uploader.

Live verification on dev (after the openframe-saas-tenant PR of this change set turns the flag on)

  • a session uploads one file per relay id under its request id, registers and plays in the player
  • the gateway gate admits the agent tunnel (it dials with the technician's relay id)
  • a reconnect (frontend letsencrypt in config.json prevents MC from starting Ylianst/MeshCentral#519) redials with a new relay id and recording continues as today
  • a monitor switch keeps display positions for the technician
  • turning the flag off restores today's behaviour

Change set flamingo-stack/meshcentral#218: these pull requests are one change, reviewed together.

  • flamingo-stack/meshcentral#218 (this pull request): Desktop multiplexer: recordings the OpenFrame uploader accepts, orphan multiplexers disposed · landed
  • …and 1 pull request not visible

Linked work

Linked by the Depends-On / Change-Set lines in these descriptions; this block is maintained by the hub.

@mikhailm-coder

Copy link
Copy Markdown
Author

@flamingo-review

@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

🦩 Flamingo Code Review

✅ No findings on the current head.

Advisory: findings do not block the merge.

2 possible problems checked and ruled out, 1 after reading more of the repository
  • meshdesktopmultiplex.js:326 abandon() path can leave orphaned agent connection when dispose() is skipped: Speculative concern about code outside the diff (the agent close-removePeer wiring) that was not read; the candidate itself admits read budget was exhausted and cannot be verified against actual behavior in this repository.
  • meshrelay.js:1255 obj.deskMultiplexor.addPeer(obj) return value check added on a path that never returns false for agents: Candidate itself concludes the new code is correct for agents and the viewer-path note is informational only, not a defect.

Review again. New commits are not reviewed until you ask:

  • Review the new commits: only what was pushed since this review
  • Review the whole diff again: everything, including what was already reviewed

Or comment @flamingo-review (new commits) or @flamingo-review full (everything). Add the flamingo-review-always label to review every push.

Started 2026-10-08 10:21 UTC · updated 2026-10-08 10:23 UTC · workflow run

…s, orphan multiplexers disposed

With settings.desktopMultiplex on, the multiplexer wrote desktopSession-<ts>-<nodeHash>.mcrec
with no sessionid/userid, so the OpenFrame uploader skipped every file and nothing registered.
The file is now relaysession-<domain>-<UTC>-<user>-<device>-<relayId>.mcrec and the header carries
sessionid (the relay id of the peer that created the multiplexer, i.e. the technician's
<requestId>.2.<nonce>), userid and username, so the upload key, the per-request bucket listing
and the player work unchanged.

A multiplexer whose session never starts no longer outlives it: the last viewer leaving disposes
it even when no agent arrived, a viewer-less one that never started is replaced when a relay under
another id reaches the device, and its header-only recording is deleted instead of published.
Before, such a leftover caught the next session on the device and recorded it under the stale id.

Also: a viewer's cmd 82 request is answered from the cache to that viewer instead of being sent back
to the agent; a viewer's cmd 11 (display list) request is forwarded to the agent as on a plain relay;
a second agent tunnel on the same device is closed instead of staying attached to nothing.
@mikhailm-coder
mikhailm-coder force-pushed the hotfix/mesh-desktop-multiplex branch from 15e6cdf to 89ad24e Compare October 8, 2026 13:09
@mikhailm-coder
mikhailm-coder merged commit 33cf6d1 into master Oct 8, 2026
13 of 14 checks passed
@mikhailm-coder
mikhailm-coder deleted the hotfix/mesh-desktop-multiplex branch October 8, 2026 16:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants