TcpUdpListener
TcpUdpListener یک wrapper در ابتدای chain است که TcpListener و UdpListener را زیر یک نود جمع میکند. با تنظیمات یکسان، یک listener داخلی برای TCP و یکی برای UDP میسازد تا یک ورودی WaterWall بتواند هر دو نوع ترافیک را روی address و مجموعه port یکسان بپذیرد.
این نود TCP را به UDP یا UDP را به TCP تبدیل نمیکند؛ فقط ترافیک ورودی هر دو adapter را به یک نود بعدی مشترک میفرستد.
جایگاه رایج
وقتی یک ورودی باید هم TCP و هم UDP را بپذیرد، از TcpUdpListener استفاده کنید:
TcpUdpListener -> SpeedTestServer
TcpUdpListener -> SniffRouter -> TcpUdpConnector
TcpUdpListener -> Router -> ...
نود بعدی باید توان کار با ترافیک ورودی را داشته باشد. اگر در محیط production هر دو نوع TCP و UDP وارد میشوند، نود بعدی باید هم lineهای معمولی TCP و هم lineهای peer در UDP را پشتیبانی کند، یا آنها را بر اساس protocol مسیریابی کند.
نمونه ساده
[
{
"name": "mixed-in",
"type": "TcpUdpListener",
"settings": {
"address": "0.0.0.0",
"port": 443,
"nodelay": true,
"large-send-buffer": true,
"large-recv-buffer": true
},
"next": "mixed-out"
},
{
"name": "mixed-out",
"type": "TcpUdpConnector",
"settings": {
"address": "127.0.0.1",
"port": 8443,
"reuseaddr": true,
"nodelay": true
}
}
]
در این مثال، TcpListener داخلی ترافیک TCP پورت 443 را میفرستد و UdpListener داخلی ترافیک UDP همان پورت را. TcpUdpConnector در انتهای chain با توجه به protocol ثبتشده در metadata هر line، خروجی TCP یا UDP را انتخاب میکند.
نمونه multiport
{
"name": "mixed-public-entry",
"type": "TcpUdpListener",
"settings": {
"address": "0.0.0.0",
"port": [
443,
8443
],
"nodelay": true,
"large-send-buffer": true,
"large-recv-buffer": true,
"interface": "eth0",
"fwmark": 10,
"balance-group": "public-mixed",
"balance-interval": 30000,
"multiport-backend": "socket",
"whitelist": [
"192.0.2.0/24",
"2001:db8::/64"
],
"blacklist": [
"192.0.2.99/32"
]
},
"next": "next-node"
}
همین فهرست port برای TCP و UDP به کار میرود. پورت TCP شماره 443 و پورت UDP شماره 443 دو socket جدا هستند و میتوانند همزمان bind شوند.
فیلدهای ضروری
فیلدهای سطح بالا:
| فیلد | نوع | توضیح |
|---|---|---|
name | string | نام دلخواه نود. باید داخل فایل config یکتا باشد. |
type | string | باید دقیقاً "TcpUdpListener" باشد. |
settings | object | تنظیمات مشترک هر دو listener داخلی؛ باید objectی غیرخالی باشد. |
next | string | نودی که هم TCP lineها و هم UDP peer lineها را دریافت میکند. |
فیلدهای ضروری داخل settings:
| فیلد | نوع | توضیح |
|---|---|---|
address | string | آدرس bind محلی برای هر دو child listener. |
port یا port-range | عدد، آرایه، یا آرایه بازه | portهایی که هر دو listener TCP و UDP استفاده میکنند. باید دقیقاً یکی از این دو فیلد را بنویسید. |
تنظیم پورت
syntax تعریف پورت در TcpUdpListener همان syntax مورد استفاده TcpListener و UdpListener است.
یک پورت
{
"settings": {
"address": "0.0.0.0",
"port": 443
}
}
لیست پورت مشخص
{
"settings": {
"address": "0.0.0.0",
"port": [
443,
8443,
2083
]
}
}
این حالت فقط روی پورتهای لیستشده برای هر دو TCP و UDP گوش میدهد.
بازه پیوسته
{
"settings": {
"address": "0.0.0.0",
"port-range": [
40000,
40100
]
}
}
port-range باید یک آرایه دو عضوی باشد: [min, max].
تنظیمات اختیاری
چون object یکسان settings به هر دو listener داخلی داده میشود، بیشتر گزینهها همانهایی هستند که در صفحههای TcpListener و UdpListener توضیح داده شدهاند.
| گزینه | روی کدام child اثر دارد | توضیح |
|---|---|---|
nodelay | TCP child | فعالسازی TCP_NODELAY روی socketهای TCP پذیرفتهشده. |
large-send-buffer | TCP و UDP children | تنظیم SO_SNDBUF در صورت پشتیبانی. |
large-recv-buffer | TCP و UDP children | تنظیم SO_RCVBUF در صورت پشتیبانی. |
interface | TCP و UDP children | محدود کردن socketها به یک interface محلی در صورت پشتیبانی. |
fwmark | TCP و UDP children | اعمال socket mark به سبک Linux در صورت پشتیبانی. |
balance-group | TCP و UDP children | listenerهای سازگار و همپورت را برای توزیع sticky در یک گروه قرار میدهد. |
balance-interval | TCP و UDP children | مدت حفظ شدن client یا peer تکراری روی یک عضو از balance group. |
initial-idle-timeout-ms | TCP child | timeout اولیه idle قبل از فعالیت payload TCP سمت listener. |
active-idle-timeout-ms | TCP child | timeout idle بعد از شروع فعالیت TCP. |
multiport-backend | TCP و UDP children | backend برای port-range پیوسته: "iptables" یا "socket". |
whitelist | TCP و UDP children | IPها و محدودههای CIDR مجاز برای client یا peer. |
blacklist | TCP و UDP children | IPها و محدودههای CIDR مسدود برای client یا peer. |
برای جزئیات گزینههای socket، پیشفرض timeoutها و تنظیمات multiport، به صفحههای TcpListener و UdpListener مراجعه کنید.
جریان runtime
هنگام راهاندازی، TcpUdpListener دو tunnel داخلی میسازد:
TcpListenerبا نامی شبیه<node-name>.tcp-listenerUdpListenerبا نامی شبیه<node-name>.udp-listener
هر دو نود داخلی در chain قرار میگیرند و مالک socketهای واقعی و lifecycle مربوط به lineهای خود هستند:
TcpListenerداخلی socketهای TCP را میپذیرد و lineهای TCP را میسازدUdpListenerداخلی برای peerهای UDP line میسازد- callbackهای upstream هر دو نود داخلی وارد
TcpUdpListenerمیشوند TcpUdpListenercallbackهای upstream شاملInit،Payload،Pause،Resume،EstوFinishرا بهnextمیفرستد
در مسیر downstream، callback نود بعدی به TcpUdpListener میرسد. wrapper سپس source protocol ثبتشده روی line را بررسی میکند:
| metadata protocol source | child downstream |
|---|---|
| TCP | child داخلی TcpListener |
| UDP | child داخلی UdpListener |
| protocol نامشخص یا flag مبهم TCP/UDP | خطای fatal در config یا routing |
به همین دلیل، نودهای بعد از TcpUdpListener باید metadata مربوط به source protocol را روی line حفظ کنند.
مالکیت line
TcpUdpListener خودش per-line state ندارد، line نمیسازد و lineDestroy() را هم فراخوانی نمیکند.
مالکیت هر line در اختیار همان adapter داخلی میماند که آن را ساخته است:
- TCP lineها متعلق به child داخلی
TcpListenerهستند - UDP peer lineها متعلق به child داخلی
UdpListenerهستند
متادیتای نود
| ویژگی | مقدار |
|---|---|
| Node flag | kNodeFlagChainHead |
| نود قبلی | مجاز نیست |
| نود بعدی | لازم است |
| layer group | kNodeLayer4 |
required_padding_left | 0 |
| اندازه line state | 0 |
اشتباههای رایج
- از
TcpUdpListenerبهعنوان protocol converter استفاده نکنید؛ هر دو protocol را میپذیرد، اما یکی را به دیگری تبدیل نمیکند. - آن را به نود بعدی که فقط TCP را میفهمد وصل نکنید اگر ترافیک UDP هم ممکن است بیاید.
- نمیتوان برای TCP و UDP دو مجموعه port متفاوت روی این wrapper تعریف کرد؛ هر دو listener همان
settingsرا دریافت میکنند. - metadata مربوط به source protocol را پیش از بازگشت callbackهای downstream به این نود حذف یا خراب نکنید.