fix(android): recover default-interface index via Os.if_nametoindex#8889
fix(android): recover default-interface index via Os.if_nametoindex#8889garmr-ulfr wants to merge 2 commits into
Conversation
NetworkInterface.getByName relies on the interface-enumeration syscall, which is restricted on some Android versions/ROMs (returns null or throws there). When it failed, checkDefaultInterfaceUpdate exhausted its retries without ever calling updateDefaultInterface, so sing-box never received a default interface and every outbound failed with "no available network interface". Fall back to Os.if_nametoindex when getByName cannot resolve the index, mirroring the already-hardened getInterfaces sibling, and retry only when the index is still unresolvable. Also early-return on a null interface name instead of burning the retry budget on getByName(null).
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Pull request overview
This PR addresses an Android-specific failure mode where sing-box never receives a default network interface index, causing all outbounds/DNS to fail with “no available network interface” even while the VPN appears connected. It hardens DefaultNetworkMonitor.checkDefaultInterfaceUpdate to recover the interface index on restricted Android ROMs by falling back to Os.if_nametoindex.
Changes:
- Add
Os.if_nametoindex(interfaceName)fallback whenNetworkInterface.getByNamecannot resolve an interface index. - Avoid retrying when the interface name is
nullby early-returning before entering the retry loop. - Retry only when the resolved index is still not usable (
<= 0).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Problem
On Android, every sing-box outbound (
direct, the auto-selector, and proxy outbounds) and DNS failed withno available network interface, while the UI still reported the VPN as Connected. Observed on Android 10 / API 29 (Samsung SM-G960U1); the condition persisted for the whole session with zero successful connections, and the auto-selector churned through servers marking eachhard_demoted— a consequence, not the cause.Root cause
DefaultNetworkMonitor.checkDefaultInterfaceUpdateis the only path that delivers the default network interface to sing-box (viaupdateDefaultInterface). It resolved the interface index solely throughNetworkInterface.getByName(name).index, which relies on the interface-enumeration syscall. That syscall is restricted on some Android versions/ROMs, wheregetByNamereturns null or throws. On failure the 10-retry loop exhausted and returned without ever callingupdateDefaultInterface, leaving sing-box with no default interface — so every outbound failed to bind.The sibling
PlatformInterfaceWrapper.getInterfaces()was already hardened for this exact case with anOs.if_nametoindexfallback;checkDefaultInterfaceUpdatewas not.Fix
Fall back to
Os.if_nametoindex(interfaceName)whengetByNamecannot resolve the index, mirroring the hardened sibling, and retry only when the index is still unresolvable (<= 0). Also early-return on a null interface name instead of burning the retry budget ongetByName(null).Testing
Needs a build + on-device check on an API 29 device to confirm.