App na Android na nagreresolba ng mga pangalan sa labas ng VPN: checklist ng binding
Maaaring magresolba ang Android sa default na network habang aktibo ang VPN. I-bind ang proseso sa VPN network at tiyakin kung aling resolver ang aktwal na ginamit ng app.
Nabibigo ang isang app na Android na i-resolba ang isang panloob na pangalan habang naaabot ito ng browser ng mismong VPN client, at gumagana ang parehong build sa ibang telepono. Hindi ang URL ang baryabol. Ang baryabol ay kung aling network ang pinapayagang gamitin ng proseso ng app para sa resolusyon, at hindi ginagarantiya ng Android na ang aktibong VPN ang network na ginagamit ng iyong mga socket. Gawin ang mga pagsusuring ito nang sunud-sunod at huminto kapag hindi tumugma ang snapshot ng resolver sa iyong palagay.
Hakbang 1: patunayan kung aling network naroroon ang app
Basahin ang sariling view ng app, hindi ang status bar. Mula sa ConnectivityManager, kunin ang aktibong network, ang LinkProperties nito, ang listahan ng mga DNS server at ang setting ng pribadong DNS. Kung may resolver ng VPN sa listahan, may daan ang app papunta rito; kung may resolver ng Wi-Fi, hindi ang tunnel ang default na network para sa prosesong iyon.
Ang icon ng VPN ay nagsasabi lamang na may tunnel. Hindi nito sinasabi na ang proseso ng app ay nakabind dito, at hindi laging itinutuon ng Android ang resolusyon ng pangalan sa network na mukhang aktibo. Ang mga lokal na VPN app na nagpapasa sa ibang device, mga Wi-Fi network na walang internet at mga build ng vendor ay maaaring mag-iwan sa app na nagtatanong sa default na resolver sa halip na sa mga server ng tunnel.
Hakbang 2: hilingin ang VPN transport at i-bind ang proseso
Kapag kailangang gamitin ng app ang resolver ng tunnel, humiling ng network na may VPN transport at i-bind ang proseso sa callback, upang hindi hulaan ng code kung kailan lilitaw ang network:
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)
}
})
Binabago ng tawag ang default na network ng buong proseso, kaya bawat socket na ginawa pagkatapos ay gumagamit nito. Ang mga socket na mayroon na ay nagpapanatili ng network kung saan sila ginawa, kaya ang isang pool ng koneksyon na binuksan bago ang binding ay maaaring magpatuloy sa pagresolba sa lumang daan. Ang ibinabalik na halaga ay boolean, at ang resultang false ay nangangahulugang hindi nangyari ang binding; subukang muli nang may maikling pagkaantala at i-log ang parehong pagtatangka.
Hakbang 3: limitahan ang binding sa kailangan lang nito
Ang binding ng buong proseso ay magaspang. Lumilipat din sa tunnel ang telemetry, mga pagsusuri ng update at mga SDK ng third party, at kapag walang internet ang tunnel ay nagsisimula silang mabigo. Para sa isang kahilingan, gamitin ang socket factory ng network at iwanan ang default ng device para sa lahat ng iba pa. Sadyang pumili ng isang modelo: makitid na binding bawat koneksyon, o binding ng proseso na may malinaw na unbind kapag nawala ang VPN.
May dalawang katangian ng resolver na maaaring talunin ang binding nang walang anumang error. Ang pribadong DNS sa strict mode ay nagpapadala ng mga query sa isang pinangalanang DoT server sa halip na sa resolver ng network, at ang app na may sariling DNS-over-HTTPS client ay ganap na lumalampas sa resolver ng system. Suriin ang pareho bago magpasya na nabigo ang binding. Ang query na hindi kailanman umabot sa DNS server ng VPN ay hindi lilitaw sa anumang log sa gilid ng tunnel.
Hakbang 4: huwag magtiwala sa hadlang na CONNECTED
NetworkType.CONNECTED sa WorkManager ay nangangahulugang may konektadong network, at natutugunan ito ng VPN transport kahit nawala ang pinagbabatayang Wi-Fi o cellular link. Tumatakbo ang trabaho, nabibigo ang bawat kahilingan, at ginagawa ito ng patakaran sa pag-uulit na isang bagyo na mukhang bug sa pag-iiskedyul. Ang tunnel ay isang network; ang hadlang ay hindi kailanman naging pagsusuri ng internet.
Suriin ang kakayahang talagang kailangan ng trabaho, tulad ng beripikadong pag-access sa internet, at panatilihin ang limitadong patakaran sa pag-uulit na may backoff. Kung kailangan ng trabaho ang pribadong pangalan, i-resolba ang pangalang iyon sa napiling network bago gawin ang trabaho, at mabilis na mabigo nang may malinaw na error sa halip na ulitin ang kahilingang hindi maaaring magtagumpay.
Hakbang 5: itala ang ebidensya at muling subukan ang saklaw
I-log ang mga uri ng transport ng napiling network, ang mga DNS server mula sa LinkProperties, kung nagbalik ng true ang binding, at ang eksaktong kabiguan ng unang kahilingan. Pagkatapos ay patakbuhin ang isang pribadong pangalan at isang pampublikong pangalan sa ilalim ng parehong binding. Ipinapakita ng pares na iyon kung ginamit ng app ang resolver ng tunnel o tahimik na bumalik sa default ng device, at iyon ang pagkakaibang nararanasan ng user.
Ulitin sa pinakalumang bersyon ng Android na sinusuportahan mo at sa isang kasalukuyang release. Ang pag-uugali ng resolver na nagpapamukhang tama ang default na daan ay eksakto kung saan nagkakaiba ang mga device at bersyon, at ang build na pumapasa lamang sa pinakabagong test device ay hindi beripikado para sa saklaw na ipinapadala mo. Ang adb shell dumpsys connectivity ay isang mabilis na paraan upang kumpirmahin kung aling mga network at kakayahan ang iniuulat ng device habang ginagaya mo ang kabiguan.