Unha aplicación Android non consegue resolver un nome interno mentres o navegador do propio cliente VPN si chega a el, e a mesma compilación funciona noutro teléfono. O URL non é a variable. A variable é que rede ten permitido usar o proceso da app para resolver, e Android non garante que a VPN activa sexa a que usan os teus sockets. Fai estas comprobacións en orde e detente cando a instantánea do resolvedor non coincida coa túa suposición.

Paso 1: Demostra en que rede está a app

Le a propia vista da app en lugar da barra de estado. Desde ConnectivityManager, obtén a rede activa, os seus LinkProperties, a lista de servidores DNS e a configuración de DNS privado. Se a lista contén o resolvedor da VPN, a app ten un camiño cara a el; se contén o resolvedor do Wi-Fi, o túnel non é a rede predeterminada para ese proceso.

Unha icona de VPN só di que existe un túnel. Non di que o proceso da app estea vinculado a el, e Android non sempre encamiña a resolución de nomes pola rede que parece activa. As apps VPN locais que reenvían a outro dispositivo, as redes Wi-Fi sen internet e as compilacións de fabricante poden deixar unha app preguntando ao resolvedor predeterminado en lugar de aos servidores do túnel.

Paso 2: Solicita o transporte VPN e vincula o proceso

Cando a app debe usar o resolvedor do túnel, solicita unha rede co transporte VPN e vincula o proceso na devolución de chamada, para que o código non adiviñe cando aparece a rede:

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)
    }
})

A chamada cambia a rede predeterminada de todo o proceso, así que cada socket creado despois úsaa. Os sockets que xa existen manteñen a rede na que se crearon, e por iso unha reserva de conexións aberta antes da vinculación pode seguir resolvendo pola ruta antiga. O valor devolto é un booleano, e un resultado falso significa que a vinculación non se produciu; volve tentar cun pequeno atraso e rexistra ambos os intentos.

Paso 3: Limita a vinculación ao que a necesita

A vinculación de todo o proceso é contundente. A telemetría, as comprobacións de actualización e os SDK de terceiros tamén pasan ao túnel, e se o túnel non ten internet comezan a fallar. Para unha soa solicitude, usa a fábrica de sockets da rede e mantén o predeterminado do dispositivo para todo o demais. Escolle un modelo a propósito: unha vinculación estreita por conexión, ou unha vinculación de proceso cunha desvinculación explícita cando a VPN desaparece.

Dúas funcións do resolvedor poden derrotar a vinculación sen ningún erro. O DNS privado en modo estrito envía as consultas a un servidor DoT con nome en lugar de ao resolvedor da rede, e unha app que inclúe o seu propio cliente DNS-over-HTTPS evita por completo o resolvedor do sistema. Comproba ambos antes de concluír que a vinculación fallou. Unha consulta que nunca chega ao servidor DNS da VPN non aparecerá en ningún rexistro do lado do túnel.

Paso 4: Non confíes nunha restrición CONNECTED

En WorkManager, NetworkType.CONNECTED significa que hai unha rede conectada, e o transporte VPN cúmpreo mesmo cando a ligazón Wi-Fi ou celular subxacente desapareceu. A tarefa execútase, todas as solicitudes fallan e a política de reintentos convértea nunha tormenta que parece un erro de planificación. O túnel é unha rede; a restrición nunca foi unha comprobación de internet.

Comproba a capacidade que o traballo realmente necesita, como o acceso a internet validado, e mantén unha política de reintentos limitada con retroceso. Se a tarefa necesita un nome privado, resolve ese nome na rede seleccionada antes de facer o traballo, e falla rápido cun erro claro en lugar de reintentar unha solicitude que non pode ter éxito.

Paso 5: Rexistra as evidencias e volve probar a gama

Rexistra os tipos de transporte da rede seleccionada, os servidores DNS de LinkProperties, se a vinculación devolveu verdadeiro e o fallo exacto da primeira solicitude. Despois executa un nome privado e un nome público coa mesma vinculación. Ese par mostra se a app usou o resolvedor do túnel ou volveu silenciosamente ao predeterminado do dispositivo, que é a diferenza que experimenta o usuario.

Repite na versión de Android máis antiga que admitas e nunha versión actual. O comportamento do resolvedor que fai que a ruta predeterminada pareza correcta é exactamente onde difiren dispositivos e versións, e unha compilación que só pasa no dispositivo de proba máis recente non está verificada para a gama que distribúes. adb shell dumpsys connectivity é unha forma rápida de confirmar que redes e capacidades informa o dispositivo mentres reproducís o fallo.

Artigos relacionados