[client] Android - Create the Android fake IP manager lazily on DNS flag enable - #6989
[client] Android - Create the Android fake IP manager lazily on DNS flag enable#6989pappz wants to merge 1 commit into
Conversation
The fake IP manager was only created at route manager construction, from the DNS feature flag fetched by the initial GetNetworkMap call. When the flag flipped to true mid-session, UpdateRoutes set useNewDNSRoute but never created the manager, so domain routes added after the flip got a DNS interceptor with a nil fake IP manager. internalDnatFw only checked for a firewall and GOOS, so the interceptor took the DNAT path and called GetFakeIP/AllocateFakeIP on the nil *fakeip.Manager. These methods lock m.mu first, which is a nil pointer dereference: the first DNS answer for such a route panicked and crashed the VPN service. The fake IP blocks (240.0.0.0/8 and its v6 pair) also never reached the TUN, since only the constructor registered them. Create the manager and its TUN routes from UpdateRoutes when the flag turns on, notify so the fake IP blocks get into the TUN without a client route change, and treat a nil manager as no internal DNAT. This is groundwork for removing the initial GetNetworkMap fetch, after which every startup goes through the flag-off-to-on transition.
📝 WalkthroughWalkthroughAndroid fake-IP route creation is now conditional and reusable during setup and runtime route updates. The Android notifier emits a network-change notification when fake routes are assigned, and internal DNAT requires an initialized fake-IP manager. ChangesAndroid fake-IP route lifecycle
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@client/internal/routemanager/manager.go`:
- Around line 472-474: Publish fake-IP route changes only after the complete
route state is committed: in client/internal/routemanager/manager.go:472-474
defer notification until the normal route update has committed currentRoutes;
initialize the notifier route state before its first notification at
manager.go:168-171; separate fake-route assignment from notification at
manager.go:194-195; and in
client/internal/routemanager/notifier/notifier_android.go:42-44 serialize or
coalesce callbacks so notifications occur only with a complete, ordered
snapshot.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 6332cc31-a676-43f4-9bb2-55bf2d21b193
📒 Files selected for processing (3)
client/internal/routemanager/dnsinterceptor/handler.goclient/internal/routemanager/manager.goclient/internal/routemanager/notifier/notifier_android.go
| if runtime.GOOS == "android" && useNewDNSRoute && m.fakeIPManager == nil { | ||
| m.enableFakeIPRoutes() | ||
| } |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
Publish fake-IP route changes only after the complete route state is committed.
The current flow emits an intermediate snapshot before initial/current routes are installed, and asynchronous callbacks can arrive out of order, potentially leaving the TUN with stale or missing routes.
client/internal/routemanager/manager.go#L472-L474: defer notification until the normal route update has committedcurrentRoutes.client/internal/routemanager/manager.go#L168-L171: initialize the notifier’s route state before the first notification.client/internal/routemanager/manager.go#L194-L195: separate fake-route assignment from notification.client/internal/routemanager/notifier/notifier_android.go#L42-L44: serialize or coalesce callbacks, or notify only after the full snapshot is ready.
📍 Affects 2 files
client/internal/routemanager/manager.go#L472-L474(this comment)client/internal/routemanager/manager.go#L168-L171client/internal/routemanager/manager.go#L194-L195client/internal/routemanager/notifier/notifier_android.go#L42-L44
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@client/internal/routemanager/manager.go` around lines 472 - 474, Publish
fake-IP route changes only after the complete route state is committed: in
client/internal/routemanager/manager.go:472-474 defer notification until the
normal route update has committed currentRoutes; initialize the notifier route
state before its first notification at manager.go:168-171; separate fake-route
assignment from notification at manager.go:194-195; and in
client/internal/routemanager/notifier/notifier_android.go:42-44 serialize or
coalesce callbacks so notifications occur only with a complete, ordered
snapshot.
Release artifactsBuilt for PR head
GHCR images (amd64)
This comment is updated by the Release workflow. Artifact links expire according to the workflow retention policy. |



Describe your changes
The fake IP manager was only created at route manager construction, from the DNS feature flag fetched by the initial GetNetworkMap call. When the flag flipped to true mid-session, UpdateRoutes set useNewDNSRoute but never created the manager, so domain routes added after the flip got a DNS interceptor with a nil fake IP manager.
internalDnatFw only checked for a firewall and GOOS, so the interceptor took the DNAT path and called GetFakeIP/AllocateFakeIP on the nil *fakeip.Manager. These methods lock m.mu first, which is a nil pointer dereference: the first DNS answer for such a route panicked and crashed the VPN service. The fake IP blocks (240.0.0.0/8 and its v6 pair) also never reached the TUN, since only the constructor registered them.
Create the manager and its TUN routes from UpdateRoutes when the flag turns on, notify so the fake IP blocks get into the TUN without a client route change, and treat a nil manager as no internal DNAT.
This is groundwork for removing the initial GetNetworkMap fetch, after which every startup goes through the flag-off-to-on transition.
Issue ticket number and link
Stack
Checklist
Documentation
Select exactly one:
Docs PR URL (required if "docs added" is checked)
Paste the PR link from https://github.com/netbirdio/docs here:
https://github.com/netbirdio/docs/pull/__
Summary by CodeRabbit