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یاALLpacket خام 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 محدود شده است. روال معمول چنین است:
PacketSenderرا با مقدارهای candidate برایsource-ipv4-rangeتنظیم کنید.PacketReceiverرا با همان rangeها تنظیم کنید.- packetها را به سمت host یا packet chain گیرنده بفرستید.
- report گیرنده را بخوانید.
- 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"
}
فیلدهای ضروری
فیلدهای سطح بالا:
| فیلد | نوع | توضیح |
|---|---|---|
name | string | نام دلخواه نود. باید داخل فایل config یکتا باشد. |
type | string | باید دقیقاً "PacketSender" باشد. |
settings | object | لازم است و نباید خالی باشد. |
next | string | لازم است. نود لایه ۳ بعدی packetهای تولیدشده را دریافت میکند. |
فیلدهای ضروری داخل settings:
| فیلد | نوع | توضیح |
|---|---|---|
source-ipv4-range | string یا آرایه string | یک CIDR range از نوع IPv4، یا آرایهای از CIDR rangeهای IPv4. |
dest-ipv4 | string | آدرس IPv4 مقصد. باید IPv4 تکی باشد، نه CIDR. |
protocol-number | string | یکی از TCP، UDP، ICMP یا ALL. به حروف کوچک و بزرگ حساس نیست. |
duration-ms | integer | مدت ارسال مثبت، بر حسب میلیثانیه. |
dest-port | integer | برای TCP، UDP و ALL لازم است. باید non-zero و در بازه 0..65535 باشد. |
src-port | integer یا "random" | برای TCP، UDP و ALL لازم است. باید non-zero یا "random" باشد. |
dest-port و src-port برای ICMP لازم نیستند.
تنظیمات اختیاری
| گزینه | نوع | پیشفرض | توضیح |
|---|---|---|---|
packets-per-ip | integer | 1 | تعداد 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 هستند و این ویژگیها را دارند:
| فیلد | مقدار |
|---|---|
| TTL | 64 |
| fragment flag | Don't Fragment (DF) |
| source IP | یک آدرس از source-ipv4-range |
| destination IP | dest-ipv4 |
| checksums | پیش از ساخته شدن packet store محاسبه میشوند |
شکلهای protocol-specific:
protocol-number | packet تولیدشده |
|---|---|
TCP | TCP segment حداقلی با flag ACK، sequence/ack numberهای deterministic، portهای تنظیمشده و checksum معتبر. |
UDP | UDP datagram حداقلی با portهای تنظیمشده و checksum معتبر. |
ICMP | ICMP 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 واتروال فیلتر شوند.