Android VpnService: TUN කියවීම අවහිර වීම ENOBUFS ලිවීමේ දෝෂ සමඟ
කිසිදා නොපැමිණෙන කියවීමක් සහ ENOBUFS සමඟ අසාර්ථක වන ලිවීමක් ප්රතිවිරුද්ධ හේතූන් ඇත. නිවැරදි කිරීම තෝරා ගැනීමට ප්රකාශිත කවුළුව සහ පැකට් දිග මනින්න.
එකම VpnService ලූපයේ රෝග ලක්ෂණ දෙකක් දිස්වන අතර දෙකටම එකම දෙයට දොස් නගනු ලැබේ: කිසිදා නොපැමිණෙන කියවන්නෙක්, සහ ENOBUFS සමඟ අසාර්ථක වන ලිවීමක්. මේවා එක් දෝෂයක ප්රභේද නොවේ. අවහිර වූ කියවීමක් යනු සමජාතීය සමඟ ප්රවාහ පාලනය පිළිබඳ එකඟ නොවීමකි; අසාර්ථක ලිවීමක් යනු අතුරුමුහුණත පිළිගන්නා නොවන පැකට්ටුවකි. ඒවා එක් ගැටලුවක් ලෙස සැලකුවහොත්, කිසිදා සම්බන්ධ නොවූ බෆර සකස් කිරීමට දිනක් ගත වේ. පහත බෙදීම යනු ලූපයේ කුමන අර්ධය පළමුව මනින්නේ දැයි මා තීරණය කරන ආකාරයයි.
එක් ලූපයක්, ස්වාධීන අසාර්ථක ලක්ෂ්ය දෙකක්
ඔබේ සේවාව TUN ගොනු විස්තරකාරකයෙන් IP පැකට්ටුවක් කියවා, එය පරීක්ෂා කර, එම විස්තරකාරකයටම පිළිතුරක් ලියයි. එම මාර්ගයේ කැඩෙන සෑම දෙයක්ම එම ඇමතුම් දෙකෙන් එකකදී දිස්වේ, එම නිසා දෙකම කැඩුණු උමගක් ලෙස වාර්තා වේ. ඇමතුම්වලට වෙනස් ගිවිසුම් ඇත. කියවීමක් කර්නලය ඔබට පැකට්ටුවක් දෙන තෙක් රැඳී සිටී, ලිවීමක් කර්නලයට ප්රතික්ෂේප කිරීමට අයිතිය ඇති පැකට්ටුවක් ලබා දෙයි.
කියවීම් සිතීමට පහසු අර්ධයයි. කිසිවක් නොපැමිණෙන කියවීමක් එක්කෝ කිසිදා නොඑන ගමනාගමනය බලා සිටී, එක්කෝ සමජාතීය යැවීම නතර කළ නිසා බලා සිටී.
අවහිර වූ කියවීමක් ප්රවාහ පාලනය පිළිබඳ එකඟ නොවීමකි
TUN උපාංගයක් කියවීම පැකට්ටුවක් ලබා ගත හැකි වන තෙක් අවහිර වේ. එය නිර්මාණය කළ හැසිරීමකි, එම නිසා read තුළ නතර වූ තන්තුවක් නිශ්චල සබැඳියක සාමාන්ය ලෙස පෙනේ. ඔබේම TCP ගොඩගැස්ම දේශීය යෙදුමෙන් දත්ත පිළිගනිමින් සිටියද, දුරස්ථ සමජාතීයට තවත් යැවීමට ප්රමාණවත් කවුළුවක් කිසිදා ප්රකාශ නොකරන විට එය එල්ලීමක් බවට පත් වේ. සමජාතීය ඔබ ප්රකාශ කළ කවුළුව පුරවා, ACK සහ කවුළු යාවත්කාලීනයක් එන තෙක් රැඳී, නතර වේ. එවිට ඔබේ කියවන්නාට ආපසු දීමට කිසිවක් නැත, යෙදුම විවෘත නමුත් නිහඬ සම්බන්ධතාවක් දකී.
සාමාන්ය හේතු වන්නේ ප්රකාශිත කවුළුව නොසොයා සොකට්ටුවට ලියන ගොඩගැස්මක්, සහ තම බෆරය හිස් කළ පසු කවුළු යාවත්කාලීනයක් යැවීමට අමතක වන එකකි. පිටතින් දෙකම එකම ලෙස පෙනේ: බයිට් පිටවේ, කිසිවක් ආපසු නොඑයි, කිසිදු දෝෂයක් ඉස්සරහට නොඑයි. කියවීම් තන්තුව විග්රහ කිරීම, DNS විසඳීම හෝ තැටි I/O මත අවහිර කිරීම සම්බන්ධයක් නැති හේතුවකින් එම හැඩයේ රෝග ලක්ෂණ ඇති කරයි, එම නිසා ප්රවාහ පාලනයට දොස් නැගීමට පෙර තන්තුව සැබවින්ම read තුළ ඇති බව තහවුරු කරන්න.
සමජාතීයගේ යැවීම් පෝලිම සහ එය අවසන් වරට දුටු කවුළුව පරීක්ෂා කරන්න. ඔබේ කවුළුව ශුන්ය නිසා සමජාතීය දත්ත රඳවා ගනී නම්, නිවැරදි කිරීම ඔබේ 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 එකක් ප්රවාහ පාලනයේ නොව, මාර්ගගත කිරීමේ ගැටලුවකි.