Nei, VpnService-forrit getur ekki kveikt á VPN símanum
Forritið á eitt göng og lífsferil þess, ekki VPN-rofa símanum. Hægt er að afturkalla samþykki, aðeins eitt VPN keyrir í einu, og pakkarnir eru þínir að greina.
Röng forsendan er sú að VpnService-forrit snúi kerfisrofa og að síminn sé þaðan af varinn. Það sem raunverulega gerist er þrengra: forritið biður um samþykki, byggir viðmót, les og skrifar pakka um skráarlýsingu og skilar viðmótinu þegar það stöðvast. Aðeins eitt slíkt göng getur verið lifandi í einu og kerfið getur tekið það án þess að spyrja. Stærstur hluti þess ruglingslega hegðunar sem fólk kennir samskiptareglunum um kemur frá þessu eignarlíkani.
Meðhöndlaðu hverja umskipti lífsferilsins sem hluta af hönnuninni, ekki sem jaðartilfelli.
Goðsögn: forritið kveikir á VPN símanum
Flæðið byrjar með VpnService.prepare(), sem skilar Intent sem notandinn verður að samþykkja, og heldur áfram með establish(), sem getur samt mistekist síðar af ástæðum sem forritið stjórnar ekki. Að koma upp öðru göngum gerir fyrsta viðmótið óvirkt og kemur í stað kerfistilkynningarinnar. Hvergi í þeirri röð á forritið kerfisvíðan rofa; það á lýsinguna sem því var veitt og pakkana sem lenda á henni. Jafnvel varanlega tilkynningin tilheyrir kerfinu en ekki hönnun forritsins.
Þar sem viðmótið er veitt en ekki gripið getur annar biðlari tekið sætið hvenær sem er. Forritið kemst að því með afturkalli, ekki með endurgildi.
Þvinguð stöðvun forritsins sést í tilkynningaspjaldinu af sömu ástæðu: kerfið greinir frá því sem það veitti, ekki því sem forritið valdi að sýna.
Goðsögn: samþykki er gefið einu sinni
Þegar kerfið afhendir göngin öðrum biðlara sendir það afturköllunarfærslu á bindersins sem grunnklassinn skilar frá onBind(). Forrit sem kemur í stað þess binders með sínum eigin verður sjálft að senda afturköllunarfærsluna áfram, annars fer VpnService.onRevoke() aldrei af stað og þjónustan heldur áfram að skrifa í lýsingu sem er ekki lengur til. Notandinn getur líka dregið samþykki til baka og kerfið getur stöðvað þjónustuna við endurræsingu eða endurtengingu í alltaf-á-stillingu.
Að fást við það er áþreifanlegt verk en ekki atriði í annál: hættu að lesa lýsinguna, lokaðu henni, hreinsaðu tengda fánann og segðu notandanum í hvaða ástandi hann er. Ákveddu svo hvort forritið eigi að koma upp aftur, spyrja aftur eða bíða, því í alltaf-á-stillingu getur kerfið komið þjónustunni aftur sjálft.
Forrit sem meðhöndlar afturköllun sem undantekningu en ekki ástand mun tilkynna að það sé tengt meðan hver pakki sem það skrifar er hent, og það er versti mögulegi bilunarhamur fyrir persónuverndartól.
Goðsögn: viðmótið síar umferð fyrir þig
Það sem berst er hrátt IP. Að grípa eða sía þýðir að greina IP-, TCP-, UDP- og IPv6-hausa, fylgjast með flæðum og skrifa svör aftur í lýsinguna, sem gerir grípurforrit að litlum netstaka en ekki kerfisaðstöðu. protect() er til svo að eigin flutningssokkur forritsins fari fram hjá göngunum sínum í stað þess að grípa sjálfan sig, og það skilar Boolean-gildi sem á skilið athugun á hverjum sokki sem er búinn til eftir að göngin eru komin upp.
Listar smiðsins yfir leyfð og bönnuð forrit ákvarða hvers umferð fer inn í viðmótið. Þeir veita ekki aðgang að hyrningu handan IP-pakkanna sem viðmótið ber, og ekkert API afhjúpar göng annars biðlara né listar VPN-snið kerfisins. Nettengigetugeta getur sagt að net sé VPN-flutningur, en ekki hvers göngin eru.
Þess vegna fá stöðuspurningar um önnur forrit mótsagnakennd svör: upplýsingunum er einfaldlega ekki afhjúpað fyrir ferlinu þínu.
Hvað lífsferillinn krefst í raun
Fylgstu með ástandinu sem þú stjórnar: undirbúið, komið upp, afturkallað, stöðvað. Endurtenging ætti að vera niðurrif og svo uppsetning, með einn eiganda að lýsingunni og flutningssokkinum, því tveir þættir sem keppa um uppsetningu munu slást um eina lausa sætið. Bakgrunnsræsingar eru takmarkaðar á nútíma Android, svo útsending við ræsingu er ekki trygging; notaðu forgrunnsþjónustu með tilkynningu hennar þar sem API-stigið leyfir.
Skráðu umskiptin en ekki bara lokastandið, og haltu stöðuvélinni nógu lítilli til að prófa hverja leið. Ástand sem þú kemst ekki í í prófi er ástand sem þú munt mæta í reitnum án annálar.
Prófaðu lífsferilinn á tæki
Hermar geta fölsuð nettengingu en ekki samþykkis- og afturköllunarleiðina á sannfærandi hátt, svo keyrðu þetta á raunverulegu tæki með öðrum VPN-biðlara uppsettan til að stela sætinu.
adb shell dumpsys connectivity | grep -i -A3 vpn
adb shell dumpsys activity services | grep -i -A2 vpnservice
adb logcat -s VpnService:V AndroidRuntime:E
adb shell am force-stop com.example.vpnapp
Ræstu göngin, staðfestu tilkynninguna og viðmótið, tengdu svo hinn biðlarann og fylgstu með hvort afturköllunarafturkallið keyri og hvort ástandið hreinsist. Þvingaðu stöðvun forritsins og athugaðu hvort eitthvað greinir enn frá lifandi lýsingu.
Endurtaktu röðina eftir endurræsingu í alltaf-á-stillingu, því sú leið er frábrugðin tengingu sem notandinn hefur frumkvæði að. Það sem þú leitar að er ekki grænt tákn heldur sönnun þess að forritið hætti að nota lýsingu sem það átti ekki lengur.