Ձեզ պետք է մեկ էկրան, որը այլ կերպ վարվի, երբ թունելը միացված է, և չկա զանգ, որը կասի ձեզ այդ մասին։ Սա թողարկման սահմանափակումն է. macOS-ում ոչ մի հանրային ֆրեյմվորկ չի հաղորդում՝ արդյոք կամայական VPN-ը միացված է, իսկ iOS-ում կարգավիճակը պատկանում է այն հավելվածին, որը տեղադրել է կոնֆիգուրացիան։ Ստորև բերված ստուգումները տանում են այդ սահմանից դեպի մի բան, որը կարող եք թողարկել, և դրանցից ցանկացածը կարող է վաղ ավարտել որոնումը։

Ստուգում 1. արդյոք հարցին ընդհանրապես հնարավոր է պատասխանել։

Sandbox-ը լուծում է հարցը ցանկացած API-ից առաջ։ Երրորդ կողմի գործընթացը չի կարող թվարկել մեկ այլ մատակարարի ընդլայնումը և չի կարող կարդալ այդ ընդլայնման կոնֆիգուրացիան, ուստի հարցնելու համար աջակցվող օբյեկտ չկա։

Ցանկացած շրջանցում բախվում է նույն պատին։ Ինտերֆեյսների ցանկերը, scutil --nc list և համակարգի կոնֆիգուրացիայի ուղղակի ընթերցումները կա՛մ պահանջում են թույլտվություններ, որոնք sandbox-ը զսպում է, կա՛մ կախված են վարքագծից, որը Apple-ը երբեք չի խոստացել։ Եթե պլանին պետք է դրանցից մեկը, խնդիրը պլանն է։ Չփաստաթղթավորված մանրամասնության վրա կառուցված ֆունկցիան առաքման ամսաթիվ ունեցող աջակցության տոմս է։

Ստուգում 2. արդյոք ձեր հավելվածն ինքն է կառավարում թունելը։

Եթե այո, դուք ունեք աջակցվող պատասխան ձեր սեփական կոնֆիգուրացիայի համար։ Բեռնեք նախապատվությունները, մշակեք սխալը, ապա կարդացեք կարգավիճակը և բաժանորդագրվեք փոփոխություններին՝ հարցումներ անելու փոխարեն։

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
}

Եղեք ճշգրիտ, թե ինչ է վերադարձնում սա՝ ձեր տեղադրած թունելի վիճակը։ Այլ հաճախորդ օգտագործող օգտատերը կցուցադրվի որպես անջատված, և դա ձեր կոդի սխալ չէ։ Որոշեք, թե այդ երկու հարցերից որն է ձեր ֆունկցիան իրականում տալիս, նախքան պատասխանի վրա կառուցելը։

Ստուգում 3. ի՞նչ կասեր ձեզ էվրիստիկան իրականում։

Լայնորեն պատճենված մոտեցումը համակարգի պրոքսի բառարանից հարցնում է նրա շրջանակված գրառումները և կարդում բանալիները, որոնք պատահաբար ինտերֆեյսների անուններ են։

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

Բանալին, որը սկսվում է tap, tun, ppp, ipsec կամ utun-ով, ենթադրում է, որ առկա է թունելի շրջանակով ինտերֆեյս։ Ամբողջ անվան համապատասխանեցումը անմիջապես ձախողվում է, որովհետև iOS 12-ը եկել է utun1-ով և utun2-ով, և որոշ պրոֆիլներ հայտնվում են որպես ipsec4, ppp0 կամ utun0։ Փոխարենը համեմատեք նախածանցերը։

Այնուամենայնիվ, անունը ոչ մի սեփականատեր չի նույնականացնում։ Համակարգի ֆունկցիաները և այլ մատակարարների ընդլայնումները նույնպես ստեղծում են utun ինտերֆեյսներ, և մեկը կարող է գոյություն ունենալ՝ չկրելով ձեր թրաֆիկի ոչինչ։ Կարդացեք սա որպես ակնարկ, որ մոտակայքում կա թունելի ձևով ինչ-որ բան, ոչ ավելին։ Կեղծ դրականն այստեղ էժան է, եթե դուք սահմանափակում եք միայն մեկ ֆունկցիա, և թանկ, եթե սահմանափակում եք մուտքի էկրանը։

Ստուգում 4. կարո՞ղ եք փոխարենը ստուգել նպատակակետը։

Եթե հավելվածին պետք է միայն իմանալ՝ արդյոք ներքին ծառայությունը հասանելի է, ստուգեք այդ ծառայությունը։ Կարճ ժամկետով փորձարկումը պատասխանում է այն հարցին, որից ֆունկցիան իրականում կախված է, և այն շարունակում է աշխատել, երբ օգտատերը փոխում է հաճախորդը կամ թունելը փոխում է ձևը։

Հասանելիությունը դիտարկում է ձեր ուղու մասին։ Ինտերֆեյսի անունը եզրակացություն է ձեր ուղուն հարակից ինչ-որ բանի մասին, դրա համար էվրիստիկան վեճեր է ստեղծում սխալների հաշվետվություններում, իսկ փորձարկումը՝ ապացույցներ։ Եթե փորձարկումը ձախողվում է, մինչ օգտատերը պնդում է, որ VPN-ը միացված է, այժմ դուք ունեք կոնկրետ ուղի վրիպազերծման համար՝ անունների լուծում, երթուղի կամ ծառայության թույլտվություն։

Ստուգում 5. կարո՞ղ է հարթակը պարտադրել այն, ինչ ձեզ պետք է։

Երբ պահանջը երաշխիքն է, որ ոչինչ չի փախչի թունելից, պրոֆիլն է դրա տեղը, ոչ թե դետեկտորը։ includeAllNetworks-ը միացնելը iOS 14 կամ ավելի նոր տարբերակում ամբողջական թունելի կոնֆիգուրացիայում փոխում է հարթակի վարքը՝ ձեր հավելվածից եզրակացնել պահանջելու փոխարեն։ Դրոշը փաստաթղթավորված է NEVPNProtocol-ի տեղեկատուում։

Սա այլ տեսակի պատասխան է՝ պարտադրում դիտարկման փոխարեն։ Այն նաև կիրառվում է միայն ձեր վերահսկած պրոֆիլների նկատմամբ, ուստի չի օգնում սպառողական հավելվածին, որը հետևում է ուրիշի թունելին։

Ստուգում 6. դարձրեք ձախողումը անվտանգ և դիտարկելի

Անջատեք միայն այն հնարավորությունը, որին պետք է թունելը, և թողեք հավելվածի մնացած մասը օգտագործելի։ Դետեկտորը, որը թաքցնում է ամբողջ ինտերֆեյսը, երբ վստահ չէ, անջատում է ստեղծում բոլորի համար, ում թունելը օգտագործում է անուն, որը դուք երբեք չեք կանխատեսել։ Փոխարենը վերադարձեք պահպանողական վարքագծին. տեղական ֆունկցիաները շարունակում են աշխատել, և անջատվում է միայն այն հեռավոր զանգը, որին իսկապես պետք է թունելը։ Այդ ընտրությունը արտադրանքի որոշում է, և այն արժանի է գրվելու էվրիստիկայի կողքին։

Գրանցեք այն, ինչ դիտարկել եք՝ ինտերֆեյսների անունները, հարթակի տարբերակը և մեկ փորձարկման արդյունքը։ Դա հաջորդ հաշվետվությունը վեճից վերածում է ստուգման։ Այնուհետև նախապատվություն տվեք աջակցվող հայտարարությանը, որտեղ այն ունեք, քանի որ կառավարվող կոնֆիգուրացիան կարող է միտքը փոխանցել բացահայտ և վերացնել անունները ստուգելու հիմնական պատճառը։

Եթե 1-ից 5 ստուգումները ձեզ թողել են առանց աջակցվող պատասխանի, թողարկեք փորձարկումը և արդյունքը պիտակավորեք ազնվորեն։ Փաստաթղթավորված լավագույն ջանքի ազդանշանը ավելի լավ արտադրանքի որոշում է, քան մասնավոր API-ն, որը կոտրվում է հաջորդ թողարկումում։

Առնչվող հոդվածներ