[package] name = "mhrv-rs" version = "1.9.16" 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