Жок, VpnService колдонмосу телефондун VPNин күйгүзө албайт
Колдонмо бир тоннелге жана анын жашоо циклинен ээ, телефондун VPN которгучуна эмес. Макулдук кайтарылып алынышы мүмкүн, бир убакта бир гана VPN иштейт, пакеттерди өзүңүз талдоого туура келет.
Туура эмес божомол — VpnService колдонмосу системалык которгучту бурат жана ошондон кийин телефон корголгон деп эсептөө. Иш жүзүндө болгон нерсе тарыраак: колдонмо макулдук сурайт, интерфейс курат, файл дескриптору аркылуу пакеттерди окуп-жазат жана токтогондо интерфейсти кайтарат. Бир убакта мындай бир гана тоннель тирүү боло алат, жана система аны сурабастан алып койсо болот. Адамдар протоколго тагышкан түшүнүксүз жүрүм-турумдун көбү ушул ээлик моделинин түзүлүшүнөн келет.
Жашоо циклинин ар бир өтүшүн четки учур эмес, долбоордун бөлүгү катары караңыз.
Уламыш: колдонмо телефондун VPNин күйгүзөт
Агым VpnService.prepare() менен башталат, ал колдонуучу кабыл алышы керек болгон Intent кайтарат, жана establish() менен уланат, ал кийин колдонмо көзөмөлдөбөгөн себептерден улам ийгиликсиз болушу мүмкүн. Экинчи тоннелди орнотуу биринчи интерфейсти өчүрөт жана системалык билдирүүнү алмаштырат. Бул ырааттуулуктун эч жеринде колдонмо бүткүл түзмөктүн которгучуна ээ эмес; ал өзүнө берилген дескрипторго жана ага түшкөн пакеттерге ээ. Ал тургай туруктуу билдирүү да колдонмонун долбооруна эмес, системага таандык.
Интерфейс тартып алынбайт, берилет, андыктан башка кардар каалаган убакта орунду ээлей алат. Колдонмо муну кайтаруу мааниси аркылуу эмес, кайтарым чакыруу аркылуу билет.
Колдонмону мажбурлап токтотуу билдирүү панелинде ошол эле себептен көрүнөт: система эмне бергенин билдирет, колдонмо эмнени көрсөтүүнү тандаганын эмес.
Уламыш: макулдук бир жолу берилет
Система тоннелди башка кардарга өткөрүп бергенде, базалык класс onBind() тен кайтарган binderге жокко чыгаруу транзакциясын жөнөтөт. Ошол binderди өзүнүкү менен алмаштырган колдонмо жокко чыгаруу транзакциясын өзү жөнөтүшү керек, болбосо VpnService.onRevoke() эч качан иштебейт жана кызмат эми жок дескрипторго жаза берет. Макулдукту колдонуучу да кайтарып ала алат, жана система кайра жүктөө же дайыма күйүк кайра туташуу учурунда кызматты токтото алат.
Муну чечүү журнал сабы эмес, конкреттүү иш: дескрипторду окууну токтотуңуз, аны жабыңыз, туташкан желегин тазалаңыз жана колдонуучуга кайсы абалда экенин айтыңыз. Андан кийин колдонмо кайра орнотушу, кайра сурашы же күтүшү керекпи, чечиңиз, анткени дайыма күйүк конфигурацияда система кызматты өзү кайтарып келиши мүмкүн.
Жокко чыгарууну абал эмес, өзгөчө учур деп эсептеген колдонмо туташкан деп билдирет, ал эми ал жазган ар бир пакет ыргытылат, бул купуялык куралы үчүн мүмкүн болгон эң начар иштен чыгуу режими.
Уламыш: интерфейс трафикти сиз үчүн чыпкалайт
Келген нерсе — чийки IP. Кармоо же чыпкалоо IP, TCP, UDP жана IPv6 аталыштарын талдоону, агымдарды көзөмөлдөөнү жана жоопторду дескрипторго кайра жазууну билдирет, бул кармоочу колдонмону система куралы эмес, кичинекей тармак стегине айландырат. protect() колдонмонун өз транспорттук сокети өзүн кармоонун ордуна өз тоннелинен өтүшү үчүн бар жана тоннель көтөрүлгөндөн кийин түзүлгөн ар бир сокетте текшерүүгө татыктуу логикалык маанини кайтарат.
Куруучунун уруксат берилген жана тыюу салынган колдонмолор тизмелери кимдин трафиги интерфейске кирерин аныктайт. Алар интерфейс ташый турган IP пакеттеринен тышкаркы пайдалуу жүккө кирүү бербейт, жана эч бир API башка кардардын тоннелин ачпайт же системанын VPN профилдерин тизмелейт. Тармак мүмкүнчүлүктөрү тармак VPN транспорту экенин айта алат, бирок тоннель кимдики экенин айта албайт.
Ошондуктан башка колдонмолор тууралуу абал суроолоруна карама-каршы жооптор келет: маалымат жөн эле сиздин процессиңизге ачылбайт.
Жашоо цикли чындыгында эмнени талап кылат
Өзүңүз көзөмөлдөгөн абалдарды көзөмөлдөңүз: даярдалган, орнотулган, жокко чыгарылган, токтотулган. Кайра туташуу бузуу, андан кийин орнотуу болушу керек, дескриптор менен транспорттук сокеттин бир ээси менен, анткени орнотуу үчүн жарышкан эки компонент жалгыз бош орун үчүн талашат. Заманбап Android'де фондук баштоолор чектелген, андыктан жүктөө учурундагы берүү кепилдик эмес; API деңгээли уруксат берген жерде билдирүүсү менен алдыңкы план кызматын колдонуңуз.
Акыркы абалды гана эмес, өтүштү журналга жазыңыз, жана ар бир жолду текшерүүгө боло тургандай абал машинасын кичине кармаңыз. Сыноодо жете албаган абал журналсыз талаада жолуга турган абал.
Жашоо циклини түзмөктө сынап көрүңүз
Эмуляторлор туташууну жасалма кыла алат, бирок макулдук жана жокко чыгаруу жолун ишенимдүү түрдө эмес, андыктан буларды орунды уурдоо үчүн экинчи VPN кардары орнотулган чыныгы түзмөктө иштетиңиз.
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
Тоннелди баштаңыз, билдирүүнү жана интерфейсти ырастаңыз, андан кийин башка кардарды туташтырып, жокко чыгаруу кайтарым чакыруусу иштеп жатабы жана абал тазаланып жатабы, көзөмөлдөңүз. Колдонмону мажбурлап токтотуп, дагы эле тирүү дескриптор тууралуу билдирүү барбы, текшериңиз.
Дайыма күйүк кайра жүктөөдөн кийин ырааттуулукту кайталаңыз, анткени бул жол колдонуучу баштаган туташуудан айырмаланат. Сиз жашыл белгини эмес, колдонмо эми өзүнө таандык эмес дескрипторду колдонууну токтотконуна далил издеп жатасыз.