Kaks teed võivad panna IP-liidese Androidi rakenduse ette ja mõlemad lõpevad sama tüüpi failideskriptoril, mille omanikud on väga erinevad. Üks kulgeb läbi VpnService'i ja selle builderi, teine läbi root-shelli ja /dev/net/tun. Iga lugemine sellel deskriptoril on väljuv pakett ja iga kirjutamine on sisenev. Teid eristab see, kelle käes on poliitika, mis elab üle OS-i uuenduse ja kui palju marsruutimistabelit tohid puutuda.

Vali platvormi tee, kui just ei oska nimetada konkreetset asja, millest see keeldub. See keeldumine on tavaliselt TAP, püüdmine väljaspool sinu enda rakenduste komplekti või marsruudireegel, mida raamistik kunagi ei paljasta.

Platvormi teel deklareerid kavatsust, mitte käske. Annad vähemalt ühe aadressi, soovitud marsruudid, DNS-serverid ja valikulise rakenduste loendi, seejärel teostab Androidi süsteemiteenus privilegeeritud seadistuse oma identiteedi all. Sa ei saa liidese nime kunagi ette teada ega väljasta kunagi ioctl-i, mis selle loob, ja see ongi mõte.

Kaks viisi IP-liidese saamiseks

Root-tee on vanem retsept. Avad /dev/net/tun, kutsud TUNSETIFF koos IFF_TUN-iga, tõstad liidese üles käsuga ip link ning lisad aadressid ja marsruudid käsitsi. Iga samm on sinu teha, ka need, mille raamistik oleks vaikselt ära teinud. Üks puuduv marsruut annab kasutajale sama raporti nagu surnud server.

Silumine erineb sama palju kui seadistamine. Root-teel kas liides on olemas või tagastas sinu ioctl vea, mida saad otse lugeda. Platvormi teel on liides olemas alles pärast seda, kui establish() õnnestub, seega saabub tõrge erandina või null-deskriptorina, mitte seadmesõlmena, milles saaks tuhnida.

Mida establish() tegelikult tagastab

Builder.establish()-il on kolm tulemust ja need nõuavad kolme erinevat vastust. Deskriptor tähendab, et liides on seadistatud ja sinu kasutada, null tähendab, et taotlus ei läinud läbi, ja visatud erand tähendab, et süsteemiteenus lükkas selle tagasi. nulli ja õnnestumise üheks booleaniks kokku surumine on kõige levinum viis, kuidas rakendus teatab töötavast tunnelist, mis ei kanna kunagi paketti. Builderi viide märgib aadressinõude ära ja seda tasub lugeda enne, kui serverit süüdistad.

Suunad määrab deskriptor, mitte sinu protokoll. Lugemised annavad sulle väljuvad paketid, mis on juba VPN-i jaoks valitud, ja kirjutamised süstivad sissetulevad paketid tagasi liidesesse. Sinu enda transport krüpteerib, autendib ja raamib need paketid, sest platvorm peatub paketi piiril.

Binder on üks hüpe, JNI on teine telg

Builderi taotlus läheb süsteemi sisse läbi Binderi ja kuskil sellest allpool kutsub platvorm välja natiivkoodi, et seadet seadistada. Need on kaks erinevat mehhanismi, mis on ühe kutse sisse virnastatud. Binder on protsessidevaheline side sinu rakenduse ja süsteemiteenuse vahel, JNI aga Java-st natiivkoodi viiv sild protsessi sees. Android 9 AOSP-puu lugemine teeb virna sõnasõnaliseks ja tasub meeles pidada, et sisemised klassinimed ja failiteed liiguvad väljaannete vahel.

See, mis ei liigu, on leping, millele võid tugineda: builder, selle tagastatav deskriptor ja selle ümber olev teenuse elutsükkel. Ükski rakendus ei tohiks kutsuda sisemist teenusetehingut ega luua seadmesõlme uuesti, et liidest saada. Kui sinu kood sõltub AOSP-i klassinimest, läheb see katki väljaandel, mida sa ei testinud.

TUN kannab IP-d, TAP kannab Etherneti

TUN on IP-liides. TAP on Etherneti liides ja see erinevus otsustab, kas sildamine on üldse võimalik. TUN-seadmel pole MAC-aadressi ega edastatavat Etherneti päist, seega ei saa TUN-klient liituda kihi 2 sillaga, ükskõik kuidas marsruudid on kirjutatud.

VpnService annab sulle IP-variandi, mida rakenduse tasandi VPN vajab ja mida see suudab toetada ilma toore Etherneti virnata. Kui sinu disain nõuab sildamist, ei vii platvormi tee sind sinna ja root-tee ainult siis, kui kernel ja seadme õigused teevad koostööd.

Kus root-tee veel võidab

Kolm tööd suruvad inimesi platvormi teelt eemale. Kihi 2 sildamine vajab TAP-i. Teiste rakenduste liikluse püüdmine väljaspool sinu VPN-i ulatust vajab nähtavust, mida raamistik ei anna. Poliitikapõhine marsruutimine, mida builder kunagi ei paljasta, näiteks eraldi tabel ühe sihtkoha jaoks, vajab reegleid, mille paigaldad ise.

Kulud tulevad hiljem: avatud bootloader või rootitud kujutis, SELinuxi poliitika, mis sinu all liigub, ja seade, mis lakkab pärast OTA-d õigesti käituma. Rootitud retsepti ei saa ka tavalise rakenduste levitamise kaudu välja anda, seega enamik meeskondi hoiab seda sisemise diagnostikateena, mitte tootena.

Valik nende vahel

Alusta liidesest, mida vajad, mitte koodist, mis sul on. Kui vastus on rakendusepiirangutega marsruutidega TUN-seade, on platvormi tee lühem ja elab uuendused üle. Kui vastus hõlmab Etherneti kaadreid, teiste rakenduste püüdmist või marsruudireegleid, mille builder tagasi lükkab, oled root-territooriumil ja peaksid sellele operatiivkuluna eelarvet tegema.

Kontroll, mis lahendab enamiku vaidlusi: ehita esmalt platvormi tee, kirjuta establish() tulemus eraldi üles kaugsessiooni olekust ja kinnita üks pakett kummaski suunas. Alles siis otsusta, kas puuduv võimekus õigustab toetatud teelt lahkumist.

Seotud artiklid