Skip to content

Commit b6ff502

Browse files
author
Leadaxe
committed
Filter VPN transport from the getActiveNetwork() seed in DefaultNetworkMonitor
start() seeds defaultNetwork from getActiveNetwork(), which returns the per-app default and may be the app's own VPN when the tun is already up. LocalResolver then queries DNS through the tun (auto_route) and loops, so apps under the VPN fail to resolve names. The async DefaultNetworkListener callback overwrites the seed with the NOT_VPN-filtered network shortly after, but the synchronous seed is used for the first resolutions; on ROMs where the tun is up at start() it is the VPN until the callback corrects it. The request's NOT_VPN capability does not apply to the direct getActiveNetwork() getter, so filter the VPN transport from the seed explicitly.
1 parent 19c3a58 commit b6ff502

1 file changed

Lines changed: 12 additions & 1 deletion

File tree

app/src/main/java/io/nekohasekai/sfa/bg/DefaultNetworkMonitor.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.nekohasekai.sfa.bg
22

33
import android.net.Network
4+
import android.net.NetworkCapabilities
45
import android.os.Build
56
import io.nekohasekai.libbox.InterfaceUpdateListener
67
import io.nekohasekai.sfa.Application
@@ -17,12 +18,22 @@ object DefaultNetworkMonitor {
1718
checkDefaultInterfaceUpdate(it)
1819
}
1920
defaultNetwork = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
20-
Application.connectivity.activeNetwork
21+
// getActiveNetwork() returns the per-app default, which may be the VPN
22+
// that applies to this app. If the tun is already up when start() runs,
23+
// seeding defaultNetwork with our own VPN makes LocalResolver query DNS
24+
// back through the tun (auto_route) and loop. The NetworkRequest carries
25+
// NET_CAPABILITY_NOT_VPN, but that does not apply to this direct getter,
26+
// so filter the VPN transport out explicitly.
27+
Application.connectivity.activeNetwork?.takeUnless(::isVpn)
2128
} else {
2229
DefaultNetworkListener.get()
2330
}
2431
}
2532

33+
private fun isVpn(network: Network): Boolean =
34+
Application.connectivity.getNetworkCapabilities(network)
35+
?.hasTransport(NetworkCapabilities.TRANSPORT_VPN) == true
36+
2637
suspend fun stop() {
2738
DefaultNetworkListener.stop(this)
2839
}

0 commit comments

Comments
 (0)