Sa vajad ühte ekraani, mis käitub teisiti, kui tunnel on üleval, ja ükski kutse ei ütle sulle seda. See on väljastamise piirang: macOS-is ei raporteeri ükski avalik raamistik, kas suvaline VPN on ühendatud, ja iOS-is kuulub olek rakendusele, mis konfiguratsiooni installis. Allpool olevad kontrollid viivad sellest piirist millegi juurde, mida saad välja lasta, ja igaüks neist võib otsingu varakult lõpetada.

Kontroll 1: kas küsimusele on üldse võimalik vastata?

Sandbox otsustab küsimuse enne ükskõik millist API-t. Kolmanda osapoole protsess ei saa loetleda teise tarnija laiendust ega lugeda ka selle laienduse konfiguratsiooni, seega pole toetatud objekti, millelt küsida.

Iga möödaviis põrkab sama seina vastu. Liidesete loendid, scutil --nc list ja otsesed süsteemikonfiguratsiooni lugemised nõuavad kas õigusi, mida sandbox kinni hoiab, või sõltuvad käitumisest, mida Apple kunagi ei lubanud. Kui plaan vajab ühte neist, on probleem plaanis. Dokumenteerimata detailile ehitatud funktsioon on tugipilet tarnekuupäevaga.

Kontroll 2: kas sinu rakendus haldab tunnelit ise?

Kui jah, on sul oma konfiguratsiooni jaoks toetatud vastus. Lae eelistused, käsitle viga, seejärel loe olek ja telli muudatused, selle asemel et küsitleda:

vpnManager.loadFromPreferences { error in
    // handle a load failure before reading status
}

NotificationCenter.default.addObserver(
    forName: .NEVPNStatusDidChange,
    object: nil,
    queue: nil
) { note in
    let status = (note.object as? NEVPNConnection)?.status
}

Ole täpne selles, mida see tagastab: sinu installitud tunneli olek. Teist klienti kasutav kasutaja kuvatakse ühendamata ja see pole sinu koodi viga. Otsusta, millist neist kahest küsimusest sinu funktsioon tegelikult küsib, enne kui vastusele ehitad.

Kontroll 3: mida ütleks sulle tegelikult heuristika?

Laialt kopeeritud lähenemine küsib süsteemi puhverserveri sõnastikult selle ulatuslikke kirjeid ja loeb võtmeid, mis juhtuvad olema liidesenimed:

let settings = CFNetworkCopySystemProxySettings()?.takeRetainedValue() as NSDictionary?
let scoped = settings?["__SCOPED__"] as? [String: Any]
let names = scoped?.keys ?? []

Võti, mis algab järgmistest: tap, tun, ppp, ipsec või utun, osutab sellele, et tunneliga seotud liides on olemas. Terviknime sobitamine ebaõnnestub kohe, sest iOS 12 tuli utun1 ja utun2-ga ning mõned profiilid ilmuvad kujul ipsec4, ppp0 või utun0. Võrdle selle asemel eesliiteid.

Sellegipoolest nimi ei identifitseeri omanikku. Süsteemifunktsioonid ja teiste tarnijate laiendused loovad samuti utun-liideseid ja üks võib eksisteerida, kandes mitte midagi sinu liiklusest. Loe seda vihjena, et läheduses on midagi tunnelikujulist, mitte enamat. Valepositiivne on siin odav, kui piirad ainult üht funktsiooni, ja kallis, kui piirad sisselogimisekraani.

Kontroll 4: kas saad selle asemel sihtkohta testida?

Kui rakendus peab vaid teadma, kas sisemine teenus on kättesaadav, testi seda teenust. Lühike ajapiiranguga proov vastab küsimusele, millest funktsioon tegelikult sõltub, ja see töötab edasi, kui kasutaja vahetab klienti või tunnel muudab kuju.

Kättesaadavus on vaatlus sinu teekonna kohta. Liidesenimi on järeldus millegi kohta sinu teekonna kõrval, mistõttu heuristika tekitab veaaruannetes vaidlusi ja proov tekitab tõendeid. Kui proov ebaõnnestub, samal ajal kui kasutaja väidab, et VPN on sees, on sul nüüd konkreetne teekond silumiseks: nimelahendus, marsruut või teenuse luba.

Kontroll 5: kas platvorm saab jõustada seda, mida vajad?

Kui nõue on garantii, et miski ei pääse tunnelist välja, on profiil selle õige koht, mitte detektor. includeAllNetworks sisselülitamine täistunneli konfiguratsioonis iOS 14 või uuemas muudab platvormi käitumist, selle asemel et paluda rakendusel seda järeldada. Lipp on dokumenteeritud NEVPNProtocoli viites.

See on teist liiki vastus: jõustamine vaatluse asemel. See kehtib ka ainult profiilide kohta, mida sina kontrollid, nii et sellest pole abi tarbijarakendusele, kes jälgib kellegi teise tunnelit.

Kontroll 6: tee ebaõnnestumine ohutuks ja jälgitavaks

Lülita välja ainult see võimekus, mis vajab tunnelit, ja jäta ülejäänud rakendus kasutatavaks. Detektor, mis peidab kogu liidese alati, kui ta pole kindel, tekitab katkestuse kõigile, kelle tunnel kasutab nime, mida sa kunagi ei oodanud. Lange selle asemel tagasi konservatiivse käitumise juurde: kohalikud funktsioonid töötavad edasi ja ainult see kaugkutse, mis tunnelit tõesti vajab, on välja lülitatud. See valik on tooteotsus ja see väärib kirjapanekut heuristika kõrvale.

Logi, mida vaatlesid: liidesenimed, platvormi versioon ja ühe proovi tulemus. See muudab järgmise aruande vaidlusest kontrolliks. Seejärel eelista toetatud deklaratsiooni, kus sul see on, sest hallatud konfiguratsioon saab kavatsust selgelt kanda ja kõrvaldada suurema osa põhjusest nimesid üldse uurida.

Kui kontrollid 1 kuni 5 jätsid su toetatud vastuseta, saada proov välja ja nimeta tulemus ausalt. Dokumenteeritud parima pingutuse signaal on parem tooteotsus kui privaatne API, mis järgmisel väljalaskel katki läheb.

Seotud artiklid