mirror of
https://github.com/therealaleph/MasterHttpRelayVPN-RUST.git
synced 2026-05-17 21:24:48 +03:00
e70947ff0d
Closes #251. In Android Full mode, Telegram worked but Google search and most other websites failed silently. `apps_script` mode on the same setup was unaffected. **Root cause**: the udpgw magic destination (`198.18.0.1:7300`) was inside `198.18.0.0/15` — the exact range tun2proxy's `--dns virtual` allocator uses to synthesise fake IPs for hostname lookups. Whenever virtual DNS assigned `198.18.0.1` to a real hostname, that hostname's traffic was intercepted by tun2proxy *itself* as a udpgw connection and dropped. Telegram was immune because it uses hardcoded numeric IPs; `apps_script` mode was immune because it never sets `--udpgw-server`. **Fix**: move `UDPGW_MAGIC_IP` to `192.0.2.1` (RFC 5737 TEST-NET-1) — outside any virtual-DNS allocation pool. Coordinated change across the tunnel-node constant and the Android `--udpgw-server` flag. ## Back-compat v1.9.25 tunnel-nodes still recognise the legacy `198.18.0.1:7300` for one deprecation cycle (removal in v1.10.0). | Android | Tunnel-node | Full-mode UDP | |---|---|---| | v1.9.25 | v1.9.25 | ✅ fully fixed | | ≤v1.9.24 | v1.9.25 | ⚠️ handshake works (legacy IP still recognised), but the old client still asks tun2proxy for `198.18.0.1`, so the #251 virtual-DNS collision is still live on-device | | v1.9.25 | ≤v1.9.24 | ❌ breaks silently (old node rejects `192.0.2.1`) | The fix lives on the client side (which magic IP it asks tun2proxy to reserve). The back-compat is on the tunnel-node side (accepting both during the deprecation window). ## Verified locally - `cargo test --lib --release`: 231/231 ✅ - `cargo build --release --features ui --bin mhrv-rs-ui`: clean ✅ - `(cd tunnel-node && cargo test --release)`: 38/38 ✅ (+2 new tests for the IP change) ## Version bump Cargo.toml already bumped to 1.9.25 in this PR; `docs/changelog/v1.9.25.md` pre-baked. Will combine with any other PRs landing into v1.9.25 before tagging. Reviewed via Anthropic Claude. Co-Authored-By: dazzling-no-more <noreply@github.com> Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
114 lines
4.2 KiB
TOML
114 lines
4.2 KiB
TOML
[package]
|
|
name = "mhrv-rs"
|
|
version = "1.9.25"
|
|
edition = "2021"
|
|
description = "Rust port of MasterHttpRelayVPN -- DPI bypass via Google Apps Script relay with domain fronting"
|
|
license = "MIT"
|
|
|
|
[lib]
|
|
name = "mhrv_rs"
|
|
path = "src/lib.rs"
|
|
# `cdylib` lets the Android app dlopen libmhrv_rs.so via System.loadLibrary.
|
|
# `rlib` keeps the desktop binaries linking normally — same .rlib is used
|
|
# for `mhrv-rs` and `mhrv-rs-ui` builds on macOS/Linux/Windows.
|
|
crate-type = ["rlib", "cdylib"]
|
|
|
|
[[bin]]
|
|
name = "mhrv-rs"
|
|
path = "src/main.rs"
|
|
|
|
[[bin]]
|
|
name = "mhrv-rs-ui"
|
|
path = "src/bin/ui.rs"
|
|
required-features = ["ui"]
|
|
|
|
[features]
|
|
default = []
|
|
ui = ["dep:eframe"]
|
|
|
|
[dependencies]
|
|
tokio = { version = "1", features = ["rt-multi-thread", "macros", "net", "time", "io-util", "signal", "sync"] }
|
|
tokio-rustls = { version = "0.26", default-features = false, features = ["ring", "tls12"] }
|
|
rustls = { version = "0.23", default-features = false, features = ["ring", "std", "tls12"] }
|
|
rustls-pemfile = "2"
|
|
webpki-roots = "0.26"
|
|
rcgen = { version = "0.13", features = ["x509-parser"] }
|
|
rustls-pki-types = "1"
|
|
time = "0.3"
|
|
serde = { version = "1", features = ["derive"] }
|
|
serde_json = "1"
|
|
tracing = "0.1"
|
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
|
thiserror = "2"
|
|
base64 = "0.22"
|
|
bytes = "1"
|
|
httparse = "1"
|
|
rand = "0.8"
|
|
h2 = "0.4"
|
|
http = "1"
|
|
flate2 = "1"
|
|
directories = "5"
|
|
futures-util = { version = "0.3", default-features = false, features = ["std"] }
|
|
# 64-bit atomics on 32-bit MIPS/ARMv5 targets. Rust's std AtomicU64 is
|
|
# only available on targets that expose native 64-bit atomics, which
|
|
# mipsel-unknown-linux-musl does not — `AtomicU64` resolves to "no
|
|
# such name in sync::atomic" and the whole crate fails to build. The
|
|
# `fallback` feature uses a global spinlock when the target can't do
|
|
# 64-bit atomically; on x86_64 / aarch64 / armv7 / etc. it compiles
|
|
# down to the native instructions with no overhead.
|
|
portable-atomic = { version = "1", features = ["fallback"] }
|
|
|
|
# Optional UI dep: only pulled in when --features ui is set.
|
|
# Both `glow` (OpenGL 2+) and `wgpu` (DX12/Vulkan/Metal) are compiled in;
|
|
# the binary picks one at startup — glow by default for compat with the
|
|
# egui look-and-feel we've been shipping, but falls back to wgpu when
|
|
# `MHRV_RENDERER=wgpu` is set. Issue #28: users on older Windows
|
|
# hardware / RDP / VMs without OpenGL 2.0 crash with
|
|
# `egui_glow requires opengl 2.0+` — the wgpu backend uses DX12/Vulkan
|
|
# instead and covers those boxes.
|
|
eframe = { version = "0.28", default-features = false, features = [
|
|
"default_fonts",
|
|
"glow",
|
|
"wgpu",
|
|
"persistence",
|
|
"accesskit",
|
|
], optional = true }
|
|
url = "2.5.8"
|
|
|
|
# Unix-only deps. Must come after `[dependencies]` because starting a new
|
|
# table here otherwise ends the main one — anything below it (incl. eframe)
|
|
# would end up scoped to cfg(unix) and disappear on Windows builds.
|
|
# libc is referenced for the RLIMIT_NOFILE bump (issue #8 — OpenWRT routers
|
|
# ship a very low fd limit that fills up fast under browser load). Already
|
|
# pulled in transitively via tokio, so zero new weight.
|
|
[target.'cfg(unix)'.dependencies]
|
|
libc = "0.2"
|
|
|
|
# Android-only deps: jni gives us the extern "system" wrappers used in
|
|
# src/android_jni.rs; zero cost on any other platform because the whole
|
|
# module is `#[cfg(target_os = "android")]`.
|
|
#
|
|
# tun2proxy is the TUN <-> SOCKS5 bridge — it reads raw IP packets from the
|
|
# fd VpnService hands us, runs a userspace TCP/IP stack (smoltcp under the
|
|
# hood), and funnels every TCP/UDP flow through our local SOCKS5. Without
|
|
# this, VpnService establishes a TUN device nothing reads from and all
|
|
# traffic black-holes (symptom: Chrome shows DNS_PROBE_STARTED).
|
|
[target.'cfg(target_os = "android")'.dependencies]
|
|
jni = { version = "0.21", default-features = false }
|
|
tun2proxy = { version = "0.7", default-features = false, features = ["udpgw"] }
|
|
|
|
[dev-dependencies]
|
|
# Used in mitm tests to sanity-check the cert extensions we emit.
|
|
x509-parser = "0.16"
|
|
# `test-util` enables `tokio::test(start_paused = true)` so timing-
|
|
# sensitive tests in `tunnel_client` (the empty-poll cadence) can
|
|
# auto-advance virtual time instead of burning real wall-clock seconds.
|
|
tokio = { version = "1", features = ["test-util"] }
|
|
|
|
[profile.release]
|
|
panic = "abort"
|
|
codegen-units = 1
|
|
lto = true
|
|
opt-level = 3
|
|
strip = true
|