Kial via iOS VPN-a aplikaĵo montras malkonektite dum la tunelo funkcias
Via iOS-a aplikaĵo regas la tunelon sed ne posedas ĝin, kaj la stato de la administrilo estas kaŝmemorita. Unue ŝargu la preferojn, poste legu staton kaj interfacajn nombrilojn.
Via aplikaĵo diras malkonektite, la menuo diras konektite, kaj la trafiko evidente fluas. Tiu diferenco ne estas vetkondiĉo, kiun vi riparas per reprovo: la aplikaĵo kaj la tunelo estas apartaj procezoj, kaj la objekto, kiun via kodo legas, estas kaŝmemorita vido de agordo, kiun la sistemo konservas. La Personal VPN-surfaco de Apple estas rega API, ne datenvojo, kaj plejparto de ĝia stranga konduto fontas el tiu unu fakto. Jen kio efektive okazas ĉe ĉiu voko.
La administrila objekto estas kaŝmemorita vido, ne la tunelo
NETunnelProviderManager pleniĝas el prefera konservejo, kiun posedas la sistemo, do ĝiaj propraĵoj signifas nenion ĝis loadFromPreferences finiĝos. Legu connection.status antaŭe kaj vi ricevos implicitan valoron, kaj tial la unua statŝanĝo post relaŭĉo raportas malkonektite dum la tunelo funkcias. Unue ŝargu, poste legu la staton kaj la protokolan agordon el la sama fina traktilo. Observu postajn ŝanĝojn per NEVPNStatusDidChange anstataŭ enketadi, kaj rimarku, ke la sciigo ankaŭ ekas por konektoj lanĉitaj de On Demand, kie tute ne ekzistas aplikaĵa voko por redoni ion ajn. La samo validas por protokolaj agordoj: ili legiĝas el la ŝargita agordo, ne el tio, kion la aplikaĵo enigis.
La tunelo mem loĝas en procezo de Network Extension-provizanto, do la aplikaĵo povas perdi sian propran staton sen perdi la konekton. Ĉio, kion la fasado montras, devas esti rekonstruita el la administrilo, ne memorita el la lasta seanco.
Ordo de lanĉo: konservu, ŝargu, poste lanĉu
Provizant-bazita konekto bezonas tri paŝojn en ordo. Skribu la provizantan agordon kaj voku saveToPreferences, ŝargu la administrilon tiel ke la konservita agordo estu tiu, kiun vi tenas, poste lanĉu per NETunnelProviderSession.startVPNTunnel(). Se vi preterlasas la konservon, la lanĉo havas nenion lanĉeblan; se vi ŝargas antaŭ la konservo, la administrilo ankoraŭ spegulas la malnovan agordon.
La bulea valoro redonata de startVPNTunnel nur diras, ke la peto estis akceptita. Fiaskoj je provizanta nivelo alvenas poste kiel statŝanĝo al malkonektite, kiun vi observas per la sciigo NEVPNStatusDidChange, kaj la sciiga traktilo devas relegi connection.status post loadFromPreferences, ĉar la kaŝmemorita valoro eble ankoraŭ estas la malnova. Fiaskoj je peta nivelo revenas tuj el la ĵeta formo de la voko, aŭ per la erara eliga parametro de startVPNTunnelAndReturnError:. Kodo, kiu traktas la redonan valoron kiel la rezulton, raportas konekton, kiu neniam establiĝis. La alia silenta fiasko estas provizanta pakaĵ-identigilo, kiu ne kongruas kun la instalita etendaĵo: la peto estas rifuzita, kaj nenio en la mesaĝo montras al la identigilo. Se la identigilo estas malĝusta, la peto kutime fiaskas tuj, antaŭ ol aperas iu ajn protokola linio de la provizanto.
Reŝargi preferojn post lanĉo estas tio, kio faras statajn ekranojn ĝustaj. La administrilo ne puŝas al vi novan agordon, kiam la sistemo ŝanĝas ĝin.
Fidmaterialo alvenas per profilo, neniam el aplikaĵa kodo
Aplikaĵo havas neniun subtenatan vojon aldoni radikan atestilon al la fidtenejo de iOS, do Personal VPN-agordo povas referenci nur materialon, kiun la aparato jam fidas: ĉenon establitan de instalita profilo, de aparatadministrado aŭ de CA, kiun la sistemo fidas pro aliaj kialoj. Aplikaĵo, kiu kreas sian propran CA ĉe la unua lanĉo kaj atendas, ke la sistemo honoru ĝin, fiaskos la validigon ene de la provizanto, kie la fasado de la aplikaĵo ne povas vidi la kialon.
Traktu tiun limon kiel la dezajnlimigon, kia ĝi estas, kaj sendu la fidankron kune kun la aliĝa profilo. Tenu VPN-aŭtentikigon aparte de la fida decido, ĉar ili fiaskas en malsamaj lokoj kaj estas sencimigataj de malsamaj homoj.
Nombriloj venas el la interfaco, ne el la VPN-API
La administrilo elmetas staton kaj agordon, kaj nenion, kio nombros bajtojn por tunelo. Se vi bezonas uzokvantojn, voku getifaddrs() kaj legu if_data por la koncerna interfaco: en0 por Wi-Fi, la interfacoj pdp_ip por poŝtelefono kaj aparato utun por la tunelo mem. La nombriloj de utun priskribas internan trafikon kaj inkluzivas protokolan superŝuton.
Tiuj ciferoj estas taksoj, ne kalkulado laŭ aplikaĵo, kaj ili nuliĝas, kiam la interfaco rekreiĝas. Etikedu ilin tiel en la fasado, aŭ iu uzos ilin por fakturi klienton. Se vi bezonas ciferojn laŭ aplikaĵo, vi bezonas tute alian mekanismon, ne pli bonan legadon de tiuj kampoj.
Purigado apartenas al stopVPNTunnel, ne al finiĝo
applicationWillTerminate donas al vi kelkajn sekundojn antaŭ ol la sistemo povas mortigi la procezon, kio ne estas fidinda loko por malkonstrui konekton. Sendu la halton al stopVPNTunnel() aŭ traktu ĝin en la halta retrovojo de la provizanto, kaj konservu la administrilan aŭ agordan identigilon, per kiu vi lanĉis, por ke la halto celi tiun konekton anstataŭ ĉiun agordon sur la aparato.
Konservu tiun identigilon apud la profilo, al kiu ĝi apartenas, ĉar administrila objekto ne registras, kiun agordon la uzanto elektis. Kaj memoru, ke konekto levita de On Demand tute ne havas aplikaĵan vokon malantaŭ si, do stata ekrano ankoraŭ devas ŝargi preferojn antaŭ ol ĝi desegnas ion ajn.