Tunnel tõuseb, võtmeikoon ilmub ja iga brauseripäring aegub endiselt. VpnService'i rakenduses tähendab see kombinatsioon tavaliselt, et lugemistsükkel elab ja väljundpool on katki, mitte et server lükkas käepigistuse tagasi. Android on liidese juba loonud, rakenduse liikluse sinna viinud ja andnud protsessile failideskriptori. Kõik pärast seda deskriptorit on teie kood, ja ühest puuduvast kutsest piisab kogu voolu alla neelamiseks.

Mida süsteem teile annab ja mida mitte

establish() tagastab tun-liidese jaoks ParcelFileDescriptori. Süsteem kirjutab sinna väljuvad IP-paketid ja ootab, et teie protsess loeb need, otsustab, kuhu need lähevad, ja saadab need tavalise soketi kaudu. Selle all pole tuuma edasisaatmist, nii et kui keegi ei loe, visatakse paketid ära ja liidese loendurid ei liigu kunagi.

Alustage lugemise asemel loendamisest. Suurendage loendurit iga õnnestunud lugemise järel ja logige esimeste pakettide sihtkoht ja protokoll. Kui loendur jääb nulli, samal ajal kui liiklus tekib, on viga teie edasisaatmiskoodist ülalpool, mis kitsendab otsingu builderi konfiguratsioonile ja lugemisrežiimile. Kui loendur liigub ja brauser ikka ebaõnnestub, on viga saatmisteel või tagasiteel.

Blokeeriv lugemine otsustab, kas tsükkel liigub

setBlocking(true) viib deskriptori blokeerivasse režiimi ja on olemas alates API 21. Vanematel väljalasetel on lahenduseks väike JNI-abiline, mis kustutab O_NONBLOCK fcntliga töötlemata deskriptoril. Režiim on oluline, sest see otsustab, mida tohib teha lugemine ilma ootava paketita.

Mitteblokeerivas režiimis naaseb see lugemine kohe negatiivse väärtusega ja tsükkel, mis tulemust eirab, keerutab tuuma, liigutamata ühtegi baiti liiklust. Blokeerivas režiimis ootab lugemine, mida edasisaatmisniit tahab, kuid siis ei saa niiti enam katkestada. Deskriptori sulgemine on toetatud viis lugemise ebaõnnestumiseks, et tsükkel saaks väljuda. Protsessi tapmine või niidi katkestamine võib jätta järgmise käivituse deskriptoriga, mis liidesega enam ei klapi.

Lugege üks pakett kutse kohta puhvrisse, mille suurus vastab liidese MTU-le, ja käsitlege nulli või negatiivset tagastust veana, mitte tühja paketina.

protect() enne esimest saatmist, mitte pärast seda

Iga soket, mis kannab kapseldatud paketti, tuleb kõigepealt kaitsta. Kaitsmata soket järgib samu marsruutimisreegleid, mille te just paigaldasite, nii et selle paketid lähevad tagasi tunnelisse ja teie enda lugemistsükkel võtab need uuesti üles. Siis saadab tunnel oma väljundit lõputult edasi ja väljastpoolt näeb see välja nagu ühendus, mis avaneb ega vasta kunagi.

Järjekord on protect, seejärel connect või bind, seejärel send. protecti kutsumine pärast connecti võib jätta varasema marsruudiotsuse paigale, nii et soket kasutab edasi vale teed, kuigi kutse tagastas true. Kontrollige tagastatavat boolean-väärtust ja ebaõnnestuge valjult, kui see on false, selle asemel et astuda saatmisse, mis ei saa toimida.

Õiguste viga sendto-st soketil, mis ei puutunud kunagi protect()i, on selle vea tavaline tunnus.

UDP näidis ei kanna HTTPSi

Edasisaatmise näidis, mida enamik õpetusi kopeerib, käsitleb UDPd ja mitte midagi muud. TCP vajab käepigistust, järjekorranumbreid, kinnitusi ja kordussaadet, ning tsükkel, mis kopeerib kasulikku koormust tun-deskriptori ja soketi vahel, ei paku neist ühtegi. Seetõttu saab UDP DNS-päring läbi, samal ajal kui iga HTTPS-päring takerdub. Kas käivitage TCP-stäkk kasutajaruumis või andke ühendused kohalikule puhverserverile, mis lõpetab TCP seadmes ja saadab voolu edasi.

Testige jaotust enne millegi ümberkirjutamist: saatke üks UDP päring ja avage sama hosti vastu üks TCP ühendus. Kui UDP tee töötab ja TCP tee jääb esimese SYN-i juures rippuma, on probleem edasisaatmiskoodis, mitte serveris. See üks võrdlus säästab palju aega, mis kulub serverilogide lugemisele, milles pole midagi kasulikku.

Marsruudiloend ja rakendusepõhised filtrid piiravad seda, mida näete

addAddress, addRoute ja addDns määravad, mida süsteem tunnelisse saadab. Marsruudiloendist väljaspool olev sihtkoht ei jõua kunagi teie deskriptorini, nii et ükski kogus edasisaatmisloogikat ei paranda seda. Logige builderi kutsed, mida teete, ja võrrelge neid aadressidega, mida rakendus tegelikult saavutada püüab.

Rakendusepõhisel valikul on oma alumine piir: addAllowedApplication ja addDisallowedApplication vajavad API 21 ning vanematel väljalasetel need meetodid lihtsalt puuduvad. Paketi järgi filtreeriv disain ei saa seal üldse töötada.

Taasloomine jätab maha vananenud deskriptorid

establish() uus kutse tagastab uue deskriptori ja sulgeb eelmise liidese. Vana deskriptor on nüüd kehtetu, nii et sellel veel blokeeruv niit saab vea, ja vana tee jaoks loodud soketid võivad vajada asendamist. onRevoke on tagasikutse tunnelile, mille kasutaja või süsteem on ära võtnud. Elutsükli hoidmine ühe omaniku käes, mis peatab lugeja enne taasloomist, hoiab ära enamiku ühendatud-kuid-surnud olekutest.

Lugege iga viga selle sammu järgi, kuhu see kuulub. recvfromi ühenduse lähtestamine tähendab, et kaugots sulgus, samal ajal kui teie kood veel luges. Halva aadressi viga viitab päise parsimisele või nihkeveale, mitte võrgule.

Töö järjekord: blokeeriv režiim sees, üks pakett lugemise kohta, päis parsitud, soket kaitstud, koormus saadetud, puhas sulgemine üleandmisel ja marsruudiloend, mis katab sihtkoha.

Seotud artiklid