দুটি ত্রুটি কোড iOS-এ Network Extension VPN-এর বেশিরভাগ প্রথম প্রচেষ্টার কারণ: NEVPNErrorDomain Code=4 এবং Code=5। কোনোটিই সার্ভারের অভিযোগ নয়। একটি দেখা যায় যখন অ্যাপ এমন একটি অবজেক্টে সেটিংস লেখে যা কখনো ডিস্ক থেকে পড়া হয়নি, আর অন্যটি যখন লেখাটাই ব্যর্থ হয়, প্রায়ই কারণ প্রোফাইলটি তখনো নিষ্ক্রিয় থাকা অবস্থায় সংরক্ষণ করা হচ্ছে। দুটোই চারটি কলের ক্রম বদলে ঠিক হয়, IKEv2 প্যারামিটার স্পর্শ করে নয়।

আগে লোড করুন, নইলে সংরক্ষণের তুলনা করার কিছু নেই

ম্যানেজার সংরক্ষিত প্রোফাইলের একটি কপি ধরে রাখে, আর আপনি যে অবজেক্ট সম্পাদনা করেন সেটি পড়ার আগ পর্যন্ত সেই কপি নয়। আগে loadFromPreferences কল করুন, তার কমপ্লিশন হ্যান্ডলারের ভিতরে সম্পাদনা করুন, তারপর সংরক্ষণ করুন। পড়াটি বাদ দিলে ফ্রেমওয়ার্ক তার কাছে যা আছে আর আপনি যা লিখছেন তার মধ্যে অসঙ্গতি দেখে। Swift-এ প্রতিটি ধাপের আকৃতি একই, আর প্রতিটি ধাপ তার নিজের ক্লোজারে থাকে:

let mgr = NEVPNManager.shared()
mgr.loadFromPreferences { loadErr in
    guard loadErr == nil else { return }
    let proto = NEVPNProtocolIKEv2()
    proto.serverAddress = "vpn.example.net"
    proto.username = "alice"
    proto.useExtendedAuthentication = true
    mgr.protocolConfiguration = proto
    mgr.isEnabled = true
    mgr.saveToPreferences { saveErr in
        // do not start here; reload, then connect
    }
}

সংরক্ষণের ক্লোজারের ভিতর থেকে টানেল চালু করা একই ভুল অন্য জায়গায়। এটি প্রোফাইল আবার পড়ার আগেই চলে, তাই স্টার্ট কল আপনার গড়া অবস্থাটি দেখে, সংরক্ষিত অবস্থাটি নয়। সংরক্ষণের ক্লোজারটি দ্বিতীয় loadFromPreferences দিয়ে শেষ হয়, আর শুধু সেই কমপ্লিশন হ্যান্ডলারই startVPNTunnel কল করে।

সক্রিয়করণ ফ্ল্যাগ সংরক্ষণেরই অংশ

সংরক্ষিত প্রোফাইল চালু না করা পর্যন্ত নিষ্ক্রিয় থাকে। একই লেখায় isEnabled = true সেট করুন, নইলে প্রোফাইল ডিস্কে নিষ্ক্রিয় অবস্থায় পড়ে এবং সেটিংস একটি সম্পূর্ণ দেখতে কনফিগারেশন দেখালেও startVPNTunnel অস্বীকার করে।

বাহ্যিক সম্পাদনা এর অন্য অর্ধেক। ব্যবহারকারী সেটিংসে কিছু বদলালে, বা ডিভাইস নেটওয়ার্কের মধ্যে সরে গেলে, মেমরিতে ধরে রাখা মানগুলো বিশ্বাস করার আগে আবার পড়ুন। অবজেক্টটি আপনার জন্য সেই পরিবর্তনগুলো লক্ষ করে না। পুরোনো কপিই হলো সেই পথ যেভাবে একটি অ্যাপ এমন প্রোফাইল লেখে যা ব্যবহারকারীর সম্পাদনা নীরবে ফিরিয়ে দেয়। পাশাপাশি দুটি ফিল্ড একই মুহূর্তে নীরব সমস্যা তৈরি করে: on-demand নিয়মগুলো খালি প্লেসহোল্ডার নয়, নিয়ম অবজেক্টের অ্যারে হতে হবে, আর disconnectOnSleep-কে কপি করা ডিফল্ট নয়, আপনি যে আচরণ বেছে নিয়েছেন তা প্রতিফলিত করতে হবে।

তৃতীয় পক্ষের অ্যাপের জন্য কেবল দুটি প্রোটোকল পাওয়া যায়

Network Extension অ্যাপকে IPsec আর IKEv2 দেয়। L2TP আর PPTP সিস্টেমের ভিতরেই থাকে, তাই যে অ্যাপের এগুলো দরকার সে এগুলো পেতে পারে না, আর বাস্তবসম্মত উত্তর হলো IKEv2-সক্ষম গেটওয়ে বা ম্যানেজড কনফিগারেশন প্রোফাইল।

শংসাপত্রও একই ধরন অনুসরণ করে। পাসওয়ার্ড Keychain-এ রাখুন আর স্ট্রিংয়ের বদলে স্থায়ী রেফারেন্স পাঠান। সংরক্ষণের সময় শূন্য রেফারেন্স সাধারণত বোঝায় আইটেমটি লেখার আগেই লুকআপ চলেছিল, ম্যানেজার নষ্ট নয়।

দুটোই কাজের সমাধান নয়, নকশার সিদ্ধান্ত। যে অ্যাপ নিজের পছন্দে পাসওয়ার্ড রাখে সে ফ্রেমওয়ার্কের নিরুৎসাহিত পথ বেছে নেয়, আর তার তৈরি ব্যর্থতা সংরক্ষণের ত্রুটির মতো শোনায়।

কোড আবার লেখার আগে entitlement বাদ দিন

যখন loadFromPreferences একেবারেই কলব্যাক করে না, সম্ভাব্য কারণ হলো অনুপস্থিত Network Extension সামর্থ্য বা এমন প্রভিশনিং প্রোফাইল যা তা বহন করে না। সেই ব্যর্থতা ত্রুটি দেওয়ার বদলে আটকে থাকে, তাই কাজ করা কোড ঘণ্টার পর ঘণ্টা আবার লেখা হয়। আপনি যে সাইন করা বিল্ড পাঠাতে চান তাতে entitlement যাচাই করুন, কারণ সিমুলেটর আর ডিভাইসে চালানো আলাদা হতে পারে আর আসল লক্ষ্য হলো ডিভাইস। লক্ষ্যের সাইনিং সেটিংস খুলে নিশ্চিত করুন Network Extension সামর্থ্যটি ঠিক সেই বিল্ডের জন্য আছে।

যে প্রভিশনিং প্রোফাইলে entitlement নেই তা হার্ডওয়্যারে একইভাবে ব্যর্থ হয়, অথচ একই বিল্ড সিমুলেটরে স্বাভাবিকভাবে লোড হতে পারে। কলের ক্রম আবার লেখার আগে সাইন করা আর্কাইভটি আসল ডিভাইসে পরীক্ষা করুন।

অনুমান নয়, স্ট্যাটাসের পরিবর্তন দেখুন

NEVPNStatusDidChangeNotification লক্ষ্য করুন আর প্রতিটি ধাপের পরে manager.connection.status লগ করুন। যে স্ট্যাটাস কখনো invalid ছাড়ে না তার অর্থ প্রোফাইল সংরক্ষিত হয়নি বা entitlement নেই। যে সংযোগ connecting পর্যন্ত পৌঁছে কখনো সংযুক্ত হয় না তা প্রস্তাব বা শংসাপত্রের দিকে ইশারা করে, আর সেটি ভিন্ন প্রমাণ নিয়ে ভিন্ন তদন্ত।

প্রোফাইলটি সেটিংস, সাধারণ, VPN-এর অধীনে দেখা যায় নিশ্চিত করুন আর প্রতিটি ক্লোজারের ত্রুটি লিখে রাখুন। এই দুটি তথ্য অনুমান ছাড়াই ক্রমের বাগ আর অনুমতির বাগ আলাদা করে।

সম্পর্কিত নিবন্ধ