VPN battery optimizations, ePDG routing, and UI fixes#546
Merged
Conversation
- Enable setBlocking(true) on VPN builder for CPU-efficient blocking I/O instead of polling the TUN file descriptor - Re-enable setUnderlyingNetworks() after establish() so Android can correctly assess VPN connectivity and metering (was disabled with && false since NetGuard v2.330, Sep 2024) - Acknowledge DuckDuckGo ATP (Apache 2.0) in README credits Both optimizations mirror DuckDuckGo's App Tracking Protection, which uses the same NetGuard native layer (libnetguard) and has validated these work correctly with epoll-based I/O. https://claude.ai/code/session_01888KqFB93HxMCJGjscYT3X
Replace dynamic subnet routing and 0.0.0.0/0 catch-all with static pre-computed routes covering all public IPv4 space. This eliminates the need for subnet/tethering/LAN user toggles — LAN access, tethering, and carrier Wi-Fi calling all work out of the box. Changes mirroring DuckDuckGo App Tracking Protection (Apache 2.0): - Add VpnRoutes.java with static route list excluding RFC1918, CGNAT, link-local, multicast, reserved, and carrier Wi-Fi calling ranges - Always use static routes (no dynamic CIDR complement computation) - setMetered(false) to prevent background sync restrictions - MTU 1280 (conservative, reduces fragmentation overhead) - Wrap each addRoute() in try/catch for OEM-specific failures - Always remove local DNS servers (LAN always excluded) - Remove unused imports (Configuration, NetworkInterface, etc.) The subnet, tethering, and lan preferences are now effectively no-ops. https://claude.ai/code/session_01888KqFB93HxMCJGjscYT3X
These settings are no longer needed — static VPN routes now always exclude local networks and carrier Wi-Fi calling ranges, making LAN access, tethering, and Wi-Fi calling work out of the box. https://claude.ai/code/session_01888KqFB93HxMCJGjscYT3X
setMetered(false) (DDG's approach) causes apps to think they're on an unmetered connection when on cellular, potentially increasing data usage. Matching the actual network status makes the VPN transparent with respect to metering — apps behave identically to without the VPN. https://claude.ai/code/session_01888KqFB93HxMCJGjscYT3X
Instead of stripping local DNS servers (which breaks Pi-hole and similar setups), add /32 host routes for them. A /32 beats the excluded /16, so DNS traffic to e.g. 192.168.1.1 enters the tunnel where TC can filter it, while all other LAN traffic still bypasses. https://claude.ai/code/session_01888KqFB93HxMCJGjscYT3X
Using the actual network MTU avoids unnecessary packet fragmentation and overhead. NetGuard has used this reliably for years. https://claude.ai/code/session_01888KqFB93HxMCJGjscYT3X
Resolve the carrier's ePDG domain at VPN setup using the 3GPP standard
pattern (epdg.epc.mnc{MNC}.mcc{MCC}.pub.3gppnetwork.org) and exclude
those IPs via excludeRoute(). This uses the carrier's own DNS (before
the tunnel is established), avoiding geo-fencing issues.
Works for any carrier worldwide without hardcoding IP ranges. Requires
Android 13+ (API 33) for excludeRoute(); older versions fall back to
the static T-Mobile/Verizon exclusions in VpnRoutes.
https://claude.ai/code/session_01888KqFB93HxMCJGjscYT3X
TC excludes itself from VPN routing (addDisallowedApplication), so ePDG DNS resolution always goes through the physical network. This re-runs on each VPN rebuild (network switch), picking up the correct carrier DNS when switching from WiFi to cellular. https://claude.ai/code/session_01888KqFB93HxMCJGjscYT3X
DNS resolution for non-existent ePDG domains (no SIM, non-standard carrier) could block VPN startup for 5-30 seconds. Wrap in a Future with 1.5s timeout — successful lookups typically complete in <500ms, so this catches most carriers while failing fast otherwise. https://claude.ai/code/session_01888KqFB93HxMCJGjscYT3X
If another app is set as Always-on VPN, Android silently refuses to show TrackerControl's VPN consent dialog, so tapping "Enable On-Device VPN" in onboarding appears to do nothing. Detect this both proactively (pre-Android S, where the setting is readable) and reactively (via onActivityResult) and show a dialog pointing the user to system VPN settings so they can disable the other always-on VPN. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
LAN and tethering already bypass TC's VPN via OS-level routing (kernel connected-route preference for LAN, separate netd forwarding context for tethering), so the excludes in VpnRoutes are defense-in-depth, not load-bearing. Capture this so it doesn't get re-litigated. Also reframe the include_system_vpn note: the real cost is wakeup frequency from background system-app traffic, not tun throughput — the earlier "download slowdown" framing misread the battery symptom. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The navigation-bar overlap fix in #558 added fitsSystemWindows="true" to the Insights CoordinatorLayout. Because Insights uses the theme's window-decor action bar (not an in-layout AppBarLayout), the status bar inset was effectively counted twice and a large empty gap appeared between the toolbar and the hero card. Mirror the approach already used for Settings/Timeline in c50bea9: drop fitsSystemWindows from the layout root and instead apply only the bottom system-bar inset to the ScrollView so the original nav-bar overlap fix still holds. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
VPN battery optimizations (from DuckDuckGo ATP)
setBlocking(true)on VPN builder for CPU-efficient blocking I/O instead of polling the TUN file descriptorsetUnderlyingNetworks()afterestablish()so Android correctly assesses VPN connectivity and meteringVPN routing improvements
setMeteredto match physical network statusjni_get_mtu()for MTU detectionePDG / Wi-Fi Calling support
Onboarding
Bug fixes
fitsSystemWindows="true"on the CoordinatorLayout double-counted the status-bar inset for activities using the window-decor action bar)