Android VpnService: TUN irakurketa blokeatuak ENOBUFS idazketa-erroreen aurka
Inoiz itzultzen ez den irakurketa batek eta ENOBUFS-ekin huts egiten duen idazketa batek aurkako arrazoiak dituzte. Neurtu iragarritako leihoa eta paketearen luzera konponbidea aukeratzeko.
Sintoma bi agertzen dira VpnService begizta berean eta gauza berari egotzi ohi zaizkio: inoiz itzultzen ez den irakurgailu bat eta ENOBUFS-ekin huts egiten duen idazketa bat. Ez dira errore bakar baten aldaerak. Blokeatutako irakurketa bat peer-arekin fluxu-kontrolari buruzko desadostasuna da; huts egindako idazketa bat interfazeak onartuko ez duen pakete bat da. Arazo bakartzat hartzen badituzu, inoiz parte hartu ez duten bufferrak doitzeko egun bat emango duzu. Beheko banaketa da begiztaren zein erdi instrumentatu erabakitzeko nire modua.
Begizta bat, hutsegite-puntu independente bi
Zure zerbitzuak TUN fitxategi-deskriptoretik IP pakete bat irakurtzen du, aztertu eta erantzun bat idazten du deskriptore berera. Bide horretan apurtzen den guztia bi deialdi horietako batean agertzen da, eta horregatik biak tunela apurtuta dagoela jakinarazten dira. Deialdiek kontratu desberdinak dituzte. Irakurketak kernelak pakete bat eman diezazun itxaroten du, eta idazketak kernelari uka dezakeen pakete bat ematen dio.
Irakurketak pentsatzeko erdi erraza dira. Ezer itzultzen ez duen irakurketa bat edo inoiz iristen ez den trafikoaren zain dago edo peer-ak bidaltzeari utzi diolako dago zain.
Blokeatutako irakurketa fluxu-kontrolari buruzko desadostasuna da
TUN gailu bat irakurtzeak pakete bat erabilgarri egon arte blokeatzen du. Dissinatutako portaera da, eta horregatik read barruan aparkatutako hari bat normala dirudi esteka inaktiboan. Zintzilikaldi bihurtzen da zure TCP pila aplikazio lokaletik datuak onartzen jarraitzen duenean baina ez duenean inoiz leiho nahikorik iragartzen urruneko peer-ak gehiago bidal dezan. Peer-ak iragarri zenuen leihoa betetzen du, ACK baten eta leiho-eguneratze baten zain egoten da, eta gelditu egiten da. Orduan zure irakurgailuak ez du ezer itzultzeko, eta aplikazioak irekita eta isilik dagoen konexio bat ikusten du.
Arrazoi ohikoenak iragarritako leihoa jarraitu gabe socketean idazten duen pila bat eta bere buffera hustu ondoren leiho-eguneratze bat bidaltzea ahazten duen beste bat dira. Kanpotik berdinak dirudite: byteak ateratzen dira, ezer ez da itzultzen, ez da errorerik sortzen. Irakurgailuaren haria parsiketan, DNS ebazpenean edo disko I/Oan blokeatzeak sintoma forma bera sortzen du lotu gabeko arrazoi batengatik, beraz egiaztatu haria benetan read barruan dagoela fluxu-kontrola erruduntzat jo aurretik.
Egiaztatu peer-aren bidalketa ilara eta azken aldiz ikusi zuen leihoa. Peer-ak datuak eusten baditu zure leihoa zero delako, konponbidea zure ACK bidean dago, ez TUN irakurketan.
ENOBUFS tamainaren arazoa da, ez buffer falta
TUN interfaze batean ENOBUFS itzultzen duen idazketa batek paketearen luzera ukatzen du normalean. Interfazeak MTU bat du, handiagoa den pakete bat ezin da ilaran jarri, eta pakete bera berriro saiatzeak modu berean huts egiten du beti. Determinismo hori da arrastoa. Benetako buffer falta presioa jaistean argitzen da, tamaina-ukatzeak ez du axola zenbat itxaroten duzun.
TCP-k horretarako mekanismo bat du, eta jendeak saltatzen duen urratsa da: MSS clamp-a. Erabiltzaile-espazioan segmentuak sintetizatzen dituzunean karga erabilgarriaren tamaina aukeratzen duzu, eta tokiko interfazearen MTU-tik tunelaren MTU-ren ordez aukeratzeak tunelak eraman ezin dituen segmentuak igortzen ditu. Murriztu bien arteko txikienarekin. Clamp-ak TCP baino ez du estaltzen, beraz tamaina handiegiko UDP datagrama zure kodeak zatikatu edo baztertu behar du.
Erregistratu idazten duzun pakete bakoitzaren luzera arazketa egiten duzun bitartean. Huts egiten duen luzera da erantzuna, eta ez da aldatuko saiakera artean.
Kasuak bereizten dituzten hiru neurketa
Ez duzu araztaile bat behar hutsegite bietarako. Hiru behaketa nahikoa dira atal egokira bideratzeko, eta berreraikitzeak baino denbora gutxiago hartzen dute.
| 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 |
Hirugarren errenkadak bat egiten badu, begizta bera ondo dago eta arazoa tunelak ikusi ezin duen tokian dago: zure VPN trafikoa tunelera itzultzen duen babesgabea den garraio-socket bat, eta hori normalean arrakastatsua den eta gero ezer ematen ez duen konexio gisa agertzen da.
Konpondu bi bideek mendeko duten instalazioa
Sintoma batek ere ez du merezi aztarnarik interfazea behar bezala eraiki arte. Garrantzitsuak diren builder deialdiak helbidea, bidea, MTU-a eta baimena dira, ordena horretan:
Builder()
.addAddress(10.8.0.2, 32)
.addRoute(0.0.0.0, 0)
.setMtu(1400)
.establish()Ezarri MTU-a tunelaren benetako baliora, adibideak erabili zuen balioan utzi beharrean. Geroago idazten duzun guztia zenbaki horrek mugatzen du, eta ezartzen duzun MTU-aren eta murrizten duzun MSS-aren arteko desadostasuna da konponketa baten ondoren idazketa-hutsegitea berriro sartzeko modurik ohikoena. Ondoren babestu VPN zerbitzarirako trafikoa daraman socketa. protect gabe, pakete horiek zure tunelera bideratzen dira berriro eta konexioa ez da inoiz osatzen, blokeatutako irakurketa dirudi baina bideratze-begizta bat da.
Baimena ezin da saihestu. prepare null itzuli gabe hasitako zerbitzu batek ez du interfazerik lortzen, eta establish null itzultzen du jaurti beharrean, beraz egiaztatu deskriptorea begizta hasi aurretik. VpnService erreferentzia da builder kontratua berresteko lekua, adibide bat kopiatu beharrean.
Egiaztatu norabide bat aldi berean
Bidali UDP oihartzun bat tunelaren bidez eta begiratu paketeen luzerei TCP ukitu aurretik. Gero ireki handshake bat eta berretsi segmentuak kalkulatu duzun MSS-aren azpitik geratzen direla. Zenbatu paketeak, ez konexioak, geldialdia kontagailuan hutsune gisa ager dadin socket zintzilikatu gisa beharrean. Idazketa multzo baten ondoren irakurketak gelditzen badira, leihoa da susmagarria; idazketak berehala huts egiten badute, luzera da.
Gero berrabiarazi gailua eta errepikatu behin, lehenengo sare-aldaketara arte bakarrik funtzionatzen duen VpnService bat bideratze-arazoa delako, ez fluxu-kontrolarena.