قد يفشل تطبيق Android في حل اسم داخلي بينما يصل متصفح عميل VPN إليه، ويعمل البناء نفسه على هاتف آخر. ليس الرابط هو المتغير. المتغير هو أي شبكة يُسمح لعملية التطبيق باستخدامها للحل، ولا يضمن Android أن يكون VPN النشط هو الذي تستخدمه مقابسك. نفّذ هذه الفحوص بالترتيب وتوقف عندما تختلف لقطة المحلل عن افتراضك.

الخطوة 1: أثبت على أي شبكة يعمل التطبيق

اقرأ رؤية التطبيق نفسه بدلا من شريط الحالة. من ConnectivityManager احصل على الشبكة النشطة وخصائصها LinkProperties، وقائمة خوادم DNS وإعداد DNS الخاص. إذا كانت القائمة تحتوي على محلل VPN، فللتطبيق مسار إليه؛ وإذا كانت تحتوي على محلل Wi-Fi، فإن النفق ليس الشبكة الافتراضية لتلك العملية.

أيقونة VPN تقول فقط إن نفقا موجود. وهي لا تقول إن عملية التطبيق رُبطت به، ولا يوجّه Android حل الأسماء دائما عبر الشبكة التي تبدو نشطة. تطبيقات VPN المحلية التي تمرر إلى جهاز آخر وشبكات Wi-Fi بلا إنترنت وبنيات المصنّعين يمكن أن تترك التطبيق يسأل المحلل الافتراضي بدلا من خوادم النفق.

الخطوة 2: اطلب نقل VPN واربط العملية

عندما يجب أن يستخدم التطبيق محلل النفق، اطلب شبكة بنقل VPN واربط العملية في الرد، حتى لا يخمّن الكود وقت ظهور الشبكة:

val request = NetworkRequest.Builder()
    .addTransportType(NetworkCapabilities.TRANSPORT_VPN)
    .build()

connectivityManager.requestNetwork(request, object : NetworkCallback() {
    override fun onAvailable(network: Network) {
        val bound = connectivityManager.bindProcessToNetwork(network)
        Log.i(TAG, "bound to VPN network: " + bound)
    }
})

يغيّر الاستدعاء الشبكة الافتراضية على مستوى العملية، فتصبح كل المقابس التي تُنشأ بعده تستخدمها. أما المقابس الموجودة بالفعل فتحتفظ بالشبكة التي أُنشئت عليها، ولهذا قد يواصل تجمّع اتصالات فُتح قبل الربط الحل عبر المسار القديم. القيمة المعادة منطقية، والنتيجة الخاطئة تعني أن الربط لم يحدث؛ أعد المحاولة بعد تأخير قصير وسجّل المحاولتين.

الخطوة 3: احصر الربط في ما يحتاجه

الربط على مستوى العملية فظ. فالقياسات عن بعد وفحوص التحديث وحزم SDK الخارجية تنتقل أيضا إلى النفق، وإذا لم يكن للنفق إنترنت بدأت تفشل. لطلب واحد استخدم مصنع مقابس الشبكة وأبقِ افتراضي الجهاز لكل ما عداه. اختر نموذجا واحدا عن قصد: ربط ضيق لكل اتصال، أو ربط للعملية مع فك ربط صريح عند اختفاء VPN.

يمكن لميزتين في المحلل أن تبطل الربط دون أي خطأ. فـ DNS الخاص في الوضع الصارم يرسل الاستعلامات إلى خادم DoT مسمّى بدلا من محلل الشبكة، والتطبيق الذي يحمل عميل DNS-over-HTTPS خاصا به يتجاوز محلل النظام كليا. افحص الاثنين قبل أن تستنتج أن الربط فشل. الاستعلام الذي لا يصل أبدا إلى خادم DNS الخاص بـ VPN لن يظهر في أي سجل من جهة النفق.

الخطوة 4: لا تثق بقيد CONNECTED

قيد NetworkType.CONNECTEDفي WorkManager يعني أن شبكة متصلة، ونقل VPN يحققه حتى عندما تكون وصلة Wi-Fi أو الشبكة الخلوية تحته مفقودة. يعمل الوظيفة، ويفشل كل طلب، وتحوّله سياسة الإعادة إلى عاصفة تشبه خللا في الجدولة. النفق شبكة؛ ولم يكن القيد يوما فحصا للإنترنت.

افحص القدرة التي تحتاجها المهمة فعلا، مثل وصول إنترنت مُتحقَّق منه، واحتفظ بسياسة إعادة محدودة مع تراجع. وإذا كانت المهمة تحتاج اسما داخليا فاحل ذلك الاسم في الشبكة المختارة قبل تنفيذ العمل، وافشل بسرعة بخطأ واضح بدلا من إعادة طلب لا يمكن أن ينجح.

الخطوة 5: سجّل الأدلة وأعد اختبار النطاق

سجّل أنواع نقل الشبكة المختارة، وخوادم DNS من LinkProperties، وما إذا كان الربط أعاد true، والخطأ الدقيق للطلب الأول. ثم شغّل اسما داخليا واسما عاما تحت الربط نفسه. يبيّن هذا الزوج هل استخدم التطبيق محلل النفق أم ارتد بصمت إلى افتراضي الجهاز، وهو الفرق الذي يختبره المستخدم.

كرّر على أقدم إصدار Android تدعمه وعلى إصدار حالي واحد. سلوك المحلل الذي يجعل المسار الافتراضي يبدو صحيحا هو بالضبط ما تختلف فيه الأجهزة والإصدارات، والبناء الذي ينجح فقط على أحدث جهاز اختبار لم يُتحقق منه للنطاق الذي تشحنه. adb shell dumpsys connectivityطريقة سريعة لتأكيد الشبكات والقدرات التي يبلّغ عنها الجهاز أثناء إعادة إنتاج الخلل.

مقالات ذات صلة