پرش به مطلب اصلی

Bgp4Server

Bgp4Server همتای سمت سرور Bgp4Client است. فریم‌های شبیه BGP را که از سمت کلاینت و در جهت upstream می‌رسند باز می‌کند و payload‌های downstream را در جهت عکس داخل همان نوع فریم قرار می‌دهد.

این node باید با Bgp4Client استفاده شود:

TcpListener -> Bgp4Client -> ... -> Bgp4Server -> TcpConnector
هشدار

Bgp4Server مسیریابی واقعی BGP، برقراری BGP peering، تبادل route یا احراز هویت BGP را پیاده‌سازی نمی‌کند. این node فقط فریم‌بندی شبیه BGP ساخته‌شده توسط Bgp4Client را می‌شناسد.

این نود چه می‌کند؟​

  • هنگام init در جهت upstream، برای هر line یک stream خواندن و state مربوط به اولین فریم را مقداردهی اولیه می‌کند.
  • نخستین فریم upstream باید فریم ساختگی OPEN از Bgp4Client باشد.
  • اطلاعات BGP و body ساختگی OPEN را از فریم نخست حذف می‌کند.
  • marker، length و type را از فریم‌های بعدی upstream برمی‌دارد.
  • payload‌های بازیابی‌شده upstream را به تونل بعدی می‌فرستد.
  • پیش از فرستادن payload‌های downstream به تونل قبلی، آن‌ها را در فریم‌های شبیه BGP قرار می‌دهد.
  • در صورت دریافت فریم نامعتبر، هر دو جهت را می‌بندد.

Bgp4Server یک تونل stream معمولی است. socket شبکه یا packet line نمی‌سازد و packet line‌ای را نیز آزاد نمی‌کند.

نمونه تنظیم​

سمت سرور:

{
"name": "bgp4-server",
"type": "Bgp4Server",
"settings": {
"password": "compat-value"
},
"next": "target"
}

سمت کلاینت متناظر:

{
"name": "bgp4-client",
"type": "Bgp4Client",
"settings": {
"password": "compat-value"
},
"next": "transport-out"
}

فیلد password برای سازگاری با config‌های قدیمی پذیرفته می‌شود، اما منطق فعلی پروتکل از آن برای رمزنگاری یا احراز هویت استفاده نمی‌کند.

فیلدهای اجباری​

فیلدهای سطح اصلی:

فیلدنوعتوضیح
namestringنام یکتای node در config.
typestringباید دقیقاً "Bgp4Server" باشد.
nextstringnode stream بعدی که payload‌های بازشده upstream را می‌گیرد.

تنظیمات اختیاری​

گزینهنوعپیش‌فرضتوضیح
passwordstring—پذیرفته می‌شود اما نادیده گرفته می‌شود؛ برای رمزنگاری یا احراز هویت کاربردی ندارد.

در حال حاضر تنظیم دیگری خوانده نمی‌شود.

فرمت فریم​

Bgp4Server همان قالب فریم شبیه BGP را می‌خواند و می‌نویسد که Bgp4Client تولید می‌کند:

16-byte marker | 2-byte body length | 1-byte BGP type | body

جزئیات فیلد:

فیلدمقدار
markerشانزده بایت با مقدار 0xff.
body lengthیک uint16_t با ترتیب big-endian؛ شامل بایت type به‌علاوه بایت‌های body.
BGP typeنخستین فریم upstream باید 1 باشد؛ فریم‌های downstream یکی از مقادیر تصادفی 2 تا 5 را می‌گیرند.
bodypayload تونل‌شده؛ در نخستین فریم upstream شامل body ساختگی OPEN و سپس payload تونل‌شده است.

مقادیر نوع پشتیبانی‌شده:

نوعنام
1OPEN
2UPDATE
3NOTIFICATION
4KEEPALIVE
5ROUTE-REFRESH

فیلد length طول قالب شبیه BGP در تونل WaterWall را نشان می‌دهد، نه طول استاندارد پیام BGP. این طول، بایت type و بایت‌های body را در بر می‌گیرد، اما marker و خود فیلد length را حساب نمی‌کند.

اولین Upstream Frame​

نخستین فریم upstream باید type برابر 1 داشته باشد و شامل body ساختگی OPEN و سپس بایت‌های payload تونل‌شده باشد.

Bgp4Server برای نخستین فریم:

  1. بررسی می‌کند که فریم دست‌کم یک بایت type و ده بایت headerِ OPEN داشته باشد.
  2. بررسی می‌کند که type برابر OPEN باشد.
  3. optional parameter length را از OPEN header می‌خواند.
  4. طول کامل پیشوند ساختگی OPEN را حساب می‌کند.
  5. اگر پس از پیشوند OPEN هیچ payload تونل‌شده‌ای باقی نمانده باشد، فریم را رد می‌کند.
  6. دریافت OPEN را در state مربوط به line ثبت می‌کند.
  7. type و پیشوند OPEN را حذف می‌کند.
  8. payload باقی‌مانده را در جهت upstream می‌فرستد.

از فریم‌های بعدی upstream فقط type یک‌بایتی حذف می‌شود. Body بازیابی‌شده نباید خالی باشد.

Downstream Wrapping​

payload‌های downstream پیش از ارسال به تونل قبلی، فریم‌بندی می‌شوند.

Bgp4Server از یک نوع BGP غیر-OPEN تصادفی برای frame‌های payload downstream استفاده می‌کند:

2, 3, 4, or 5

این node payload را رمزنگاری یا احراز هویت نمی‌کند؛ فقط آن را در فریم قرار می‌دهد.

محدودیت‌ها و Padding​

مقدارمقداریادداشت
حداکثر طول body65535 بایتشامل type یک‌بایتی.
حداکثر payload در body عادی65534 بایتمجموع payload و type باید در 65535 بایت جا شود.
سقف بایت‌های نگه‌داری‌شده در هر جهت2162705مستقل از اندازهٔ pool، پروفایل حافظه و splice.
سقف فریم‌های خروجی در صف1024تعداد قطعه‌های ورودی محدود نمی‌شود.
required_padding_left19 بایتبرای marker، length و type فریم.

دادهٔ بزرگ به چند فریم با حداکثر ۶۵۵۳۴ بایت payload عادی تقسیم می‌شود. فضای واقعی پیشوند OPEN از فریم نخست کم می‌شود و فقط یک OPEN فرستاده می‌شود.

جریان داده​

جهت upstream:

previous node -> Bgp4Server unwraps -> next node

جهت downstream:

next node -> Bgp4Server wraps -> previous node

سمت upstream باید فریم‌های تولیدشده توسط Bgp4Client را دریافت کند. اگر نخستین فریم upstream همان فریم ساختگی OPEN مورد انتظار نباشد، line بسته می‌شود.

رفتار Lifecycle​

با دریافت init در جهت upstream، Bgp4Server state مربوط به line را مقداردهی اولیه می‌کند و init را در همان جهت به تونل بعدی می‌فرستد.

با دریافت est در جهت downstream، هر اعلان، حتی تکراری، را به تونل قبلی می‌فرستد.

payload‌های upstream را buffer، parse و اعتبارسنجی می‌کند، فریم را باز می‌کند و داده بازیابی‌شده را به تونل بعدی می‌فرستد. payload‌های downstream را فریم‌بندی و به تونل قبلی ارسال می‌کند.

با دریافت finish از هر جهت، state مربوط به line را از بین می‌برد و finish را در همان جهت منتشر می‌کند: در upstream به تونل بعدی و در downstream به تونل قبلی.

در صورت دریافت فریم نامعتبر، Bgp4Server state محلی را از بین می‌برد و هر دو جهت را با ترتیب لازم برای یک تونل میانی می‌بندد: ابتدا finish در upstream و سپس finish در downstream.

Pause و Resume اعلان‌های راهنمای تکرارپذیر هستند. callbackهای پیش‌فرض هر اعلان را فوراً در همان جهت منتقل می‌کنند؛ وضعیت توقف مصرف‌کننده ذخیره نمی‌شود و ارسال payload به Resume وابسته نیست:

callbackمقصد ارسال
upstream pause/resumenext tunnel upstream
downstream pause/resumeprevious tunnel downstream

نکته‌ها​

  • برای استفاده عملی از Bgp4Server باید آن را با Bgp4Client جفت کنید.
  • در پیاده‌سازی فعلی، password قابلیت امنیتی محسوب نمی‌شود.
  • نخستین فریم upstream باید یک فریم OPEN باشد که پس از body ساختگی OPEN، payload تونل‌شده داشته باشد.
  • فیلد طول در قالب شبیه BGP، بایت‌های marker و length را در نظر نمی‌گیرد.
  • upstream est و downstream init غیرفعال هستند.
  • این node یک تونل stream لایه ۴ است، نه packet tunnel.

متادیتای نود​

metadata برگرفته از کد منبع:

ویژگیمقدار
node flagskNodeFlagSupportsSplice
can_have_prevtrue
can_have_nexttrue
layer_groupkNodeLayer4
layer_group_prev_nodekNodeLayer4
layer_group_next_nodekNodeLayer4
required_padding_left19 bytes

Splice، فریم‌بندی و کنترل فشار​

هر دو جهت buffer عادی، بدنهٔ داخل pipe خصوصی و ترکیب این دو را می‌پذیرند. فریم تک‌تکه با استفاده از padding موجود در همان buffer ساخته می‌شود؛ بودجهٔ padding کلاینت ۳۹ و سرور ۱۹ بایت است. ورودی بزرگ پیش از نخستین callback به یک دستهٔ کامل از فریم‌های مستقل تبدیل می‌شود. شکست ساخت pipe یا پرشدن مقصد برای همان فریم به buffer عادی با اندازهٔ کافی برمی‌گردد؛ کل ورودی به یک buffer عادی تجمیع نمی‌شود.

گیرنده header نوزده‌بایتی را cache می‌کند و body هر فریم را جداگانه تحویل می‌دهد. سرور فقط ۱۰ بایت ثابت OPEN و حداکثر ۲۵۵ بایت اختیاری را بررسی یا مصرف می‌کند؛ بقیهٔ payload می‌تواند داخل pipe بماند. کلاینت ۳ تا ۱۰ بایت اختیاری تولید می‌کند و اندازهٔ واقعی آن را از ظرفیت فریم نخست کم می‌کند. ورودی خالی فریمی تولید نمی‌کند و وضعیت نخستین OPEN را مصرف نمی‌کند. روی هر line کلاینت دقیقاً یک OPEN پذیرفته می‌شود.

سقف ثابت هر جهت ۲٬۱۶۲٬۷۰۵ بایت منطقی (2 MiB + 65553) است و به پروفایل حافظه، اندازهٔ buffer، ظرفیت واقعی pipe، پلتفرم یا misc.splice وابسته نیست. گیرنده بایت‌های wire نگه‌داری‌شده، شامل header کش‌شده، را می‌شمارد؛ فرستنده بایت‌های فریم‌های خروجی، شامل header‌های تولیدشده، را حساب می‌کند. صف خروجی حداکثر ۱۰۲۴ فریم دارد؛ این سقف برای تعداد قطعه‌های ورودی نیست. حداکثر فریم کامل ۶۵٬۵۵۳ و payload فریم غیر-OPEN حداکثر ۶۵٬۵۳۴ بایت است.

هر فریم دریافتی callback جداگانه دارد. هر دو نود از همان line عادی قرض‌گرفته‌شده استفاده می‌کنند و تمام payloadها را تبدیل می‌کنند؛ بنابراین bypass دائمی ندارند. Pause و Resume، حتی اگر تکراری باشند، با callbackهای پیش‌فرض در هر دو جهت شفاف منتقل می‌شوند. فریم‌های کامل پذیرفته‌شده بدون انتظار برای Resume تخلیه می‌شوند. محافظ تخلیه در هر جهت ترتیب FIFO را هنگام callbackهای بازگشتی حفظ می‌کند؛ stream ورودی دادهٔ ناقص را نگه می‌دارد و صف محدود خروجی، دسته‌های کامل فریم‌بندی‌شده را پیش از ورودی بازگشتی ارسال می‌کند. هر ورودی پیش از نخستین callback مربوط به خود با سقف‌های ثابت نگه‌داری بررسی می‌شود. دادهٔ نامعتبر، عبور از سقف نگه‌داری یا رد شدن به‌دلیل محدودیت ظرفیت صف فقط همان اتصال را از طریق مالک line می‌بندد. Finish منابع محلی را پیش از ارسال در جهت دور از فرستنده آزاد می‌کند. این پشتیبانی تضمین zero-copy یا افزایش throughput بدون اندازه‌گیری نیست.