Android VpnService: د TUN لوستلو ټکنۍ کېدل د ENOBUFS لیکنې غلطیو په وړاندې
هغه لوستل چې هیڅکله نه راګرځي او هغه لیکنه چې د ENOBUFS سره ناکامه شي مخالف لاملونه لري. د سمون د ټاکلو لپاره اعلان شوې کړکۍ او د بنډل اوږدوالی وټاکئ.
په هماغه VpnService کړۍ کې دوه نښې ښکاري او دواړو ته یو شی تورن کېږي: لوستونکی چې هیڅکله نه راګرځي، او لیکنه چې د ENOBUFS سره ناکامه شي. دا د یوې غلطۍ بېلابېل ډولونه نه دي. ټکنی لوستل د peer سره د بهیر کنټرول په اړه ناندرې ده؛ ناکامه لیکنه هغه بنډل دی چې انټرفېس به یې ومني نه. که دوی د یوې ستونزې په توګه وګورئ، یوه ورځ به د هغو بفرونو په تنظیم کې تېره کړئ چې هېڅکله پکې نه وو. لاندې وېش دا دی چې زه څنګه پرېکړه کوم چې د کړۍ کومه نیمه لومړی اندازه کړم.
یوه کړۍ، دوه خپلواکې د ناکامۍ نقطې
ستاسو خدمت له TUN دوتنې ډیسکریپټر څخه IP بنډل لولي، ګوري یې او بیا هماغه ډیسکریپټر ته ځواب لیکي. هر څه چې په دې لار کې مات شي په هماغو دوو غږونو کې یوه کې ښکاري، له همدې کبله دواړه د مات شوي تونل په توګه راپور شي. غږونو بېل تړونونه لري. لوستل انتظار کوي چې کرنل تاسو ته بنډل درکړي، او لیکنه کرنل ته هغه بنډل ورکوي چې د ردولو حق لري.
لوستل د فکر کولو لپاره اسانه نیمه ده. هغه لوستل چې هیڅ نه راګرځوي یا د هغه ترافیک انتظار کوي چې هیڅکله نه راځي یا انتظار کوي ځکه چې peer لیږل بند کړي.
ټکنی لوستل د بهیر کنټرول ناندرې ده
د TUN وسیلې لوستل تر هغه بند وي چې بنډل شتون ولري. دا ډیزاین شوی چلند دی، او له همدې امله په read کې ولاړ تار په بېکاره لینک کې نورمال ښکاري. دا هغه وخت ځوړندېدل کېږي چې ستاسو خپل TCP سټک له محلي اپ څخه ډاټا منلو ته دوام ورکړي خو د لرې peer لپاره د نورو لیږلو لپاره کافي کړکۍ هیڅکله اعلان نه کړي. Peer ستاسو اعلان شوې کړکۍ ډکوي، د ACK او کړکۍ تازه کولو انتظار کوي، او درېږي. بیا ستاسو لوستونکي د بېرته ورکولو لپاره هیڅ نه لري، او اپ یو پرانیستی خو غلی اړیکه ویني.
عام لاملونه هغه سټک دی چې د اعلان شوې کړکۍ تعقیب پرته ساکټ ته لیکي، او بل چې خپل بفر خالي کولو وروسته د کړکۍ تازه کول لیږل هېروي. له بهر څخه دواړه یو شان ښکاري: بایټونه وځي، هیڅ نه راګرځي، هیڅ تېروتنه نه پورته کېږي. د لوستلو تار په پارس، DNS حل یا ډیسک I/O کې بندول د بېاړیکې لامل له مخې هماغه بڼه نښه جوړوي، نو د بهیر کنټرول تورنولو دمخه ډاډ ترلاسه کړئ چې تار واقعاً په read کې دی.
د peer د لیږلو قطار او هغه کړکۍ چې وروستی ځل یې لیدلې وګورئ. که peer ډاټا ساتي ځکه چې ستاسو کړکۍ صفر ده، سمون ستاسو د ACK په لار کې دی، نه په TUN لوستلو کې.
ENOBUFS د اندازې ستونزه ده، نه د بفر کمښت
په TUN انټرفېس باندې ENOBUFS راګرځونکې لیکنه معمولاً د بنډل اوږدوالی ردوي. انټرفېس MTU لري، تر هغه لوی بنډل په قطار نه شي کېدای، او هماغه بنډل بیا هڅه کول هربار هماغسې ناکامېږي. دا ټاکلتیا نښه ده. ریښتینی د بفر کمښت د فشار په کمېدو سره ورکېږي، خو د اندازې رد تاسو څومره انتظار کوئ پروا نه لري.
TCP د دې لپاره یو میکانیزم لري، او هماغه ګام دی چې خلک یې پرېږدي: MSS کلپ. کله چې تاسو په کاروونکي فضا کې سیګمنټونه جوړوئ، د پیلوډ اندازه تاسو ټاکئ، او له تونل MTU پرته د محلي انټرفېس MTU څخه یې اخیستل هغه سیګمنټونه باسي چې تونل یې نه شي وړلای. له دوو څخه کوچني ته محدود کړئ. کلپ یوازې TCP پوښي، نو ډېر لوی UDP ډاټاګرام باید ستاسو کوډ ټوټې یا پرېږدي.
د نیمګړتیا د لټون پر مهال د هر هغه بنډل اوږدوالی ثبت کړئ چې لیکئ. هغه اوږدوالی چې ناکامېږي هماغه ځواب دی، او د هڅو ترمنځ به نه بدلېږي.
درې اندازې چې قضیې جلا کوي
د دواړو ناکامیو لپاره ستاسو ډیبګر ته اړتیا نشته. درې کتنې د دې لپاره بس دي چې ځان سمې برخې ته ورسوئ، او د بیا جوړولو څخه لږ وخت نیسي.
| What you see | Where to look |
|---|---|
| Reader parked, peer send queue empty, last advertised window zero | Window updates in your ACK path |
| Write fails on one length and succeeds on a smaller one | MSS clamp and tunnel MTU |
| Both directions look fine, app still sees no data | Protected socket and routing loop |
که دریمه کرښه سمه وي، کړۍ پخپله سمه ده او ستونزه هغه ځای دی چې تونل یې نه شي لیدلای: یو نه ساتل شوی انتقالي ساکټ چې ستاسو خپل VPN ترافیک تونل ته بېرته وړي، کوم چې معمولاً د هغې اړیکې په ډول ښکاري چې بریالۍ شي او بیا هیڅ نه رسوي.
هغه نلونه سم کړئ چې دواړه لارې پرې تکیه دي
تر هغه چې انټرفېس سم جوړ شوی نه وي، د هیڅ نښې تعقیب ارزښت نه لري. مهم builder غږونه پته، لار، MTU او رضایت دي، په همدې ترتیب:
Builder()
.addAddress(10.8.0.2, 32)
.addRoute(0.0.0.0, 0)
.setMtu(1400)
.establish()MTU په نمونې کارول شوې ارزښت کې پرېږدئ نه، بلکې د تونل ریښتیني ارزښت ته یې وټاکئ. هغه څه چې وروسته یې لیکئ ټول په دې شمېره محدود دي، او ستاسو د ټاکل شوې MTU او هغه MSS ترمنځ ناسمونې چې محدودوئ ورته، د سمون وروسته د لیکنې ناکامۍ بېرته راوستلو ترټولو عامه لار ده. بیا هغه ساکټ وساتئ چې ترافیک پخپل VPN سرور ته وړي. پرته له protect هغه بنډلونه ستاسو خپل تونل ته بېرته لارښودل کېږي او اړیکه هیڅکله بشپړه نه شي، کوم چې د ټکني لوستلو په څېر ښکاري خو د لارښوونې کړۍ ده.
رضایت نه شي پریښودل کېدای. هغه خدمت چې پرته له دې چې prepare null راوګرځوي پیل شي انټرفېس نه اخلي، او establish د غورځولو پرځای null راګرځوي، نو د کړۍ له پیل دمخه ډیسکریپټر وګورئ. VpnService حواله هغه ځای دی چې د نمونې کاپي کولو پرځای builder تړون تایید کړئ.
په یو وخت کې یوه لوری تایید کړئ
د TCP د لمس دمخه له تونل څخه UDP انګور وليږئ او د بنډلونو اوږدوالی وګورئ. بیا لاس ورکول پرانیزئ او تایید کړئ چې سیګمنټونه ستاسو حساب شوي MSS لاندې پاتې کېږي. اړیکې نه، بنډلونه وشمېرئ، تر څو ټکنۍ کېدل د ځوړند ساکټ پرځای په شمېرونکي کې تشه ښکاره شي. که د لیکنو له یوې څپې وروسته لوستل ودرېږي، کړکۍ شکمنه ده؛ که لیکنې سمدلاسه ناکامه شي، اوږدوالی دی.
بیا وسیله بیا پیل کړئ او یو ځل تکرار کړئ، ځکه هغه VpnService چې یوازې تر لومړني شبکې بدلون پورې کار کوي د بهیر کنټرول نه، د لارښوونې ستونزه ده.