Reikia vieno ekrano, kuris elgtųsi kitaip, kai tunelis įjungtas, o jokio kvietimo, kuris tai pasakytų, nėra. Tai išleidimo apribojimas: macOS jokia vieša sistema nepraneša, ar prijungtas bet koks VPN, o iOS būsena priklauso programai, kuri įdiegė konfigūraciją. Toliau pateikti patikrinimai veda nuo šios ribos iki to, ką galite išleisti, ir bet kuris jų gali anksti baigti paiešką.

1 patikrinimas: ar į šį klausimą apskritai galima atsakyti?

„Sandbox“ išsprendžia klausimą anksčiau už bet kokią API. Trečiosios šalies procesas negali išvardyti kito tiekėjo plėtinio ir negali perskaityti to plėtinio konfigūracijos, todėl nėra palaikomo objekto, kurio būtų galima paklausti.

Kiekvienas apėjimas atsimuša į tą pačią sieną. Sąsajų sąrašai, scutil --nc list ir tiesioginis sistemos konfigūracijos skaitymas arba reikalauja teisių, kurių „sandbox“ nesuteikia, arba priklauso nuo elgsenos, kurios „Apple“ niekada nežadėjo. Jei planui reikia vieno iš šių dalykų, problema yra planas. Funkcija, pastatyta ant nedokumentuotos detalės, yra palaikymo bilietas su pristatymo data.

2 patikrinimas: ar jūsų programa pati valdo tunelį?

Jei taip, savo konfigūracijai turite palaikomą atsakymą. Įkelkite nuostatas, apdorokite klaidą, tada perskaitykite būseną ir užsiprenumeruokite pakeitimus, o ne apklausinėkite:

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
}

Būkite tikslūs, ką tai grąžina: jūsų įdiegto tunelio būseną. Vartotojas, naudojantis kitą klientą, bus rodomas kaip atsijungęs, ir tai ne jūsų kodo klaida. Nuspręskite, kurį iš šių dviejų klausimų jūsų funkcija iš tikrųjų užduoda, prieš statydami ant atsakymo.

3 patikrinimas: ką euristika jums iš tikrųjų pasakytų?

Plačiai kopijuojamas metodas klausia sistemos tarpinio serverio žodyno apie jo apimties įrašus ir skaito raktus, kurie atsitiktinai yra sąsajų pavadinimai:

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

Raktas, prasidedantis tap, tun, ppp, ipsec arba utun reiškia, kad yra tunelio apimties sąsaja. Viso pavadinimo sutapimas iš karto nepavyksta, nes „iOS 12“ atėjo su utun1 ir utun2, o kai kurie profiliai rodomi kaip ipsec4, ppp0 arba utun0. Palyginkite prefiksus.

Vis dėlto pavadinimas nenurodo savininko. Sistemos funkcijos ir kitų tiekėjų plėtiniai taip pat kuria utun sąsajas, ir tokia gali egzistuoti nepernešdama nieko iš jūsų srauto. Skatykite tai kaip užuominą, kad netoliese yra kažkas tunelio formos, ne daugiau. Klaidingas teigiamas rezultatas čia pigus, jei ribojate tik vieną funkciją, ir brangus, jei ribojate prisijungimo ekraną.

4 patikrinimas: ar galite vietoj to išbandyti paskirties tašką?

Jei programai tereikia žinoti, ar pasiekiama vidinė paslauga, išbandykite tą paslaugą. Trumpa patikra su laiko limitu atsako į klausimą, nuo kurio funkcija iš tikrųjų priklauso, ir ji veikia toliau, kai vartotojas pakeičia klientą arba tunelis pakeičia formą.

Pasiekiamumas yra stebėjimas apie jūsų kelią. Sąsajos pavadinimas yra išvada apie kažką, esantį šalia jūsų kelio, todėl euristika kuria ginčus klaidų ataskaitose, o patikra – įrodymus. Jei patikra nepavyksta, kai vartotojas tvirtina, kad VPN įjungtas, dabar turite konkretų kelią derinti: vardų skyrimą, maršrutą ar paslaugos leidimą.

5 patikrinimas: ar platforma gali primesti tai, ko jums reikia?

Kai reikalavimas yra garantija, kad niekas neištrūks iš tunelio, profilis yra tinkama vieta, o ne detektorius. includeAllNetworks įjungimas viso tunelio konfigūracijoje „iOS 14“ ar naujesnėje versijoje pakeičia platformos elgseną, o ne prašo jūsų programos tai numatyti. Vėliavėlė dokumentuota NEVPNProtocol nuorodoje.

Tai kitokia atsakymo rūšis: primetimas, o ne stebėjimas. Be to, jis taikomas tik jūsų valdomiems profiliams, todėl nepadeda vartotojų programai, stebinčiai kito tunelį.

6 patikrinimas: padarykite gedimą saugų ir stebimą

Išjunkite tik tą galimybę, kuriai reikia tunelio, ir palikite likusią programą naudingą. Detektorius, kuris kaskart, kai nėra tikras, paslepia visą sąsają, sukuria trikdį kiekvienam, kurio tunelis naudoja pavadinimą, kurio niekada nenumatėte. Grįžkite prie konservatyvios elgsenos: vietinės funkcijos veikia toliau, o išjungiamas tik tas nuotolinis kvietimas, kuriam tikrai reikia tunelio. Šis pasirinkimas yra produkto sprendimas, ir jis nusipelno būti užrašytas šalia euristikos.

Užregistruokite, ką stebėjote: sąsajų pavadinimus, platformos versiją ir vienos patikros rezultatą. Tai paverčia kitą ataskaitą iš ginčo patikrinimu. Tada pirmenybę teikite palaikomai deklaracijai, kai ją turite, nes valdoma konfigūracija gali aiškiai perteikti ketinimą ir pašalinti didžiąją dalį priežasties tikrinti pavadinimus.

Jei 1–5 patikrinimai paliko jus be palaikomo atsakymo, išleiskite patikrą ir sąžiningai pažymėkite rezultatą. Dokumentuotas geriausių pastangų signalas yra geresnis produkto sprendimas nei privati API, kuri lūžta kitame leidime.

Susiję straipsniai