الخلاصة

  • أعطى RFC 768 الصفر في حقل checksum الخاص بـUDP معنيين مختلفين: تُرسل النتيجة الحسابية الصفرية على هيئة 0xFFFF، بينما تعني 0x0000 أن المرسل لم يُنشئ checksum.
  • أبقت متطلبات المضيفين لعام 1989 إمكان الإغفال، لكنها جعلت الحساب مفعلاً افتراضياً. ثم أوجب IPv6 checksum، قبل أن يسمح تحديث عام 2013 بحالة نفق ضيقة الشروط.

صفران في حقل واحد

في أغسطس 1980، عرّف RFC 768، الذي كتبه جون بوستل، بروتوكول User Datagram Protocol لتبادل تطبيقات الشبكة مخططات بيانات بأقل قدر من الآليات. لم يضمن UDP ترتيب التسليم أو منع التكرار أو موثوقية التسليم. وكان رأسه ثمانية ثمانيات فقط: منفذ المصدر، ومنفذ الوجهة، والطول، وchecksum، ثم البيانات.

يبدو الحقل الأخير بسيطاً إلى أن تفرض عليه الحسابات حالة خاصة. يستخدم UDP checksum من 16 بتاً بمتمم الواحد، وهو الأسلوب المستخدم أيضاً في TCP. يشمل الحساب رأس UDP وبياناته، إضافة إلى رأس زائف يضم عنواني IP للمصدر والوجهة، ورقم البروتوكول، وطول UDP. وقال بوستل إن هذا الرأس الزائف يساعد على الحماية من توجيه مخطط البيانات إلى غير وجهته.

في حساب متمم الواحد، للصفر تمثيلان بتّيّان: جميع البتات صفراً، وجميعها واحداً. خصص RFC 768 لكل منهما وظيفة مختلفة على السلك. إذا أعطى الحساب صفراً، وجب على المرسل إرسال جميع البتات واحداً. أما إذا كان الحقل المرسل كله صفراً، فهذا يعني أن المرسل لم ينشئ checksum. وهكذا حمل التنسيق نتيجة الحساب وإشارة حالة صغيرة من دون إضافة بت علم.

هذه هي النقطة التاريخية المحددة هنا. لم يكن «checksum UDP صفراً» checksum محسوباً نتيجته صفر؛ بل كان ترميزاً للغياب. وقد يؤدي الخلط بين الحالتين إلى رفض مخطط بيانات صالح، أو إلى اعتبار غياب كشف الأخطاء كأنه تحقق ناجح.

الإتاحة لم تجعلها القيمة الافتراضية

سمحت المواصفة الأصلية بإغفال checksum لأغراض مثل التصحيح أو حين لا يهتم بروتوكول أعلى به. وبعد تسع سنوات، أوضح RFC 1122، الخاص بمتطلبات مضيفي الإنترنت، القاعدة التشغيلية. يجب على المضيف تنفيذ إنشاء checksum والتحقق منه؛ ويمكن للتطبيق التحكم في إنشائه، لكن يجب أن يكون مفعلاً افتراضياً. كما يمكن للمستقبل اختيار ما إذا كان سيمرر مخططات البيانات غير المزوّدة بـchecksum إلى التطبيق.

وأشار RFC 1122 أيضاً إلى خطأ شائع في التنفيذ: إذا كانت النتيجة المحسوبة صفراً، فتُرسل كـ65535؛ أما الحقل الصفري بالكامل فيعني «غير موجود». وذكر أن بعض التطبيقات المستخدمة فقط في الشبكات المحلية عطّلت checksums سعياً إلى الكفاءة، وأن أخطاء كثيرة لم تُكتشف. لكنه لم يقدم أعداداً أو حوادث مسماة أو مقاماً إحصائياً. لذلك فهذا دليل على قلق سجله واضعو المعايير، لا قياس لمدى انتشار الممارسة.

لم يكن checksum توقيعاً قط. يمكن للرأس الزائف كشف بعض حالات سوء التسليم، ويمكن للحساب كشف بعض التلف العرضي. لكنه لا يوثق هوية المرسل، ولا يمنع التعديل المتعمد، ولا يثبت سلامة معنى بيانات التطبيق. «وجود checksum» و«موثوقية الحزمة» ادعاءان مختلفان.

ضيّق IPv6 هذا الحد

أوجب معيار IPv6 لعام 1998، RFC 2460، استخدام UDP checksum. وإذا أعطى الحساب صفراً، فيجب كتابته أيضاً على هيئة 0xFFFF؛ وعلى المستقبل إسقاط مخطط بيانات UDP عبر IPv6 إذا كان حقل checksum صفراً. وبذلك لم يعد مؤشر الإغفال الاختياري مقبولاً في حركة UDP العادية عبر IPv6.

ثم ظهرت حالة أداء محددة. ففي 2013، حدّث RFC 6935 وRFC 6936 معالجة IPv6 لبعض أنفاق UDP. فقد تحمل الأنفاق حزمًا لها بالفعل وسائل تحقق من سلامتها، وقد تفرض كلفة حساب checksum خارجي عبئاً إضافياً. ويتوقف الاستثناء على شروط الانطباق وسلوك الطرفين وتوافق الأجهزة الوسيطة؛ ولم يحوّل الصفر إلى خيار عام في IPv6.

يوضح تسلسل المعايير أن نمط البتات بقي كما هو، لكن السياق المسموح به تغيّر. ففي IPv4، أمكن للصفر أن يدل على الغياب، مع جعل الحساب القيمة الافتراضية في متطلبات المضيفين. وفي IPv6، رُفض الغياب أولاً، ثم أعيد بشروط لاستخدام محدد في رأس النفق الخارجي. لم تكن القيمة وحدها كافية للمستقبل ليعرف إن كان الإغفال مقبولاً؛ بل لزم معرفة إصدار IP وسياق الاستخدام.

المصادر