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

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 استفاده نمی‌شود.

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

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

فیلدنوعتوضیح
namestringنام یکتای نود در پیکربندی.
typestringباید دقیقاً "ConnectionFisherServer" باشد.
nextstringاجباری. نود stream بعدی که payload بعد از فاز probe را دریافت می‌کند.

ConnectionFisherServer باید نود قبلی نیز داشته باشد؛ این نود ابتدا یا انتهای chain نیست.

تنظیمات

در حال حاضر هیچ فیلدی از settings خوانده نمی‌شود.

تبادل Probe

جهتBytesمعنی
کلاینت به سرورFISH?پنج بایت الزامی ابتدای upstream.
سرور به کلاینتFISH!پس از دریافت probe معتبر ارسال می‌شود.

Markerها بایت‌های ثابت ASCII هستند و سازوکار امنیتی محسوب نمی‌شوند.

مرحله‌های سرور

پیاده‌سازی از سه فاز استفاده می‌کند:

فازرفتار
wait pingبایت‌های upstream تا رسیدن دست‌کم ۵ بایت بافر می‌شوند.
wait payloadProbe معتبر بوده و FISH! فرستاده شده است؛ با این حال next هنوز مقداردهی نشده، مگر اینکه payload اضافه از قبل در بافر باشد.
establishednext مقداردهی شده و callbackهای payload و lifecycle به‌طور عادی عبور داده می‌شوند.

جریان Handshake

با دریافت Init در upstream، سرور فقط state محلی line را مقداردهی اولیه می‌کند و هنوز tunnelNextUpStreamInit() را فراخوانی نمی‌کند.

پردازش payloadِ upstream پیش از برقراری کامل:

  1. سرور بایت‌های ورودی را بافر می‌کند.
  2. اگر بافر handshake از 4096 بایت بگذرد، line بسته می‌شود.
  3. وقتی حداقل ۵ بایت در دسترس باشد، ۵ بایت اول خوانده می‌شوند.
  4. اگر دقیقاً FISH? نباشند، line بسته می‌شود.
  5. اگر منطبق باشند، FISH! در جهت downstream به سمت previous فرستاده می‌شود.
  6. اگر پس از پنج بایت اول payloadی مانده باشد، سرور next را مقداردهی اولیه می‌کند و payload باقی‌مانده را در upstream می‌فرستد.
  7. اگر 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 وجود ندارد.

محدودیت‌ها

محدودیتمقداررفتار
طول probe5 بایتپنج بایت نخست باید FISH? باشند.
Handshake buffer4096 بایتاگر پیش از کامل شدن probe بایت‌های بیشتری جمع شوند، line بسته می‌شود.
required_padding_left0سرور چیزی به بافرهای موجود اضافه نمی‌کند.

برای پاسخ FISH! یک بافر کوچک جداگانه گرفته می‌شود.

نکته‌ها

  • با ConnectionFisherClient متناظر استفاده کنید.
  • آن را پس از هر تونل سمت سرور قرار دهید که transport میان کلاینت و سرور را decode می‌کند.
  • برای chainهای stream طراحی شده است، نه packet-line.
  • probe ثابت و عمومی است؛ برای امنیت واقعی از نودهای دیگر WaterWall استفاده کنید.
  • upstream Est و downstream Init برای این نود غیرفعال هستند.