mirror of
https://github.com/therealaleph/MasterHttpRelayVPN-RUST.git
synced 2026-05-18 06:24:35 +03:00
40c2b6c509
Adds end-to-end UDP support: SOCKS5 client UDP ASSOCIATE → tunnel-mux
udp_open/udp_data ops → tunnel-node UDP sessions → real UDP to upstream.
QUIC/HTTP3, DNS, and STUN now traverse full mode without falling back to
TCP or leaking outside the tunnel.
Apps Script proxies the new ops opaquely through the existing batch
endpoint; CodeFull.gs only gets a doc-comment update.
Highlights:
- proxy_server.rs: SOCKS5 UDP ASSOCIATE handler with per-session task,
bounded uplink mpsc channel, adaptive empty-poll backoff (500 ms → 30 s),
source-IP validation against the control TCP peer, port-locking on
first valid datagram, and self-removal from the dispatch map on eof.
- tunnel_client.rs: UdpOpen / UdpData / close_session mux variants
alongside the existing TCP plumbing; pkts decoder helper.
- tunnel-node: UdpSessionInner with bounded VecDeque queue, drop-oldest
on overflow with queue_drops counter and warn-then-throttled logs,
last_active refreshed only on real activity (uplink send or upstream
recv — empty polls do not refresh), independent TCP/UDP drain in
handle_batch Phase 2, separate active-drain (150 ms) and retry
(250 ms) windows for UDP, idle long-poll (5 s).
- Tests: SOCKS5 UDP packet parser (IPv4/IPv6/DOMAIN round-trips,
truncation rejects, fragmented rejects), UDP queue overflow drop +
counter, regression test that batch with both UDP and TCP-data ops
still runs the TCP retry pass.
Docs: README + android.{md,fa.md} updated to reflect UDP availability
in full mode; tunnel-node/README documents the new ops.
129 lines
4.0 KiB
Markdown
129 lines
4.0 KiB
Markdown
# Tunnel Node
|
||
|
||
HTTP tunnel bridge server for MasterHttpRelayVPN "full" mode. Bridges HTTP tunnel requests (from Apps Script) to real TCP connections.
|
||
|
||
## Architecture
|
||
|
||
```
|
||
Phone → mhrv-rs → [domain-fronted TLS] → Apps Script → [HTTP] → Tunnel Node → [real TCP] → Internet
|
||
```
|
||
|
||
The tunnel node manages persistent TCP and UDP sessions. TCP sessions are real TCP connections to a destination server; UDP sessions are connected UDP sockets to one destination host:port. Data flows through a JSON protocol:
|
||
|
||
- **connect** — open TCP to host:port, return session ID
|
||
- **data** — write client data, return server response
|
||
- **udp_open** — open UDP to host:port, optionally send the first datagram
|
||
- **udp_data** — send one UDP datagram, or poll for returned datagrams when `d` is omitted
|
||
- **close** — tear down session
|
||
- **batch** — process multiple ops in one HTTP request (reduces round trips)
|
||
|
||
## Deployment
|
||
|
||
### Cloud Run
|
||
|
||
```bash
|
||
cd tunnel-node
|
||
gcloud run deploy tunnel-node \
|
||
--source . \
|
||
--region us-central1 \
|
||
--allow-unauthenticated \
|
||
--set-env-vars TUNNEL_AUTH_KEY=$(openssl rand -hex 24) \
|
||
--memory 256Mi \
|
||
--cpu 1 \
|
||
--max-instances 1
|
||
```
|
||
|
||
### Docker — prebuilt image (any VPS)
|
||
|
||
The fastest path. Pull a prebuilt image and run it; no Rust toolchain needed on the VPS.
|
||
|
||
```bash
|
||
# Generate a strong secret. Save it — you'll paste the same value into CodeFull.gs.
|
||
SECRET=$(openssl rand -hex 24)
|
||
echo "Your TUNNEL_AUTH_KEY: $SECRET"
|
||
|
||
# Pull + run.
|
||
docker run -d \
|
||
--name mhrv-tunnel \
|
||
--restart unless-stopped \
|
||
-p 8080:8080 \
|
||
-e TUNNEL_AUTH_KEY="$SECRET" \
|
||
ghcr.io/therealaleph/mhrv-tunnel-node:latest
|
||
```
|
||
|
||
The `:latest` tag tracks the most recent release. To pin a specific version (recommended for production), use `ghcr.io/therealaleph/mhrv-tunnel-node:v1.5.0` (or whatever release you're on). Image is available for `linux/amd64` and `linux/arm64`.
|
||
|
||
**docker-compose.yml** if you prefer:
|
||
|
||
```yaml
|
||
services:
|
||
tunnel:
|
||
image: ghcr.io/therealaleph/mhrv-tunnel-node:latest
|
||
restart: unless-stopped
|
||
ports:
|
||
- "8080:8080"
|
||
environment:
|
||
TUNNEL_AUTH_KEY: ${TUNNEL_AUTH_KEY}
|
||
```
|
||
|
||
Then `TUNNEL_AUTH_KEY=your-secret docker compose up -d`.
|
||
|
||
### Docker — build from source
|
||
|
||
If you'd rather build the image yourself (or add custom changes):
|
||
|
||
```bash
|
||
cd tunnel-node
|
||
docker build -t tunnel-node .
|
||
docker run -p 8080:8080 -e TUNNEL_AUTH_KEY=your-secret tunnel-node
|
||
```
|
||
|
||
### Direct binary
|
||
|
||
```bash
|
||
cd tunnel-node
|
||
cargo build --release
|
||
TUNNEL_AUTH_KEY=your-secret PORT=8080 ./target/release/tunnel-node
|
||
```
|
||
|
||
## Environment Variables
|
||
|
||
| Variable | Required | Default | Description |
|
||
|----------|----------|---------|-------------|
|
||
| `TUNNEL_AUTH_KEY` | Yes | `changeme` | Shared secret — must match `TUNNEL_AUTH_KEY` in CodeFull.gs |
|
||
| `PORT` | No | `8080` | Listen port (Cloud Run sets this automatically) |
|
||
|
||
## Protocol
|
||
|
||
### Single op: `POST /tunnel`
|
||
|
||
```json
|
||
{"k":"auth","op":"connect","host":"example.com","port":443}
|
||
{"k":"auth","op":"data","sid":"uuid","data":"base64"}
|
||
{"k":"auth","op":"close","sid":"uuid"}
|
||
```
|
||
|
||
### Batch: `POST /tunnel/batch`
|
||
|
||
```json
|
||
{
|
||
"k": "auth",
|
||
"ops": [
|
||
{"op":"data","sid":"uuid1","d":"base64"},
|
||
{"op":"udp_data","sid":"uuid2","d":"base64"},
|
||
{"op":"close","sid":"uuid3"}
|
||
]
|
||
}
|
||
→ {"r": [{...}, {...}, {...}]}
|
||
```
|
||
|
||
### Health check: `GET /health` → `ok`
|
||
|
||
## Performance: deployment count and pipeline depth
|
||
|
||
The mhrv-rs client runs a pipelined batch multiplexer in full mode. Each Apps Script round-trip takes ~2s, so the client fires multiple batch requests concurrently — the pipeline depth equals the number of configured script deployment IDs (minimum 2, no upper cap).
|
||
|
||
More deployments = more concurrent batches hitting the tunnel-node = lower per-session latency. With 6 deployments, a new batch arrives every ~0.3s instead of every 2s.
|
||
|
||
The tunnel-node itself is stateless per-request (sessions are keyed by UUID), so it handles concurrent batches naturally. For best results, deploy 3–12 Apps Script instances across separate Google accounts and list all their deployment IDs in the client config.
|