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های قدیمی پذیرفته میشود، اما منطق فعلی پروتکل از آن برای رمزنگاری یا احراز هویت استفاده نمیکند.
فیلدهای اجباری
فیلدهای سطح اصلی:
| فیلد | نوع | توضیح |
|---|---|---|
name | string | نام یکتای node در config. |
type | string | باید دقیقاً "Bgp4Server" باشد. |
next | string | node stream بعدی که payloadهای بازشده upstream را میگیرد. |
تنظیمات اختیاری
| گزینه | نوع | پیشفرض | توضیح |
|---|---|---|---|
password | string | — | پذیرفته میشود اما نادیده گرفته میشود؛ برای رمزنگاری یا احراز هویت کاربردی ندارد. |
در حال حاضر تنظیم دیگری خوانده نمیشود.
فرمت فریم
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 را میگیرند. |
| body | payload تونلشده؛ در نخستین فریم upstream شامل body ساختگی OPEN و سپس payload تونلشده است. |
مقادیر نوع پشتیبانیشده:
| نوع | نام |
|---|---|
1 | OPEN |
2 | UPDATE |
3 | NOTIFICATION |
4 | KEEPALIVE |
5 | ROUTE-REFRESH |
فیلد length طول قالب شبیه BGP در تونل WaterWall را نشان میدهد، نه طول استاندارد پیام BGP. این طول، بایت type و بایتهای body را در بر میگیرد، اما marker و خود فیلد length را حساب نمیکند.
اولین Upstream Frame
نخستین فریم upstream باید type برابر 1 داشته باشد و شامل body ساختگی OPEN و سپس بایتهای payload تونلشده باشد.
Bgp4Server برای نخستین فریم:
- بررسی میکند که فریم دستکم یک بایت type و ده بایت headerِ OPEN داشته باشد.
- بررسی میکند که type برابر OPEN باشد.
- optional parameter length را از OPEN header میخواند.
- طول کامل پیشوند ساختگی OPEN را حساب میکند.
- اگر پس از پیشوند OPEN هیچ payload تونلشدهای باقی نمانده باشد، فریم را رد میکند.
- دریافت OPEN را در state مربوط به line ثبت میکند.
- type و پیشوند OPEN را حذف میکند.
- payload باقیمانده را در جهت upstream میفرستد.
از فریمهای بعدی upstream فقط type یکبایتی حذف میشود. Body بازیابیشده نباید خالی باشد.
Downstream Wrapping
payloadهای downstream پیش از ارسال به تونل قبلی، فریمبندی میشوند.
Bgp4Server از یک نوع BGP غیر-OPEN تصادفی برای frameهای payload downstream استفاده میکند:
2, 3, 4, or 5
این node payload را رمزنگاری یا احراز هویت نمیکند؛ فقط آن را در فریم قرار میدهد.
محدودیتها و Padding
| مقدار | مقدار | یادداشت |
|---|---|---|
| حداکثر طول body | 65535 بایت | شامل type یکبایتی. |
| حداکثر payload در body عادی | 65534 بایت | مجموع payload و type باید در 65535 بایت جا شود. |
| سقف بایتهای نگهداریشده در هر جهت | 2162705 | مستقل از اندازهٔ pool، پروفایل حافظه و splice. |
| سقف فریمهای خروجی در صف | 1024 | تعداد قطعههای ورودی محدود نمیشود. |
required_padding_left | 19 بایت | برای 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/resume | next tunnel upstream |
| downstream pause/resume | previous tunnel downstream |
نکتهها
- برای استفاده عملی از
Bgp4Serverباید آن را باBgp4Clientجفت کنید. - در پیادهسازی فعلی،
passwordقابلیت امنیتی محسوب نمیشود. - نخستین فریم upstream باید یک فریم OPEN باشد که پس از body ساختگی OPEN، payload تونلشده داشته باشد.
- فیلد طول در قالب شبیه BGP، بایتهای marker و length را در نظر نمیگیرد.
- upstream
estو downstreaminitغیرفعال هستند. - این node یک تونل stream لایه ۴ است، نه packet tunnel.
متادیتای نود
metadata برگرفته از کد منبع:
| ویژگی | مقدار |
|---|---|
| node flags | kNodeFlagSupportsSplice |
can_have_prev | true |
can_have_next | true |
layer_group | kNodeLayer4 |
layer_group_prev_node | kNodeLayer4 |
layer_group_next_node | kNodeLayer4 |
required_padding_left | 19 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 بدون اندازهگیری نیست.