Bgp4Client
Bgp4Client یک تونل stream در لایه ۴ است. Payloadهای upstream را در فریمهایی شبیه BGP قرار میدهد و فریمهای downstream ساختهشده توسط Bgp4Server را باز میکند.
این نود باید با Bgp4Server استفاده شود:
TcpListener -> Bgp4Client -> ... -> Bgp4Server -> TcpConnector
در استقرار واقعی، ... معمولاً مسیر transport میان دو طرف است؛ مانند TCP، TLS، mux، reverse یا بخشی دیگر از chain در WaterWall.
Bgp4Client مسیریابی واقعی BGP، برقراری BGP peering، تبادل route یا احراز هویت BGP را پیادهسازی نمیکند. شکل فریم شبیه BGP فقط برای استتار و فریمبندی stream به کار میرود.
این نود چه میکند؟
- هنگام
initدر جهت upstream، برای هر line یک stream خواندن و state مربوط به اولین فریم را مقداردهی اولیه میکند. - در اولین payloadِ upstream، یک body ساختگی BGP OPEN را پیش از بایتهای برنامه prepend میکند.
- payloadهای upstream را در فریمهای شبیه BGP قرار میدهد.
- یک نوع BGP غیر-OPEN تصادفی برای frameهای payload upstream بعدی انتخاب میکند.
- فریمهای شبیه BGP در جهت downstream را از یک stream buffer میخواند.
- اطلاعات فریم downstream را حذف و payload بازیابیشده را به تونل قبلی میفرستد.
- در صورت دریافت فریم نامعتبر، هر دو جهت را میبندد.
Bgp4Client یک تونل stream معمولی است. Socket شبکه یا packet line نمیسازد و packet lineای را نیز آزاد نمیکند.
نمونه تنظیم
سمت کلاینت:
{
"name": "bgp4-client",
"type": "Bgp4Client",
"settings": {
"password": "compat-value"
},
"next": "transport-out"
}
سمت سرور متناظر:
{
"name": "bgp4-server",
"type": "Bgp4Server",
"settings": {
"password": "compat-value"
},
"next": "target"
}
فیلد password برای سازگاری با پیکربندیهای قدیمی پذیرفته میشود، اما منطق فعلی پروتکل از آن برای رمزنگاری یا احراز هویت استفاده نمیکند.
فیلدهای اجباری
فیلدهای سطح اصلی:
| فیلد | نوع | توضیح |
|---|---|---|
name | string | نام یکتای نود در پیکربندی. |
type | string | باید دقیقاً "Bgp4Client" باشد. |
next | string | نود stream بعدی که فریمهای بستهبندیشده را میگیرد. |
تنظیمات اختیاری
| گزینه | نوع | پیشفرض | توضیح |
|---|---|---|---|
password | string | "passwd" | فیلد سازگاری. هنگام راهاندازی hash میشود، اما منطق فعلی فریمبندی از این hash استفاده نمیکند. |
در حال حاضر تنظیم دیگری خوانده نمیشود.
فرمت فریم
همه payloadهای upstream با این ساختار بستهبندی میشوند:
16-byte marker | 2-byte body length | 1-byte BGP type | body
جزئیات فیلد:
| فیلد | مقدار |
|---|---|
| marker | شانزده بایت با مقدار 0xff. |
| body length | یک uint16_t با ترتیب big-endian؛ شامل بایت type بهعلاوه بایتهای body. |
| BGP type | مقدار 1 برای نخستین فریم OPEN؛ یکی از مقادیر تصادفی 2 تا 5 برای فریمهای بعدی payload. |
| body | payload تونلشده؛ در نخستین فریم upstream شامل body ساختگی OPEN و سپس payload تونلشده است. |
مقادیر نوع پشتیبانیشده:
| نوع | نام |
|---|---|
1 | OPEN |
2 | UPDATE |
3 | NOTIFICATION |
4 | KEEPALIVE |
5 | ROUTE-REFRESH |
طول فریم با طول استاندارد پیام BGP یکسان نیست. قالب قدیمی شبیه BGP در WaterWall، طول را برابر بایت type بهعلاوه بایتهای body در نظر میگیرد و marker شانزدهبایتی و فیلد طول دوبایتی را حساب نمیکند.
اولین Upstream Payload
Bgp4Client هنگام init فریم OPEN مستقلی نمیفرستد. در عوض، نخستین payloadِ upstream را با BGP type برابر 1 فریم میکند و پیش از بایتهای برنامه یک body ساختگی OPEN قرار میدهد.
فیلدهای synthetic OPEN:
| فیلد | رفتار |
|---|---|
| version | همیشه 4. |
| AS number | یک uint16_t تصادفی که هنگام ساخت instance تونل تولید میشود. |
| hold time | 90 ثانیه. |
| router id | مقدار تصادفی تولیدشده در هنگام ساخته شدن tunnel instance. |
| optional parameter length | طول تصادفی بین 3 تا 10 بایت. |
| optional parameter bytes | بایتهای تصادفی در بازه 0 تا 199. |
پس از نخستین فریم، open_sent برای line تنظیم میشود. Payloadهای بعدی upstream بدون پیشوند ساختگی OPEN بستهبندی میشوند و یک type تصادفی غیر از OPEN میگیرند.
از آنجا که Bgp4Server انتظار دارد داده تونلشده برنامه پس از پیشوند OPEN قرار بگیرد، نخستین فریم OPEN باید بعد از body ساختگی OPEN دارای بایتهای payload باشد.
Downstream Parsing
بایتهای downstream در یک buffer_stream_t جمع میشوند.
Bgp4Client برای هر فریم کامل downstream:
- بررسی میکند که هر ۱۶ بایت اول
0xffباشند. - فیلد دوبایتی طول body را میخواند.
- فریمهایی را که طول body آنها از فیلد یکبایتی type بیشتر نیست رد میکند.
- تا بافر شدن کل فریم منتظر میماند.
- marker، length و type را حذف میکند.
- فریمهایی را که پس از آن payloadی ندارند نمیپذیرد.
- payload بازیابیشده را در جهت downstream به تونل قبلی میفرستد.
اگر فریم ناقص باشد، parser منتظر بایتهای بعدی میماند. اگر حجم داده بافرشده از سقف فعلی بافر بگذرد، line بسته میشود.
محدودیتها و Padding
| مقدار | مقدار | یادداشت |
|---|---|---|
| حداکثر طول body | 65535 بایت | شامل type یکبایتی. |
| حداکثر payload در body عادی | 65534 بایت | مجموع payload و type باید در 65535 بایت جا شود. |
| حداکثر بایت در بافر خواندن | حدود 131106 بایت | معادل دو پیام فریمشده با بیشترین اندازه. |
required_padding_left | 39 بایت | برای پیشوند فریم و بزرگترین پیشوند ساختگی OPEN کافی است. |
اگر payloadِ upstream در یک فریم شبیه BGP جا نشود، رد میشود و فریمی فرستاده نخواهد شد.
جریان داده
جهت upstream:
previous node -> Bgp4Client wraps -> next node
جهت downstream:
next node -> Bgp4Client unwraps -> previous node
Bgp4Client انتظار دارد در سمت مقابل Bgp4Server قرار گرفته باشد. هر peer ناسازگاری که فریم مورد انتظار را نسازد، خطای پروتکل ایجاد میکند.
رفتار Lifecycle
با دریافت init در جهت upstream، Bgp4Client state مربوط به line را مقداردهی اولیه میکند و init را در همان جهت به تونل بعدی میفرستد.
با دریافت est در جهت downstream، آن را به تونل قبلی میفرستد.
Payloadهای upstream را فریمبندی و به تونل بعدی میفرستد. Payloadهای downstream را بافر و تجزیه میکند، فریم را باز میکند و داده بازیابیشده را به تونل قبلی میفرستد.
با دریافت finish از هر جهت، state مربوط به line را از بین میبرد و finish را در همان جهت منتشر میکند: در upstream به تونل بعدی و در downstream به تونل قبلی.
در صورت دریافت فریم نامعتبر، Bgp4Client state محلی را از بین میبرد و هر دو جهت را با ترتیب لازم برای یک تونل میانی میبندد: ابتدا finish در upstream و سپس finish در downstream.
Pause و resume در همان جهت دریافتشده عبور داده میشوند:
| Callback | مقصد ارسال |
|---|---|
| upstream pause/resume | next tunnel upstream |
| downstream pause/resume | previous tunnel downstream |
نکتهها
- برای استفاده عملی از
Bgp4Clientباید آن را باBgp4Serverجفت کنید. - در پیادهسازی فعلی،
passwordقابلیت امنیتی محسوب نمیشود. - فیلد طول در قالب شبیه BGP، بایتهای marker و length را در نظر نمیگیرد.
- اولین OPEN frame فقط وقتی اولین upstream payload برسد فرستاده میشود.
- upstream
estو downstreaminitغیرفعال هستند. - این نود یک تونل stream لایه ۴ است، نه packet tunnel.