Uygulamanız bağlantı kesildi diyor, menü çubuğu bağlandı diyor ve trafik açıkça akıyor. Bu boşluk yeniden denemeyle düzeltilecek bir yarış durumu değil: uygulama ile tünel ayrı süreçlerdir ve kodunuzun okuduğu nesne, sistemin sakladığı bir yapılandırmanın önbelleğe alınmış görünümüdür. Apple'ın Personal VPN yüzeyi bir kontrol API'sidir, veri yolu değildir ve tuhaf davranışının çoğu bu tek gerçekten kaynaklanır. Her çağrıda gerçekte ne olduğu şöyle.

Yönetici nesnesi önbelleğe alınmış bir görünüm, tünel değil

NETunnelProviderManager sistemin sahip olduğu bir tercih deposundan doldurulur, bu yüzden loadFromPreferences tamamlanana kadar özellikleri hiçbir anlam taşımaz. Ondan önce connection.status okursanız varsayılan bir değer alırsınız ve bu yüzden yeniden başlatmadan sonraki ilk durum yenilemesi tünel çalışırken bağlantı kesildi bildirir. Önce yükleyin, sonra durumu ve protokol yapılandırmasını aynı tamamlama işleyicisinden okuyun. Sonraki değişiklikleri yoklamak yerine NEVPNStatusDidChange üzerinden izleyin ve bildirimin On Demand tarafından başlatılan bağlantılar için de tetiklendiğini unutmayın; orada herhangi bir şey döndürecek uygulama çağrısı hiç yoktur. Aynısı protokol ayarları için de geçerlidir: bunlar yüklenen yapılandırmadan okunur, uygulamanın geçirdiğinden değil.

Tünelin kendisi bir Network Extension sağlayıcı sürecinde yaşar, bu yüzden uygulama bağlantıyı kaybetmeden kendi durumunu kaybedebilir. Arayüzün gösterdiği her şey yöneticiden yeniden kurulmalıdır, önceki oturumdan hatırlanmamalıdır.

Başlatma sırası: kaydet, yükle, sonra başlat

Sağlayıcı tabanlı bir bağlantı sırayla üç adım gerektirir. Sağlayıcı yapılandırmasını yazın ve saveToPreferences çağırın, kaydedilen yapılandırmanın elinizdeki olması için yöneticiyi yükleyin, sonra NETunnelProviderSession.startVPNTunnel() üzerinden başlatın. Kaydetmeyi atlarsanız başlatmanın başlatacak bir şeyi yoktur; kaydetmeden önce yüklerseniz yönetici hâlâ eski yapılandırmayı yansıtır.

startVPNTunnel tarafından döndürülen Boolean yalnızca isteğin kabul edildiğini söyler. Sağlayıcı düzeyindeki hatalar daha sonra bağlantı kesildi durumuna geçiş olarak gelir; bunu NEVPNStatusDidChange bildirimi aracılığıyla izlersiniz ve bildirim işleyicisi loadFromPreferences sonrasında connection.status değerini yeniden okumalıdır çünkü önbellekteki değer hâlâ eski olabilir. İstek düzeyindeki hatalar, çağrının istisna fırlatan biçiminden hemen döner veya startVPNTunnelAndReturnError: hatasının çıkış parametresi aracılığıyla gelir. Dönen değeri sonuç olarak gören kod, hiç kurulmamış bir bağlantı bildirir. Diğer sessiz hata, yüklü uzantıyla eşleşmeyen bir sağlayıcı paket tanımlayıcısıdır: istek reddedilir ve mesajda hiçbir şey tanımlayıcıya işaret etmez. Tanımlayıcı yanlışsa istek genellikle hemen başarısız olur, sağlayıcının tek bir günlük satırı bile görünmeden önce.

Başlatmadan sonra tercihleri yeniden yüklemek, durum ekranlarını doğru yapan şeydir. Sistem yapılandırmayı değiştirdiğinde yönetici size yeni bir yapılandırma itmez.

Güven malzemesi profil yoluyla gelir, asla uygulama kodundan gelmez

Bir uygulamanın iOS güven deposuna kök sertifika eklemek için desteklenen bir yolu yoktur, bu yüzden Personal VPN yapılandırması yalnızca cihazın zaten güvendiği malzemeye başvurabilir: yüklü bir profil, cihaz yönetimi veya sistemin başka nedenlerle güvendiği bir CA tarafından kurulan bir zincir. İlk açılışta kendi CA'sını üretip sistemin onu tanımasını bekleyen bir uygulama, sağlayıcının içindeki doğrulamada başarısız olur; orada uygulamanın arayüzü nedeni göremez.

Bu sınırı olduğu gibi bir tasarım kısıtı olarak görün ve güven çapasını kayıt profiliyle birlikte gönderin. VPN kimlik doğrulamasını güven kararından ayrı tutun, çünkü farklı yerlerde başarısız olurlar ve farklı kişiler tarafından ayıklanırlar.

Sayaçlar arayüzden gelir, VPN API'sinden değil

Yönetici durumu ve yapılandırmayı sunar, tünel başına bayt sayan hiçbir şey sunmaz. Kullanım sayılarına ihtiyacınız varsa getifaddrs() çağırın ve ilgili arayüz için if_data okuyun: Wi-Fi için en0, hücresel için pdp_ip arayüzleri ve tünelin kendisi için utun aygıtı. utun sayaçları iç trafiği tanımlar ve protokol yükünü içerir.

Bu sayılar tahmindir, uygulama başına muhasebe değildir ve arayüz yeniden oluşturulduğunda sıfırlanır. Arayüzde bunları böyle etiketleyin, yoksa biri bunları bir müşteriye fatura kesmek için kullanır. Uygulama başına sayılara ihtiyacınız varsa tamamen başka bir mekanizma gerekir, bu alanların daha iyi okunması değil.

Temizlik stopVPNTunnel içindedir, sonlandırmada değil

applicationWillTerminate sistem süreci öldürebilmeden önce size birkaç saniye verir ve bu bir bağlantıyı sökmek için güvenilir bir yer değildir. Durdurmayı stopVPNTunnel() adresine gönderin veya sağlayıcının durdurma geri çağrısında ele alın ve başlattığınız yönetici veya yapılandırma tanımlayıcısını saklayın, böylece durdurma cihazdaki her yapılandırmayı değil o bağlantıyı hedefler.

Bu tanımlayıcıyı ait olduğu profilin yanında saklayın, çünkü yönetici nesnesi kullanıcının hangi yapılandırmayı seçtiğini kaydetmez. Ve On Demand'in kaldırdığı bağlantının arkasında hiçbir uygulama çağrısı olmadığını unutmayın, bu yüzden bir durum ekranı bir şey çizmeden önce hâlâ tercihleri yüklemek zorundadır.

İlgili makaleler