JunkDatagramSender
JunkDatagramSender تونلی میانی و قابل ترکیب است که پیش از نخستین payloadِ upstream روی هر line، چند payload ساختگی شبیه datagramهای UDP تزریق میکند.
این node برای آزمایش استتار و نویز پروتکل در مسیرهای شبیه UDP طراحی شده است و payload واقعی را تغییر نمیدهد. با رسیدن payloadِ upstream، ممکن است ابتدا مجموعهای تصادفی از payloadهای junk را به next بفرستد و سپس داده واقعی را بدون تغییر عبور دهد.
JunkDatagramSender یک تونل عادی با state مخصوص هر line است. Adapter مبتنی بر socket یا packet tunnel خام IPv4 نیست و objectای از نوع line_t نمیسازد و آزاد نمیکند.
جایگاه رایج
مسیر UDP-style:
UdpListener -> JunkDatagramSender -> UdpConnector
با nodeهای دیگری که datagram را حفظ میکنند:
UdpListener -> JunkDatagramSender -> EncryptionClient -> UdpConnector
در جایی از آن استفاده کنید که انتظار میرود یک WaterWall payload مثل یک datagram رفتار کند. در مسیرهای TCP stream معمولی، payloadهای junk به بایتهای اضافه تبدیل میشوند که معمولاً application protocol انتظارش را ندارد.
این نود چه میکند؟
- شمارنده triggerهای باقیمانده هر line را از
resend-again-timesمقداردهی اولیه میکند. - junk را فقط وقتی upstream payload callback برسد میفرستد.
- junk را قبل از upstream payload واقعی میفرستد.
- تعدادی تصادفی payloadِ junk میان
packet-count-perline-minوpacket-count-perline-maxمیفرستد. - generator پروتکل هر payloadِ junk را بهطور تصادفی از
selected-protocolsانتخاب میکند. - میتواند ارسال یک کپی با تأخیر از هر payloadِ junk را زمانبندی کند.
- پس از مجموعه junk، payload واقعی upstream را بدون تغییر عبور میدهد.
- payloadهای downstream و callbackهای
Est،PauseوResumeرا بدون تغییر در همان جهت عبور میدهد. - پیش از انتشار
Finishدر هر جهت، state محلی line را از بین میبرد.
اگر هنگام ساخت یا ارسال junk، line پیش از فرستادن payload واقعی بسته شود، node buffer داده واقعی را برای استفاده مجدد برمیگرداند و از callback خارج میشود.
نمونه تنظیم
{
"name": "junk",
"type": "JunkDatagramSender",
"settings": {
"packet-count-perline-min": 2,
"packet-count-perline-max": 5,
"resend-again-times": 2,
"selected-protocols": [
"dns",
"ntp",
"quic-http3",
"rtp-rtcp-srtp"
],
"keep-sending-max-ms": 1500
},
"next": "udp-out"
}
با تنظیمات پیشفرض، رسیدن نخستین upstream payload روی هر line باعث تولید یک junk payload میشود؛ سپس payload واقعی به مسیر خود ادامه میدهد.
فیلدهای لازم
فیلدهای سطح اصلی:
| فیلد | نوع | توضیح |
|---|---|---|
name | string | نام دلخواه node که باید در فایل config یکتا باشد. |
type | string | باید دقیقاً "JunkDatagramSender" باشد. |
settings | object | object تنظیمات اختیاری؛ تنظیمات خالی از مقادیر پیشفرض استفاده میکند. |
next | string | در metadata node اختیاری است، اما معمولاً نام تونل بعدی را میگیرد که payloadِ upstream را دریافت میکند. |
تنظیمات
| گزینه | نوع | پیشفرض | توضیح |
|---|---|---|---|
packet-count-perline-min | integer | 1 | کمترین تعداد payloadِ junk برای هر trigger. مقادیر منفی به 0 محدود میشوند. |
packet-count-perline-max | integer | 1 | حداکثر تعداد junk payload تولیدشده برای هر trigger. مقادیر منفی به 0 و بالاتر از 256 به 256 clamp میشوند. اگر کمتر از min باشد، به min clamp میشود. |
resend-again-times | integer | 1 | تعداد callbackهای payloadِ upstream که روی هر line ارسال junk را فعال میکنند. مقدار 0 این ارسال را غیرفعال میکند. مقادیر منفی به 0 و مقادیر بالاتر از 256 به 256 محدود میشوند. |
selected-protocols | array از string | همه protocolهای پیادهسازیشده | generator protocolهایی که برای انتخاب random واجد شرایط هستند. اگر حذف شود، از همه generatorهای پیادهسازیشده استفاده میشود. array خالی قابل قبول است اما node را به pass-through بدون junk تبدیل میکند. |
keep-sending-max-ms | integer | 0 | مقدار 0 delayed duplicate sends را غیرفعال میکند. وقتی بزرگتر از 0 باشد، هر junk payload تولیدشده یک بار duplicate میشود و با delay random از 1 تا این مقدار به میلیثانیه schedule میشود. مقادیر منفی delayed send را غیرفعال میکنند. |
رفتار trigger
resend-again-times تعداد callbackهای payloadِ upstream را میشمارد، نه تعداد بایتها یا تلاشهای اتصال را.
مثلاً:
{
"packet-count-perline-min": 2,
"packet-count-perline-max": 4,
"resend-again-times": 3
}
روی هر line، هریک از سه callback نخست payloadِ upstream مجموعهای تصادفی شامل 2 تا 4 payloadِ junk تولید میکنند. payload چهارم و بعدی بدون junk اضافه عبور داده میشوند.
هیچ junkای در طول Init بهتنهایی فرستاده نمیشود. node منتظر میماند تا یک upstream payload واقعی برسد.
انتخاب Protocol
نامهای اصلی قابل قبول:
| نام اصلی | نامهای مستعار قابل قبول |
|---|---|
dns | ندارد |
dhcp | ندارد |
ntp | ندارد |
quic-http3 | quic، http3، http/3، quic/http3 |
rtp-rtcp-srtp | rtp، rtcp، srtp |
stun-turn-ice | stun، turn، ice |
mdns | ندارد |
snmp | ندارد |
syslog | ندارد |
ipsec-nat-t | ipsec-natt، natt |
sip | ندارد |
از "all" داخل selected-protocols استفاده کنید تا صریحاً همه generatorهای پیادهسازیشده فعال شوند:
{
"selected-protocols": ["all"]
}
در پیادهسازی فعلی، نام protocolها به بزرگی و کوچکی حروف حساس نیست. نامهای این مستند با حروف کوچک نوشته شدهاند.
نامهای Protocol غیرفعال
نامهای زیر فقط placeholderهای غیرفعال هستند. اگر هریک در selected-protocols باشند، راهاندازی شکست میخورد:
| نام غیرفعال | یادداشت |
|---|---|
tftp | فقط placeholder generator |
ssdp | فقط placeholder generator |
radius | فقط placeholder generator |
gtp-u / gtpu | فقط placeholder generator |
game-udp-protocols / game-udp / game | فقط placeholder generator |
coap | فقط placeholder generator |
انواع Payload تولیدشده
ماژولهای پیادهسازیشده payloadهایی شبیه داده برنامه UDP میسازند، نه headerِ UDP/IP:
| protocol | شکل تولیدشده |
|---|---|
dns | payloadهای DNS query، گاهی با داده EDNS(0)-style. |
dhcp | payloadهای client-message DHCPv4. |
ntp | payloadهای client request NTP. |
quic-http3 | payloadهای QUIC Initial-like با HTTP/3 ALPN data. |
rtp-rtcp-srtp | payloadهای RTP media، RTCP control و SRTP-shaped. |
stun-turn-ice | payloadهای STUN، TURN و ICE connectivity یا relay-control. |
mdns | payloadهای multicast DNS query و announcement. |
snmp | payloadهای SNMP v1/v2c manager request. |
syslog | پیامهای syslog به سبک RFC3164/RFC5424. |
ipsec-nat-t | payloadهای NAT-T keepalive، IKEv2 و ESP-in-UDP-shaped. |
sip | payloadهای SIP request و response. |
node آرگومانهای generator را با بازه هدف پیشفرض 12 تا 1200 بایت میفرستد. generatorهای مختلف ممکن است با توجه به قالب پروتکل، اندازههای ثابتی انتخاب کنند.
رفتار جهتها
| callback ورودی | رفتار |
|---|---|
upstream Init | state مربوط به line را مقداردهی اولیه میکند و سپس Init را به next میفرستد. |
upstream Payload | اگر trigger باقی مانده باشد مجموعه junk را میفرستد و سپس payload واقعی را به next عبور میدهد. |
upstream Est / Pause / Resume | به next فرستاده میشوند. |
upstream Finish | state محلی line را از بین میبرد و سپس Finish را به next میفرستد. |
downstream Init | state مربوط به line را مقداردهی اولیه میکند و سپس Init را به node قبلی میفرستد. |
downstream Payload | بدون تغییر به node قبلی میرود. |
downstream Est / Pause / Resume | به node قبلی فرستاده میشوند. |
downstream Finish | state محلی line را از بین میبرد و سپس Finish را به node قبلی میفرستد. |
کد منبع یک helper برای junk در downstream دارد، اما مسیر فعال payload تنها در callbackِ payloadِ upstream ارسال junk را آغاز میکند.
ایمنی Line
JunkDatagramSender یک شمارنده و gateهای جهتدار Finish را برای هر line نگه میدارد:
remaining_resend_again_times
upstream_finished / downstream_finished
هنگام پردازش payloadِ upstream، node برای فرستادن مجموعه junk با lineRef() یک reference موقت از line نگه میدارد، سپس lineIsAlive() را بررسی و reference را با lineUnref() آزاد میکند. این reference فقط تخصیص حافظه را نگه میدارد و قفل یا دسترسی میانworker ایجاد نمیکند. کپیهای تأخیردار best-effort هستند و در همهٔ نتیجههای submission مالکیت buffer را به lineScheduleDelayedTaskWithBuf() منتقل میکنند. scheduler اگر line عادی پیش از اجرا بسته شده باشد buffer را آزاد میکند. packet line تا نابودی chain زنده میماند؛ بنابراین Finish در هر جهت هر دو gate را میبندد و کپیای که قبلاً زمانبندی شده بهجای انتشار پس از callback پایانی recycle میشود.
این node lineDestroy() را فراخوانی نمیکند. state یک line عادی پیش از انتشار Finish نابود میشود؛ state مربوط به packet line با gateهای بسته تا cleanup همان worker باقی میماند.
یادداشتهای Buffer و Padding
JunkDatagramSender بایتی به ابتدای payload واقعی اضافه نمیکند و buffer آن را تغییر نمیدهد. برای payloadهای junk، bufferهای بزرگ و جداگانه میگیرد.
metadata node تنظیم میکند:
required_padding_left = 0
layer_group = kNodeLayerAnything
با اینکه metadata محدودیتی برای لایه نمیگذارد، داده تولیدی payloadی شبیه برنامه UDP است. این node را ابزاری برای دستکاری packetهای IPv4 در نظر نگیرید؛ برای تغییر packet خام از nodeهایی مانند IpManipulator یا IpOverrider استفاده کنید.
یادداشتهای عملی
resend-again-times: 0node را به pass-through تبدیل میکند.packet-count-perline-max: 0node را به pass-through تبدیل میکند.selected-protocols: []node را به pass-through تبدیل میکند و یک warning log میکند.keep-sending-max-msبرای هر payloadِ junk یک کپی با تأخیر زمانبندی میکند و ارسال را برای همیشه ادامه نمیدهد.- scheduler مربوط به line ترتیب کپیهای با تأخیر را تضمین نمیکند.
- این node آدرس، port، checksum یا headerِ packet را بازنویسی نمیکند.
- payloadهای تولیدشده تنها نویز استتاری هستند و رمزنگاری یا احراز هویت فراهم نمیکنند.
متادیتای نود
metadata برگرفته از کد منبع:
| ویژگی | مقدار |
|---|---|
| node flags | kNodeFlagSupportsSplice |
can_have_prev | true |
can_have_next | true |
layer_group | kNodeLayerAnything |
layer_group_prev_node | kNodeLayerSameAsNext |
layer_group_next_node | kNodeLayerSameAsPrev |
required_padding_left | 0 bytes |
پشتیبانی splice
دادهٔ junk تولیدشده و نسخههای تأخیری آن همچنان buffer عادی هستند. payload برنامه بدون بررسی بدنه عبور میکند و بدنهٔ pipe خصوصی و ترتیب فعلی نسبت به junk فوری حفظ میشود. جهت بستهشده ورودی را دور میریزد؛ اگر ارسال junk، line را ببندد، buffer برنامه که هنوز تحت مالکیت node است بازیافت میشود.
bufferهای عادیِ fallback همچنان پذیرفته میشوند. splice به build پشتیبانیشدهٔ Linux، فعالبودن misc.splice، نبود node packet و پشتیبانی همهٔ nodeهای chainِ نهایی پس از گسترش و ادغام نیاز دارد. flag قابلیت این بررسیها را دور نمیزند. بدون اندازهگیری، بهبود کارایی تضمین نمیشود.
config packet این node دولایه همچنان splice را فعال نمیکند.