Skip to content

1.6.0: compress remote output and attach behind the hello - #20

Merged
Lakr233 merged 2 commits into
mainfrom
remote-latency
Oct 11, 2026
Merged

Lakr233 merged 2 commits into
mainfrom
remote-latency

Conversation

@Lakr233

@Lakr233 Lakr233 commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

For 1.6.0, not a patch: it adds a negotiated hello field and a header flag.

What changes

  1. Host → device frame compression. The device's hello offers cmpr (LZFSE). The host turns it on for that link only after the device proof checks out.
    • Each frame of 1 KiB or more is compressed on its own (no shared dictionary). Header padding byte 5 is the flag, then the u32 plain length.
    • Device input, small frames and pairing links stay plain.
    • The decoder refuses any length over the frame limit before it decodes anything. A host never accepts a compressed frame.
    • The link window and its receipts count a compressed frame as the plain frame it stands for, so the 1 MiB window still bounds terminal output.
  2. Pipelined reattach. On a remote link the app sends attachSession right behind the hello. The attach reply is held until the hello's reply and dropped if the hello failed.
    • Opens still wait for the hello, so a hello given up on can't leave an orphan shell on the host.
    • A close requested while the hello fails is now delivered over a link of its own.
  3. Lab and harness.
    • remote-lab latency times each phase of a reattach.
    • The lab offers compression, as the app does.
    • The flood scenario's ACK can no longer be spliced into a flood write (it failed on every run before this fix).
    • The remote harness gains 15 compression checks: round trip, mixed stream, window accounting, refusals.

Compatibility: an older peer on the 1.5 line simply doesn't offer or doesn't accept, and gets plain frames. A pipelined attach works against the unchanged 1.5.x host. Verified against the released 1.5.2 on a vphone.

Measured

remote-lab latency reattaches a session with a full 256 KiB replay. Median of 8–15 runs. Paths go through netem-proxy.py: wifi = 30 ms RTT at 40 Mbit, cellular = 180 ms RTT at 8 Mbit, awful = 700 ms RTT at 600 kbit.

Host Path 1.5.x this branch
tart macOS 27 (VM loopback) wifi 265 ms 145 ms
tart cellular 1105 ms 540 ms
vphone iOS 26.6.2 (roothide) wifi 222 ms 124 ms
vphone cellular 1027 ms 522 ms
vphone awful 6115 ms 2139 ms
vphone, 8 cores busy wifi / cellular 178 / 1011 ms 100 / 535 ms
tart, memory pressure wifi / cellular 274 / 1035 ms 154 / 522 ms
  • On a clean path nothing changes: within ±3 ms.
  • Replay on the wire is 262 KB before and 34–38 KB after.
  • sz of an 8 MiB text file (1.5.1 → branch):
    • wifi: 5.4 → 3.1 s
    • cellular: 15.5 → 9.0 s
    • awful: 135.5 → 59.5 s
    • flapping: 43.5 → 22.0 s
  • sz of random data is unchanged.
  • Helper peak footprint on tart: 12 → 13 MB.

Scenario suite, 46 runs on tart against the 1.5.1 helper and against this branch's: the same pass/fail set on both. The only failures are awful/paste and tunnel/deadzone, which fail identically on 1.5.1. Tunnel and deadzone outlast the 20 s reply limit by design; the profile comments still say 45 s.

App, end to end: vphone app ⇄ tart host through a local relay.

  • The host log shows the attach landing in the same millisecond as the hello's authentication.
  • Four cold restores (background, kill, relaunch) each reattached with a complete replay.
  • Live output keeps flowing after the reattach.

BREACH: on by default (decided)

Per-frame compression stops one frame's size from leaking another frame's contents. It does not cover a single frame that holds both a secret and attacker-chosen text, resent many times while someone watches record sizes. A terminal doesn't resend on its own, so this is judged impractical; compression stays on for every link that offers it, with the residual risk recorded beside RemoteFrameCompression.

Not in this PR (found while testing)

  • vphone, ~7 GB of incompressible memory pressure: jetsam kills ighostvtd (the proxy) within seconds, and io exits with it. Every session is lost. The released 1.5.2 behaves identically. 5 GB is survived.
  • Bonjour .service resolution costs about 5 ms here, so dialing the advertised IPv4 directly was not pursued.

Review

Three adversarial review rounds by subagents. Every finding was fixed or documented in the code: BREACH wording, orphan-shell risk, link window counted in wire bytes, scratch allocation, decoder threshold, deferred close on hello failure, deinit leak.

make check, make test (harnesses) and make deb / make mac-zip all pass.

🤖 Generated with Claude Code

Lakr233 and others added 2 commits October 11, 2026 02:45
A device's hello offers LZFSE frame compression and the host turns it
on once the proof checks out: each frame of 1 KiB and up is compressed
alone, flagged in the header's padding, so a reattach's 256 KiB replay
crosses as 30-60 KiB. The link window counts a compressed frame as the
plain one it stands for. On a remote link a reattach now leaves right
behind the hello and its answer waits for the hello's, saving a round
trip; an open still waits, so a hello given up on cannot leave a shell
no tab knows. A close asked for while the hello fails now reaches the
host over a link of its own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`remote-lab latency` dials, says hello and attaches a session again and
again, phase by phase, with the attach pipelined or not and compression
offered or not. The lab offers compression as the app does, and the
flood scenario's ACK can no longer be spliced into a write of the flood.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Lakr233
Lakr233 marked this pull request as ready for review October 11, 2026 01:43
@Lakr233
Lakr233 merged commit 612da41 into main Oct 11, 2026
6 checks passed
@Lakr233
Lakr233 deleted the remote-latency branch October 11, 2026 02:12
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.

1 participant