Mbrojtja e VpnService dështon kur një VPN tjetër është tashmë aktiv
Android lejon një ndërfaqe VPN për çdo përdorues. Kryeni kontrollet prepare, establish, protect dhe të pronësisë me radhë, më pas zgjidhni revokim ose përjashtim për aplikacion.
Programi juaj thërret VpnService.prepare, merr null, ndërton një tunel dhe përshkruesi duket i vlefshëm, por asgjë nuk arrin te serveri. Ose prepare kthen një Intent, përdoruesi e miraton dhe establish vazhdon të dështojë. Të dyja rezultatet zakonisht nënkuptojnë të njëjtën gjë: një aplikacion tjetër zotëron tashmë ndërfaqen VPN për këtë përdorues, dhe thirrjet tuaja protect po shënojnë soketa që tuneli juaj nuk mund t'i përdorë. Kaloni nëpër kontrollet më poshtë me radhë dhe ndaloni te e para që dështon, sepse një hap i mëvonshëm nuk mund të riparojë një të mëparshëm.
Kontrolloni vendin e VPN-ut para se të prekni protect
Android i jep çdo përdoruesi saktësisht një ndërfaqe VPN aktive. Ky është një rregull i platformës, jo një leje që programi juaj mund të kërkojë, prandaj dy klientë që duan të dy të jenë tuneli nuk mund të bashkëjetojnë.
Një VPN gjithmonë aktiv i vendosur për një aplikacion tjetër është rasti më i vështirë, sepse sistemi e mban atë aplikacion të lidhur dhe refuzon një marrje kontrolli. Një filtër trafiku si AdGuard, një klient korporativ ose një VPN konsumatori mund ta mbajë vendin ndërsa përdoruesi ka harruar se është instaluar. Kërkojini përdoruesit të hapë Cilësimet dhe të lexojë zërin e listuar nën VPN; emri atje është pronari me të cilin po konkurroni. Derisa ai zë të shkëputet ose cilësimi gjithmonë aktiv të fshihet, VpnService juaj nuk mund të bëhet ndërfaqja.
Hapi 1: lexoni çfarë kthen prepare
VpnService.prepare përgjigjet një pyetjeje të vetme: a mund të bëhet ky aplikacion VPN-i? Kthen null kur pëlqimi ekziston tashmë, dhe një Intent kur përdoruesi duhet ende ta miratojë, të cilin duhet ta nisni me startActivityForResult. Trajtojeni një kthim null si leje për të vazhduar, jo si provë që establish do të ketë sukses.
Intent intent = VpnService.prepare(context);
if (intent != null) {
startActivityForResult(intent, REQUEST_VPN);
}Nëse rruga e Intent kthehet dhe përdoruesi ka refuzuar, prepare do të vazhdojë të kthejë një Intent në provën tjetër. Regjistroni kodin e rezultatit në vend që të riprovoni në cikël, sepse një pëlqim i refuzuar është vendim i përdoruesit, jo gabim kalimtar.
Hapi 2: konfirmoni se ndërfaqja i përket programit tuaj
Pas establish, ParcelFileDescriptor që merrni është prova e pronësisë tuaj, dhe ia vlen ta kontrolloni para çdo pune me soketa. Një përshkrues null ose tashmë i mbyllur do të thotë që ndërfaqja nuk u krijua kurrë, edhe nëse nuk u shfaq asnjë përjashtim. Krahasoni emrin e ndërfaqes nga builder me atë që sistemi raporton për VPN-në aktive, duke përdorur dumpsys në një pajisje testuese. Nëse ndryshojnë, tuneli që ndërtuat nuk është tuneli që transporton trafikun.
adb shell dumpsys connectivityI njëjti mospërputhje shpjegon një ikonë të lidhur me trafik të vdekur. Sistemi shfaq tunelin e aplikacionit tjetër, ndërsa kodi juaj mban një përshkrues për një ndërfaqe që nuk e zotëron.
Hapi 3: thirrni protect para connect
Pasi ndërfaqja ekziston, soketat që hap programi juaj drejtohen në tunel si parazgjedhje. Transporti i jashtëm nuk mund ta ndjekë atë rregull, përndryshe paketa e inkapsuluar do të kthehej në ndërfaqe, prandaj VpnService protect shënon një soket për të anashkaluar VPN-në dhe për të përdorur rrjetin themelor. Thirrja kthen një boolean, dhe injorimi i tij është mënyra se si përfundoni me një soket që duket i shëndetshëm dhe nuk transporton asgjë.
Thirrni protect para connect ose bind, kurrë pas. Mbrojtja duhet të jetë në vend para se soketa të lidhet me rrjetin, sepse një soket i lidhur e ka zgjedhur tashmë rrugën dhe një protect i mëvonshëm nuk e lëviz në mënyrë të besueshme. Nëse protect kthen false, ndaloni dhe rikontrolloni pronësinë: dështon kur ndërfaqja nuk i përket programit tuaj, që është pikërisht gjendja që lë një VPN tjetër. Një kthim false është sinjal për t'u kthyer te Hapi 1, jo për të riprovuar të njëjtin soket.
DatagramSocket socket = new DatagramSocket();
if (!vpnService.protect(socket)) {
return;
}
socket.connect(serverAddress, serverPort);Hapi 4: lidhni një proces kur një soket është i papërshtatshëm
Disa transportues nuk janë një soket i vetëm: një bibliotekë mund të hapë disa, ose mund të dëshironi që çdo lidhje në një proces ndihmës të përdorë të njëjtin dalje. ConnectivityManager.bindProcessToNetwork e lidh procesin me një rrjet të zgjedhur, dhe setProcessDefaultNetwork i vjetër bënte të njëjtën gjë përpara se të hiqej. Kërkoni lidhjen themelore me NET_CAPABILITY_NOT_VPN në mënyrë që lidhja të zgjedhë rrjetin nën tunelin tuaj dhe jo vetë tunelin.
NetworkRequest request = new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
.build();Lidhja e një procesi nuk është një VPN i dytë. Zgjedh një dalje për atë proces, gjë që është e dobishme për transportin tuaj dhe e padobishme për të drejtuar dy tunele njëkohësisht.
Riparoni pajisjen e përdoruesit, jo rrugën e kodit
Nuk ka asnjë API që lejon dy aplikacione të ndajnë vendin e VPN-ut, prandaj rregullimi i përket gjendjes së pajisjes. Ofroni përdoruesit dy rrugë konkrete: shkëputni ose fshini gjithmonë aktiv për aplikacionin tjetër që prepare juaj të marrë kontrollin, ose hapni cilësimet për aplikacion të atij aplikacioni dhe përjashtoni programin tuaj nga tuneli i tij. Përjashtimi e mban filtrin duke punuar për çdo gjë tjetër dhe lejon programin tuaj të përdorë lidhjen e zakonshme, që shpesh është rezultati që përdoruesi dëshiron vërtet.
Shkruani të dyja rrugët në dokumentacionin tuaj të mbështetjes, sepse përdoruesit rrallë e dinë se cili aplikacion zotëron VPN-në. Kërkojuni të dërgojnë emrin e VPN-së aktive nga Cilësimet dhe rezultatet e prepare, establish dhe protect nga regjistrat tuaj, dhe brenda një minute mund të thoni cili hap dështoi. Më pas verifikoni me trafik të vërtetë: një kërkim emri, një lidhje TCP dhe një kërkesë përmes tunelit, jo vetëm një ikonë e lidhur. Një përshkrues i vlefshëm dhe një tregues i gjelbër provojnë në rastin më të mirë pronësinë, kurrë se transporti i mbijetoi rregullave të rrugëzimit.
Nëse të katër kontrollet kalojnë dhe trafiku vdes prapë, pronësia nuk është më problemi juaj. Kaloni te rrugëzimi dhe aksesueshmëria e serverit, dhe provoni të njëjtat kredenciale nga një pajisje pa aplikacion VPN të instaluar.