Kodėl jūsų iOS VPN programa rodo atsijungus, nors tunelis veikia
Jūsų iOS programa valdo tunelį, bet jo neturi, o valdytojo būsena saugoma podėlyje. Pirmiausia įkelkite nuostatas, tada skaitykite būseną ir sąsajos skaitiklius.
Jūsų programa sako atsijungus, meniu juosta sako prisijungus, o srautas akivaizdžiai teka. Šis skirtumas nėra lenktynių sąlyga, kurią ištaisysite bandydami dar kartą: programa ir tunelis yra atskiri procesai, o objektas, kurį skaito jūsų kodas, yra podėlyje saugoma sistemos laikomos konfigūracijos kopija. „Apple“ Personal VPN paviršius yra valdymo API, o ne duomenų kelias, ir didžioji dalis jo keisto elgesio kyla iš šio vieno fakto. Štai kas iš tikrųjų vyksta kiekvieno kvietimo metu.
Valdytojo objektas yra podėlyje saugoma kopija, o ne tunelis
NETunnelProviderManager užpildomas iš sistemos valdomos nuostatų saugyklos, todėl jo savybės nieko nereiškia, kol nebaigiamas loadFromPreferences. Jei prieš tai perskaitysite connection.status, gausite numatytąją reikšmę, ir būtent todėl pirmasis būsenos atnaujinimas po paleidimo iš naujo praneša apie atsijungimą, nors tunelis veikia. Pirmiausia įkelkite, tada skaitykite būseną ir protokolo konfigūraciją iš to paties užbaigimo apdorojimo. Vėlesnius pokyčius stebėkite per NEVPNStatusDidChange, o ne apklausinėdami, ir atkreipkite dėmesį, kad pranešimas suveikia ir jungtims, kurias paleido On Demand, kur apskritai nėra programos kvietimo, galinčio ką nors grąžinti. Tas pats galioja protokolo nustatymams: jie skaitomi iš įkeltos konfigūracijos, o ne iš to, ką programa perdavė.
Pats tunelis gyvena Network Extension tiekėjo procese, todėl programa gali prarasti savo būseną neprarasdama ryšio. Viskas, ką rodo sąsaja, turi būti atkurta iš valdytojo, o ne prisiminta iš praėjusios sesijos.
Paleidimo tvarka: išsaugoti, įkelti, tada paleisti
Tiekėju pagrįstam ryšiui reikia trijų žingsnių iš eilės. Įrašykite tiekėjo konfigūraciją ir iškvieskite saveToPreferences, įkelkite valdytoją, kad išsaugota konfigūracija būtų ta, kurią laikote, tada paleiskite per NETunnelProviderSession.startVPNTunnel(). Jei praleisite išsaugojimą, paleidimas neturės ko paleisti; jei įkelsite prieš išsaugojimą, valdytojas vis dar atspindi seną konfigūraciją.
startVPNTunnel grąžinama loginė reikšmė tik pasako, kad užklausa priimta. Tiekėjo lygio gedimai ateina vėliau kaip būsenos pasikeitimas į atsijungusią, kurį stebite per NEVPNStatusDidChange pranešimą, o pranešimo apdorojimas turi iš naujo perskaityti connection.status po loadFromPreferences, nes podėlyje saugoma reikšmė gali vis dar būti sena. Užklausos lygio gedimai grįžta iš karto iš kvietimo formos, kuri meta išimtį, arba per startVPNTunnelAndReturnError: klaidos išvesties parametrą. Kodas, kuris grąžinamą reikšmę laiko rezultatu, praneša apie ryšį, kuris niekada nebuvo užmegztas. Kitas tylus gedimas yra tiekėjo paketo identifikatorius, kuris neatitinka įdiegto plėtinio: užklausa atmetama, ir niekas pranešime nenurodo identifikatoriaus. Jei identifikatorius neteisingas, užklausa paprastai nepavyksta iš karto, prieš pasirodant bet kuriai tiekėjo žurnalo eilutei.
Nuostatų įkėlimas iš naujo po paleidimo yra tai, kas padaro būsenos ekranus teisingus. Valdytojas nestumia jums naujos konfigūracijos, kai sistema ją pakeičia.
Pasitikėjimo medžiaga ateina per profilį, niekada iš programos kodo
Programa neturi palaikomo būdo pridėti šakninį sertifikatą į iOS pasitikėjimo saugyklą, todėl Personal VPN konfigūracija gali nurodyti tik medžiagą, kuria įrenginys jau pasitiki: grandinę, kurią sukūrė įdiegtas profilis, įrenginio valdymas arba CA, kuria sistema pasitiki dėl kitų priežasčių. Programa, kuri pirmą kartą paleidus sukuria savo CA ir tikisi, kad sistema ją pripažins, žlugs validuojant tiekėjo viduje, kur programos sąsaja negali matyti priežasties.
Traktuokite šią ribą kaip dizaino apribojimą, koks ji yra, ir pateikite pasitikėjimo inkarą kartu su registracijos profiliu. Laikykite VPN autentifikavimą atskirai nuo pasitikėjimo sprendimo, nes jie žlunga skirtingose vietose ir juos derina skirtingi žmonės.
Skaitikliai ateina iš sąsajos, o ne iš VPN API
Valdytojas atskleidžia būseną ir konfigūraciją, ir nieko, kas skaičiuotų baitus vienam tuneliui. Jei reikia naudojimo skaičių, iškvieskite getifaddrs() ir perskaitykite if_data atitinkamai sąsajai: en0 Wi-Fi, pdp_ip sąsajos mobiliojo ryšio tinklui ir utun įrenginys pačiam tuneliui. utun skaitikliai apibūdina vidinį srautą ir apima protokolo pridėtines išlaidas.
Šie skaičiai yra įverčiai, o ne apskaita pagal programas, ir jie nustatomi iš naujo, kai sąsaja sukuriama iš naujo. Pažymėkite juos taip sąsajoje, kitaip kas nors jais naudosis klientui išrašydamas sąskaitą. Jei reikia skaičių pagal programas, reikia visiškai kito mechanizmo, o ne geresnio šių laukų skaitymo.
Valymas priklauso stopVPNTunnel, o ne užbaigimui
applicationWillTerminate duoda jums kelias sekundes, kol sistema gali nužudyti procesą, ir tai nėra patikima vieta ryšiui išardyti. Siųskite sustabdymą stopVPNTunnel() arba apdorokite jį tiekėjo sustabdymo atgaliniame kviete, ir išsaugokite valdytojo ar konfigūracijos identifikatorių, su kuriuo pradėjote, kad sustabdymas būtų nukreiptas į tą ryšį, o ne į kiekvieną įrenginio konfigūraciją.
Saugokite šį identifikatorių šalia profilio, kuriam jis priklauso, nes valdytojo objektas neįrašo, kurią konfigūraciją pasirinko naudotojas. Ir atminkite, kad On Demand pakeltas ryšys apskritai neturi programos kvietimo už savęs, todėl būsenos ekranas vis tiek turi įkelti nuostatas prieš ką nors piešdamas.