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

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 واقعی به مسیر خود ادامه می‌دهد.

فیلدهای لازم​

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

فیلدنوعتوضیح
namestringنام دلخواه node که باید در فایل config یکتا باشد.
typestringباید دقیقاً "JunkDatagramSender" باشد.
settingsobjectobject تنظیمات اختیاری؛ تنظیمات خالی از مقادیر پیش‌فرض استفاده می‌کند.
nextstringدر metadata node اختیاری است، اما معمولاً نام تونل بعدی را می‌گیرد که payloadِ upstream را دریافت می‌کند.

تنظیمات​

گزینهنوعپیش‌فرضتوضیح
packet-count-perline-mininteger1کمترین تعداد payloadِ junk برای هر trigger. مقادیر منفی به 0 محدود می‌شوند.
packet-count-perline-maxinteger1حداکثر تعداد junk payload تولیدشده برای هر trigger. مقادیر منفی به 0 و بالاتر از 256 به 256 clamp می‌شوند. اگر کمتر از min باشد، به min clamp می‌شود.
resend-again-timesinteger1تعداد callback‌های payloadِ upstream که روی هر line ارسال junk را فعال می‌کنند. مقدار 0 این ارسال را غیرفعال می‌کند. مقادیر منفی به 0 و مقادیر بالاتر از 256 به 256 محدود می‌شوند.
selected-protocolsarray از stringهمه protocol‌های پیاده‌سازی‌شدهgenerator protocol‌هایی که برای انتخاب random واجد شرایط هستند. اگر حذف شود، از همه generator‌های پیاده‌سازی‌شده استفاده می‌شود. array خالی قابل قبول است اما node را به pass-through بدون junk تبدیل می‌کند.
keep-sending-max-msinteger0مقدار 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-http3quic، http3، http/3، quic/http3
rtp-rtcp-srtprtp، rtcp، srtp
stun-turn-icestun، turn، ice
mdnsندارد
snmpندارد
syslogندارد
ipsec-nat-tipsec-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شکل تولیدشده
dnspayload‌های DNS query، گاهی با داده EDNS(0)-style.
dhcppayload‌های client-message DHCPv4.
ntppayload‌های client request NTP.
quic-http3payload‌های QUIC Initial-like با HTTP/3 ALPN data.
rtp-rtcp-srtppayload‌های RTP media، RTCP control و SRTP-shaped.
stun-turn-icepayload‌های STUN، TURN و ICE connectivity یا relay-control.
mdnspayload‌های multicast DNS query و announcement.
snmppayload‌های SNMP v1/v2c manager request.
syslogپیام‌های syslog به سبک RFC3164/RFC5424.
ipsec-nat-tpayload‌های NAT-T keepalive، IKEv2 و ESP-in-UDP-shaped.
sippayload‌های SIP request و response.

node آرگومان‌های generator را با بازه هدف پیش‌فرض 12 تا 1200 بایت می‌فرستد. generator‌های مختلف ممکن است با توجه به قالب پروتکل، اندازه‌های ثابتی انتخاب کنند.

رفتار جهت‌ها​

callback ورودیرفتار
upstream Initstate مربوط به line را مقداردهی اولیه می‌کند و سپس Init را به next می‌فرستد.
upstream Payloadاگر trigger باقی مانده باشد مجموعه junk را می‌فرستد و سپس payload واقعی را به next عبور می‌دهد.
upstream Est / Pause / Resumeبه next فرستاده می‌شوند.
upstream Finishstate محلی line را از بین می‌برد و سپس Finish را به next می‌فرستد.
downstream Initstate مربوط به line را مقداردهی اولیه می‌کند و سپس Init را به node قبلی می‌فرستد.
downstream Payloadبدون تغییر به node قبلی می‌رود.
downstream Est / Pause / Resumeبه node قبلی فرستاده می‌شوند.
downstream Finishstate محلی 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: 0 node را به pass-through تبدیل می‌کند.
  • packet-count-perline-max: 0 node را به 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 flagskNodeFlagSupportsSplice
can_have_prevtrue
can_have_nexttrue
layer_groupkNodeLayerAnything
layer_group_prev_nodekNodeLayerSameAsNext
layer_group_next_nodekNodeLayerSameAsPrev
required_padding_left0 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 را فعال نمی‌کند.