نظرة عامة
هذه هي المواصفات لبروتوكول مزرعة الثوم للسلك، بناءً على JRaft، كود “exts” الخاص به للتنفيذ عبر الـTCP، وتطبيق العينة “dmprinter” JRAFT. JRaft هو تنفيذ لبروتوكول Raft RAFT.
لم نتمكن من العثور على أي تنفيذ يحتوي على بروتوكول سلك موثق. ومع ذلك، فإن تنفيذ JRaft بسيط بما فيه الكفاية لدرجة يمكننا من خلالها فحص الكود ثم توثيق بروتوكوله. هذا الاقتراح هو نتيجة لهذا الجهد.
سيكون هذا هو الجانب الخلفي لتنسيق نشر أجهزة التوجيه لإدخالات في مجموعة Meta LeaseSet. انظر الاقتراح 123.
الأهداف
- حجم كود صغير
- قائم على التنفيذ الحالي
- لا يحتوي على كائنات جافا مسلسلة أو أي ميزات أو ترميز خاص بجافا
- أي بدء تشغيل خارجي عن النطاق. يفترض أن يكون هناك على الأقل خادم آخر مشفّراً، أو مكون بشكل غير مدرج في هذا البروتوكول.
- دعم حالات الاستخدام خارج النطاق وداخل I2P.
التصميم
بروتوكول Raft ليس بروتوكولًا ملموسًا؛ إنما يحدد فقط آلة حالات. لذلك نوثق بروتوكول JRaft الملموس ونعتمد بروتوكولنا عليه. لا توجد تغييرات على بروتوكول JRaft غير إضافة عملية مصافحة للمصادقة.
يختار Raft قائدًا تكون مهمته نشر سجل. يحتوي السجل على بيانات تكوين Raft وبيانات التطبيق. تحتوي بيانات التطبيق على حالة جهاز التوجيه الخاص بكل خادم والوجهة لمجموعة Meta LS2. تستخدم الخوادم خوارزمية شائعة لتحديد الناشر والمحتويات لـ Meta LS2. ليس بالضرورة أن يكون ناشر Meta LS2 هو قائد Raft.
المواصفات
البروتوكول السلكي يكون عبر مقابس SSL أو مقابس I2P غير SSL. تمرّ مقابس I2P عبر وكيل HTTP. لا يوجد دعم لمقابس غير SSL على شبكة الإنترنت العادية.
المصافحة والمصادقة
غير معرف بواسطة JRaft.
الأهداف:
- طريقة مصادقة اسم المستخدم/كلمة المرور
- معرف النسخة
- معرف الكتلة
- قابلية الامتداد
- سهولة التوسيط عند الاستخدام لمقابس I2P
- عدم الكشف عن الخادم كخادم لمزرعة الثوم بدون ضرورة
- بروتوكول بسيط بحيث لا يتطلب تنفيذ خادم ويب كامل
- متوافق مع المعايير الشائعة، لذا يمكن للتنفيذ استخدام المكتبات القياسية إذا رغب
سنستخدم مصافحة شبيهة بالويب سوكيت WEBSOCKET والمصادقة الهضمية HTTP RFC-2617. المصادقة الأساسية لـ RFC 2617 غير مدعومة. عند التوسيط عبر وكيل HTTP، تواصل مع الوكيل كما هو محدد في RFC-2616.
البيانات الاعتمادية
سواءً كانت أسماء المستخدمين وكلمات المرور لكل كتلة أو لكل خادم يعتمد على التنفيذ.
طلب HTTP 1
سيرسل المنشئ ما يلي.
جميع السطور تنتهي بـCRLF كما هو مطلوب بواسطة HTTP.
GET /GarlicFarm/CLUSTER/VERSION/websocket HTTP/1.1
Host: (ip):(port)
Cache-Control: no-cache
Connection: close
(أي رؤوس أخرى متجاهلة)
(سطرا فارغا)
CLUSTER هو اسم الكتلة (افتراضي "farm")
VERSION هو إصدار مزرعة الثوم (حاليًا "1")
استجابة HTTP 1
إذا كان المسار غير صحيح، سيرسل المستلم استجابة “HTTP/1.1 404 Not Found” كما هو في RFC-2616.
إذا كان المسار صحيحًا، سيرسل المستلم استجابة “HTTP/1.1 401 Unauthorized” القياسية، متضمنة رأس المصادقة الهضمي HTTP WWW-Authenticate، كما هو في RFC-2617.
سيغلق كلا الطرفين المقبس بعد ذلك.
طلب HTTP 2
سيرسل المنشئ ما يلي، كما في RFC-2617 وWEBSOCKET.
جميع السطور تنتهي بـCRLF كما هو مطلوب بواسطة HTTP.
GET /GarlicFarm/CLUSTER/VERSION/websocket HTTP/1.1
Host: (ip):(port)
Cache-Control: no-cache
Connection: keep-alive, Upgrade
Upgrade: websocket
(رؤوس Sec-Websocket-* إذا كان عبر الوكيل)
Authorization: (رأس الترخيص الهضمي HTTP كما في RFC 2617)
(أي رؤوس أخرى متجاهلة)
(سطرا فارغا)
CLUSTER هو اسم الكتلة (افتراضي "farm")
VERSION هو إصدار مزرعة الثوم (حاليًا "1")
استجابة HTTP 2
إذا كانت المصادقة غير صحيحة، سيرسل المستلم استجابة “HTTP/1.1 401 Unauthorized” القياسية الأخرى، كما هو في RFC-2617.
إذا كانت المصادقة صحيحة، سيرسل المستلم الاستجابة التالية، كما هو في WEBSOCKET.
جميع السطور تنتهي بـCRLF كما هو مطلوب بواسطة HTTP.
HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: websocket
(رؤوس Sec-Websocket-*)
(أي رؤوس أخرى متجاهلة)
(سطرا فارغا)
عند استقبال هذا، يظل المقبس مفتوحًا. يبدأ بروتوكول Raft كما هو معرف أدناه، على نفس المقبس.
التخزين المؤقت
يجب تخزين المصدقات لمدة لا تقل عن ساعة واحدة، بحيث يمكن للاتصالات اللاحقة الانتقال مباشرة إلى “طلب HTTP 2” أعلاه.
أنواع الرسائل
هناك نوعان من الرسائل، الطلبات والاستجابات. قد تحتوي الطلبات على إدخالات السجل، وتكون متغيرة الحجم؛ لا تحتوي الاستجابات على إدخالات السجل، وهي ثابتة الحجم.
الأنواع الرسائلية 1-4 هي رسائل النداء البعيد القياسية المعرفة بواسطة Raft. هذا هو بروتوكول Raft الأساسي.
الأنواع الرسائلية 5-15 هي رسائل النداء البعيد الممتدة المعرفة بواسطة JRaft، لدعم العملاء، التغييرات الديناميكية للخادم، والتزامن الفعال للسجل.
الأنواع الرسائلية 16-17 هي رسائل ضغط السجل المعرفة في قسم 7 من Raft.
| الرسالة | الرقم | المُرسل | المُستلم | الملاحظات |
|---|---|---|---|---|
| RequestVoteRequest | 1 | المرشح | التابع | نداء بعيد Raft قياسي؛ لا يجب أن يحتوي على إدخالات السجل |
| RequestVoteResponse | 2 | التابع | المرشح | نداء بعيد Raft قياسي |
| AppendEntriesRequest | 3 | القائد | التابع | نداء بعيد Raft قياسي |
| AppendEntriesResponse | 4 | التابع | القائد / العميل | نداء بعيد Raft قياسي |
| ClientRequest | 5 | العميل | القائد / التابع | الاستجابة هي AppendEntriesResponse؛ يجب أن يحتوي فقط على إدخالات سجل التطبيق |
| AddServerRequest | 6 | العميل | القائد | يجب أن يحتوي على إدخال سجل ClusterServer واحد فقط |
| AddServerResponse | 7 | القائد | العميل | سيرسل القائد أيضًا JoinClusterRequest |
| RemoveServerRequest | 8 | التابع | القائد | يجب أن يحتوي على إدخال سجل ClusterServer واحد فقط |
| RemoveServerResponse | 9 | القائد | التابع | |
| SyncLogRequest | 10 | القائد | التابع | يجب أن يحتوي على إدخال سجل LogPack واحد فقط |
| SyncLogResponse | 11 | التابع | القائد | |
| JoinClusterRequest | 12 | القائد | الخادم الجديد | دعوة للانضمام؛ يجب أن يحتوي على إدخال Configuration واحد فقط |
| JoinClusterResponse | 13 | الخادم الجديد | القائد | |
| LeaveClusterRequest | 14 | القائد | التابع | أمر للمغادرة |
| LeaveClusterResponse | 15 | التابع | القائد | |
| InstallSnapshotRequest | 16 | القائد | التابع | قسم 7 من Raft؛ يجب أن يحتوي على إدخال سجل SnapshotSyncRequest واحد فقط |
| InstallSnapshotResponse | 17 | التابع | القائد | قسم 7 من Raft |
التأسيس
بعد المصافحة HTTP، تسلسل التأسيس كالتالي:
خادم جديد أليس تابع عشوائي بوب
طلب العميل ------->
<--------- استجابة إدخال الإدخالات
إذا قال بوب إنه القائد، تابع كما هو موضح أدناه.
وإلا، يجب على أليس قطع الاتصال بوب والاتصال بالقائد.
خادم جديد أليس القائد تشارلي
طلب العميل ------->
<--------- استجابة إدخال الإدخالات
طلب إضافة الخادم ------->
<--------- استجابة إضافة الخادم
<--------- طلب الانضمام للكتلة
استجابة الانضمام للكتلة ------->
<--------- طلب تزامن السجل
أو طلب تثبيت اللقطة
استجابة تزامن السجل ------->
أو استجابة تثبيت اللقطة
تسلسل الفصل:
تابع أليس القائد تشارلي
طلب إزالة الخادم ------->
<--------- استجابة إزالة الخادم
<--------- طلب مغادرة الكتلة
استجابة مغادرة الكتلة ------->
تسلسل الانتخابات:
مرشح أليس تابع بوب
طلب تصويت ------->
<--------- استجابة طلب تصويت
إذا فازت أليس بالانتخابات:
قائد أليس تابع بوب
طلب إدخال الإدخالات ------->
(نبضة حتى)
<--------- استجابة إدخال الإدخالات
التعريفات
- المصدر: يحدد منشئ الرسالة
- الوجهة: يحدد مستلم الرسالة
- المصطلحات: راجع Raft. تم تهيئته إلى 0، ويزداد بشكل تصاعدي
- الفهارس: راجع Raft. تم تهيئته إلى 0، ويزداد بشكل تصاعدي
الطلبات
تطلب الطلبات تحتوي على رأس وصفر أو أكثر من إدخالات السجل. تطلب الطلبات تحتوي على رأس ثابت الحجم وإدخالات السجل الاختيارية ذات الحجم المتغير.
رأس الطلب
رأس الطلب هو 45 بايت، كما يلي. جميع القيم غير موقعة وبالترتيب البايت الكبير.
نوع الرسالة: 1 بايت
المصدر: المعرف، عدد يبلغ 4 بايت
الوجهة: المعرف، عدد يبلغ 4 بايت
المصطلح: المصطلح الحالي (انظر الملاحظات)، عدد يبلغ 8 بايت
المصطلح الأخير في السجل: عدد يبلغ 8 بايت
الفهرس الأخير في السجل: عدد يبلغ 8 بايت
فهرس الالتزام: عدد يبلغ 8 بايت
حجم إدخالات السجل: الحجم الكلي بالبايتات، عدد يبلغ 4 بايت
إدخالات السجل: انظر أدناه، الطول الكلي كما هو محدد
الملاحظات
في طلب التصويت، المصطلح هو مصطلح المرشح. فيما عدا ذلك، هو المصطلح الحالي للقائد.
في طلب إدخال الإدخالات، عندما يكون حجم إدخالات السجل صفراً، تكون هذه الرسالة نبضة (حفاظ) للعيش.
إدخالات السجل
السجل يحتوي على صفر أو أكثر من إدخالات السجل. كل إدخال سجل هو كما يلي. جميع القيم غير موقعة وبالترتيب البايت الكبير.
المصطلح: عدد يبلغ 8 بايت
نوع القيمة: 1 بايت
حجم الإدخال: بالبايتات، عدد يبلغ 4 بايت
الإدخال: الطول كما هو محدد
محتويات السجل
جميع القيم غير موقعة وبالترتيب البايت الكبير.
| نوع قيمة السجل | الرقم |
|---|---|
| التطبيق | 1 |
| التكوين | 2 |
| خادم الكتلة | 3 |
| حزمة السجل | 4 |
| طلب تزامن اللقطة | 5 |
التطبيق
محتويات التطبيق تم ترميزها بـ UTF-8 JSON. راجع قسم الطبقة التطبيقية أدناه.
التكوين
يستخدم هذا لتسلسل القائد تكوين مجموعة جديد ونشرها إلى الأقران. يحتوي على صفر أو أكثر من تكوينات خادم الكتلة.
فهرس السجل: عدد يبلغ 8 بايت
الفهرس الأخير في السجل: عدد يبلغ 8 بايت
بيانات خادم الكتلة لكل خادم:
المعرف: عدد يبلغ 4 بايت
طول بيانات الفائدة: بالبايتات، عدد يبلغ 4 بايت
بيانات الفائدة: سلسلة ASCII من الشكل "tcp://localhost:9001"، الطول كما هو محدد
خادم الكتلة
معلومات التكوين لخادم في الكتلة. يتم تضمين هذه فقط في رسالة طلب إضافة الخادم أو طلب إزالة الخادم.
عند استخدامها في رسالة طلب إضافة الخادم:
المعرف: عدد يبلغ 4 بايت
طول بيانات الفائدة: بالبايتات، عدد يبلغ 4 بايت
بيانات الفائدة: سلسلة ASCII من الشكل "tcp://localhost:9001"، الطول كما هو محدد
عند استخدامها في رسالة طلب إزالة الخادم:
المعرف: عدد يبلغ 4 بايت
حزمة السجل
يتم تضمين هذا فقط في رسالة طلب تزامن السجل.
ما يلي يتم ضغطه قبل الإرسال:
طول بيانات الفهرس: بالبايتات، عدد يبلغ 4 بايت
طول بيانات السجل: بالبايتات، عدد يبلغ 4 بايت
بيانات الفهرس: 8 بايت لكل فهرس، الطول كما هو محدد
بيانات السجل: الطول كما هو محدد
طلب تزامن اللقطة
يتم تضمين هذا فقط في رسالة طلب تثبيت اللقطة.
الفهرس الأخير في السجل: عدد يبلغ 8 بايت
المصطلح الأخير في السجل: عدد يبلغ 8 بايت
طول بيانات التكوين: بالبايتات، عدد يبلغ 4 بايت
بيانات التكوين: الطول كما هو محدد
الإزاحة: إزاحة البيانات في قاعدة البيانات، بالبايتات، عدد يبلغ 8 بايت
طول البيانات: بالبايتات، عدد يبلغ 4 بايت
البيانات: الطول كما هو محدد
هل انتهى: 1 إذا انتهى، 0 إذا لم ينته (1 بايت)
الاستجابات
جميع الاستجابات 26 بايت، كما يلي. جميع القيم غير موقعة وبالترتيب البايت الكبير.
نوع الرسالة: 1 بايت
المصدر: المعرف، عدد يبلغ 4 بايت
الوجهة: عادة معرف الوجهة الفعلي (انظر الملاحظات)، عدد يبلغ 4 بايت
المصطلح: المصطلح الحالي، عدد يبلغ 8 بايت
الفهرس التالي: مبادراً إلى آخر فهرس في السجل للقائد + 1، عدد يبلغ 8 بايت
هل يقبل: 1 إذا تم القبول، 0 إذا لم يتم القبول (انظر الملاحظات)، 1 بايت
الملاحظات
معرف الوجهة هو عادة الوجهة الفعلية لهذه الرسالة. ومع ذلك، بالنسبة لاستجابة إدخال الإدخالات، استجابة إضافة الخادم، واستجابة إزالة الخادم، هو معرف القائد الحالي.
في استجابة طلب التصويت، تقبل يكون 1 لصالح التصويت للمرشح (الطالب)، و0 لعدم التصويت.
الطبقة التطبيقية
يتم نشر كل خادم دوريًا بيانات التطبيق إلى السجل في طلب العميل. تحتوي بيانات التطبيق على حالة جهاز التوجيه لكل خادم والوجهة لمجموعة Meta LS2. تستخدم الخوادم خوارزمية شائعة لتحديد الناشر والمحتويات لـ Meta LS2. الخادم الذي لديه الحالة “الأفضل” الأخيرة في السجل هو ناشر Meta LS2. ليس بالضرورة أن يكون ناشر Meta LS2 هو قائد Raft.
محتويات بيانات التطبيق
محتويات التطبيق مرمزة بـ UTF-8 JSON, لأجل البساطة والامتداد. المواصفات الكاملة TBD. الهدف هو توفير البيانات الكافية لكتابة خوارزمية لتحديد جهاز التوجيه “الأفضل” لنشر Meta LS2، وللناشر أن يكون لديه معلومات كافية لتحديد الأوزان للوجهات في Meta LS2. ستحتوي البيانات على كل من إحصائيات جهاز التوجيه والوجهة.
قد تحتوي البيانات اختياريًا على بيانات استشعار عن بُعد حول صحة الخوادم الأخرى، والقدرة على جلب Meta LS. لن يتم دعم تلك البيانات في الإصدار الأول.
قد تحتوي البيانات اختياريًا على معلومات تكوين تم نشرها بواسطة عميل المسؤول. لن تدعم تلك البيانات في الإصدار الأول.
إذا تم العثور على “name: value”، فهذا يحدد المفتاح والقيمة لخريطة JSON. بخلاف ذلك، تُحدد المواصفات من خلال المُتوقع لاحقاً.
بيانات المجموعة (المستوى العلوي):
- الكتلة: اسم الكتلة
- التاريخ: تاريخ هذه البيانات (طويل، ملي ثانية منذ البدء)
- المعرف: معرف Raft (عدد صحيح)
بيانات التكوين (التكوين):
- أي معاملات تكوين
حالة نشر MetaLS (meta):
- الوجهة: وجهة الميتادست، base64
- LastPublishedLS: إذا كان موجودًا، ترميز base64 لآخر نشر للميتادست
- LastPublishedTime: بالملي ثانية، أو 0 إذا لم يُنشر أبدًا
- نشر التكوين: حالة نشر التكوين قبالة / تفعيل / تلقائي
- النشر: حالة نشر الميتادست العالمية المنطقية true/false
بيانات جهاز التوجيه (router):
- LastPublishedRI: إذا كان موجودًا، ترميز base64 لمعلومات آخر نشر لجهاز التوجيه
- وقت العمل: وقت تشغيل بالملي ثانية
- تأخر الوظيفة
- الأنفاق الاستكشافية
- الأنفاق المشاركة
- عرض النطاق الترددي المكون
- عرض النطاق الترددي الحالي
الوجهات (الوجهات): القائمة
بيانات الوجهة:
- الوجهة: الوجهة، base64
- وقت العمل: وقت تشغيل بالملي ثانية
- الأنفاق المكونة
- الأنفاق الحالية
- عرض النطاق الترددي المكون
- عرض النطاق الترددي الحالي
- الاتصالات المكونة
- الاتصالات الحالية
- بيانات القائمة السوداء
بيانات استشعار جهاز التوجيه عن بعد:
- آخر إصدار RI تم رؤيته
- وقت جلب LS
- بيانات اختبار الاتصال
- أقرب ملفات فيضاعد الملف الشخصي لفترات الزمنية أمس، اليوم، وغدًا
بيانات استشعار الوجهة عن بعد:
- آخر إصدار LS تم رؤيته
- وقت جلب LS
- بيانات اختبار الاتصال
- أقرب ملفات فيضاعد الملف الشخصي لفترات الزمنية أمس، اليوم، وغدًا
استشعار Meta LS data:
- آخر إصدار تم رؤيته
- وقت الجلب
- أقرب ملفات فيضاعد الملف الشخصي لفترات الزمنية أمس، اليوم، وغدًا
واجهة الإدارة
TBD، ربما اقتراح منفصل. غير مطلوب للإصدار الأول.
متطلبات واجهة الإدارة:
- دعم الوجهات الرئيسية المتعددة، أي مجموعات (مزارع) افتراضية متعددة
- توفير عرض شامل لحالة المجموعة المشتركة - جميع الإحصائيات المنشورة من قبل الأعضاء، من هو القائد الحالي، إلخ.
- القدرة على استبعاد المشاركين أو القائد من الكتلة بالقوة
- القدرة على فرض نشر metaLS (إذا كان العقدة الحالية هي المالك)
- القدرة على استبعاد الشيفرات التجزئة من metaLS (إذا كان العقدة الحالية هي المالك)
- وظائف استيراد/تصدير التكوين للنشرات الجماعية
واجهة جهاز التوجيه
TBD، ربما اقتراح منفصل. لا يتطلب i2pcontrol للإصدار الأول وستتضمن التغييرات المفصلة في اقتراح منفصل.
متطلبات مزرعة الثوم لواجهة بروتوكول التطبيق إلى جهاز التوجيه (في جافا JVM أو i2pcontrol)
- getLocalRouterStatus()
- getLocalLeafHash(Hash masterHash)
- getLocalLeafStatus(Hash leaf)
- getRemoteMeasuredStatus(Hash masterOrLeaf) // ربما ليس في MVP
- publishMetaLS(Hash masterHash, List
contents) // أو مجموعة التورق MetaLease الموقع؟ من الذي يوقع؟ - stopPublishingMetaLS(Hash masterHash)
- المصادقة TBD؟
التبرير
Atomix كبير جدًا ولن يسمح بالتخصيص لنا لتوجيه البروتوكول عبر I2P. أيضًا، تنسيقه السلكي غير موثق، ويعتمد على تسلسل جافا.
الملاحظات
القضايا
- لا توجد طريقة لعميل لمعرفة والاتصال بقائد غير معروف. سيكون تغييرا طفيفًا للتابع لإرسال التكوين كإدخال سجل في استجابة إدخال الإدخالات.
الترحيل
لا توجد قضايا توافق مع الإصدارات السابقة.