Die verkeerde aanname is dat ’n VpnService-program ’n stelselskakelaar omdraai en dat die foon van toe af beskerm is. Wat werklik gebeur, is smaller: die program vra toestemming, bou ’n koppelvlak, lees en skryf pakkette deur ’n lêerbeskrywer, en gee die koppelvlak terug wanneer dit stop. Net een so ’n tonnel kan op ’n slag leef, en die stelsel kan dit sonder om te vra wegneem. Die meeste verwarrende gedrag wat mense aan die protokol toeskryf, kom uit daardie eienaarskapmodel.

Behandel elke oorgang in die lewensiklus as deel van die ontwerp, nie as ’n randgeval nie.

Mite: die program skakel die foon se VPN aan

Die vloei begin met VpnService.prepare(), wat ’n Intent teruggee wat die gebruiker moet aanvaar, en gaan voort met establish(), wat daarna steeds kan misluk om redes wat die program nie beheer nie. Om ’n tweede tonnel te vestig, deaktiveer die eerste koppelvlak en vervang die stelselkennisgewing. Nêrens in daardie reeks besit die program ’n toestelwye skakelaar nie; dit besit die beskrywer wat aan hom gegee is en die pakkette wat daarop beland. Selfs die aanhoudende kennisgewing behoort aan die stelsel eerder as aan die program se ontwerp.

Omdat die koppelvlak gegee word eerder as gegryp, kan ’n ander kliënt die plek enige tyd inneem. Die program leer dit deur ’n terugroep, nie deur ’n terugkeerwaarde nie.

Om die program met geweld te stop, is in die kennisgewingstrook sigbaar om dieselfde rede: die stelsel rapporteer wat hy gegee het, nie wat die program gekies het om te wys nie.

Mite: toestemming word net een keer gegee

Wanneer die stelsel die tonnel aan ’n ander kliënt oorhandig, stuur dit ’n herroepingstransaksie op die binder wat die basisklas uit onBind() teruggee. ’n Program wat daardie binder met sy eie vervang, moet die herroepingstransaksie self deurstuur, anders vuur VpnService.onRevoke() nooit nie en bly die diens in ’n beskrywer skryf wat nie meer bestaan nie. Goedkeuring kan ook deur die gebruiker teruggetrek word, en die stelsel kan die diens stop tydens ’n herbegin of ’n altyd-aan-herverbinding.

Om dit te hanteer is konkrete werk, nie ’n logreël nie: stop met die lees van die beskrywer, sluit dit, maak die gekoppelde vlag skoon en sê vir die gebruiker in watter toestand hy is. Besluit dan of die program moet hervestig, weer moet vra of moet wag, want op ’n altyd-aan-opstelling kan die stelsel die diens self terugbring.

’n Program wat herroeping as ’n uitsondering eerder as ’n toestand behandel, sal rapporteer dat hy gekoppel is terwyl elke pakket wat hy skryf, laat val word, wat die slegste moontlike foutmodus vir ’n privaatheidsinstrument is.

Mite: die koppelvlak filter verkeer vir jou

Wat aankom, is rou IP. Om vas te vang of te filter beteken om IP-, TCP-, UDP- en IPv6-opskrifte te ontleed, vloei te volg en antwoorde terug na die beskrywer te skryf, wat ’n vasvangprogram ’n klein netwerkstapel maak eerder as ’n stelselfasiliteit. protect() bestaan sodat die program se eie vervoersokkel sy tonnel omseil in plaas daarvan om homself vas te vang, en dit gee ’n boole terug wat ’n kontrole verdien op elke sokkel wat geskep word nadat die tonnel op is.

Die bouer se toegelate en verbode toepassingslyste bepaal wie se verkeer die koppelvlak binnekom. Hulle verleen nie toegang tot loonvragte buite die IP-pakkette wat die koppelvlak dra nie, en geen API stel ’n ander kliënt se tonnel bloot of lys die stelsel se VPN-profiele. Netwerkvermoëns kan sê dat ’n netwerk VPN-vervoer is, maar nie wie se tonnel dit is nie.

Dit is waarom statusvrae oor ander programme teenstrydige antwoorde kry: die inligting word bloot nie aan jou proses blootgestel nie.

Wat die lewensiklus werklik vereis

Volg die toestande wat jy beheer: voorberei, gevestig, herroep, gestop. Herverbinding moet afbreek wees gevolg deur vestiging, met ’n enkele eienaar vir die beskrywer en die vervoersokkel, want twee komponente wat om die een beskikbare plek resies jaag, sal daaroor baklei. Agtergrondstarts word op moderne Android beperk, so ’n selflaai-uitsending is nie ’n waarborg nie; gebruik ’n voorgronddiens met sy kennisgewing waar die API-vlak dit toelaat.

Merk die oorgang aan eerder as net die eindtoestand, en hou die toestandmasjien klein genoeg om elke pad te toets. ’n Toestand wat jy nie in ’n toets kan bereik nie, is ’n toestand wat jy in die veld sonder ’n log sal teëkom.

Toets die lewensiklus op ’n toestel

Emulators kan konnektiwiteit namaak, maar nie die toestemmings- en herroepingspad oortuigend nie, so voer hierdie op ’n regte toestel uit met ’n tweede VPN-kliënt geïnstalleer om die plek te steel.

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

Begin die tonnel, bevestig die kennisgewing en die koppelvlak, verbind dan die ander kliënt en kyk of die herroepingsterugroep loop en die toestand skoonmaak. Stop die program met geweld en kyk of iets steeds ’n lewende beskrywer rapporteer.

Herhaal die reeks ná ’n altyd-aan-herbegin, want daardie pad verskil van ’n gebruiker-geïnisieerde verbinding. Wat jy soek, is nie ’n groen ikoon nie, maar bewyse dat die program opgehou het om ’n beskrywer te gebruik wat hy nie meer besit nie.

Verwante artikels