NetGuard
NetGuard copied to clipboard
Fix race condition where a VPN is still active while detecting connetion type
I was experiencing a bug where the change from metered to un-metered did not take effect. After investigating, this was caused by the VPN service continuing to be active while attempting to detect the after network. This resulted in the a VPN network being set as the active network for the VPN. This prevented other calls that determine the metered status from accurately determining the metered status and it seems it defaulted to true if the underlying network for the VPN was a VPN.
Here's an example from Logcat of the issue: 2024-08-16 20:46:55.843 9252-9296 NetGuard.Service eu.faircode.netguard I Setting underlying network=1073 [type: VPN[], state: DISCONNECTED/DISCONNECTED, reason: (unspecified), extra: (none), failover: false, available: true, roaming: false]
There's a twofold fix here:
- When bringing up the VPN, instead of starting the VPN then detecting/setting the active network, the active network is detected first and set on the builder object. Then the VPN is started.
- When the VPN is being restarted, after it is stopped, a loop checks if the active network still shows as a VPN so that when the VPN is started again, it will not be detecting the stopped VPN as the active network
I'm not happy with the change in part 2 since it uses busy-waiting. The API documentation for the network status API says that the information should be tracked by using the network status callbacks and memorizing the information. This may make waiting for the VPN to go down before setting the underlying network unnecessary. https://developer.android.com/reference/android/net/NetworkInfo#isConnected()