ستاسو اپلیکیشن VpnService.prepare غواړي، null ترلاسه کوي، یوه تونل جوړوي، او ډسکریپټر سم ښکاري، خو هیڅ شی سرور ته نه رسیږي۔ یا prepare یو Intent بیرته راګرځوي، کارونکی یې مني، او establish بیا هم ناکام کیږي۔ دواړه پایلې معمولا یو شی معنی لري: یو بل اپلیکیشن دمخه د دې کارونکي VPN انٹرفیس لري، او ستاسو protect غوښتنې هغه ساکټونه نښه کوي چې ستاسو تونل یې نشي کارولی۔ لاندې ازموینې په ترتیب سره ترسره کړئ او په لومړنۍ ناکامه ازموینه ودریږئ، ځکه چې وروستی ګام نشي کولی پخوانی ګام سم کړي۔

د protect د لمس کولو دمخه د VPN ځای وازموئ

Android هر کارونکي ته په دقیق ډول یو فعال VPN انٹرفیس ورکوي۔ دا د پلیټفارم قاعده ده، نه هغه اجازه چې ستاسو اپلیکیشن یې غوښتنه کولی شي، نو دوه کلاینټونه چې دواړه غواړي تونل وي نشي کولی یوځای وي۔

د بل اپلیکیشن لپاره ټاکل شوی همېشه فعال VPN ترټولو سخت حالت دی، ځکه چې سیسټم هغه اپلیکیشن تړلی ساتي او د لاس اخیستلو څخه انکار کوي۔ د ټرافیک فلټر لکه AdGuard، کارپوریټ کلاینټ یا د مصرف کونکي VPN کولی شي ځای ونیسي، پداسې حال کې چې کارونکی هیر کړی چې دا نصب دی۔ له کارونکي وغواړئ چې تنظیمات پرانیزي او د VPN لاندې لیست شوې ننوتنه ولولي؛ هلته نوم هغه مالک دی چې تاسو ورسره سیالي کوئ۔ تر هغه چې هغه ننوتنه نه وي جلا شوې یا همېشه فعال تنظیم نه وي پاک شوی، ستاسو VpnService نشي کولی انٹرفیس شي۔

ګام 1: ولولئ چې prepare څه بیرته راګرځوي

VpnService.prepare یوې پوښتنې ته ځواب ورکوي: آیا دا اپلیکیشن کولی شي VPN شي؟ دا null بیرته راګرځوي کله چې رضایت دمخه وي، او Intent کله چې کارونکی باید لا یې تصویب کړي، کوم چې تاسو باید د startActivityForResult سره پیل کړئ۔ د null بیرته راګرځیدل د دوام اجازه وګڼئ، نه د دې ثبوت چې establish به بریالی شي۔

Intent intent = VpnService.prepare(context);
if (intent != null) {
    startActivityForResult(intent, REQUEST_VPN);
}

که د Intent لاره بیرته راشي او کارونکی انکار کړی وي، prepare به په بل هڅه کې بیا Intent بیرته راوګرځوي۔ د لوپ په ځای د پایلې کوډ ولیکئ، ځکه چې رد شوی رضایت د کارونکي پریکړه ده، نه لنډ مهاله تېروتنه۔

ګام 2: تایید کړئ چې انٹرفیس ستاسو اپلیکیشن دی

د establish وروسته ترلاسه شوی ParcelFileDescriptor ستاسو د مالکیت ثبوت دی، او د هر ساکټ کار دمخه یې ازموینه ارزښت لري۔ null یا دمخه تړل شوی ډسکریپټر معنی دا ده چې انٹرفیس هیڅکله نه دی جوړ شوی، حتی که هیڅ استثنا نه وي راڅرګنده شوې۔ د builder انٹرفیس نوم د سیسټم هغه نوم سره پرتله کړئ چې د فعال VPN لپاره یې راپور ورکوي، په ازموینه وسیله کې dumpsys کاروئ۔ که دواړه توپیر ولري، هغه تونل چې تاسو جوړ کړی د هغه تونل سره سم نه دی چې ټرافیک وړي۔

adb shell dumpsys connectivity

همدا ناسم والی د تړل شوې آیکون سره د مړ ټرافیک توضیح کوي۔ سیسټم د بل اپلیکیشن تونل ښیي، پداسې حال کې چې ستاسو کوډ د هغه انٹرفیس ډسکریپټر لري چې د هغه مالک نه دی۔

ګام 3: د connect دمخه protect وغواړئ

کله چې انٹرفیس شتون ولري، هغه ساکټونه چې ستاسو اپلیکیشن یې خلاصوي په ډیفالټ ډول تونل ته لارښودل کیږي۔ بهرنی ټرانسپورټ نشي کولی دا قاعده تعقیب کړي، که نه نو کپسول شوی پیکټ به انٹرفیس ته بیرته راشي، له همدې امله VpnService protect یو ساکټ نښه کوي ترڅو VPN ته څنګه ووهي او لاندې شبکه وکاروي۔ غوښتنه boolean بیرته راګرځوي، او د هغې له پامه غورځول هماغه لاره ده چې تاسو یو ساکټ ته رسیږئ چې روغ ښکاري او هیڅ نه وړي۔

protect د connect یا bind دمخه وغواړئ، هیڅکله وروسته نه۔ ساتنه باید د ساکټ د تړلو یا وتلو دمخه په خپل ځای وي، ځکه چې تړل شوی ساکټ خپله لاره دمخه ټاکلې ده او وروستی protect هغه په باوري ډول نه خوځوي۔ که protect false بیرته راګرځوي، ودریږئ او مالکیت بیا وازموئ: دا هغه وخت ناکام کیږي چې انٹرفیس ستاسو اپلیکیشن نه وي، کوم چې هماغه حالت دی چې بل VPN پریږدي۔ د false بیرته راګرځیدل د ګام 1 ته د بیرته تګ نښه ده، نه د هماغه ساکټ بیا هڅه کول۔

DatagramSocket socket = new DatagramSocket();
if (!vpnService.protect(socket)) {
    return;
}
socket.connect(serverAddress, serverPort);

ګام 4: کله چې ساکټ ستونزمن وي پروسه وتړئ

ځینې ټرانسپورټونه یو ساکټ نه دي: یوه کتابخانه ممکن څو خلاص کړي، یا تاسو غواړئ چې په مرستندویه پروسه کې هر اړیکه ورته وتل وکاروي۔ ConnectivityManager.bindProcessToNetwork پروسه ټاکل شوې شبکې سره تړي، او زوړ setProcessDefaultNetwork هم همدا کار کاوه، مخکې لدې چې زوړ وبلل شي۔ لاندې اړیکه د NET_CAPABILITY_NOT_VPN سره وغواړئ ترڅو تړل ستاسو د تونل لاندې شبکه وټاکي، نه پخپله تونل۔

NetworkRequest request = new NetworkRequest.Builder()
    .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
    .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
    .build();

د پروسې تړل دویم VPN نه دی۔ دا د هغې پروسې لپاره وتل ټاکي، کوم چې ستاسو ټرانسپورټ لپاره ګټور او د دوو تونلونو په یوځای چلولو کې بې ګټې دی۔

د کوډ لاره نه، د کارونکي وسیله سمه کړئ

هیڅ API نشته چې دوه اپلیکیشنونو ته د VPN ځای شریکولو اجازه ورکړي، نو سمون د وسیلې حالت ته اړه لري۔ کارونکي ته دوه روښانه لارې وړاندې کړئ: د بل اپلیکیشن اړیکه پرې کړئ یا همېشه فعال یې پاک کړئ ترڅو ستاسو prepare لاس واخلي، یا د هغه اپلیکیشن د هر اپلیکیشن تنظیمات پرانیزئ او خپل اپلیکیشن د هغه له تونل څخه وباسئ۔ ایستل د نورو هر څه لپاره فلټر روان ساتي او ستاسو اپلیکیشن ته اجازه ورکوي چې عادي اړیکه وکاروي، کوم چې ډیری وخت هغه پایله ده چې کارونکی یې واقعیا غواړي۔

دواړه لارې په خپل ملاتړ اسنادو کې ولیکئ، ځکه چې کارونکي په ندرت سره پوهیږي چې کوم اپلیکیشن د VPN مالک دی۔ له هغوی وغواړئ چې د تنظیماتو څخه د فعال VPN نوم او ستاسو د لاګ څخه د prepare، establish او protect پایلې واستوي، او په یوه دقیقه کې ووایاست چې کوم ګام ناکام شو۔ بیا د ریښتیني ټرافیک سره تایید کړئ: د نوم پلټنه، TCP اړیکه او د تونل له لارې یوه غوښتنه، نه یوازې تړل شوې آیکون۔ سم ډسکریپټر او شنه اشاره ډیر څه مالکیت ثابتوي، هیڅکله نه دا چې ټرانسپورټ د لارښودنې له قواعدو ژوندی پاتې شو۔

که څلور واړه ازموینې تیرې شوې او ټرافیک بیا هم مړ کیږي، مالکیت نور ستاسو ستونزه نه ده۔ لارښودنې او سرور ته د رسیدو خواته لاړ شئ، او هغه credentials له هغې وسیلې څخه وازموئ چې د VPN اپلیکیشن نصب نه وي۔

اړوندې مقالې