e83dba94a09808c5468572db212832b62e5599fe
* 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>
v2rayNG
A V2Ray client for Android, support Xray core and v2fly core
Telegram Channel
Usage
Geoip and Geosite
- geoip.dat and geosite.dat files are in
Android/data/com.v2ray.ang/files/assets(path may differ on some Android device) - download feature will get enhanced version in this repo (Note it need a working proxy)
- latest official domain list and ip list can be imported manually
- possible to use third party dat file in the same folder, like h2y
More in our wiki
Development guide
Android project under V2rayNG folder can be compiled directly in Android Studio, or using Gradle wrapper. But the v2ray core inside the aar is (probably) outdated.
The aar can be compiled from the Golang project AndroidLibV2rayLite or AndroidLibXrayLite.
For a quick start, read guide for Go Mobile and Makefiles for Go Developers
v2rayNG can run on Android Emulators. For WSA, VPN permission need to be granted via
appops set [package name] ACTIVATE_VPN allow
Languages
Kotlin
95.5%
HTML
4.2%
Shell
0.3%