Skip to content

feat(vp): XRay/REALITY client engine (xray-core + gVisor tun2socks)#7

Merged
bodaay merged 1 commit into
mainfrom
feat/xray-reality-engine
Jun 6, 2026
Merged

feat(vp): XRay/REALITY client engine (xray-core + gVisor tun2socks)#7
bodaay merged 1 commit into
mainfrom
feat/xray-reality-engine

Conversation

@bodaay

@bodaay bodaay commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

caravel's data-plane engine gains an XRay/REALITY path alongside AmneziaWG, behind the same vp surface (single binary, both protocols). Consumes the XRayTunnel from #6; pairs with node #14 (REALITY server) and coxswain #50.

What

  • UpXRay(cfg XRayConfig, tunDev tun.Device) mirrors Up for AmneziaWG: 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.

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.
  • The engine cross-compiles for 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 core package + 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

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>
@bodaay bodaay merged commit fc7355a into main Jun 6, 2026
@bodaay bodaay deleted the feat/xray-reality-engine branch June 6, 2026 17:48
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