Vaša aplikácia hlási odpojené, panel ponuky hlási pripojené a prevádzka zjavne tečie. Ten rozdiel nie je pretekárska podmienka, ktorú opravíte opakovaním: aplikácia a tunel sú samostatné procesy a objekt, ktorý váš kód číta, je uložený pohľad na konfiguráciu, ktorú spravuje systém. Personal VPN rozhranie od Apple je riadiace API, nie dátová cesta, a väčšina jeho podivného správania vyplýva z tohto jediného faktu. Tu je, čo sa pri každom volaní skutočne deje.

Objekt správcu je uložený pohľad, nie tunel

NETunnelProviderManager sa plní z úložiska predvolieb, ktoré vlastní systém, takže jeho vlastnosti nič neznamenajú, kým sa loadFromPreferences nedokončí. Ak prečítate connection.status skôr, dostanete predvolenú hodnotu, a preto prvé obnovenie stavu po reštarte hlási odpojené, kým tunel beží. Najprv načítajte a potom čítajte stav aj konfiguráciu protokolu z toho istého obslužného programu dokončenia. Neskoršie zmeny sledujte cez NEVPNStatusDidChange namiesto dotazovania a všimnite si, že oznámenie prichádza aj pre spojenia spustené cez On Demand, kde neexistuje žiadne volanie aplikácie, ktoré by niečo vrátilo. To isté platí pre nastavenia protokolu: čítajú sa z načítanej konfigurácie, nie z toho, čo aplikácia odovzdala.

Tunel sám žije v procese poskytovateľa Network Extension, takže aplikácia môže stratiť vlastný stav bez straty spojenia. Všetko, čo rozhranie zobrazuje, sa musí znova zostaviť zo správcu, nie pamätať z poslednej relácie.

Poradie spustenia: uložiť, načítať, potom spustiť

Spojenie založené na poskytovateľovi vyžaduje tri kroky v poradí. Zapíšte konfiguráciu poskytovateľa a zavolajte saveToPreferences, načítajte správcu, aby uložená konfigurácia bola tá, ktorú držíte, a potom spustite cez NETunnelProviderSession.startVPNTunnel(). Ak uloženie preskočíte, spustenie nemá čo spustiť; ak načítate pred uložením, správca stále odráža starú konfiguráciu.

Logická hodnota vrátená z startVPNTunnel hovorí len to, že požiadavka bola prijatá. Zlyhania na úrovni poskytovateľa prichádzajú neskôr ako zmena stavu na odpojené, ktorú pozorujete cez oznámenie NEVPNStatusDidChange, a obsluha oznámenia musí znova prečítať connection.status po loadFromPreferences, pretože uložená hodnota môže byť stále stará. Zlyhania na úrovni požiadavky sa vracajú okamžite z podoby volania, ktorá vyhadzuje výnimky, alebo cez výstupný parameter chyby startVPNTunnelAndReturnError:. Kód, ktorý vrátenú hodnotu považuje za výsledok, hlási spojenie, ktoré sa nikdy nenadviazalo. Ďalšia tichá porucha je identifikátor balíka poskytovateľa, ktorý nezodpovedá nainštalovanému rozšíreniu: požiadavka je odmietnutá a nič v správe na identifikátor neukazuje. Ak je identifikátor nesprávny, požiadavka zvyčajne zlyhá hneď, skôr než sa objaví čo i len jeden riadok logu poskytovateľa.

Opätovné načítanie predvolieb po spustení je to, čo robí obrazovky stavu správnymi. Správca vám neposiela novú konfiguráciu, keď ju systém zmení.

Materiál dôvery prichádza profilom, nikdy z kódu aplikácie

Aplikácia nemá podporovaný spôsob, ako pridať koreňový certifikát do úložiska dôvery iOS, takže konfigurácia Personal VPN môže odkazovať len na materiál, ktorému zariadenie už dôveruje: reťazec vytvorený nainštalovaným profilom, správou zariadenia alebo CA, ktorej systém dôveruje z iných dôvodov. Aplikácia, ktorá pri prvom spustení vytvorí vlastnú CA a očakáva, že ju systém uzná, zlyhá pri validácii vnútri poskytovateľa, kde rozhranie aplikácie dôvod nevidí.

Berte túto hranicu ako návrhové obmedzenie, ktorým je, a doručujte kotvu dôvery spolu s profilom na zápis. Držte VPN autentifikáciu oddelene od rozhodnutia o dôvere, pretože zlyhávajú na rôznych miestach a ladia ich rôzni ľudia.

Počítadlá prichádzajú z rozhrania, nie z VPN API

Správca vystavuje stav a konfiguráciu a nič, čo by počítalo bajty na tunel. Ak potrebujete čísla o využití, zavolajte getifaddrs() a prečítajte if_data príslušného rozhrania: en0 pre Wi-Fi, rozhrania pdp_ip pre mobilnú sieť a zariadenie utun pre samotný tunel. Počítadlá utun opisujú vnútornú prevádzku a zahŕňajú réžiu protokolu.

Tieto čísla sú odhady, nie účtovanie po aplikáciách, a resetujú sa, keď sa rozhranie znova vytvorí. Označte ich tak v rozhraní, inak ich niekto použije na fakturáciu zákazníka. Ak potrebujete čísla po aplikáciách, potrebujete úplne iný mechanizmus, nie lepšie čítanie týchto polí.

Čistenie patrí do stopVPNTunnel, nie do ukončenia

applicationWillTerminate vám dá niekoľko sekúnd, kým systém môže proces zabiť, čo nie je spoľahlivé miesto na rozpojenie spojenia. Pošlite zastavenie na stopVPNTunnel() alebo ho obslúžte v spätnom volaní zastavenia poskytovateľa, a ponechajte si identifikátor správcu alebo konfigurácie, s ktorým ste začali, aby zastavenie mierilo na toto spojenie a nie na každú konfiguráciu v zariadení.

Uložte tento identifikátor vedľa profilu, ku ktorému patrí, pretože objekt správcu nezaznamenáva, ktorú konfiguráciu používateľ vybral. A pamätajte, že spojenie vyvolané On Demand nemá za sebou žiadne volanie aplikácie, takže obrazovka stavu aj tak musí načítať predvoľby, kým čokoľvek vykreslí.

Súvisiace články