Android VpnService яагаад зарим урсгалыг барьж, бүгдийг нь биш
Маршрутууд, DNS бичлэгүүд болон програм тус бүрийн хүрээ нь аль пакетууд tun төхөөрөмжид хүрэхийг, локал төхөөрөмжүүд яагаад алга болохыг, бүтээгч юунаас татгалздагийг тодорхойлдог.
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 нь харах газрууд юм. Давхарга бүрт нэг шалгалт хагас өдрийн таамаглалыг хэмнэдэг.