ConnectionFisherServer
ConnectionFisherServer بخش سرور ConnectionFisherClient است. منتظر probe ثابت کلاینت میماند، با marker ثابت سرور پاسخ میدهد و تنها پس از آن اجازه میدهد line وارد حالت عادی عبور stream شود.
این نود را فقط در مسیری قرار دهید که انتظار دارید ترافیک ConnectionFisherClient را دریافت کند.
جایگاه رایج
طرحبندی ساده TCP:
TcpListener -> ConnectionFisherServer -> TcpConnector
جفت با client:
TcpListener -> ConnectionFisherClient -> TcpConnector
TcpListener -> ConnectionFisherServer -> TcpConnector
همراه با تونلهای stream دیگر در میانه مسیر:
ConnectionFisherClient -> EncryptionClient -> TcpConnector
TcpListener -> EncryptionServer -> ConnectionFisherServer -> TcpConnector
پس از decode شدن داده در هر جفت تونل کلاینت/سرور میانی، سرور باید دقیقاً همان بایتهای FISH? ارسالی کلاینت را ببیند.
این نود چه میکند؟
- با دریافت
Initدر upstream، فقط state محلی line را مقداردهی اولیه میکند. - upstream
Initبهnextرا به تأخیر میاندازد. - بایتهای upstream را تا رسیدن دستکم ۵ بایت بافر میکند.
- نیاز دارد ۵ بایت اول دقیقاً
FISH?باشند. - پاسخ ثابت
FISH!را downstream به client میفرستد. nextرا تنها پس از رسیدن payload بعد از probe مقداردهی اولیه میکند.- پس از کامل شدن مرحله probe، payload را بهصورت عادی عبور میدهد.
- اگر probe نامعتبر باشد یا حجم داده handshake در بافر از حد بگذرد، line را میبندد.
ConnectionFisherServer یک تونل میانی stream است. مستقیماً socket یا packet line نمیسازد.
نمونه تنظیم
{
"name": "fisher-server",
"type": "ConnectionFisherServer",
"next": "service"
}
در نسخه فعلی settings استفاده نمیشود.
فیلدهای اجباری
فیلدهای سطح اصلی:
| فیلد | نوع | توضیح |
|---|---|---|
name | string | نام یکتای نود در پیکربندی. |
type | string | باید دقیقاً "ConnectionFisherServer" باشد. |
next | string | اجباری. نود stream بعدی که payload بعد از فاز probe را دریافت میکند. |
ConnectionFisherServer باید نود قبلی نیز داشته باشد؛ این نود ابتدا یا انتهای chain نیست.
تنظیمات
در حال حاضر هیچ فیلدی از settings خوانده نمیشود.
تبادل Probe
| جهت | Bytes | معنی |
|---|---|---|
| کلاینت به سرور | FISH? | پنج بایت الزامی ابتدای upstream. |
| سرور به کلاینت | FISH! | پس از دریافت probe معتبر ارسال میشود. |
Markerها بایتهای ثابت ASCII هستند و سازوکار امنیتی محسوب نمیشوند.
مرحلههای سرور
پیادهسازی از سه فاز استفاده میکند:
| فاز | رفتار |
|---|---|
| wait ping | بایتهای upstream تا رسیدن دستکم ۵ بایت بافر میشوند. |
| wait payload | Probe معتبر بوده و FISH! فرستاده شده است؛ با این حال next هنوز مقداردهی نشده، مگر اینکه payload اضافه از قبل در بافر باشد. |
| established | next مقداردهی شده و callbackهای payload و lifecycle بهطور عادی عبور داده میشوند. |
جریان Handshake
با دریافت Init در upstream، سرور فقط state محلی line را مقداردهی اولیه میکند و هنوز tunnelNextUpStreamInit() را فراخوانی نمیکند.
پردازش payloadِ upstream پیش از برقراری کامل:
- سرور بایتهای ورودی را بافر میکند.
- اگر بافر handshake از
4096بایت بگذرد، line بسته میشود. - وقتی حداقل ۵ بایت در دسترس باشد، ۵ بایت اول خوانده میشوند.
- اگر دقیقاً
FISH?نباشند، line بسته میشود. - اگر منطبق باشند،
FISH!در جهت downstream به سمت previous فرستاده میشود. - اگر پس از پنج بایت اول payloadی مانده باشد، سرور
nextرا مقداردهی اولیه میکند و payload باقیمانده را در upstream میفرستد. - اگر payload اضافهای نباشد، سرور منتظر payload بعدی upstream میماند؛ سپس
nextرا مقداردهی اولیه و آن payload را ارسال میکند.
پس از مقداردهی اولیه next، این تونل line را برقرارشده در نظر میگیرد و payloadهای بعدی بهصورت عادی عبور داده میشوند.
رفتار Lifecycle
قبل از establishment:
Initدر upstream فقط محلی است.- upstream payload بهعنوان probe یا اولین payload بعد از probe در نظر گرفته میشود
PauseوResumeدر upstream عبور داده نمیشوند.Est،PauseوResumeدر downstream عبور داده نمیشوند.- Payloadِ downstream در این مرحله غیرمنتظره است؛ بافر آن برای استفاده مجدد برمیگردد و line بسته میشود.
بعد از establishment:
- payloadِ upstream به
nextفرستاده میشود. - payloadِ downstream به نود قبلی میرود.
- Pause و resume در upstream به
nextفرستاده میشوند. - Est، pause و resume در downstream به نود قبلی میروند.
با دریافت Finish در upstream، سرور state محلی را از بین میبرد. تنها در صورتی Finish را در upstream منتشر میکند که next قبلاً مقداردهی اولیه شده باشد. اگر پیش از ایجاد سمت next خطای پروتکل رخ دهد، فقط سمت previous بسته میشود، زیرا هنوز lineای در سمت next وجود ندارد.
محدودیتها
| محدودیت | مقدار | رفتار |
|---|---|---|
| طول probe | 5 بایت | پنج بایت نخست باید FISH? باشند. |
| Handshake buffer | 4096 بایت | اگر پیش از کامل شدن probe بایتهای بیشتری جمع شوند، line بسته میشود. |
required_padding_left | 0 | سرور چیزی به بافرهای موجود اضافه نمیکند. |
برای پاسخ FISH! یک بافر کوچک جداگانه گرفته میشود.
نکتهها
- با
ConnectionFisherClientمتناظر استفاده کنید. - آن را پس از هر تونل سمت سرور قرار دهید که transport میان کلاینت و سرور را decode میکند.
- برای chainهای stream طراحی شده است، نه packet-line.
- probe ثابت و عمومی است؛ برای امنیت واقعی از نودهای دیگر WaterWall استفاده کنید.
- upstream
Estو downstreamInitبرای این نود غیرفعال هستند.