feat(vp): XRay/REALITY client engine (xray-core + gVisor tun2socks)#7
Merged
Conversation
caravel's data-plane engine gains an XRay/REALITY path alongside AmneziaWG, behind the same vp surface (single binary, both protocols): - UpXRay(cfg XRayConfig, tunDev tun.Device) mirrors Up for AmneziaWG: it starts an embedded xray-core client (loopback SOCKS inbound + VLESS+REALITY outbound to the node) and bridges the platform tun through it. - tun2socks bridges the tun to the xray client via a userspace gVisor netstack: a TCP forwarder terminates each app flow and re-originates it as a SOCKS connection to the original destination, which xray carries over REALITY. Cross-platform by design — it uses gVisor's channel endpoint over the amneziawg-go tun.Device abstraction (which already handles the macOS utun header / mobile fd / Windows wintun), NOT the Linux-only fdbased endpoint. - clientJSON renders the xray client config (VLESS + REALITY: serverName, fingerprint, publicKey, shortId) from the resolved XRayConfig. - Stats counts rx/tx at the splice. Tests: an always-run config-builder test, and a live REALITY engine test that stands up an in-process server + the client and proves a request rides the tunnel and egresses (skipped when the decoy host is unreachable). The engine cross-compiles for linux/arm64, windows/amd64, and darwin (gVisor + amneziawg-go + xray-core across the platform matrix). The gomobile-export wrapper (root core package) + per-platform shell wiring that supplies the tun device — and live verification of the tun2socks packet path — land with the live test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Khalefa <khalefa@alahmad.org>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
caravel's data-plane engine gains an XRay/REALITY path alongside AmneziaWG, behind the same
vpsurface (single binary, both protocols). Consumes theXRayTunnelfrom #6; pairs with node #14 (REALITY server) and coxswain #50.What
UpXRay(cfg XRayConfig, tunDev tun.Device)mirrorsUpfor AmneziaWG: starts an embedded xray-core client (loopback SOCKS inbound + VLESS+REALITY outbound to the node) and bridges the platform tun through it.tun2socksbridges the tun to the xray client via a userspace gVisor netstack: a TCP forwarder terminates each app flow and re-originates it as a SOCKS connection to the original destination, which xray carries over REALITY. Cross-platform by design — it uses gVisor'schannelendpoint over theamneziawg-gotun.Deviceabstraction (which already handles the macOS utun header / mobile fd / Windows wintun), not the Linux-onlyfdbasedendpoint.clientJSONrenders the xray client config (VLESS + REALITY: serverName, fingerprint, publicKey, shortId) from the resolvedXRayConfig.Statscounts rx/tx at the splice.Why this is sound (de-risked first)
Before writing this I de-risked the combo on the native builder: (1) an xray-core client embed carries a real REALITY flow + egresses, CGO-free static; (2) gVisor netstack + xray-core compile together into one CGO-free static binary. Both proven.
Tests
TestXRayClientJSON— always-run; asserts the rendered xray config (SOCKS inbound, VLESS vnext, REALITY camouflage, chrome fingerprint default).TestXRayRealityEngine— stands up an in-process REALITY server + the engine's client and proves a request rides the tunnel and egresses (skipped when the decoy host is unreachable, so airgapped CI passes). It runs and passes where there's network.linux/arm64,windows/amd64,darwin/arm64,linux/amd64— gVisor + amneziawg-go + xray-core across the platform matrix.Not in this PR (lands with the live test)
The gomobile-export wrapper in the root
corepackage + per-platform shell wiring that supplies the tun device, and live verification of the tun2socks packet path (it compiles + the standard pattern, but moving real packets needs a real tun — that's the deferred live test).🤖 Generated with Claude Code