VpnService ичинде эч нерсе трафикти өзү кармабайт. Ал системадан tun интерфейсин сурайт, ал интерфейске даректер жана маршруттар топтомун берет, жана ошол учурдан тартып ядро ошол маршруттарга дал келген ар бир пакетти колдонмо окуй ала турган файл дескрипторуна көчүрөт. Колдонмонун коду маршруттар тандабаган пакеттерди эч качан көрбөйт, ошондуктан туннелдин чеги программалоо маселесине чейин маршруттоо таблицасынын маселеси. Ошондуктан бир эле кызматтын ишке ашырылышы бир телефондо бардык агымды жута алат, экинчисинде болсо бир бөлүгүн гана, жана ошондуктан маршрут кошуу кээде сынгандай көрүнгөн туннелди оңдойт. Сиз алганыңыз — жарыялаганыңыз, куруучу үнсүз баш тарткандын баарын алып салганда.

Кайсы пакеттер келерин маршруттар чечет

Builder.addRoute(prefix, prefixLength) VPN тармагынын маршруттоо таблицасына префикс орнотот. Система бул тармакты чөйрөдөгү колдонмолор үчүн демейки деп эсептейт, ошондуктан анын жазуулары физикалык тармактын демейки маршрутунан мурун каралат жана дал келген префикс агымды бурууга жетиштүү. Ошондуктан 0.0.0.0/0 үчүн маршрут IPv4-тү толугу менен алат, принтер, cast бутасы жана маршрутизатордун административдик бети менен кошо.

Физикалык демейки жазууну өчүрбөй ошол жабууну каалаган кардарлар анын ордуна 0.0.0.0/1 жана 128.0.0.0/1 түгөйүн колдонушат. Эки так маршрут демейки маршрутту жеңет, чогуу алар бардык дарек мейкиндигин жабат, жана телефондун өз демейки жазуусу физикалык тармакка байланган сокеттер үчүн таблицада калат.

Даректер жана DNS жазуулары ошол эле куруучудан келип, башка суроого жооп берет. addAddress интерфейске префикс узундугу менен дарек берет, ал эми addDnsServer чөйрөдөгү колдонмолор интерфейс аркылуу сурай турган чечүүчүнү орнотот. Эки үй-бүлө тең бир интерфейсте отура алат, ошондуктан IPv6 дарегинин жанындагы IPv4 гана маршруттар топтому туура окулган жана баары бир агып кеткен конфигурация. Эгер интерфейсте дареги жок үй-бүлөнү маршруттасаңыз, ядронун ал пакеттер үчүн баштапкы дареги болбойт жана алар дескриптордо эч качан көрүнбөйт.

establish() эмне кайтарат

establish() ParcelFileDescriptor кайтарат, же колдонмо уруксат берилбегенде null. null тармактын катасы эмес, макулдук абалы: VpnService.prepare() мурунтан null кайтарган болушу керек, же колдонуучу чакыруудан мурун система диалогун уруксат кылган болушу керек. Макулдук кызмат иштеп турганда кайтарылып алынышы мүмкүн, жана интерфейс сиздин окуу циклиңизге эч кандай кайтарым чакыруусуз бутуңуздун астында жабылат.

Дескриптор башкача айтпасаңыз бөгөттөбөйт, ошондуктан окуу агымды токтотуунун ордуна дайынсыз дароо кайтат. Бөгөттөгүч сокет үчүн жазылган цикл бир ядрону күйгүзөт, ал эми бош окууну өлүмгө алып келет деп эсептеген цикл бош секундда туннелди жарып салат. Builder.setBlocking(true) бул жүрүм-турумду өзгөртөт, ал эми баасы окуунун ичинде күткөн агым.

Маршрут жана дарек аргументтери LinkAddress маанилери катары текшерилет, ал эми 224.0.0.0/4 сыяктуу multicast буталары дароо четке кагылат. Пункттан пунктка tun интерфейсинде да жарыялоо домени жок, ошондуктан анын аркылуу multicast издөө үчүн дагы бир маршрут эмес, башка дизайн керек. Текшерүүчү тизме — VpnService.Builder, чалуу этибарсыз калды деген тыянакка келүүдөн мурун.

Колдонмо боюнча чөйрө топтомду тарылтат, туннелди эмес

API 21ден баштап куруучу addAllowedApplication жана addDisallowedApplication кабыл алат, жана эки тизме бир куруучунун ичинде бири-бирин жокко чыгарат. Уруксат тизмеси ошол пакеттер үчүн туннелди бар кылып турат, калганынын баары физикалык тармакты сактайт; тыюу тизмеси аталган пакеттерден башканын баарын кармайт, муну кардар бөлүнгөн туннелдөө катары сунуштайт. API 21ге чейин платформалык механизм такыр жок, ал эми колдонмо боюнча жүрүм-турум өз багыттоочусунун ичинде UID боюнча чыпкалаган үчүнчү тарап кардарларынан келген. Бул айырма мүчүлүштүктү оңдоодо маанилүү, анткени бир пакеттик уруксат тизмеси бар колдонмо боюнча туннел дээрлик трафик жаратпайт жана бул туура жүрүм-турум, сынган маршрут эмес.

Чөйрө кандай болбосун, колдонмоңуз VPN серверине ачкан сокет өзү куруп жаткан туннелден өтпөшү керек. VpnService.protect(socket) ошол сокетти астындагы тармакка байлайт, ошондуктан анын пакеттери tun түзмөгүн айланып өтөт. Чакырууну өткөрүп жиберсеңиз, кол кармоону аны көтөрүшү керек болгон интерфейс жутат.

VpnService.setUnderlyingNetworks системага туннелди кайсы физикалык тармак ташып жатканын айтып, тегерекчени жабат. Бул маани VPN башка колдонмолорго туташуу жөнүндө кантип билдирерин аныктайт, жана null же эскирген маани телефондун калган бөлүгү оффлайн деп эсептеген туташкан туннелдин кадимки себеби. Аны астындагы тармак өзгөргөндө жаңыртыңыз, иштетилгенде гана эмес.

Текшерүү суммалары жана MTU: туура маршрут да ийгиликсиз болгон жер

Пакеттер келгенден кийин пакет деңгээлиндеги эки детал бир нерсенин учтан учка иштээрин чечет. Биринчиси — баштапкы дарек: бир нече интерфейс дареги болсо ядро биринчисин алып жүргөн пакеттерди жибериши мүмкүн, ошондуктан аталыштарды кайра жазган багыттоочу даректи жана аны жапкан текшерүү суммасын оңдошу керек.

Экинчиси — текшерүү суммасынын чөйрөсү. Колдонмо TCP же UDP пакеттерин өзү кураса, текшерүү суммасы баштапкы даректи, бутадагы даректи, протокол номерин жана ташуу узундугун камтыган жасалма аталышты жабат, жана алардын кайсынысын болбосун калтыруу келип, ыргытылган пакеттерди берет. Бул ийгиликсиздик эч качан келбеген жооптон кийинки убакыттын бүтүшүнө окшош, жана бул көпчүлүктү маршруттарга кайтарат. setMtu интерфейстин MTU-сун бекемдейт, жана ар бир окуу так бир толук IP пакетин кайтарат, ошондуктан байт агымы үчүн жазылган буфер пакетти эмес, сиздин талдоону бөлүктөйт.

Каймарларды бөлүүчү текшерүү айлампасы

Чөйрө кайда жаңылышканын табуу үчүн каймарларды ирети менен сынаңыз. VPN тармагы чындап эле кайсы маршруттарды кармай турганын түзмөктөн сураңыз, анан белгилүү дарекке агым дескриптордо окуу катары көрүнөрүн текшериңиз, анан багыттоочуңуз жиберген пакеттин туура түзүлгөнүн текшериңиз. Маршрут маселеси дескриптордо эч нерсе көрсөтпөйт, ал эми текшерүү суммасынын маселеси келип жоголгон пакетти көрсөтөт.

Эгер дескрипторго эч нерсе жетпесе, шектүү окуучу эмес, маршруттар топтому: префикстерди ырастаңыз, ошол эле үй-бүлөдө дарек бар экенин ырастаңыз жана колдонмо сиз койгон чөйрөнүн ичинде экенин ырастаңыз. Эгер пакеттер дескрипторго жетсе, бирок эч нерсе кайтпаса, маршрутка кайра тийүүдөн мурун protect() жана астындагы тармактын маанисин текшериңиз. Эгер алыскы тарап бузулган пакеттер тууралуу билдирсе, текшерүү суммасы жана MTU — кароо керек болгон жерлер. Ар бир каймарга бир текшерүү жарым күн болжолдоону үнөмдөйт.

Тектеш макалалар