feat(connect): Crabfleet Connect foundation — Go RFB core + Linux backend - #101
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e5d4ced529
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // Backend close must precede the wait: a platform capture call may be | ||
| // blocked in an OS round trip that ignores Go context cancellation. | ||
| server.wg.Wait() | ||
| <-cleanupDone |
There was a problem hiding this comment.
Do not wait after the cleanup timeout fires
When a backend input release blocks or ignores the 500 ms context, the select above can continue on cleanupContext.Done(), but this unconditional receive waits for releaseAll anyway. In that shutdown path Close() can still hang indefinitely, and session goroutines may also be stuck behind the coordinator lock, so the teardown is not actually fenced; return after the timeout or make the final wait conditional on cleanupDone already closing.
Useful? React with 👍 / 👎.
Summary
Foundation for Crabfleet Connect — the cross-platform host agent you install on a machine to share it to the macOS viewer / web client (like Jump Desktop Connect). This is the first increment: a shared Go implementation of the host side of Crabfleet's RFB wire protocol plus a Linux backend. It builds, cross-compiles, and passes protocol tests in CI without physical Linux hardware; real X11 capture is behind a build tag.
internal/rfb— host-side RFB 3.8: handshake, per-run VNC-DES auth (Security None removed on direct listeners, constant-time compare, standard bit-reversed key), ClientInit/ServerInit, SetEncodings negotiation, FramebufferUpdateRequest loop, Tight/JPEG encoding, client-side cursor pseudo-encodings, pointer/key input. Strict bounds, big-endian, malformed → session close, bounded queues, fenced teardown.internal/connect—Capturer/InputSinkbackends: a pure-Go synthetic backend (CI-safe on any OS) and a Linux X11 backend (MIT-SHM capture + XFixes cursor + XTest input) behind//go:build linux.cmd/crabfleet-connect— the host binary: per-run share password, listener bind (loopback default; explicit bind required for remote since VNC-DES doesn't encrypt), synthetic fallback when no real capture.Honest scope
This is a foundation, not a finished product. Real: protocol core, Tight/JPEG, VNC-DES auth, synthetic backend, Linux X11 backend compiles under
GOOS=linux. Deferred: H.264/HEVC encode, Wayland/PipeWire, ARD host auth, audio, clipboard, service packaging, and real-hardware validation (no physical Linux box was available). No untested hardware capture is claimed to work.Proof
go build ./...,go vet ./...: cleango test ./...: 159 pass (RFB handshake/auth vectors, Tight/JPEG framing, bounds/malformed rejection, synthetic end-to-end handshake+auth+framebuffer)pnpm test: 969/969 (unchanged; no TS touched)