الخلاصة

  • ألزم RFC 2066 المتلقي بإرسال ACCEPTED حتى إذا كان يستخدم بالفعل مجموعة محارف واردة في الطلب؛ لم يعد الصمت احتمالًا صالحًا للنجاح.
  • لم تُحلّ مصادفة طلبي CHARSET REQUEST متماثلين على نحو متماثل: كان على الخادم رفض طلب العميل، وعلى العميل الرد على طلب الخادم.
  • أثبت الرد وصول الطلب وحدد ترميز النص اللاحق، لكنه لم يثبت صحة البايتات أو الترجمة أو استخدام التطبيق أو المصادقة أو أمان الجلسة.

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

رفض RFC 2066 أن يجعل هذا الالتباس جزءًا من حالة البروتوكول. نُشر في يناير 1997 بوصفه RFC تجريبيًا، وعرّف خيار Telnet رقم 42، أي CHARSET، كي يتمكن العميل والخادم من تسمية ترميز النص، ومن تبادل جداول ترجمة اختياريًا. ولم يكن أهم ما فيه قائمة الترميزات، بل القرار بأن انتقال مجموعة المحارف يحتاج إلى إيصال.

كانت قاعدة منع الدوامة منطقية، لكنها لم تكفِ هنا

بُني تفاوض خيارات Telnet المعتاد على DO وDON'T وWILL وWON'T. جعل RFC 854 الصياغة متماثلة، واعتبر طلبين متزامنين إقرارين إيجابيين متبادلين. لكنه حذّر أيضًا من أن التماثل قد يولّد سلسلة إقرارات لا تنتهي. فلا ينبغي لطرف أن يجيب عن طلب ظاهري لوضع نافذ أصلًا، بينما يجب أن يتلقى طلب تغيير حقيقي جوابًا.

ووضع RFC 855 تبادل المعاملات بعد ذلك الاتفاق الأول. يتفق الطرفان أولًا على مناقشة الخيار، ثم يحمل التفاوض الفرعي المعاملات بين IAC SB وIAC SE. كانت الطبقتان تجيبان عن سؤالين مختلفين: سمحت DO CHARSET وWILL CHARSET بالتفاوض، لكنهما لم تحددا بعد كيف ينبغي تفسير بايت النص التالي.

لذلك لم يسمح RFC 2066 بنقل قاعدة الصمت إلى طلب مجموعة المحارف. إذا كان المتلقي يرسل ويتوقع بالفعل مجموعة واردة في REQUEST الجديد، وجب عليه مع ذلك إرسال ACCEPTED، ولم يجز له تجاهل الطلب. وذكر RFC العلة: الحسم. لا ينبغي للطالب أن ينتظر حتى تنتهي مهلة ثم يستنتج جوابًا. ولأن ACCEPTED نفسه لا يتلقى إقرارًا، لم يؤدّ الرد الصريح إلى إعادة تشغيل الدوامة.

القائمة المرتبة عرض وليست إعلانًا

لا يستطيع إرسال CHARSET REQUEST إلا طرف تلقى DO CHARSET وأرسل WILL CHARSET، بأي ترتيب. يسرد الطلب اسمًا واحدًا أو أكثر بحسب الأفضلية عادة. وكان على الأسماء أن تكون مسجلة لدى IANA ما لم تبدأ بالبادئة الخاصة X-. أما المتلقي فاحتفظ بحرية اختيار ما يدعمه وفق تفضيلاته.

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

أنهت كل من ACCEPTED وREJECTED التفاوض الفرعي الجاري. غيّر الأول التزام ترميز النص اللاحق، بينما أبقى الثاني الترميزات المقترحة خارج النفاذ. ولم يصف أي منهما كامل قدرة البرنامج أو يمنع عرضًا لاحقًا.

احتاج الطلبان المتزامنان إلى طرف يتنازل أولًا

ظهرت الحالة الأصعب حين أرسل الطرفان المؤهلان CHARSET REQUEST قبل أن يصل طلب الآخر. فالطلب الجديد ليس جوابًا صالحًا عن طلب معلّق. ومن دون قاعدة إضافية، كان كل طرف يستطيع انتظار رد نهائي على عرضه بينما يحتفظ بطلب نظيره بلا جواب.

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

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

وضع الرد حدًا داخل مجرى البايتات

بعد ACCEPTED، كان على كل طرف ترميز النص اللاحق بالمجموعة المختارة. وأثناء التفاوض الفرعي، ينبغي وضع البيانات في طابور وعدم إطلاقها حتى تنتهي المفاوضة. لذلك كان الإقرار أيضًا علامة ترتيب تفصل البايتات الخاضعة للفهم القديم عن البايتات الخاضعة للفهم الجديد.

ظل النطاق محدودًا. طُبقت الترجمة على النص لا على أوامر Telnet، وفقط عندما يكون وضع BINARY فعالًا. وبدون BINARY بقيت البيانات وفق NVT ASCII. وفي المحطات الطرفية ذات نمط الكتل، أوصى RFC بخيار End of Record كي تظل حدود السجلات قابلة للتحديد. لم يُلغِ اختيار مجموعة محارف بقية عقد Telnet.

وكان لجداول الترجمة إيصالاتها الخاصة. أكد TTABLE-ACK الوصول وفعّل الترميز المرسوم، وطلب TTABLE-NAK إعادة الإرسال. لكن الفشل المتكرر كان ينبغي أن ينتهي بـTTABLE-REJECTED أو CHARSET REJECTED بدل تبادل لا محدود لرسائل عقيمة. هنا أيضًا فضّل التصميم حالة نهائية قابلة للملاحظة على نفاد الصبر.

كان الإيصال مفيدًا لأن ادعاءه صغير

يثبت تسجيل ACCEPTED ادعاءً تاريخيًا محددًا: تلقى النظير طلبًا معينًا واختار اسم مجموعة من قائمته للنص اللاحق. لكنه لا يثبت أن البايتات التالية مطابقة، أو أن جدول الترجمة صحيح، أو أن التطبيق فهم النص، أو أن المستخدم أتم مهمة. ويثبت REJECTED الوصول ورفض تلك القائمة في تلك الجولة، لا عجزًا دائمًا.

ولم يمنح الخيار أي غطاء أمني. تقول فقرة Security Considerations في RFC 2066 إن المسائل الأمنية غير مناقشة. لا يؤدي تفاوض الترميز إلى توثيق هوية الطرفين أو تفويض تطبيق أو تشفير الجلسة أو حماية سلامة النص. يمكن أن يكون انتقال الحالة حاسمًا فيما تظل القناة التي تحمله غير آمنة.

ولا يثبت سجل النشر مقدار التبني. ما زال سجل IANA الحالي يعرّف الرقم 42 باسم CHARSET، وما زال RFC 2066 مصنفًا تجريبيًا. يوثّق هذان الأمران المواصفة والتخصيص، ولا يعدّان التطبيقات أو يثبتان التشغيل البيني. وإذا قُرئت الآلية في ضوء إطار Lu Heng اللاحق حول «المواصفة الأولية الدنيا»، فهي مثال صغير على طبقة مشتركة لا تفعل إلا ما لا بد من مشاركته: أهلية الطلب، والردود النهائية، وحد البايتات، وقاعدة تصادم يطبقها كل طرف محليًا. هذه مقارنة تحريرية وليست دليلًا على قصد مؤلف RFC. أما الدرس التاريخي الأوثق فهو أبسط: عندما يحتمل الصمت أكثر من معنى، تبدأ قابلية التشغيل البيني بجعل الإيصال المفقود صريحًا.

المصادر