Tunnelning o'z paketlarini tunneldan tashqarida ushlab turishning ikki yo'li bor: transport soketini himoya qilish yoki butun ilovani VPN-dan chiqarish. Ular turli muammolarni hal qiladi va ulash osonroq bo'lgani uchun kengroqini tanlash ilovalar sezmay turib mahalliy tarmoqqa kirishni va bo'lingan DNSni yo'qotishining aynan sababidir. Tunneldan tashqarida qolishi kerak bo'lgan narsadan boshlang, so'ng shuni ta'minlaydigan eng kichik qamrovni tanlang.

protect() tunneldan nimani olib tashlaydi

VpnService.protect() bitta soket uchun chaqiruv. Siz unga tunnelni tashuvchi soket yoki deskriptorni berasiz va Android bu soketni trafigi VPN interfeysi o'rniga ostidagi tarmoqdan foydalanadigan qilib belgilaydi. Ilova yuboradigan qolgan hamma narsa odatdagi VPN yo'lidan boradi.

Aynan shu tor qamrov maqsad. Himoyalangan soket HTTP mijozi nomlarni qanday hal qilishini, tahliliy chaqiruvlaringiz qaysi interfeysdan foydalanishini yoki keyinroq ochilgan ikkinchi ulanishga nima bo'lishini o'zgartirmaydi.

Qamrovni belgilaydigan uch shart

Birinchi shart — faqat tunnel transporti chiqishi kerakmi. Agar ilovaning boshqa trafigi hali ham VPN orqali o'tishi kerak bo'lsa, soket himoyasi to'g'ri qamrov. Ikkinchi shart — soket yaratishni o'zingiz nazorat qilasizmi. Ichkarida chuqur o'z soketini ochadigan kutubxona, agar ilgak taqdim etmasa yoki tayyor soketni qabul qilmasa, sizga protect() chaqirish joyini qoldirmaydi. Uchinchi shart — ilova mahalliy tarmoqqa yoki ushlab qoluvchi portalga bevosita yetishi kerakmi; bu tunnelni tirik saqlashdan boshqa talab.

Ilovani addDisallowedApplication() bilan chiqarib tashlash qo'pol asbob. U ilova yaratadigan har bir ulanishni, tekshirmoqchi bo'lganlaringiz ham, VPN-dan olib tashlaydi va ba'zi qurilmalarda mahalliy aniqlash xatti-harakatini ham o'zgartiradi.

Uchinchi variant — transportni tanlangan tarmoqqa bindProcessToNetwork() yoki soket darajasidagi tarmoq tutqichi bilan bog'lash. Qurilmada bir vaqtda Wi-Fi va uyali tarmoq bo'lsa va tunnel ma'lum bir yuqori kanaldan o'tishini istasangiz, bu foydali.

Uni transport yaratilayotganda chaqiring

protect() ni transportni yaratadigan o'sha blokda, connect() yoki send() dan oldin chaqiring. Chaqiruv false qaytarsa, soketni yoping va sozlash muvaffaqiyatsiz bo'lsin; davom etish sizga paketlari o'z interfeysingizga qayta kirishi mumkin bo'lgan transport qoldiradi.

Shakl bir joyda saqlanadigan darajada kichik:

DatagramSocket transport = new DatagramSocket();
if (!protect(transport)) {
    transport.close();
    throw new IOException("transport not protected");
}
transport.connect(serverAddress);

Bu yerda uchta tafsilot tishlaydi. Birinchidan, siz oladigan yagona signal mantiqiy qiymatdir, shuning uchun xatoni bekor qilingan rozilikni rad etilgan chaqiruvdan ajratish uchun yetarli kontekst bilan yozib qo'ying. Ikkinchidan, protect() deskriptor raqamini emas, soketni qamrab oladi: soketni yopsangiz va keyin o'sha butun sonni boshqa soket uchun ishlatsangiz, yangi soket himoyalanmagan bo'ladi. Uchinchidan, transportni mahalliy kutubxona ochsa, mahalliy kod ulanmasidan oldin deskriptorni himoya qiling, aks holda marshrut allaqachon tanlangan bo'lishi mumkin. VpnService ma'lumotnomasi maqsad API darajangiz aslida qaysi ortiqcha yuklamalarni taqdim etishini tasdiqlaydigan joy.

To'silgan yo'lni ham sinang, faqat omadli yo'lni emas

Tunnel ishlab turganda tekshiring, chunki ikki yo'l faqat shu holatda farq qilishi mumkin. Bitta so'rovni himoyalangan transport orqali, yana birini hech qachon protect() chaqirmagan kod yo'lidan yuboring, so'ng uzoq uch ko'radigan narsani solishtiring: himoyalangan ulanish manba sifatida ostidagi tarmoq bilan kelishi kerak, himoyalanmagani esa tunnelning o'z manzilini ko'rsatadi va uning bayt hisoblagichlarini qimirlatadi. Qurilmada ss yoki netstat biror narsa radiodan chiqishidan oldin xuddi shu bo'linishni ko'rsatadi.

Bekor qilishni alohida sinab ko'ring, chunki rozilik o'zgarishi soket kodingizga tegmasdan interfeysni buzadi. VPN roziligini bekor qiling yoki xizmatni to'xtating, transportni qayta quring va protect() hali ham true qaytarishini hamda rozilik yana berilgach transport qayta ulanishini tasdiqlang.

Himoyalangan so'rov baribir tunnel bo'ylab ketsa, himoya chaqiruvi ehtimol soket allaqachon yo'naltirilgandan keyin sodir bo'ladi. Uni avvalroq ko'chiring va yana sinab ko'ring.

Qarorni transport sozlamasi yonida yozib saqlang: qaysi soketlar himoyalangan, ilovaning qaysi trafigi chiqarib tashlangan va himoya muvaffaqiyatsiz bo'lganda ilova nima qiladi. Aynan shu satr keyingi refaktoringning, bitta test yiqilgani uchun, chiqarib tashlashni butun ilovaga kengaytirishini to'xtatadi. U keyingi odamga manifestni teskari injiniring qilmasdan niyatni tekshirish yo'lini ham beradi.

O'xshash maqolalar