أحد طرفَي نفق IPv6 يرسل ping إلى الآخر، ولا يستجيب إلا اتجاه واحد. الواجهة قائمة، والمسار يبدو صحيحًا، ولا شيء في السجل يفسّر ذلك. العنوان الذي عيّنته هو عنوان anycast لموجّه الشبكة الفرعية، وهو ليس عنوان مضيف على الإطلاق، وعلى وصلة ذات طرفين له هدف تسليم واحد فقط: المرسِل. لا تُصلح أي قيمة للمهلة ذلك، لأن العنوان لا يفعل ما تظنه يفعل.

العَرَض الذي يشير إلى العنوان

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

المعرّف الصفري بالكامل محجوز كـ anycast

يحتفظ RFC 4291 بالمعرّف الصفري بالكامل كعنوان anycast لموجّه الشبكة الفرعية، لذا فإن /64 مثل 2001:db8:4a::/64 لا يحتوي على أي مضيف صالح عند 2001:db8:4a::. ويستحق هذا الحجز مكانه: إعلانات الموجّه واكتشاف الجيران تخاطب ذلك الشكل، والموجّه يستجيب للبادئة التي يخدمها. وإن تعيين تلك القيمة على طرف نفق يمنح دور موجّه لورقة، ولهذا لا يعود شيء. أي معرّف آخر في البادئة يعمل كمضيف، لذا فإن الإصلاح عادةً رقم واحد.

تعامل مع الحجز كدور لا يحق لك شغله من طرف نفق، لا كخصوصية يمكن الالتفاف حولها بالتوجيه.

عيّن عناوين المضيفين ووجّه البادئة

اختر ::1 و ::2 للطرفين، وأضف أحدهما بالأمر ip -6 addr add 2001:db8:4a::2/64 dev tun0، ثم وجّه البادئة البعيدة بدلًا من محاولة عنونتها. فالمسار إلى 2001:db8:4a::/64 عبر النفق يجعل الطرف البعيد قابلًا للوصول؛ أما العنوان وحده فلا يجعل سوى الواجهة المحلية مهيّأة.

في النفق الكامل هناك خطوة ثالثة، وهي مسار افتراضي لـ unicast العام عبر الجهاز، وهو المكافئ في IPv6 لإرسال كل شيء إلى النفق. وإن أغفلتها بقي IPv6 يستخدم الوصلة الفيزيائية بينما ينتقل IPv4 داخل النفق، فيسرّب المضيف تحديدًا الحركة التي كنت تظنها مغطاة. أكّد بالأمر ip -6 route get 2001:4860:4860::8888 واقرأ اسم الجهاز الذي يذكره بدلًا من افتراض الجواب.

يُرفض multicast قبل التوجيه

يتحقق Android من العناوين والمسارات الخاصة بـ VpnService.Builder عبر LinkAddress، ويرفض ذلك المُنشئ multicast رفضًا قاطعًا. أعطه بادئة multicast كمسار فيكون الناتج فشل معاملات LinkAddress غير الصالحة بدلًا من مسار، وهو جواب تحقّق لا جواب شبكة. والرفض يطابق الوسط: جهاز tun لنقطة بنقطة لا يملك multicast على طبقة الوصلة، لذا فمسار جماعي عليه لا يملك نموذج تسليم يمكن تثبيته. وعناوين المجموعات ينشئها المكدّس نفسه ويستهلكها بدلًا من تهيئتها يدويًا.

عناوين IPv6 all-nodes و solicited-node تخضع للقاعدة نفسها. الواجهة تحملها لأن المكدّس وضعها هناك، لا لأن سياسة قصدتها.

ما الذي يمكن للنفق أن يحمله بدلًا من ذلك

نقل اكتشاف multicast عبر نفق يحتاج طبقة تفهم عضوية المجموعة: جسر TAP يعرض مقطع Ethernet، أو مرحّل بمستوى التطبيق، أو بروتوكول توجيه يُقال له صراحةً إلى أي أقران ينسخ. لا شيء من ذلك موجود في نموذج VpnService، حيث يقرأ التطبيق الحزم ويكتبها وليس لديه نداء ينضم إلى مجموعة من أجل النفق. فإما أن تضيف المكوّن الذي يفهم المجموعات أو تُسقط الشرط من التصميم.

أما unicast، في المقابل، فلا يحتاج شيئًا إضافيًا يتجاوز العناوين والمسارات أعلاه، ولهذا يُتوقع عادةً من الأنفاق أن تحمله ثم تُلام عندما يفشل بروتوكول اكتشاف.

ثلاثة فحوص قبل أن تعيّن أي شيء

تأكد أن العنوان ليس صيغة anycast، وتأكد أنه ليس multicast، وتأكد أن البادئة موجّهة لا مجرّد معيّنة على الجهاز. ثم أرسل اختبارك إلى وجهة مضيف حقيقي، لأن ping الموجّه إلى عنوان anycast يقيس المرسِل ولا يقول شيئًا عن المسار. واحفظ هذه الفحوص الثلاثة في سجل التغييرات كي لا يعيد النشر التالي اكتشافها.

المسار الذي لم يثبّته النظام لا يمكن تصحيحه بالانتظار أطول، والعنوان الذي لم يكن مضيفًا قط لا يمكن إصلاحه بـ ping أفضل.

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