Az alkalmazásod leválasztva ír, a menüsor csatlakozva, és a forgalom láthatóan folyik. Ez a rés nem versenyhelyzet, amit újrapróbálkozással javítasz: az alkalmazás és az alagút külön folyamatok, és az objektum, amit a kódod olvas, egy gyorsítótárazott nézet a rendszer által tárolt konfigurációról. Az Apple Personal VPN felülete vezérlő API, nem adatút, és furcsa viselkedésének nagy része ebből az egy tényből fakad. Íme, mi történik valójában az egyes hívásoknál.

A kezelőobjektum gyorsítótárazott nézet, nem az alagút

NETunnelProviderManager egy rendszer tulajdonában lévő beállítástárból töltődik fel, így a tulajdonságai semmit sem jelentenek, amíg a loadFromPreferences be nem fejeződik. Ha előbb olvasod a connection.status-t, alapértéket kapsz, és ezért jelent az újraindítás utáni első státuszfrissítés leválasztottat, miközben az alagút él. Először töltsd be, aztán olvasd a státuszt és a protokoll-konfigurációt ugyanabból a befejezéskezelőből. A későbbi változásokat NEVPNStatusDidChange útján figyeld lekérdezgetés helyett, és vedd figyelembe, hogy az értesítés az On Demand által indított kapcsolatoknál is elsül, ahol egyáltalán nincs alkalmazáshívás, ami bármit visszaadhatna. Ugyanez vonatkozik a protokollbeállításokra: a betöltött konfigurációból olvasódnak, nem abból, amit az alkalmazás átadott.

Maga az alagút egy Network Extension-szolgáltató folyamatában él, így az alkalmazás elveszítheti a saját állapotát anélkül, hogy elveszítené a kapcsolatot. Mindent, amit a felület mutat, a kezelőből kell újraépíteni, nem az előző munkamenetből felidézni.

Indítási sorrend: mentés, betöltés, aztán indítás

A szolgáltatóalapú kapcsolat három lépést igényel sorrendben. Írd meg a szolgáltató konfigurációját, és hívd a saveToPreferences-et, töltsd be a kezelőt, hogy a mentett konfiguráció legyen a nálad lévő, majd indíts a NETunnelProviderSession.startVPNTunnel()-ön keresztül. Ha kihagyod a mentést, az indításnak nincs mit elindítania; ha a mentés előtt töltesz be, a kezelő még a régi konfigurációt tükrözi.

A startVPNTunnel által visszaadott logikai érték csak azt mondja meg, hogy a kérés elfogadásra került. A szolgáltatószintű hibák később leválasztott állapotra váltásként érkeznek, amit a NEVPNStatusDidChange értesítésen keresztül figyelsz, és az értesítéskezelőnek a loadFromPreferences után újra kell olvasnia a connection.status-t, mert a gyorsítótárazott érték még a régi lehet. A kérészintű hibák azonnal visszatérnek a hívás kivételt dobó formájából, vagy a startVPNTunnelAndReturnError: hiba-kimeneti paraméterén keresztül. Az a kód, amely a visszatérési értéket eredményként kezeli, olyan kapcsolatot jelent, amely soha nem jött létre. A másik csendes hiba egy szolgáltatói csomagazonosító, amely nem egyezik a telepített kiterjesztéssel: a kérés elutasításra kerül, és semmi sem mutat az azonosítóra az üzenetben. Ha az azonosító rossz, a kérés általában azonnal meghiúsul, mielőtt bármilyen szolgáltatói naplósor megjelenne.

A beállítások újratöltése indítás után az, ami helyessé teszi a státuszképernyőket. A kezelő nem tol új konfigurációt, amikor a rendszer megváltoztatja.

A bizalmi anyag profil útján érkezik, soha nem alkalmazáskódból

Az alkalmazásnak nincs támogatott módja gyökér-tanúsítvány hozzáadására az iOS bizalmi tárolójához, így a Personal VPN konfiguráció csak olyan anyagra hivatkozhat, amelyben az eszköz már bízik: telepített profil, eszközkezelés vagy olyan CA által létrehozott láncra, amelyben a rendszer más okból bízik. Az az alkalmazás, amely első indításkor saját CA-t készít, és elvárja, hogy a rendszer elfogadja, a szolgáltatón belüli érvényesítésnél elbukik, ahol az alkalmazás felülete nem látja az okot.

Tekintsd ezt a határt annak a tervezési kényszernek, ami, és szállítsd a bizalmi horgonyt a regisztrációs profillal együtt. Tartsd a VPN-hitelesítést külön a bizalmi döntéstől, mert más helyen buknak el, és más emberek hibakeresik őket.

A számlálók az interfészből jönnek, nem a VPN API-ból

A kezelő státuszt és konfigurációt tesz elérhetővé, és semmit, ami alagútonként bájtokat számolna. Ha használati számokra van szükséged, hívd a getifaddrs()-et, és olvasd a if_data-t a megfelelő interfészhez: en0 a Wi-Fihez, a pdp_ip interfészek a mobilhálózathoz, és egy utun eszköz magához az alagúthoz. A utun számlálói a belső forgalmat írják le, és tartalmazzák a protokoll többletét.

Ezek a számok becslések, nem alkalmazásonkénti elszámolás, és visszaállnak, amikor az interfész újra létrejön. Címkézd így őket a felületen, különben valaki ügyfél számlázására használja. Ha alkalmazásonkénti számokra van szükséged, teljesen más mechanizmusra van szükséged, nem ezeknek a mezőknek a jobb olvasására.

A tisztítás a stopVPNTunnel-be tartozik, nem a leállításba

applicationWillTerminate néhány másodpercet ad, mielőtt a rendszer megölheti a folyamatot, ami nem megbízható hely a kapcsolat bontására. Küldd a leállítást a stopVPNTunnel()-nek, vagy kezeld a szolgáltató leállítási visszahívásában, és tartsd meg a kezelő vagy konfiguráció azonosítóját, amellyel indítottál, hogy a leállítás azt a kapcsolatot célozza, ne az eszköz minden konfigurációját.

Tárold ezt az azonosítót annak a profilnak a mellé, amelyhez tartozik, mivel a kezelőobjektum nem rögzíti, melyik konfigurációt választotta a felhasználó. És ne feledd, hogy az On Demand által felhozott kapcsolat mögött egyáltalán nincs alkalmazáshívás, így a státuszképernyőnek továbbra is be kell töltenie a beállításokat, mielőtt bármit rajzol.

Kapcsolódó cikkek