VpnService protect() же колдонмону чыгаруу: маршруттоону эмне оңдойт
Туннелди алып жүргөн сокетти коргоңуз же бүт колдонмону чыгарыңыз: Android VPNиңизге кандай камтуу керек экенин аныктоочу үч шарт.
Туннелдин өз пакеттерин туннелден тышкары кармоонун эки жолу бар: транспорттук сокетти коргоо же бүт колдонмону VPNден чыгаруу. Алар ар башка маселелерди чечет, ал эми туташтыруу жеңил болгондуктан кененирээк вариантты тандоо — колдонмолордун байкабай эле жергиликтүү тармакка кирүү жана бөлүнгөн DNSтен ажырашынын жолу. Туннелден тышкары калышы керек нерседен баштаңыз, анан ага жетүүчү эң кичине камтууну тандаңыз.
protect() туннелден эмнени алып салат
VpnService.protect() ар бир сокет үчүн чакыруу. Сиз ага туннелди алып жүргөн сокетти же дескрипторду бересиз, ал эми Android ошол сокетти белгилейт, ошондо анын трафиги VPN интерфейсинин ордуна астындагы тармакты пайдаланат. Колдонмо жөнөткөн калган нерселердин баары кадимки VPN маршрутун улантат.
Так ошол тар камтуу — маселенин маңызы. Корголгон сокет HTTP кардарыңыздын аттарды кантип чечкенин, аналитикалык чакырууларыңыз кайсы интерфейсти колдонорун же кийин ачылган экинчи туташууга эмне болорун өзгөртпөйт.
Камтууну аныктоочу үч шарт
Биринчи шарт — туннелдин транспорту гана чыгышы керекпи. Эгер колдонмонун калган трафиги дагы эле VPN аркылуу өтүшү керек болсо, сокетти коргоо туура камтуу. Экинчи шарт — сокет жасоону өзүңүз көзөмөлдөйсүзбү. Ичинен тереңде өз сокетин ачкан китепкана сизге protect() чакырууга орун калтырбайт, эгер ал илгич бербесе же даяр сокетти кабыл албаса. Үчүнчү шарт — колдонмо жергиликтүү тармакка же captive portalга түз жетиши керекпи, бул туннелди тирүү кармоодон башка талап.
Колдонмону addDisallowedApplication() аркылуу чыгаруу — одоно курал. Ал колдонмо түзгөн ар бир туташууну VPNден алып салат, анын ичинде текшергиңиз келгендерди да, ал эми кээ бир түзмөктөрдө жергиликтүү табуу жүрүм-турумун да өзгөртөт.
Үчүнчү вариант — транспортту тандалган тармакка байлоо:bindProcessToNetwork() же сокет деңгээлиндеги тармак туткасы аркылуу. Бул түзмөктө бир убакта Wi-Fi жана уюлдук тармак болгондо жана туннелдин белгилүү бир жогорку канал аркылуу жүрүшүн кааласаңыз пайдалуу.
Аны транспорт түзүлүп жатканда чакырыңыз
Чакырыңыз protect() транспортту түзгөн ошол блокто,connect() же send() чейин. Эгер чакыруу false кайтарса, сокетти жаап, орнотууну ийгиликсиз кылыңыз; улантуу сизди пакеттери өз интерфейсиңизге кайра кириши мүмкүн болгон транспорт менен калтырат.
Форма бир жерде кармоого жетиштүү кичине:
DatagramSocket transport = new DatagramSocket();
if (!protect(transport)) {
transport.close();
throw new IOException("transport not protected");
}
transport.connect(serverAddress);Бул жерде үч деталь тиштеп алат. Биринчиден,boolean — алган жалгыз сигналыңыз, ошондуктан ийгиликсиздикти кайтарылып алынган макулдукту четке кагылган чакыруудан ажырата турган контекст менен жазыңыз. Экинчиден,protect() сокетти камтыйт, дескриптордун номерин эмес: сокетти жаап, кийин ошол эле бүтүн санды башка сокет үчүн кайра колдонсоңуз, жаңы сокет корголгон эмес. Үчүнчүдөн, native китепкана транспортту ачканда, native код туташканга чейин дескрипторду коргоңуз, болбосо маршрут мурун эле тандалган болушу мүмкүн.VpnService маалымдамасы буталышкан API деңгээлиңиз чындыгында кандай жүктөөлөрдү сунуштаарын ырастоочу жер.
Бактылуу жолду гана эмес, тосулган жолду да сынаңыз
Туннел көтөрүлгөн абалда текшериңиз, анткени эки жол ушунда гана айырмаланышы мүмкүн. Корголгон транспорт аркылуу бир суроо-талап жана protect() эч качан чакырбаган код жолунан дагы бир суроо-талап жөнөтүп, алыскы тарап эмнени көрөрүн салыштырыңыз: корголгон туташуу астындагы тармак менен булак катары келиши керек, ал эми корголбогон туннелдин өз дарегин көрсөтүп, анын байт эсептегичтерин кыймылдатат. Түзмөктө ss же netstat радиодон бир нерсе чыкканга чейин ошол эле бөлүнүштү көрсөтөт.
Кайтарып алууну өзүнчө сынаңыз, анткени макулдуктун өзгөрүшү сокет кодуңузга тийбестен интерфейсти кулатат. VPN макулдугун кайтарып алыңыз же кызматты токтотуңуз, транспортту кайра куруп,protect() дагы эле true кайтарарын жана макулдук кайра берилгенде транспорттун кайра туташарын ырастаңыз.
Эгер корголгон суроо-талап баары бир туннелди ээрчисе, коргоо чакыруу сокет мурун эле маршрутталгандан кийин болуп жатат. Аны эртерек жылдырып, кайра сынаңыз.
Чечимди транспорт конфигурациясынын жанында жазып кармаңыз: кайсы сокеттер корголгон, кайсы колдонмо трафиги чыгарылган жана коргоо ийгиликсиз болгондо колдонмо эмне кылат. Ушундай сап кийинки рефактордун бир тест кулагандыгы үчүн чыгарууну бүт колдонмого кеңейтүүсүнө жол бербейт. Ал ошондой эле кийинки адамга манифестти тескери инженерия кылбай эле ниетти текшерүү жолун берет.