Aplikasi anda berkata terputus, bar menu berkata bersambung, dan trafik jelas mengalir. Jurang itu bukan keadaan perlumbaan yang anda betulkan dengan cubaan semula: aplikasi dan terowong ialah proses berasingan, dan objek yang kod anda baca ialah paparan cache bagi konfigurasi yang disimpan sistem. Permukaan Personal VPN Apple ialah API kawalan, bukan laluan data, dan sebahagian besar tingkah laku peliknya berpunca daripada satu fakta itu. Berikut ialah apa yang sebenarnya berlaku pada setiap panggilan.

Objek pengurus ialah paparan cache, bukan terowong

NETunnelProviderManager diisi daripada stor keutamaan yang dimiliki sistem, jadi sifatnya tidak bermakna sehingga loadFromPreferences selesai. Baca connection.status sebelum itu dan anda dapat nilai lalai, sebab itulah muat semula status pertama selepas pelancaran semula melaporkan terputus semasa terowong aktif. Muat dahulu, kemudian baca status dan konfigurasi protokol daripada pengendali penyempurnaan yang sama. Perhatikan perubahan kemudian melalui NEVPNStatusDidChange dan bukan meninjau, dan ambil perhatian bahawa pemberitahuan juga dicetuskan untuk sambungan yang dimulakan On Demand, di mana tiada panggilan aplikasi untuk memulangkan apa-apa. Perkara sama berlaku pada tetapan protokol: ia dibaca daripada konfigurasi yang dimuatkan, bukan daripada apa yang dihantar aplikasi.

Terowong itu sendiri hidup dalam proses penyedia Network Extension, jadi aplikasi boleh kehilangan keadaannya sendiri tanpa kehilangan sambungan. Semua yang dipaparkan antara muka mesti dibina semula daripada pengurus, bukan diingati daripada sesi lepas.

Urutan mula: simpan, muat, kemudian mula

Sambungan berasaskan penyedia memerlukan tiga langkah mengikut urutan. Tulis konfigurasi penyedia dan panggil saveToPreferences, muat pengurus supaya konfigurasi tersimpan ialah yang anda pegang, kemudian mula melalui NETunnelProviderSession.startVPNTunnel(). Jika anda langkau penyimpanan, permulaan tiada apa untuk dimulakan; jika anda muat sebelum menyimpan, pengurus masih mencerminkan konfigurasi lama.

Boolean yang dipulangkan startVPNTunnel hanya mengatakan bahawa permintaan diterima. Kegagalan peringkat penyedia datang kemudian sebagai perubahan status kepada terputus, yang anda perhatikan melalui pemberitahuan NEVPNStatusDidChange, dan pengendali pemberitahuan mesti membaca semula connection.status selepas loadFromPreferences kerana nilai cache mungkin masih yang lama. Kegagalan peringkat permintaan kembali serta-merta daripada bentuk panggilan yang melontar pengecualian, atau melalui parameter keluaran ralat startVPNTunnelAndReturnError:. Kod yang menganggap nilai pulangan sebagai hasil melaporkan sambungan yang tidak pernah terbentuk. Kegagalan senyap yang lain ialah pengecam bundel penyedia yang tidak sepadan dengan sambungan yang dipasang: permintaan ditolak, dan tiada apa dalam mesej menunjuk kepada pengecam itu. Jika pengecam salah, permintaan biasanya gagal serta-merta, sebelum apa-apa baris log penyedia muncul.

Memuat semula keutamaan selepas permulaan ialah yang menjadikan skrin status betul. Pengurus tidak menolak konfigurasi baharu kepada anda apabila sistem mengubahnya.

Bahan kepercayaan datang melalui profil, tidak pernah daripada kod aplikasi

Aplikasi tiada cara yang disokong untuk menambah sijil akar ke stor kepercayaan iOS, jadi konfigurasi Personal VPN hanya boleh merujuk bahan yang sudah dipercayai peranti: rantaian yang dibentuk oleh profil yang dipasang, pengurusan peranti atau CA yang dipercayai sistem atas sebab lain. Aplikasi yang mencipta CA sendiri pada pelancaran pertama dan mengharapkan sistem menerimanya akan gagal pengesahan dalam penyedia, di mana antara muka aplikasi tidak dapat melihat sebabnya.

Anggap sempadan itu sebagai kekangan reka bentuk sebagaimana adanya dan hantar sauh kepercayaan bersama profil pendaftaran. Jauhkan pengesahan VPN daripada keputusan kepercayaan, kerana kedua-duanya gagal di tempat berbeza dan dinyahpepijat oleh orang berbeza.

Pembilang datang daripada antara muka, bukan daripada API VPN

Pengurus mendedahkan status dan konfigurasi, dan tiada apa yang mengira bait setiap terowong. Jika anda perlukan angka penggunaan, panggil getifaddrs() dan baca if_data untuk antara muka berkenaan: en0 untuk Wi-Fi, antara muka pdp_ip untuk selular dan peranti utun untuk terowong itu sendiri. Pembilang utun menerangkan trafik dalaman dan termasuk overhed protokol.

Angka itu anggaran, bukan perakaunan setiap aplikasi, dan ia ditetapkan semula apabila antara muka dicipta semula. Labelkan begitu dalam antara muka, atau seseorang akan menggunakannya untuk mengebilkan pelanggan. Jika anda perlukan angka setiap aplikasi, anda perlukan mekanisme yang sama sekali berbeza, bukan bacaan yang lebih baik bagi medan ini.

Pembersihan terletak dalam stopVPNTunnel, bukan dalam penamatan

applicationWillTerminate memberi anda beberapa saat sebelum sistem boleh membunuh proses, dan itu bukan tempat yang boleh dipercayai untuk merungkai sambungan. Hantar hentian kepada stopVPNTunnel() atau kendalikannya dalam callback hentian penyedia, dan simpan pengecam pengurus atau konfigurasi yang anda mulakan supaya hentian menyasarkan sambungan itu dan bukan setiap konfigurasi pada peranti.

Simpan pengecam itu bersama profil miliknya, kerana objek pengurus tidak merekodkan konfigurasi yang dipilih pengguna. Dan ingat bahawa sambungan yang dinaikkan On Demand tiada panggilan aplikasi di belakangnya sama sekali, jadi skrin status masih perlu memuat keutamaan sebelum melukis apa-apa.

Artikel berkaitan