Eine Android-App kann einen internen Namen nicht auflösen, während der Browser des VPN-Clients ihn erreicht, und derselbe Build funktioniert auf einem anderen Telefon. Die URL ist nicht die Variable. Die Variable ist, welches Netzwerk der App-Prozess für die Auflösung verwenden darf, und Android garantiert nicht, dass das aktive VPN dasjenige ist, das Ihre Sockets nutzen. Arbeiten Sie diese Prüfungen der Reihe nach ab und hören Sie auf, wenn der Resolver-Snapshot nicht zu Ihrer Annahme passt.

Schritt 1: Beweisen Sie, in welchem Netzwerk die App ist

Lesen Sie die Sicht der App selbst statt der Statusleiste. Holen Sie sich aus ConnectivityManager das aktive Netzwerk, seine LinkProperties, die Liste der DNS-Server und die Einstellung für privates DNS. Enthält die Liste den Resolver des VPN, hat die App einen Pfad dorthin; enthält sie den Resolver des WLAN, ist der Tunnel nicht das Standardnetzwerk für diesen Prozess.

Ein VPN-Symbol sagt nur, dass ein Tunnel existiert. Es sagt nicht, dass der Prozess der App daran gebunden wurde, und Android leitet die Namensauflösung nicht immer über das Netzwerk, das aktiv aussieht. Lokale VPN-Apps, die an ein anderes Gerät weiterleiten, WLAN-Netze ohne Internet und Hersteller-Builds können dazu führen, dass eine App den Standard-Resolver statt der Server des Tunnels fragt.

Schritt 2: Fordern Sie den VPN-Transport an und binden Sie den Prozess

Wenn die App den Resolver des Tunnels nutzen muss, fordern Sie ein Netzwerk mit dem VPN-Transport an und binden Sie den Prozess im Callback, damit der Code nicht rät, wann das Netzwerk erscheint:

val request = NetworkRequest.Builder()
    .addTransportType(NetworkCapabilities.TRANSPORT_VPN)
    .build()

connectivityManager.requestNetwork(request, object : NetworkCallback() {
    override fun onAvailable(network: Network) {
        val bound = connectivityManager.bindProcessToNetwork(network)
        Log.i(TAG, "bound to VPN network: " + bound)
    }
})

Der Aufruf ändert das prozessweite Standardnetzwerk, sodass jeder danach erzeugte Socket es verwendet. Bereits vorhandene Sockets behalten das Netzwerk, in dem sie erzeugt wurden; deshalb kann ein Verbindungspool, der vor dem Bind geöffnet wurde, weiter über den alten Pfad auflösen. Der Rückgabewert ist ein Boolean, und ein false-Ergebnis bedeutet, dass das Binden nicht stattgefunden hat; wiederholen Sie den Versuch nach einer kurzen Verzögerung und protokollieren Sie beide Versuche.

Schritt 3: Begrenzen Sie das Binden auf das, was es braucht

Prozessweites Binden ist grob. Telemetrie, Update-Prüfungen und SDKs von Drittanbietern wandern ebenfalls in den Tunnel, und wenn der Tunnel kein Internet hat, beginnen sie zu scheitern. Für eine einzelne Anfrage nutzen Sie die Socket-Factory des Netzwerks und behalten für alles andere das Geräte-Standardnetz. Wählen Sie bewusst ein Modell: ein enges Binden pro Verbindung oder ein Prozess-Bind mit explizitem Unbind, wenn das VPN verschwindet.

Zwei Resolver-Funktionen können das Binden ohne jeden Fehler aushebeln. Privates DNS im strikten Modus sendet Anfragen an einen benannten DoT-Server statt an den Netzwerk-Resolver, und eine App mit eigenem DNS-over-HTTPS-Client umgeht den System-Resolver vollständig. Prüfen Sie beides, bevor Sie schließen, dass das Binden fehlgeschlagen ist. Eine Anfrage, die den DNS-Server des VPN nie erreicht, erscheint in keinem tunnelsetigen Protokoll.

Schritt 4: Vertrauen Sie keiner CONNECTED-Bedingung

Die NetworkType.CONNECTEDvon WorkManager bedeutet, dass ein Netzwerk verbunden ist, und der VPN-Transport erfüllt sie auch dann, wenn die zugrunde liegende WLAN- oder Mobilfunkverbindung weg ist. Der Job läuft, jede Anfrage scheitert, und die Retry-Richtlinie macht daraus einen Sturm, der wie ein Planungsfehler aussieht. Der Tunnel ist ein Netzwerk; die Bedingung war nie eine Internet-Prüfung.

Prüfen Sie die Fähigkeit, die die Arbeit wirklich braucht, etwa validierten Internetzugang, und halten Sie eine begrenzte Retry-Richtlinie mit Backoff ein. Wenn der Job einen internen Namen braucht, lösen Sie diesen Namen im ausgewählten Netzwerk auf, bevor Sie die Arbeit tun, und scheitern Sie schnell mit einem klaren Fehler, statt eine Anfrage zu wiederholen, die nicht gelingen kann.

Schritt 5: Sichern Sie die Belege und testen Sie die Reichweite erneut

Protokollieren Sie die Transporttypen des ausgewählten Netzwerks, die DNS-Server aus LinkProperties, ob das Binden true zurückgab und den genauen Fehler der ersten Anfrage. Führen Sie dann einen internen und einen öffentlichen Namen unter derselben Bindung aus. Dieses Paar zeigt, ob die App den Resolver des Tunnels genutzt oder still auf den Gerätestandard zurückgefallen ist, und das ist der Unterschied, den der Nutzer erlebt.

Wiederholen Sie das auf der ältesten Android-Version, die Sie unterstützen, und auf einer aktuellen Version. Das Resolver-Verhalten, das den Standardpfad korrekt aussehen lässt, ist genau der Punkt, an dem sich Geräte und Versionen unterscheiden, und ein Build, der nur auf dem neuesten Testgerät besteht, ist für den Bereich, den Sie ausliefern, nicht verifiziert. adb shell dumpsys connectivityist ein schneller Weg zu bestätigen, welche Netzwerke und Fähigkeiten das Gerät meldet, während Sie den Fehler reproduzieren.

Ähnliche Artikel