a1b45bbfb2a6b66f57219b25d0683323e5db8d2e
1
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
e83dba94a0 |
feat: add a root, system-wide run mode without VpnService (#5812)
* feat: add a root, system-wide run mode without VpnService Adds an optional Root mode for rooted devices that routes the whole device's traffic through the existing in-process core without Android's VpnService, plus an opt-in LAN/tethering sharing feature. Non-root devices are unaffected and keep VPN / Proxy-only (VPN stays the default). - ERunMode (VPN, PROXY_ONLY, TUN2SOCKS) persisted in the existing PREF_MODE; RootManager gates root modes (greyed-out for non-root, service refuses to start). - CoreRootService + core/root/RootProxyManager run hev-socks5-tunnel as a standalone root process into the core's SOCKS inbound, steered by an iptables mangle MARK chain + a dedicated route table. Full TCP + UDP. hev-socks5-tunnel is the same engine already bundled for the VPN hev path, so no new third-party dependency is added. - Capture parity with VpnService incl. per-app proxy/bypass; DNS funneled into the core (netd-aware, no uid filter) so names resolve through the configured resolver with no LAN-resolver leak. - IPv6 parity: routed into the tun when enabled, otherwise native v6 is blackholed for the captured apps (REJECT) so they fall back to v4-through-proxy, like a v4-only VpnService. - MTU taken from the existing VPN MTU setting; hev tun multi-queue + SOCKS tcp-fastopen enabled. - CI fetches the hev-socks5-tunnel binary per-ABI from heiher/hev-socks5-tunnel releases (the same upstream the VPN hev path uses). * build: compile libhevsockstun.so from source instead of downloading Build the standalone hev-socks5-tunnel binary used by Root mode from the pinned hev-socks5-tunnel submodule in compile-hevtun.sh, alongside the existing JNI shared library, and drop the prebuilt release download from the build workflow. Both hev artifacts now come from the same in-tree source, so the binary is fully auditable and version-locked to the submodule rather than a fetched release asset. The executable is built without -DENABLE_LIBRARY (so hev-main.c's main() is included) via BUILD_EXECUTABLE, reusing the NDK toolchain already used for the JNI library. * refactor(root): address review feedback - LAN-sharing guard now checks the cheap, usually-false PREF_ROOT_LAN_SHARING preference before RootManager.cachedRoot(), so the common path short-circuits without touching root state. - Move RootManager into the core.root package next to RootProxyManager and RootShell (CoreRootService stays under service/). - Probe su only when the user opts into a root feature — selecting a root mode or enabling LAN sharing — instead of automatically on every Settings open. If root is denied the selection is reverted with a toast. This avoids an unsolicited root-grant prompt for the common non-root case; root mode for a persisted selection is still re-verified when the service starts. * refactor(root): use coroutines instead of Thread for su probing Replace raw Thread usage in the root path with kotlinx coroutines, as requested in review. RootManager.refreshAsync (a callback + daemon Thread) becomes a suspending refresh() that runs the blocking su probe on Dispatchers.IO and returns the result. Callers updated accordingly: - SettingsActivity probes on demand via lifecycleScope.launch and updates the UI directly on resume (no manual runOnUiThread). - CoreVpnService starts the LAN-sharing client over CoroutineScope(IO) instead of a daemon Thread. * fix(root): don't capture all apps when per-app proxy resolves no uids In allow (proxy-only) mode the mangle/v6 builders fell through to the catch-all "mark/reject everything" branch whenever selectedUids was empty. That is a fail-open: if the selected packages momentarily fail to resolve to uids (e.g. at early boot, before PackageManager is ready), every unselected app gets tunneled instead of none — a privacy leak and the cause of per-app "proxying everything" after a reboot. Gate the catch-all on the mode itself (all-apps or bypass) rather than on "selected list happened to be non-empty". In allow mode mark only the resolved uids; if none resolved, mark nothing (fail closed). Mirror the same fix in the IPv6 blackhole chain. * fix(root): wait for async rule setup before teardown on stop CoreRootService/CoreVpnService post the foreground notification as soon as the core starts but install the root routing rules in a launched coroutine, which can take seconds (the setup script waits for the tun device to appear). If the user stops the service during that window, onDestroy/stopAllService ran the synchronous teardown first and the still-running setup then re-installed the rules and tun afterwards — leaving orphan routing rules and a tun forwarding into a now-dead core, which blackholes all traffic until the next start/stop cycle clears it (the "disconnect from the notification kills the internet, reconnect+disconnect to fix it" bug). Track the setup job and cancelAndJoin it before tearing down so teardown always runs last and removes everything the setup installed. * Adjust root package and add RootLanSharing object * Remove ERunMode , add PREF_ROOT_MODE_ENABLE * fix(root): handle tethered clients' IPv6 in LAN sharing to stop leaks LAN/tethering sharing only set up IPv4 forwarding for clients, so a hotspot/USB-tethered client with a native (RA-assigned) global IPv6 egressed the upstream interface directly, bypassing the proxy — an IPv6 leak. buildLanShareSetup now handles forwarded clients' v6: - IPv6 enabled: route it through the tun. A mangle PREROUTING chain marks non-LOCAL-sourced (forwarded) v6 into the tun route table, keeps loopback/link-local/ULA/multicast direct, and hijacks client DNS; FORWARD accepts traffic to/from the tun. A trailing REJECT fails closed so anything not marked into the tun (e.g. addrtype match unavailable) is dropped instead of leaked. - IPv6 disabled: REJECT all forwarded v6 (the device's own v6 is already blackholed in OUTPUT). Teardown drops the two new ip6tables chains; the v6 route/rule into the tun table were already cleaned. Ported from vincentng295/Magic_V2Ray cae4f7f. * Update build.gradle.kts * Adjust settings --------- Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com> |