Appen din seier fråkobla, menylinja seier tilkobla, og trafikken flyt tydeleg. Det gapet er ikkje ein race condition du fiksar med eit nytt forsøk: appen og tunnelen er separate prosessar, og objektet koden din les er ei bufra vising av ein konfigurasjon systemet lagrar. Apples Personal VPN-flate er eit kontroll-API, ikkje ei databane, og det meste av den merkelege åtferda følgjer av nettopp det. Her er kva som faktisk skjer ved kvart kall.

Behandlarobjektet er ei bufra vising, ikkje tunnelen

NETunnelProviderManager blir fylt frå eit innstillingslager som systemet eig, så eigenskapane betyr ingenting før loadFromPreferences er fullført. Les du connection.status før det, får du ein standardverdi, og difor rapporterer den første statusoppdateringa etter omstart fråkobla medan tunnelen køyrer. Last inn først, og les deretter status og protokollkonfigurasjon frå same fullføringshandteraren. Følg med på seinare endringar via NEVPNStatusDidChange i staden for å polle, og legg merke til at varslinga også blir utløyst for tilkoblingar som On Demand startar, der det ikkje finst noko appkall som kan returnere noko. Det same gjeld protokollinnstillingar: dei blir lesne frå den innlasta konfigurasjonen, ikkje frå det appen sende inn.

Sjølve tunnelen lever i ein Network Extension-leverandørprosess, så appen kan miste sin eigen tilstand utan å miste tilkoblinga. Alt grensesnittet viser må byggjast opp att frå behandlaren, ikkje minnast frå førre økt.

Startrekkjefølgje: lagre, last inn, start deretter

Ei leverandørbasert tilkobling treng tre steg i rekkjefølgje. Skriv leverandørkonfigurasjonen og kall saveToPreferences, last inn behandlaren slik at den lagra konfigurasjonen er den du held i handa, og start deretter via NETunnelProviderSession.startVPNTunnel(). Hoppar du over lagringa, har starten ingenting å starte; lastar du inn før lagringa, speglar behandlaren framleis den gamle konfigurasjonen.

Boolsk verdi som startVPNTunnel returnerer seier berre at førespurnaden vart godteken. Feil på leverandørnivå kjem seinare som ei statusendring til fråkobla, som du observerer via varslet NEVPNStatusDidChange, og varselhandteraren må lese connection.status på nytt etter loadFromPreferences fordi den bufra verdien framleis kan vere den gamle. Feil på førespurnadsnivå kjem straks tilbake frå den kastande forma av kallet, eller via feilut-parameteren til startVPNTunnelAndReturnError:. Kode som behandlar returverdien som resultatet, rapporterer ei tilkobling som aldri vart etablert. Den andre stille feilen er ein leverandørbundle-identifikator som ikkje samsvarar med den installerte utvidinga: førespurnaden blir avvist, og ingenting i meldinga peikar på identifikatoren. Er identifikatoren feil, feilar førespurnaden vanlegvis med ein gong, før noka logglinje frå leverandøren blir synleg.

Å laste innstillingane på nytt etter ein start er det som gjer statusskjermar riktige. Behandlaren dyttar ikkje ein ny konfigurasjon til deg når systemet endrar han.

Tillitsmateriale kjem via profil, aldri frå appkode

Ein app har ingen støtta måte å leggje eit rotsertifikat til iOS’ tillitslager, så ein Personal VPN-konfigurasjon kan berre referere materiale eininga allereie stolar på: ei kjede etablert av ein installert profil, av einingstyring eller av ein CA systemet stolar på av andre grunnar. Ein app som lagar sin eigen CA ved første oppstart og ventar at systemet anerkjenner han, vil feile valideringa inne i leverandøren, der grensesnittet til appen ikkje kan sjå årsaka.

Behandle den grensa som den designavgrensinga ho er, og lever tillitsankeret saman med registreringsprofilen. Hald VPN-autentisering skild frå tillitsavgjerda, fordi dei feilar på ulike stader og blir feilsøkte av ulike folk.

Tellarane kjem frå grensesnittet, ikkje frå VPN-API-et

Behandlaren eksponerer status og konfigurasjon, og ingenting som tel byte per tunnel. Treng du brukstal, kall getifaddrs() og les if_data for det aktuelle grensesnittet: en0 for Wi-Fi, pdp_ip-grensesnitta for mobil og ei utun-eining for sjølve tunnelen. Tellarane til utun skildrar indre trafikk og inkluderer protokolloverhead.

Desse tala er anslag, ikkje rekneskap per app, og dei blir nullstilte når grensesnittet blir gjenskapt. Merk dei slik i grensesnittet, elles brukar nokon dei til å fakturere ein kunde. Treng du tal per app, treng du ein heilt annan mekanisme, ikkje ei betre lesing av desse felta.

Opprydding høyrer i stopVPNTunnel, ikkje i avslutning

applicationWillTerminate gir deg nokre sekund før systemet kan drepe prosessen, og det er ikkje ein påliteleg stad å rive ned ei tilkobling. Send stoppen til stopVPNTunnel() eller handter han i stopp-callbacken til leverandøren, og hald på behandlar- eller konfigurasjonsidentifikatoren du starta med, slik at stoppen treff den tilkoblinga i staden for kvar konfigurasjon på eininga.

Lagre den identifikatoren ved sida av profilen han høyrer til, sidan eit behandlarobjekt ikkje registrerer kva konfigurasjon brukaren valde. Og hugs at ei tilkobling som On Demand reiser, ikkje har noko appkall bak seg i det heile, så ein statusskjerm må framleis laste innstillingane før han teiknar noko.

Relaterte artiklar