mirror of
https://github.com/therealaleph/MasterHttpRelayVPN-RUST.git
synced 2026-05-18 05:44:35 +03:00
b734f41faa
Three reported issues from v1.0.0 — one real bug, two UX gaps. google_ip auto-resolve (THE FIX) -------------------------------- Google rotates the A record for www.google.com across their anycast pool. A hardcoded default IP breaks new installs on any network that isn't geo-homed to the same edge — symptom is "all SNIs time out" even with a fresh deployment. On Start and via a new "Auto-detect" button, we now do a JVM-side InetAddress lookup BEFORE establishing the VPN (so the resolver uses the underlying network, not our own Virtual-DNS TUN — avoids a loop), update the config, and continue. The auto-resolve lives in the HomeScreen click handler (not MainActivity) so it goes through the same `persist(cfg)` the text fields use. Previous iteration did `ConfigStore.load → modify → save` directly to disk, which left Compose's in-memory cfg stale and a subsequent field edit would overwrite the fresh IP. One source of truth now. Also defensively repairs front_domain: if it's been corrupted into an IP literal (bad paste, whatever) we restore "www.google.com" — the TLS SNI on the outbound leg has to be a hostname or the handshake lands on the wrong vhost. Robust Stop ----------- The Stop button now dispatches both ACTION_STOP (graceful: runs teardown, stops tun2proxy, closes TUN fd, shuts down Rust runtime) AND stopService() (defensive: covers force-closed-then-reopened zombie state where Android auto-restarted our START_STICKY service in a fresh process and the in-memory TUN reference is gone). Check-for-updates ----------------- Tapping the version badge in the top bar now runs the same update_check that the desktop UI uses, via a new `Native.checkUpdate()` JNI entry point. Returns a JSON blob the Kotlin side parses into an "Up to date", "Update available: v→v <url>", "Offline: ...", or "Check failed: ..." snackbar. Mirrors the desktop's behavior so a user doesn't have to manually poll GitHub for new builds. Crash visibility ---------------- New MhrvApp.kt registers a process-wide uncaught exception handler. Crashes are now stamped into logcat under the `mhrv-crash` tag with the thread name before the default handler kills the process — previously the JVM crash in coroutines / the log drain / the tun2proxy worker was invisible unless you caught the dropoff in real time. Version bump: 1.0.0 → 1.0.1 (versionCode 100 → 101). Release APK rebuilt and replaces the 1.0.0 copy in releases/; CI will regenerate on the v1.0.1 tag push. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
92 lines
3.0 KiB
TOML
92 lines
3.0 KiB
TOML
[package]
|
|
name = "mhrv-rs"
|
|
version = "1.0.1"
|
|
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"] }
|
|
|
|
# Optional UI dep: only pulled in when --features ui is set.
|
|
eframe = { version = "0.28", default-features = false, features = [
|
|
"default_fonts",
|
|
"glow",
|
|
"persistence",
|
|
], optional = true }
|
|
|
|
# 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 }
|
|
|
|
[dev-dependencies]
|
|
# Used in mitm tests to sanity-check the cert extensions we emit.
|
|
x509-parser = "0.16"
|
|
|
|
[profile.release]
|
|
panic = "abort"
|
|
codegen-units = 1
|
|
lto = true
|
|
opt-level = 3
|
|
strip = true
|