feat: add v2.6 WebSocket reverse carrier with Go interop CI #104

Merged
ada merged 4 commits from feat/v260-websocket-carrier into master 2026-10-03 09:09:22 +00:00
Collaborator

Problem

Upstream v2.6.0 official client uses portal.reverse.v1 WebSocket+yamux reverse sessions; the Rust relay only accepted the older raw reverse carrier. A Rust↔Rust test alone cannot establish the Go client wire contract.

Change

  • Route WebSocket /sdk/connect before overlay/raw, with capability in requested subprotocols and marker-only response.
  • One replaceable mux session per lease; per-stream current-capability reauthentication (8 KiB/10 s, one-byte decision) and max 8 concurrent auth tasks to prevent unbounded idle-stream resource amplification.
  • Keep raw and IVNP routes untouched. Include pinned upstream Go DialReverseMux/Open interop and make it a required PR CI step.
  • Document that this is a preparatory v2.6 slice, not complete official-client/public Axis B acceptance.

Validation

  • cargo fmt --all --check, cargo test --locked -p portal-relay: 205 passed, 4 ignored; cargo clippy --locked -p portal-relay --all-targets -- -D warnings; git diff --check origin/master...HEAD.
  • bash scripts/v260-reverse-mux-interop.sh against immutable upstream v2.6.0 695b60121b9aba68c4612a9bb990e086a2bfd36f: real Go handshake, stale/fresh capability, bidirectional bytes, stream close, mux cancellation PASS. Exact tag/commit and override rejection checked.
  • Five repeated idle-stream flood regressions passed. The interop test is now in CI; exact PR head must pass both required contexts before merge.

Remaining gates

No full official CLI→Rust TLS endpoint, container parity, browser fetch, authenticated public IVNP Axis B or production release evidence yet. Cargo package remains v2.5.1; metadata retarget is separate and unmerged. No tag/deploy or worker latch change.

## Problem Upstream v2.6.0 official client uses `portal.reverse.v1` WebSocket+yamux reverse sessions; the Rust relay only accepted the older raw reverse carrier. A Rust↔Rust test alone cannot establish the Go client wire contract. ## Change - Route WebSocket `/sdk/connect` before overlay/raw, with capability in requested subprotocols and marker-only response. - One replaceable mux session per lease; per-stream current-capability reauthentication (8 KiB/10 s, one-byte decision) and max 8 concurrent auth tasks to prevent unbounded idle-stream resource amplification. - Keep raw and IVNP routes untouched. Include pinned upstream Go `DialReverseMux`/`Open` interop and make it a required PR CI step. - Document that this is a preparatory v2.6 slice, not complete official-client/public Axis B acceptance. ## Validation - `cargo fmt --all --check`, `cargo test --locked -p portal-relay`: 205 passed, 4 ignored; `cargo clippy --locked -p portal-relay --all-targets -- -D warnings`; `git diff --check origin/master...HEAD`. - `bash scripts/v260-reverse-mux-interop.sh` against immutable upstream v2.6.0 `695b60121b9aba68c4612a9bb990e086a2bfd36f`: real Go handshake, stale/fresh capability, bidirectional bytes, stream close, mux cancellation PASS. Exact tag/commit and override rejection checked. - Five repeated idle-stream flood regressions passed. The interop test is now in CI; exact PR head must pass both required contexts before merge. ## Remaining gates No full official CLI→Rust TLS endpoint, container parity, browser fetch, authenticated public IVNP Axis B or production release evidence yet. Cargo package remains v2.5.1; metadata retarget is separate and unmerged. No tag/deploy or worker latch change.
ci: require pinned Go reverse mux interoperability
All checks were successful
Rust CI / Format, lint, and test (pull_request) Successful in 3m4s
Rust CI / Build and start linux/arm64 image (no push) (pull_request) Successful in 1m2s
2feedd6fc2
ada merged commit 3b98bdca14 into master 2026-10-03 09:09:22 +00:00
ada deleted branch feat/v260-websocket-carrier 2026-10-03 09:09:22 +00: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
gofix/portal-tunnel-rs!104
No description provided.