Sinu rakendus ütleb lahtiühendatud, menüüriba ütleb ühendatud ja liiklus voolab selgelt. See vahe ei ole võidujooksutingimus, mille saab korduskatsega parandada: rakendus ja tunnel on eraldi protsessid ning objekt, mida sinu kood loeb, on süsteemi hoitava konfiguratsiooni vahemällu salvestatud vaade. Apple’i Personal VPN-i pind on juhtimis-API, mitte andmetee, ja enamik selle kummalisest käitumisest tuleneb sellest ühest faktist. Siin on, mis iga kutse juures tegelikult juhtub.

Halduri objekt on vahemällu salvestatud vaade, mitte tunnel

NETunnelProviderManager täidetakse eelistuste hoidlast, mille omanik on süsteem, seega ei tähenda selle omadused midagi enne, kui loadFromPreferences lõpeb. Kui loed connection.status enne seda, saad vaikeväärtuse, mistõttu teatab esimene olekuvärskendus pärast taaskäivitust lahtiühendatud, kui tunnel töötab. Laadi kõigepealt ja seejärel loe olekut ning protokolli konfiguratsiooni samast lõpetamiskäsitlejast. Jälgi hilisemaid muudatusi NEVPNStatusDidChange kaudu, mitte küsitledes, ja pane tähele, et teade käivitub ka On Demandiga algatatud ühenduste puhul, kus rakenduse kutset, mis midagi tagastaks, polegi olemas. Sama kehtib protokolli seadete kohta: neid loetakse laaditud konfiguratsioonist, mitte sellest, mille rakendus edastas.

Tunnel ise elab Network Extensioni pakkuja protsessis, seega võib rakendus kaotada oma oleku ilma ühendust kaotamata. Kõik, mida liides näitab, tuleb haldurist uuesti üles ehitada, mitte eelmisest seansist mäletada.

Käivitamise järjekord: salvesta, laadi, seejärel käivita

Pakkujapõhine ühendus vajab kolme sammu järjekorras. Kirjuta pakkuja konfiguratsioon ja kutsu saveToPreferences, laadi haldur, et salvestatud konfiguratsioon oleks see, mida hoiad, ja käivita seejärel NETunnelProviderSession.startVPNTunnel() kaudu. Kui jätad salvestamise vahele, pole käivitusel midagi käivitada; kui laadid enne salvestamist, peegeldab haldur endiselt vana konfiguratsiooni.

startVPNTunnel tagastatav tõeväärtus ütleb ainult, et taotlus võeti vastu. Pakkuja tasandi tõrked saabuvad hiljem olekumuutusena lahtiühendatuks, mida jälgid teate NEVPNStatusDidChange kaudu, ja teate käsitleja peab pärast loadFromPreferences uuesti lugema connection.status, sest vahemällu salvestatud väärtus võib olla veel vana. Taotluse tasandi tõrked tulevad kohe tagasi kutse erindit viskavast vormist või startVPNTunnelAndReturnError: vea väljundparameetri kaudu. Kood, mis käsitleb tagastusväärtust tulemusena, teatab ühendusest, mida kunagi ei loodud. Teine vaikne tõrge on pakkuja komplekti identifikaator, mis ei ühti paigaldatud laiendiga: taotlus lükatakse tagasi ja miski sõnumis ei viita identifikaatorile. Kui identifikaator on vale, nurjub taotlus tavaliselt kohe, enne kui ilmub ükski pakkuja logirida.

Eelistuste uuesti laadimine pärast käivitust on see, mis teeb olekuekraanid õigeks. Haldur ei lükka sulle uut konfiguratsiooni, kui süsteem seda muudab.

Usaldusmaterjal saabub profiili kaudu, mitte kunagi rakenduse koodist

Rakendusel pole ühtegi toetatud viisi juurdada juursertifikaat iOS-i usaldushoidlasse, seega saab Personal VPN-i konfiguratsioon viidata ainult materjalile, mida seade juba usaldab: ahel, mille on loonud paigaldatud profiil, seadmehaldus või CA, mida süsteem usaldab muudel põhjustel. Rakendus, mis loob esmasel käivitamisel oma CA ja ootab, et süsteem seda tunnustaks, nurjub valideerimisel pakkuja sees, kus rakenduse liides ei näe põhjust.

Käsitle seda piiri nii, nagu see on – disainipiiranguna – ja tarni usaldusankur koos registreerimisprofiiliga. Hoia VPN-i autentimine usaldusotsusest eraldi, sest need nurjuvad eri kohtades ja neid silub eri inimene.

Loendurid tulevad liidesest, mitte VPN-API-st

Haldur paljastab oleku ja konfiguratsiooni ning mitte midagi, mis loeks baite tunneli kohta. Kui vajad kasutusnumbreid, kutsu getifaddrs() ja loe if_data asjakohase liidese jaoks: en0 Wi-Fi jaoks, pdp_ip liidesed mobiilse jaoks ja utun seade tunneli enda jaoks. utun loendurid kirjeldavad sisemist liiklust ja sisaldavad protokolli üldkulu.

Need arvud on hinnangud, mitte rakendusepõhine arvestus, ja need nullitakse, kui liides uuesti luuakse. Märgista need liideses nii, muidu kasutab keegi neid kliendi arveldamiseks. Kui vajad numbreid rakenduse kaupa, vajad hoopis teistsugust mehhanismi, mitte nende väljade paremat lugemist.

Puhastamine kuulub stopVPNTunnelisse, mitte lõpetamisse

applicationWillTerminate annab sulle paar sekundit enne, kui süsteem võib protsessi tappa, mis ei ole usaldusväärne koht ühenduse lammutamiseks. Saada peatus stopVPNTunnel()-le või käsitle seda pakkuja peatamise tagasikutses, ja hoia alles halduri või konfiguratsiooni identifikaator, millega alustasid, et peatus tabaks just seda ühendust, mitte seadme iga konfiguratsiooni.

Salvesta see identifikaator selle profiili kõrvale, kuhu see kuulub, sest halduri objekt ei registreeri, millise konfiguratsiooni kasutaja valis. Ja pea meeles, et On Demandiga üles tõstetud ühenduse taga pole ühtegi rakenduse kutset, seega olekuekraan peab ikkagi enne millegi joonistamist eelistused laadima.

Seotud artiklid