SpeedTestClient
SpeedTestClient یک tunnel مصنوعی برای benchmark است که در ابتدای chain قرار
میگیرد. این نود lineهای معمول واتروال را میسازد، ترافیک frameشده speed-test را
به tunnel بعدی میفرستد، frameهای برگشتی از SpeedTestServer را اعتبارسنجی میکند
و گزارشهای دورهای و نهایی throughput را چاپ میکند.
این نود برای اندازهگیری کارایی یک chain یا مسیر transport در واتروال است. خودش socket باز نمیکند، application proxy نیست و packet-line tunnel هم محسوب نمیشود.
جایگاه رایج
SpeedTestClient باید نخستین نود chain باشد؛ lineهای آزمایش را خودش تولید میکند و آنها را به transport stack تنظیمشده میفرستد.
SpeedTestClient -> TcpConnector
SpeedTestClient -> UdpConnector
SpeedTestClient -> TlsClient -> TcpConnector
SpeedTestClient -> EncryptionClient -> TcpConnector
سمت remote معمولاً باید به SpeedTestServer متناظر ختم شود:
TcpListener -> SpeedTestServer
UdpListener -> SpeedTestServer
TcpListener -> TlsServer -> SpeedTestServer
TcpListener -> EncryptionServer -> SpeedTestServer
نمونه TCP
سمت client:
[
{
"name": "speedtest-client",
"type": "SpeedTestClient",
"settings": {
"mode": "tcp",
"direction": "bidirectional",
"duration-ms": 10000,
"warmup-ms": 1000,
"report-interval-ms": 1000,
"connection-count": 4,
"payload-size": 131072,
"terminate-on-complete": true
},
"next": "speedtest-out"
},
{
"name": "speedtest-out",
"type": "TcpConnector",
"settings": {
"address": "198.51.100.10",
"port": 9000,
"nodelay": true
}
}
]
سمت server:
[
{
"name": "speedtest-listener",
"type": "TcpListener",
"settings": {
"address": "0.0.0.0",
"port": 9000,
"nodelay": true
},
"next": "speedtest-server"
},
{
"name": "speedtest-server",
"type": "SpeedTestServer",
"settings": {
"report-interval-ms": 1000,
"json-summary": true
}
}
]
نمونه UDP
سمت client:
[
{
"name": "speedtest-client",
"type": "SpeedTestClient",
"settings": {
"mode": "udp",
"direction": "upload",
"duration-ms": 10000,
"warmup-ms": 1000,
"payload-size": 3800,
"udp-target-bits-per-sec": 10000000,
"terminate-on-complete": true
},
"next": "speedtest-udp-out"
},
{
"name": "speedtest-udp-out",
"type": "UdpConnector",
"settings": {
"address": "198.51.100.10",
"port": 9001
}
}
]
سمت server:
[
{
"name": "speedtest-udp-listener",
"type": "UdpListener",
"settings": {
"address": "0.0.0.0",
"port": 9001
},
"next": "speedtest-server"
},
{
"name": "speedtest-server",
"type": "SpeedTestServer"
}
]
فیلدهای لازم
وجود next برای SpeedTestClient الزامی است. نود بعدی همان مسیری است که ترافیک آزمایشی تولیدشده را دریافت میکند.
settings در عمل اختیاری است و در صورت حذف شدن، مقدارهای پیشفرض به کار میروند.
برای انتخاب mode، مدت، جهت، اندازه payload، تعداد stream، نرخ pacing یا قالب
خروجی مشخص، آن را اضافه کنید.
تنظیمات اختیاری
| فیلد | پیشفرض | توضیح |
|---|---|---|
mode | tcp | mode framing. مقدارهای مجاز: tcp, TCP, udp, UDP. |
direction | upload | جهت تست. مقدارهای مجاز: upload, UPLOAD, send, download, DOWNLOAD, receive, bidirectional, both, BOTH. |
duration-ms | 10000 | مدت اندازهگیری پس از warmup؛ باید مثبت باشد. |
warmup-ms | 0 | مدت warmup؛ باید منفی نباشد. frameهای warmup ارسال و اعتبارسنجی میشوند، اما در مجموع بایتهای اندازهگیریشده حساب نمیشوند. |
report-interval-ms | 1000 | فاصله میان گزارشهای دورهای؛ باید مثبت باشد. |
start-delay-ms | 50 | تأخیر آغاز هر stream پس از startup؛ باید منفی نباشد. |
timeout-ms | warmup-ms + duration-ms + 30000 | watchdog هر stream. باید بزرگتر از warmup-ms + duration-ms باشد. |
connection-count | 1 | تعداد lineهای معمول واتروال که بهصورت موازی ساخته میشوند؛ باید مثبت باشد. |
payload-size | TCP: 131072, UDP: 3800 | تعداد byte داخل payload فریم DATA، بدون هدر 48 بایتی speed-test. |
target-bits-per-sec | TCP: 0 | pacing اختیاری بر حسب bit/sec. مقدار 0 یعنی تا جایی که backpressure اجازه دهد ارسال شود. |
udp-target-bits-per-sec | UDP: 10000000 | pacing مخصوص UDP بر حسب bit/sec. |
target-megabits-per-sec | تنظیم نشده | فرم جایگزین pacing بر حسب megabit/sec. |
json-summary | false | علاوه بر logهای معمول، یک خلاصه فشرده شبیه JSON چاپ میکند. |
terminate-on-complete | true | پس از پایان همه streamها واتروال را متوقف میکند؛ exit code در حالت موفق 0 و در صورت خطا 1 است. |
تنها یکی از target-bits-per-sec، udp-target-bits-per-sec و target-megabits-per-sec را میتوان همزمان تنظیم کرد. مقدار پهنایباند نباید منفی باشد.
payload-size باید بین 1 و 16777216 باشد. در UDP حداکثر 64952 است، چون هر UDP payload یک فریم کامل speed-test با
هدر 48 بایتی دارد.
جریان Protocol
| Frame | جهت | کاربرد |
|---|---|---|
HELLO | client به server | mode، direction، duration، warmup، report interval، payload size، pacing، تعداد stream و stream id را اعلام میکند. |
ACK | server به client | تایید HELLO. در UDP client قبل از ارسال data منتظر آن میماند. |
DATA | sender به receiver | payload deterministic برای upload یا download. |
END | sender به receiver | پایان یک جهت sender. |
REPORT | server به client | آمار final sender/receiver. |
ERROR | server به client | خطای protocol. |
header هر frame برابر ۴۸ بایت است. payload-size فقط اندازه payload در frame نوع DATA را مشخص میکند و header را شامل نمیشود.
Startup و مالکیت line
هنگام شروع tunnel، client یک task جدا برای هر stream زمانبندی میکند. برای هر stream:
- worker را با
stream_id % workers_countانتخاب میکند - یک
line_tعادی میسازد - line state مربوط به
SpeedTestClientرا مقداردهی اولیه میکند Initرا به سمت نود بعدی میفرستد- watchdog مربوط به
timeout-msرا arm میکند
چون client این lineها را میسازد، از بین بردن آنها نیز بر عهده خودش است. با کامل شدن یا شکست هر stream، در صورت لزوم upstream Finish را میفرستد و سپس line خودش را از بین میبرد.
رفتار TCP
در حالت TCP، بایتهای دریافتی در stream buffer جمع و به frameهای speed-test decode میشوند. TCP بهطور پیشفرض pacing ندارد و تا جایی که chain و backpressure اجازه دهند ارسال میکند، مگر آنکه target bandwidth تنظیم شده باشد.
client پس از دریافت downstream Est از tunnel بعدی شروع به ارسال میکند. با
رسیدن callbackهای downstream Pause و Resume نیز task ارسال خودش را متوقف یا
از سر میگیرد.
رفتار UDP
در حالت UDP، هر buffer payload در واتروال دقیقاً یک frame کامل speed-test است.
client تا دریافت ACK، frame نوع HELLO را دوباره میفرستد. فاصله retry برابر
مقدار کوچکتر میان report-interval-ms و ۲۵۰ ms است. frame نهایی END برای
upload نیز سه بار ارسال میشود تا از دست رفتن یک datagram مانع پایان تست نشود.
نرخ پیشفرض UDP برابر udp-target-bits-per-sec: 10000000 است. این حالت loss،
packetهای تکراری و خارج از ترتیب، خطاهای اعتبارسنجی و jitter را گزارش میکند.
آمار
سمت receiver این آمار را نگه میدارد:
- bytes
- packets
- valid packets
- lost packets
- duplicate packets
- out-of-order packets
- validation errors
- jitter estimate
payloadها از الگویی deterministic بر اساس stream id، sequence number و direction استفاده میکنند؛ در نتیجه هر دو سمت میتوانند خرابی داده یا ترتیب غیرمنتظره را تشخیص دهند.
در پایان، client گزارشهای remote per-stream را از server چاپ میکند و یک summary نهایی aggregate میسازد. اگر
json-summary: true باشد، یک خط compact JSON-style aggregate هم چاپ میشود.
متادیتای نود
| ویژگی | مقدار |
|---|---|
| flag | kNodeFlagChainHead |
| previous node | مجاز نیست |
| next node | اجباری |
| layer group | kNodeLayer4 |
required_padding_left | 0 |
اشتباههای رایج
- این نود را وسط chain ترافیک واقعی قرار ندهید؛ chain head است و خودش line میسازد.
- بدون
SpeedTestServerمتناظر از آن استفاده نکنید. - انتظار باز کردن socket مستقیم از آن نداشته باشید؛ پس از آن
TcpConnector،UdpConnectorیا transport stack دیگری قرار دهید. - برای UDP payload خیلی بزرگ انتخاب نکنید مگر اینکه کل مسیر آن را بدون fragmentation/loss تحمل کند.