Android VpnService tengist en engin pakki nær netinu
Göngin eru uppi og síður mistakast enn: athugaðu lestrarmáta, vernd sokks, TCP-stuðning og leiðalistann áður en þú kennir VPN-þjóninum um.
Göngin koma upp, lyklatáknið birtist og hver beiðni í vafranum rennur enn út á tíma. Í VpnService-forriti þýðir sú samsetning venjulega að lestrarhringurinn lifir og úttakshlutinn er brotinn, ekki að þjónninn hafi hafnað handabandi. Android hefur þegar búið til viðmótið, fært umferð forritsins inn í það og afhent ferlinu þínu skráarlýsingu. Allt eftir þá lýsingu er þinn kóði, og eitt vantað kall nægir til að gleypa alla strauminn.
Hvað kerfið gefur þér og hvað ekki
establish() skilar ParcelFileDescriptor fyrir tun-viðmót. Kerfið skrifar útleiðandi IP-pakka í það og gerir ráð fyrir að ferlið þitt lesi þá, ákveði hvert þeir fara og sendi þá um venjulegan sokk. Undir er engin kjarnaframsending, svo þegar enginn les eru pakkarnir látnir falla og teljarar viðmótsins hreyfast aldrei.
Byrjaðu á að telja í stað þess að giska. Hækkaðu teljara við hverja farsæla lestur og skráðu áfangastað og samskiptareglu fyrstu pakkanna. Ef teljarinn stendur í núlli á meðan umferð er búin til liggur gallinn ofan við framsendingarkóðann þinn, sem þrengir leitina að stillingum builder og lestrarmátanum. Ef teljarinn hreyfist og vafrinn mistekst samt er gallinn í sendingarleiðinni eða á leiðinni til baka.
Blokkkandi lestur ræður því hvort hringurinn hreyfist
setBlocking(true) setur lýsinguna í blokkkandi hátt og hefur verið til síðan API 21. Á eldri útgáfum er lausnin lítill JNI-hjálpari sem hreinsar O_NONBLOCK með fcntl á hráu lýsingunni. Hátturinn skiptir máli því hann ræður því hvað lestur án biðandi pakka má gera.
Í óblokkkandi hátt snýr sá lestur strax til baka með neikvæðu gildi, og hringur sem hunsar niðurstöðuna snýr kjarna án þess að færa nokkra umferð. Í blokkkandi hátt bíður lesturinn, sem framsendingarþráður vill, en þá er ekki lengur hægt að trufla þráðinn. Að loka lýsingunni er studd leið til að láta lesturinn mistakast svo hringurinn geti farið út. Að drepa ferlið eða trufla þráðinn getur hins vegar skilið næstu ræsingu eftir með lýsingu sem passar ekki lengur við viðmótið.
Lestu einn pakka fyrir hvert kall í biðminni sem er að stærð MTU viðmótsins, og meðhöndlaðu núll eða neikvæða niðurstöðu sem villu, ekki tóman pakka.
protect() fyrir fyrstu sendingu, ekki eftir hana
Hver sá sokkur sem ber umbúðapakka verður fyrst að vera varinn. Óvarinn sokkur hlýðir sömu leiðarreglum og þú settir upp, svo pakkarnir hans fara aftur í göngin og lestrarhringurinn þinn tekur þá upp aftur. Þá framsendir göngin eigin úttak endalaust, og að utan lítur það út eins og tenging sem opnast og svarar aldrei.
Röðin er protect, svo connect eða bind, svo send. Kall á protect eftir connect getur látið fyrri leiðarákvörðun standa, svo sokknum heldur að nota rangar slóðir þótt kallið hafi skilað true. Athugaðu booleans-gildið sem það skilar og mistaktu hátt þegar það er false í stað þess að ganga inn í sendingu sem getur ekki virkað.
Heimildarvilla frá sendto á sokk sem hefur aldrei snert protect() er venjulegt einkenni þessarar villu.
UDP-dæmið ber ekki HTTPS
Framsendingardæmið sem flest kennsluefni afrita höndlar UDP og ekkert annað. TCP þarf handaband, raðnúmer, staðfestingar og endursendingu, og hringur sem afritar farm á milli tun-lýsingar og sokk snýr engu af þessu. Þess vegna getur UDP DNS-fyrirspurn farið í gegn á meðan hver HTTPS-beiðni stöðvast. Annaðhvort keyrðu TCP-stakk í notendarými eða fela tengingunum til staðbundins proxy sem lýkur TCP á tækinu og framsendir strauminn.
Prófaðu skiptinguna áður en þú skrifar nokkuð upp á nýtt: sendu eina UDP-fyrirspurn og opnaðu eina TCP-tengingu á sama hýsil. Ef UDP-leiðin virkar og TCP-leiðin stendur á fyrsta SYN er framsendingarkóðinn vandamálið en ekki þjónninn. Þessi eina samanburður sparar mikinn tíma sem fer í að lesa þjónaskrár sem innihalda ekkert gagnlegt.
Leiðalistinn og síur eftir forritum takmarka það sem þú sérð
addAddress, addRoute og addDns skilgreina hvað kerfið sendir í göngin. Áfangastaður utan leiðalistans nær aldrei lýsingunni þinni, svo engin magn af framsendingarlógík bætir það. Skráðu builder-köllin sem þú gerir og berðu þau saman við heimilisföngin sem forritið reynir í raun að ná.
Val eftir forritum hefur eigið gólf: addAllowedApplication og addDisallowedApplication þurfa API 21, og á eldri útgáfum vantar einfaldlega þessar aðferðir. Hönnun sem síar eftir pakka getur alls ekki keyrt þar.
Enduruppsetning skilur eftir úreltar lýsingar
Nýtt kall á establish() skilar nýrri lýsingu og lokar fyrra viðmótinu. Gamla lýsingin er nú ógild, svo þráður sem er enn blokktur á henni fær villu, og sokkarnir sem búnir voru til fyrir gömlu leiðina kunna að þurfa að vera skipt út. onRevoke er bakkallið fyrir göng sem notandinn eða kerfið hefur tekið. Að halda lífsferlinum hjá einum eiganda, sem stöðvar lestrann áður en sett er upp aftur, kemur í veg fyrir flest tengd-en-dauð stöður.
Lestu hverja villu eftir því skrefi sem hún tilheyrir. Endurstilling tengingar frá recvfrom þýðir að fjarlægi endinn lokaði á meðan kóðinn þinn var enn að lesa. Villa um slæmt heimilisfang bendir á hausagreiningu eða offset-villu, ekki á netið.
Röð vinnunnar: blokkkandi háttur á, einn pakki á hverja lestur, haus greindur, sokkur varinn, farmur sendur, hrein lokun við afhendingu og leiðalisti sem nær yfir áfangastaðinn.