InviZible icon indicating copy to clipboard operation
InviZible copied to clipboard

Fast network switching on GrapheneOS (Pixel 8 A16) disables Wi-Fi

Open keybreak opened this issue 4 months ago • 23 comments

Why that happens? Any way to avoid it?

I've tried Compatibility mode with no luck, same behavior.

keybreak avatar Aug 13 '25 14:08 keybreak

This is something that InviZible is unable to do, as any other user app. Are you referring to the Wi-Fi being completely turned off or simply losing the internet connection?

Gedsh avatar Aug 15 '25 08:08 Gedsh

  1. Connected to Wi-Fi network
  2. Launch InviZible pro
  3. If specifically Tor module is launched - you'll get immediately disconnected from Wi-Fi network into SIM card's provided internet, LTE or whatnot

Same thing doesn't happen with Orbot, for instance.

So....you're thinking that somehow InviZible just triggers such behavior by GrapheneOS then? Like some VPN leak protection?

P.S. I'm using InviZible pro stable, from F-Droid default repo, if that's important.

keybreak avatar Aug 15 '25 09:08 keybreak

somehow InviZible just triggers such behavior by GrapheneOS then?

I'm pretty sure about this. InviZible uses a rare feature called fast network switching. So, if you have Wi-Fi and mobile data turned on, you'll see both icons at the same time. Wi-Fi has priority. If you lose your Wi-Fi connection, you will be immediately switched to mobile data without delay. However, it seems that there is a bug in GrapheneOS that prevents fast network switching from working.

It would be good if you could leave this issue to the GrapheneOS developers so that we can find out their response.

Gedsh avatar Aug 15 '25 10:08 Gedsh

https://github.com/Gedsh/InviZible/issues/249

Gedsh avatar Aug 15 '25 11:08 Gedsh

@Gedsh This isn't being caused by GrapheneOS since we don't make any changes relevant to this. Most of your users on Android 16 are likely on GrapheneOS. Android 16 is only available for Pixels so far and Pixels are the only devices we support. There are around 325k GrapheneOS users on Android 16.

GrapheneOS makes small changes to VPN lockdown mode to resolve all of the known outbound VPN leaks on Android. We close 5 different kinds of leaks. The changes are explained here:

https://grapheneos.org/features#improved-vpn-leak-blocking

  • DNS leaks (not relevant)
  • mDNS leaks (not relevant)
  • multicast leaks from apps (not relevant)
  • multicast leaks from the kernel via apps (not relevant)
  • interface binding bypassing the VPN (would not cause Wi-Fi to turn off even if it was relevant)

thestinger avatar Aug 15 '25 16:08 thestinger

It's likely either an Android 16 bug or the app is using the API in a way which was broken by backwards incompatible changes in Android 16. If it's the latter, then the app can likely fix the issue. It's quite possible that it's just an Android 16 bug which ma be resolved in Android 16 QPR1.

thestinger avatar Aug 15 '25 16:08 thestinger

@thestinger, thanks for your prompt response! I plan to add the option to disable fast network switching so that InviZible works like any other regular VPN. However, I believe this feature is useful, so I will continue to investigate the problem.

InviZible uses the Android VPN service function https://developer.android.com/reference/android/net/VpnService.Builder#setUnderlyingNetworks(android.net.Network[]) to set available networks so that the necessary interfaces are available all the time, allowing fast switching between networks when the network changes.

@keybreak, please send me the logs right after reproducing the problem. Menu -> Logs -> Collect Logs. If you want to view the contents of the file being sent, you can change the extension from txt to zip.

Gedsh avatar Aug 18 '25 07:08 Gedsh

While reading issue #249, Just in case i might be missing something, reading more about this feature, i wasn't familiar before...

The Method i'm defining what network is running at the moment on GrapheneOS is:

  1. Open top Quick settings bar
  2. On network icon:
    • If Wi-Fi is on and it shows name of Wi-Fi you're connected to - then Wi-Fi is actually running
    • If it says LTE or some other mobile data term - it means that it's actually running.

So in context of that issue, once Tor is active it immediately shows LTE. Is this even reliable way to check in case of that feature?

please send me the logs right after reproducing the problem. Menu -> Logs -> Collect Logs. If you want to view the contents of the file being sent, you can change the extension from txt to zip.

I'm very iffy on sharing logs...i'd have to contact my inner-paranoic first 🕵️ might take some time, depending on logs. Is there something of interest in particular you're looking for, that i could quickly grep?

keybreak avatar Aug 18 '25 10:08 keybreak

Is this even reliable way to check in case of that feature?

Usually, when InviZible is running in VPN mode, you should see both Wi-Fi and LTE icons if you have both Wi-Fi and LTE enabled. But I don't know how it works in GrapheneOS, as it's not standard Android.

Is there something of interest in particular you're looking for

I need the logcat.log file in particular. You can replace all IPs with asterisks or something similar. I don't think there is any other information there that could be sensitive. Even the IPs you find there don't usually indicate your location or anything else. In fact, InviZible does not collect any private data when you press the Collect logs button.

Gedsh avatar Aug 18 '25 12:08 Gedsh

@Gedsh

InviZible uses the Android VPN service function https://developer.android.com/reference/android/net/VpnService.Builder#setUnderlyingNetworks(android.net.Network[]) to set available networks so that the necessary interfaces are available all the time, allowing fast switching between networks when the network changes.

This feature is very fragile and has to be used a very specific way in order to work properly. Not sure on the exact details of that. RehinkDNS tried to adopt it recently and had a lot of issues.

thestinger avatar Aug 18 '25 14:08 thestinger

@thestinger This feature has been working in InviZible for a long time without any problems, until this particular issue. The only problem is users' confusion and surprise when they see both Wi-Fi and cellular data icons.

Gedsh avatar Aug 18 '25 14:08 Gedsh

The way it's being used may have issues on Android 16. Have you tested with Android 16 specifically?

thestinger avatar Aug 18 '25 14:08 thestinger

Have you tested with Android 16 specifically?

Unfortunately no. I don't have a real device with this version, and I don't see the point of using an emulator in this case. So this is a good point to start debugging the issue with real users.

Gedsh avatar Aug 18 '25 14:08 Gedsh

@Gedsh

I don't think there is any other information there that could be sensitive. Even the IPs you find there don't usually indicate your location or anything else. In fact, InviZible does not collect any private data when you press the Collect logs button.

Any metadata is a metric of privacy in my book...

Redacted:

  1. Removed all language mentions
  2. ipv4 / dns replaced with placeholder: x.x.x.x
  3. ipv6 replaced with placeholder: x:x:x:x:x:x:x:x
  4. Replaced all mobile data ISP string with placeholder: internet.redacted.lol
  5. Replaced UID in WM-Processor (not sure what it is, so...) with: <SOME_UID_REDACTED>

This is logcat.log from InviZible pro (beta), just to be up to date: https://paste.nolog.cz/?769e3b46736bf2fc#nnXf6VAeeUwX5Dj6B2jd3dWmkj8nef7MpZzzJZVtRZ6

Temp link will die in 1 day.

Process for log:

  1. Completely killed app to start from scratch
  2. Stopped
  3. Started

keybreak avatar Aug 19 '25 10:08 keybreak

From your logs:

pan.alexander.TPDCLogs: VPN Handler Setting underlying network=[type: WIFI[], state: CONNECTED/CONNECTED, reason: (unspecified), extra: , failover: false, available: true, roaming: false] pan.alexander.TPDCLogs: VPN Handler Setting underlying network=[type: MOBILE[LTE], state: CONNECTED/CONNECTED, reason: (unspecified), extra: internet.redacted.lol, failover: false, available: true, roaming: false]

Thus, there are no problems on the app side. InviZible sets two underlying networks with Wi-Fi priority. This is absolutely correct. The problem is on the Android system side.

I plan to add an option to disable fast network switching. Regarding this issue, let's see if other users will come forward to say whether it is related to the Android version or something else, so that I can take appropriate measures to resolve it.

Gedsh avatar Aug 19 '25 12:08 Gedsh

Ok...well, good to know, i guess! 😆 Can you describe key benefits of using Fast network switching, for end-user, assuming it works as intended?

keybreak avatar Aug 19 '25 12:08 keybreak

Can you describe key benefits of using Fast network switching

You have immediate switching between Wi-Fi and cellular networks and vice versa. This is very convenient, especially if you use Tor, as it does not like interruptions in the internet connection. The longer the interruption in the internet connection, the longer Tor will take to connect on a new network.

for end-user, assuming it works as intended?

What do you mean?

Gedsh avatar Aug 19 '25 13:08 Gedsh

What do you mean?

Pretty much what you've already answered 👍 I meant assuming it doesn't turn off Wi-Fi like in case of Android 16 bug.

When thinking about it, i guess while using Orbot, indeed it didn't really like if you go out of Wi-Fi area...might give some unpredictable behavior once in a while.

keybreak avatar Aug 19 '25 13:08 keybreak

I meant assuming it doesn't turn off Wi-Fi like in case of Android 16 bug.

Previously, there were no complaints about this feature, except for users' curiosity.

might give some unpredictable behavior once in a while

InviZible flexibly handles such things.

Gedsh avatar Aug 19 '25 14:08 Gedsh

@keybreak, please try the latest beta and disable fast network switching in the common settings.

Gedsh avatar Aug 26 '25 13:08 Gedsh

@Gedsh Yeah, Wi-Fi works when i disable Fast network. Thx 👍 I'll leave the issue open though, so we can track progress on upstream Android bug.

P.S. btw, i'm installing beta version directly from GitHub (Invizible_Pro__beta_ver.2.5.7_arm64.apk), because for some reason IzzyOnDroid reports as "No compatible version available", are you posting arm64.apkin there?

keybreak avatar Aug 26 '25 15:08 keybreak

are you posting arm64.apkin there?

The IzzyOnDroid repo only supports one version. The armv7a version is used as a still more universal option.

Gedsh avatar Aug 27 '25 08:08 Gedsh

rdns dev here

allowing fast switching between networks when the network changes

VpnService.setUnderlyingNetworks isn't necessary for "fast switching", but only necessary if you'd want to expose the capabilities of all underlying networks as the VPN's (that is, declare to apps listening on Network events that the VPN supports both WiFi and Mobile at the same time, though it is unclear how apps can ask the VPN to bind to those networks without VPN allowing it via VpnService.allowBypass, which will NOT work in VPN Lockdown mode).

You have immediate switching between Wi-Fi and cellular networks and vice versa. This is very convenient, especially if you use Tor, as it does not like interruptions

For uninterrupted connectivity (on network changes or when recreating the VPN tunnel to get a new fd, for example), Android supports "seamless handover" where the previous tun fd can be read until EOF alongside the newly created tun fd. In our experiments, this works, but not in VPN Lockdown mode ("Block connections without VPN" turned ON).

Leaving VpnService.setUnderlyingNetworks to null, Android will set the actual underlying network for the VPN tunnel to ConnectivityManager.activeNetwork in all circumstances. Which, along with "seamless handover", might just be enough.


feature is very fragile and has to be used a very specific way in order to work properly.

Yes, which is why we've disabled it by default. It seems to work differently across different OEMs and ROMs, but Rethink's bar with the latest release was to make it work on Graphene, if no where else.

Not sure on the exact details of that. RehinkDNS tried to adopt it recently and had a lot of issues.

The issues were resolved by:

  • Calling VpnService.setUnderlyingNetwork on every capability change of whatever Network objects were previously set as underlying network.
  • Not attempting "seamless handover" when in VPN Lockdown mode.
  • When no validated (internet-capable) networks are available, setting VpnService.setUnderlyingNetwork(null) as the underlying network instead of an empty array, [], when in VPN Lockdown mode (but this is changeable by the end user, if it works on their Android version / ROM).
  • Never setting an unvalidated network as the underlying network when in VPN Lockdown mode (but this may break LAN connectivity over networks that won't have default routes to the Internet).
  • Binding to one of the networks set as the underlying network, explicitly, for egress sockets created by Rethink on behalf of apps (again, only in VPN Lockdown mode).
  • (I may be forgetting other stuff but the code is up, and it isn't the prettiest from handling a myriad of configurations, as you can imagine).

I'd only recommend VpnService.setUnderlyingNetworks to my worst enemy (:

ignoramous avatar Sep 06 '25 22:09 ignoramous