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

PacketSender

PacketSender یک تولیدکننده packet لایه ۳ برای IPv4 است. این نود هنگام startup، packetهای خام IPv4 را از پیش می‌سازد و در مدت تعیین‌شده آن‌ها را روی worker packet lineهای واتروال می‌فرستد.

کاربرد اصلی آن آزمایش کنترل‌شده مسیر packet است. در کنار PacketReceiver می‌توان از آن برای پیدا کردن source IPهای قابل دسترس یا مجاز در محیط‌های محدودشده بر اساس IP استفاده کرد: از بازه‌های پیشنهادی packet بسازید، آن‌ها را از مسیر مورد نظر بفرستید و سپس گزارش گیرنده را بررسی کنید تا مشخص شود packetهای کدام source IP رسیده‌اند.

هشدار

این نود را فقط روی شبکه‌ها و بازه‌های آدرسی به کار ببرید که مجوز آزمایش آن‌ها را دارید. نتیجه آزمایش source IP به شبکه سمت sender نیز وابسته است. اگر provider، مسیر kernel، backend مربوط به raw socket یا شبکه upstream آدرس‌های source غیرمحلی را مسدود کند، ممکن است packetهای تولیدشده اصلاً از sender خارج نشوند.

جایگاه رایج

خروجی raw IPv4:

PacketSender -> RawSocket

همراه packet manipulation:

PacketSender -> IpManipulator -> RawSocket

Packet transport شبیه WireGuard:

PacketSender -> WireGuardDevice -> UdpStatelessSocket

سمت receiver متناظر:

RawSocket -> PacketReceiver

PacketSender یک adapter از نوع chain-head و singleton است. باید در ابتدای یک chain لایه ۳ قرار بگیرد و وجود next برای آن الزامی است.

چه کاری انجام می‌دهد

  • یک بازه CIDR برای source IPv4 یا آرایه‌ای از این بازه‌ها را می‌پذیرد.
  • یک آدرس IPv4 برای destination می‌پذیرد.
  • برای TCP، UDP، ICMP یا ALL packet خام IPv4 می‌سازد.
  • برای هر source IP به تعداد packets-per-ip تکرار ارسال می‌کند.
  • پیش از آغاز ارسال، کل packet store را در حافظه می‌سازد.
  • indexهای packet را میان workerها تقسیم می‌کند.
  • با تعیین deadline برای هر packet، ارسال‌ها را در طول duration-ms پخش می‌کند.
  • پیش از هر ارسال، routing context روی packet line را به‌روزرسانی می‌کند.
  • پس از پایان ارسال، worker packet lineها را نمی‌بندد و برایشان Finish نمی‌فرستد.
  • اگر سمت downstream روی worker packet line مربوطه Finish بفرستد، timer و حلقه ارسال آن worker را متوقف می‌کند.

بازه‌های source به همان ترتیبی که در config آمده‌اند پردازش می‌شوند و ارسال آن‌ها با هم interleave نمی‌شود.

تست Source-IP Allowlist

PacketSender و PacketReceiver برای سناریوهایی مناسب‌اند که دسترسی به مسیر یا سرویس بر اساس source IP محدود شده است. روال معمول چنین است:

  1. PacketSender را با مقدارهای candidate برای source-ipv4-range تنظیم کنید.
  2. PacketReceiver را با همان rangeها تنظیم کنید.
  3. packetها را به سمت host یا packet chain گیرنده بفرستید.
  4. report گیرنده را بخوانید.
  5. source IPهایی را که تحویل کامل یا نزدیک به کامل دارند به‌عنوان گزینه‌های بهتر در نظر بگیرید.

برای modeهای single-protocol، مقدار PacketReceiver.expected-packets-per-ip را برابر PacketSender.packets-per-ip بگذارید. برای protocol-number: "ALL" مقدار آن باید packets-per-ip * 255 باشد.

نمونه تنظیم

ICMP probing:

{
"name": "packet-sender",
"type": "PacketSender",
"settings": {
"source-ipv4-range": [
"198.51.100.0/24",
"203.0.113.0/24"
],
"dest-ipv4": "203.0.113.20",
"protocol-number": "ICMP",
"duration-ms": 5000,
"packets-per-ip": 100
},
"next": "raw-ip"
}

TCP-shaped probing:

{
"name": "packet-sender",
"type": "PacketSender",
"settings": {
"source-ipv4-range": "198.51.100.0/24",
"dest-ipv4": "203.0.113.20",
"protocol-number": "TCP",
"duration-ms": 5000,
"packets-per-ip": 10,
"dest-port": 443,
"src-port": "random"
},
"next": "raw-ip"
}

فیلدهای ضروری

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

فیلدنوعتوضیح
namestringنام دلخواه نود. باید داخل فایل config یکتا باشد.
typestringباید دقیقاً "PacketSender" باشد.
settingsobjectلازم است و نباید خالی باشد.
nextstringلازم است. نود لایه ۳ بعدی packetهای تولیدشده را دریافت می‌کند.

فیلدهای ضروری داخل settings:

فیلدنوعتوضیح
source-ipv4-rangestring یا آرایه stringیک CIDR range از نوع IPv4، یا آرایه‌ای از CIDR rangeهای IPv4.
dest-ipv4stringآدرس IPv4 مقصد. باید IPv4 تکی باشد، نه CIDR.
protocol-numberstringیکی از TCP، UDP، ICMP یا ALL. به حروف کوچک و بزرگ حساس نیست.
duration-msintegerمدت ارسال مثبت، بر حسب میلی‌ثانیه.
dest-portintegerبرای TCP، UDP و ALL لازم است. باید non-zero و در بازه 0..65535 باشد.
src-portinteger یا "random"برای TCP، UDP و ALL لازم است. باید non-zero یا "random" باشد.

dest-port و src-port برای ICMP لازم نیستند.

تنظیمات اختیاری

گزینهنوعپیش‌فرضتوضیح
packets-per-ipinteger1تعداد repeat مثبت برای هر source IP. در mode ALL، هر repeat تعداد 255 protocol variant می‌فرستد.

وقتی src-port برابر "random" باشد، پیاده‌سازی فعلی بر اساس source IP، destination IP و protocol یک port ثابت از بازه ephemeral یعنی 49152..65535 انتخاب می‌کند. این انتخاب برای شکل packet تولیدشده deterministic است و برای هر packet دوباره تصادفی نمی‌شود.

شکل Packetهای تولیدشده

همه packetهای تولیدشده IPv4 هستند و این ویژگی‌ها را دارند:

فیلدمقدار
TTL64
fragment flagDon't Fragment (DF)
source IPیک آدرس از source-ipv4-range
destination IPdest-ipv4
checksumsپیش از ساخته شدن packet store محاسبه می‌شوند

شکل‌های protocol-specific:

protocol-numberpacket تولیدشده
TCPTCP segment حداقلی با flag ACK، sequence/ack numberهای deterministic، portهای تنظیم‌شده و checksum معتبر.
UDPUDP datagram حداقلی با portهای تنظیم‌شده و checksum معتبر.
ICMPICMP echo request با identifier/sequence deterministic و checksum معتبر.
ALLبرای هر source IP و هر تکرار، یک packet برای protocol numberهای 0 تا 254 می‌سازد. Protocolهای 6، 17 و 1 به‌ترتیب شکل معتبر TCP، UDP و ICMP دارند؛ سایر موارد packetهای IPv4 با payload هشت‌بایتی opaque هستند.

Mode ALL در هر repeat تعداد 255 protocol variant تولید می‌کند، نه 256.

زمان‌بندی و Workerها

پیش از شروع runtime، PacketSender همه packetها را در یک packet store پیوسته می‌سازد. هنگام startup:

  • indexهای کل packetها میان workerها تقسیم می‌شوند
  • هر worker از worker packet line پایدار خودش استفاده می‌کند
  • هر packet بر اساس index و duration-ms یک deadline سراسری می‌گیرد
  • workerها packetهای آماده را می‌فرستند و اگر زمان packet بعدی هنوز نرسیده باشد، one-shot timer را دوباره فعال می‌کنند

به این ترتیب packetها در تمام مدت تعیین‌شده پخش می‌شوند و کل store یک‌باره به‌صورت burst ارسال نمی‌شود. اگر موعد چند packet هم‌زمان برسد، ممکن است یک worker آن‌ها را پشت سر هم بفرستد.

محدودیت‌ها

  • تعداد کل source IPها باید داخل uint32_t جا شود.
  • تعداد کل packetها باید داخل uint64_t جا شود.
  • تعداد کل byteهای packet materialized باید داخل size_t جا شود.
  • packet store materialized به 8 GiB محدود است.
  • required_padding_left = 0.

Rangeهای بزرگ، mode ALL و مقدارهای زیاد packets-per-ip مصرف حافظه را سریع بالا می‌برند. در صورت نیاز تست‌های بزرگ را به rangeهای کوچک‌تر یا چند run جدا تقسیم کنید.

معناشناسی Packet-Line

PacketSender از worker packet lineهایی استفاده می‌کند که chain ساخته است. این‌ها lineهای کمکی و پایدار هر worker هستند، نه lineهای جداگانه برای هر connection.

PacketSender packet lineها را از بین نمی‌برد و Finish را نشانه تکمیل موفق نمی‌داند. یک Finish از سمت downstream، timer و حلقه ارسال worker مربوطه را برای همیشه متوقف می‌کند؛ در حالت تکمیل عادی، فقط زمانی در log ثبت می‌شود که همه packetهای تخصیص‌یافته ارسال شده باشند.

نکته‌های عملی

  • سمت target از PacketReceiver استفاده کنید تا count تحویل per-source را بگیرید.
  • مقدار report-after-ms روی PacketReceiver را بیشتر از duration-ms سمت sender به علاوه delay و reordering time احتمالی network تنظیم کنید.
  • وقتی اجازه داده شده، برای probing ساده مسیر از ICMP استفاده کنید.
  • وقتی محیط محدودشده رفتار متفاوتی بر اساس protocol یا port دارد، از TCP، UDP یا ALL استفاده کنید.
  • اگر شبکه سمت sender اعتبارسنجی source address انجام دهد، ممکن است بازه‌های source جعلی یا غیرمحلی پیش از رسیدن به peer واتروال فیلتر شوند.