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 ایسا حل کنندہ نصب کرتا ہے جسے دائرے کی ایپس انٹرفیس کے ذریعے پوچھیں گی۔ دونوں خاندان ایک ہی انٹرفیس پر ہو سکتے ہیں، اس لیے صرف IPv4 راستوں کا مجموعہ IPv6 پتے کے ساتھ ایسی ترتیب ہے جو درست پڑھی جاتی ہے اور پھر بھی رستی ہے۔ اگر آپ ایسا خاندان روٹ کریں جس میں انٹرفیس کا پتہ نہیں، کرنل کے پاس اُن پیکٹوں کے لیے ماخذ پتہ نہیں ہوتا اور وہ ڈسکرپٹر پر کبھی ظاہر نہیں ہوتے۔
establish() کیا واپس کرتا ہے
establish() ParcelFileDescriptor واپس کرتا ہے، یا null جب ایپ مجاز نہ ہو۔ null نیٹ ورک کی خرابی نہیں بلکہ رضامندی کی حالت ہے: VpnService.prepare() پہلے ہی null واپس کر چکا ہوگا، یا صارف نے کال سے پہلے نظامی مکالمہ منظور کیا ہوگا۔ سروس کے چلنے کے دوران رضامندی واپس لی جا سکتی ہے، اور انٹرفیس آپ کے پڑھنے کے لوپ میں کسی کال بیک کے بغیر آپ کے قدموں تلے بند ہو جاتا ہے۔
ڈسکرپٹر رکاوٹ نہیں ڈالتا جب تک آپ دوسری بات نہ کہیں، اس لیے پڑھنا تھریڈ کو روکنے کے بجائے بغیر ڈیٹا کے فوراً واپس آتا ہے۔ رکاوٹ ڈالنے والے ساکٹ کے لیے لکھا گیا لوپ ایک کور جلا دیتا ہے، اور خالی پڑھنے کو مہلک سمجھنے والا لوپ بیکار سیکنڈ میں ٹنل کو پھاڑ دیتا ہے۔ Builder.setBlocking(true) اس رویے کو بدلتا ہے، اور قیمت پڑھنے کے اندر انتظار کرنے والا تھریڈ ہے۔
راستے اور پتے کی دلیلہ LinkAddress قدروں کے طور پر جانچی جاتی ہیں، اور 224.0.0.0/4 جیسے ملٹی کاسٹ ہدف سیدھے مسترد کیے جاتے ہیں۔ نقطہ بہ نقطہ tun انٹرفیس میں بھی نشریاتی ڈومین نہیں ہوتا، اس لیے اُس کے ذریعے ملٹی کاسٹ تلاش کے لیے ایک اور راستہ نہیں بلکہ مختلف ڈیزائن چاہیے۔ جانچنے کی فہرست 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 دیکھنے کی جگہیں ہیں۔ ہر تہہ پر ایک جانچ آدھا دن کا اندازہ بچاتی ہے۔