Android programėlė negali išspręsti vidinio vardo, nors paties VPN kliento naršyklė jį pasiekia, ir tas pats rinkinys veikia kitame telefone. URL nėra kintamasis. Kintamasis yra tai, kurį tinklą programėlės procesui leidžiama naudoti sprendimui, ir Android negarantuoja, kad aktyvus VPN yra tas, kurį naudoja jūsų soketai. Atlikite šiuos patikrinimus iš eilės ir sustokite, kai resolverio momentinė kopija nesutampa su jūsų prielaida.

1 žingsnis: įrodykite, kuriame tinkle yra programėlė

Skaitykite pačios programėlės vaizdą, o ne būsenos juostą. Iš ConnectivityManager gaukite aktyvų tinklą, jo LinkProperties, DNS serverių sąrašą ir privataus DNS nustatymą. Jei sąraše yra VPN resolveris, programėlė turi kelią į jį; jei jame yra Wi-Fi resolveris, tunelis nėra numatytasis to proceso tinklas.

VPN piktograma tik sako, kad tunelis egzistuoja. Ji nesako, kad programėlės procesas buvo su juo susietas, ir Android ne visada nukreipia vardų sprendimą per tinklą, kuris atrodo aktyvus. Vietinės VPN programėlės, persiunčiančios į kitą įrenginį, Wi-Fi tinklai be interneto ir gamintojo rinkiniai gali palikti programėlę klausiančią numatytojo resolverio, o ne tunelio serverių.

2 žingsnis: paprašykite VPN transporto ir susiekite procesą

Kai programėlė privalo naudoti tunelio resolverį, paprašykite tinklo su VPN transportu ir susiekite procesą atgaliniame iškvietime, kad kodas nespėliotų, kada tinklas atsiras:

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

Iškvietimas pakeičia viso proceso numatytąjį tinklą, todėl kiekvienas vėliau sukurtas soketas jį naudoja. Jau egzistuojantys soketai išlaiko tinklą, kuriame buvo sukurti, todėl prieš susiejimą atidarytas jungčių telkinys gali toliau spręsti senu keliu. Grąžinama reikšmė yra loginė, o false rezultatas reiškia, kad susiejimas neįvyko; bandykite dar kartą su trumpa pauze ir užregistruokite abu bandymus.

3 žingsnis: apribokite susiejimą tuo, kam jo reikia

Viso proceso susiejimas yra grubus. Telemetrija, atnaujinimų patikros ir trečiųjų šalių SDK taip pat persikelia į tunelį, o jei tunelis neturi interneto, jie pradeda gesti. Vienai užklausai naudokite tinklo soketų gamyklą, o visa kita palikite įrenginio numatytajam. Sąmoningai pasirinkite vieną modelį: siaurą susiejimą kiekvienai jungčiai arba proceso susiejimą su aiškiu atsiejimu, kai VPN išnyksta.

Dvi resolverio funkcijos gali nugalėti susiejimą be jokios klaidos. Privatus DNS griežtu režimu siunčia užklausas į pavadintą DoT serverį, o ne į tinklo resolverį, o programėlė, turinti savo DNS-over-HTTPS klientą, visiškai apeina sistemos resolverį. Patikrinkite abu prieš darydami išvadą, kad susiejimas nepavyko. Užklausa, kuri niekada nepasiekia VPN DNS serverio, nepasirodys jokiame tunelio pusės žurnale.

4 žingsnis: nepasitikėkite CONNECTED apribojimu

NetworkType.CONNECTED WorkManager reiškia, kad tinklas prijungtas, ir VPN transportas jį tenkina net tada, kai pagrindinė Wi-Fi arba korinio ryšio jungtis dingo. Užduotis vykdoma, kiekviena užklausa nepavyksta, o kartojimo politika paverčia tai audra, kuri atrodo kaip planavimo klaida. Tunelis yra tinklas; apribojimas niekada nebuvo interneto patikra.

Patikrinkite gebėjimą, kurio darbui iš tikrųjų reikia, pavyzdžiui, patvirtintą interneto prieigą, ir laikykitės ribotos kartojimo politikos su atsitraukimu. Jei užduočiai reikia privataus vardo, išspręskite tą vardą pasirinktame tinkle prieš atlikdami darbą ir greitai nutraukite su aiškia klaida, o ne kartokite užklausą, kuri negali pavykti.

5 žingsnis: užregistruokite įrodymus ir iš naujo išbandykite diapazoną

Užregistruokite pasirinkto tinklo transporto tipus, DNS serverius iš LinkProperties, ar susiejimas grąžino true, ir tikslią pirmosios užklausos klaidą. Tada paleiskite privatų vardą ir viešą vardą su tuo pačiu susiejimu. Ši pora parodo, ar programėlė naudojo tunelio resolverį, ar tyliai grįžo prie įrenginio numatytojo, ir tai yra skirtumas, kurį patiria naudotojas.

Pakartokite seniausioje palaikomoje Android versijoje ir viename dabartiniame leidime. Resolverio elgsena, dėl kurios numatytasis kelias atrodo teisingas, yra būtent ta vieta, kur skiriasi įrenginiai ir versijos, o rinkinys, kuris praeina tik naujausiame bandymų įrenginyje, nepatvirtintas jūsų siunčiamam diapazonui. adb shell dumpsys connectivity yra greitas būdas patvirtinti, kokius tinklus ir galimybes įrenginys praneša, kol atkuriate gedimą.

Susiję straipsniai