Skip to content

Explainer

Why DataGuard Rebuilds the VPN on Network Change (Engineering Notes)

Why an Android firewall connection log can go silent: how DataGuard rebuilds its VpnService when the active network changes, and the active-network-is-VPN edge.

Why DataGuard Rebuilds the VPN on Network Change (Engineering Notes) preview

Written by the Fulldive product engineering team, based on direct inspection of the repositories listed below.

If you have ever used a no-root Android firewall connection log and wondered why the app sometimes needs a second to catch up after you toggle Wi-Fi, this post is for you. DataGuard No Root Firewall contains specific code, in specific commits, that exists because Android’s network state machine and the VpnService API do not quite line up when the active network changes. This post explains what the problem is and why the fix looks like a full filter rebuild.

It is the engineering counterpart to the user-facing How no-root Android firewalls work.

The setup

DataGuard filters network traffic by opening a VpnService and pointing Android’s default route at its local virtual interface. Each outbound packet comes through, DataGuard reads the app’s Linux UID, checks the user’s per-app rule, and either forwards or drops. Normal case, everything works.

The tricky case is what happens when the underlying network — the real Wi-Fi or cellular connection — changes out from under the VPN.

What Android does during a network change

A mobile device’s active network is surprisingly fluid:

  • Wi-Fi toggles on or off.
  • Wi-Fi signal drops and the device hands over to mobile data.
  • Mobile data hands the device to a different cell or a different technology (LTE to 5G, or the reverse).
  • The user toggles airplane mode.
  • Tethering starts or stops.
  • Another app (e.g., an MDM profile or another VPN) claims the network.

For each of those, Android’s ConnectivityManager fires a callback and the “active network” changes. For a normal app, this just means a reconnect. For a VpnService-based firewall, it can mean the filter is now sitting on top of the wrong underlying network, or the underlying network’s DNS/routes have changed, or in the worst case, a different app has taken the single VPN slot.

If DataGuard does nothing, the filter can end up in one of several bad states:

  • Silently passing traffic through without matching UIDs correctly.
  • Blocking everything because the tunnel is still up but the route is stale.
  • Showing an active-running notification that is technically true but useless.

None of those are acceptable for a tool whose whole value is accurately deciding what an app can do.

What DataGuard does

Two commits in fulldiveVR/FulldveExtension.DataGuard speak directly to this:

  • c5e9414b — rebuilt VPN on active network change. When the active network changes, DataGuard tears down its current VpnService and builds a new one bound to the new network state. This is a “big hammer” fix, and that is the right call: the cheap “patch the existing filter” approach is fragile because Android’s internal VPN state is not fully exposed to apps. Rebuilding from scratch is slower by a few hundred milliseconds but correct.

  • ba0e8c22 — workaround for the active network being a VPN. This is a subtler bug. On some Android configurations, the “active network” as reported by ConnectivityManager.getActiveNetwork() is itself marked as a VPN — either because another VPN is installed, because Play Services overlays a network, or because of OEM-specific behavior. Without the workaround, DataGuard’s own VPN tries to start on top of what it thinks is already a VPN, and the filter does not come up correctly. The commit special-cases that condition so DataGuard attaches to the correct underlying transport.

Both of these are invisible to users when working. They are extremely visible when missing, because the firewall silently stops doing its job — the worst failure mode a security tool can have.

Why “rebuild” instead of “patch”

There is a philosophical point here that extends beyond DataGuard: when a tool lives on top of a system API whose internal state is not fully exposed, the safest reaction to an underlying change is to rebuild, not to patch.

  • Patching the existing filter requires you to know, from outside, exactly which parts of the OS have just changed. VpnService does not expose that.
  • Rebuilding has a well-understood cost: a short moment without filtering. But it guarantees correctness once the new filter is up.

For a firewall, a known half-second gap is better than an unknown-duration silent passthrough. For a tunneling VPN, the same logic often applies; for a DNS-based VPN ad blocker, the cost-benefit is similar (see Cold start and DNS lifecycle bugs in VPN ad blockers, which covers the equivalent problem for Wize AdBlock VPN).

The bigger reliability picture

The network-change rebuild is one example in a broader pattern: DataGuard has had to absorb Android platform changes repeatedly. The commit log for the same app shows, among other things:

We walk through the full release cadence in A decade of DataGuard Android firewall maintenance. The point here is that reliability work is not optional for a VpnService-based tool: it is the majority of the job.

What users actually notice

In day-to-day use, the network-change rebuild shows up as:

  • A brief visual dimming/reconnection of the ongoing notification when Wi-Fi flips to mobile data.
  • A half-second during which a just-opened app may see a network error before the filter is back (apps retry, so this is almost always harmless).
  • Zero visible change when things are working — which is the whole point.

Users who keep an eye on the connection log may see a reset marker at network transitions. That is the rebuild completing.

Why we publish commit hashes

This post cites specific commit hashes (c5e9414b, ba0e8c22) because “trust us” is not a good argument in a privacy/security category. A no-root firewall is a trust-critical tool; readers should be able to see that specific problems have specific fixes with specific dates. That is the same reason our app-evolution posts across Fulldive — for WizeUp, Wize AdBlock VPN, and others — lean on git history rather than marketing copy. The broader Fulldive approach is described in the Fulldive company story.

Limits: what an Android firewall cannot do

The network-change rebuild solves a reliability problem (keep the filter accurate across network transitions). It does not change what an Android firewall is. A no-root firewall still:

  • Does not tunnel or encrypt traffic to a remote server (see No-root firewall vs VPN on Android).
  • Does not filter per-domain within an app’s allowed traffic.
  • Does not detect malware.
  • Does not manage Android runtime permissions.
  • Does not block push notifications delivered through Play Services’ shared channel.

The full honest list is in What Android firewalls can and cannot protect against.

If you’re building in this space

Three lessons from DataGuard’s rebuild-on-change pattern, for anyone evaluating or building a VpnService-based tool:

  1. Subscribe to ConnectivityManager network callbacks, not to connectivity broadcasts alone. The callback API is more accurate and less likely to miss transitions on newer Android versions.
  2. Treat “active network is a VPN” as a real case, not a theoretical one. The NetGuard open-source project documents similar edge cases; DataGuard’s ba0e8c22 is a specific instance.
  3. Prefer rebuild over patch when the underlying state is not exposed. The user-visible cost is small; the correctness benefit is large.

Where to go next

Last updated: 2026-04-16. Commit hashes and version numbers are drawn from Fulldive repositories inspected on 2026-04-13.