SpeedTestServer
SpeedTestServer همتای chain-end برای SpeedTestClient است. frameهای speed-test
را از upstream میگیرد، داده upload را اعتبارسنجی میکند، در صورت درخواست داده
download را در جهت downstream میفرستد و گزارش نهایی sender/receiver را به client
برمیگرداند.
این یک tunnel معمول connection-oriented است. خودش line نمیسازد، مالک از بین بردن line ساختهشده توسط listener نیست و packet-line tunnel هم محسوب نمیشود.
جایگاه رایج
SpeedTestServer باید آخرین نود chain باشد.
TcpListener -> SpeedTestServer
UdpListener -> SpeedTestServer
TcpListener -> TlsServer -> SpeedTestServer
TcpListener -> EncryptionServer -> SpeedTestServer
سمت client معمولاً با SpeedTestClient متناظر آغاز میشود:
SpeedTestClient -> TcpConnector
SpeedTestClient -> UdpConnector
SpeedTestClient -> TlsClient -> TcpConnector
SpeedTestClient -> EncryptionClient -> TcpConnector
نمونه TCP
[
{
"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,
"quiet": false
}
}
]
سمت client matching:
[
{
"name": "speedtest-client",
"type": "SpeedTestClient",
"settings": {
"mode": "tcp",
"direction": "bidirectional",
"duration-ms": 10000,
"warmup-ms": 1000,
"connection-count": 4,
"payload-size": 131072
},
"next": "speedtest-out"
},
{
"name": "speedtest-out",
"type": "TcpConnector",
"settings": {
"address": "198.51.100.10",
"port": 9000,
"nodelay": true
}
}
]
نمونه UDP
سمت server:
[
{
"name": "speedtest-udp-listener",
"type": "UdpListener",
"settings": {
"address": "0.0.0.0",
"port": 9001
},
"next": "speedtest-server"
},
{
"name": "speedtest-server",
"type": "SpeedTestServer",
"settings": {
"report-interval-ms": 1000
}
}
]
سمت client matching:
[
{
"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
},
"next": "speedtest-udp-out"
},
{
"name": "speedtest-udp-out",
"type": "UdpConnector",
"settings": {
"address": "198.51.100.10",
"port": 9001
}
}
]
فیلدهای لازم
SpeedTestServer نود انتهایی chain است و نباید next داشته باشد.
settings اختیاری است و در صورت حذف شدن، مقدارهای پیشفرض به کار میروند.
تنظیمات اختیاری
| فیلد | پیشفرض | توضیح |
|---|---|---|
report-interval-ms | 1000 | فاصله پیشفرض گزارشها پیش از دریافت HELLO. پس از آن، interval درخواستی client برای همان line استفاده میشود. باید مثبت باشد. |
json-summary | false | مقدار پیشفرض برای خلاصه شبیه JSON هر stream. client نیز میتواند از طریق HELLO آن را برای هر line درخواست کند. |
quiet | false | logهای runtime مانند پذیرفته شدن stream، گزارش دورهای، خلاصه نهایی و خطاهای هر stream را خاموش میکند. خطاهای fatal مربوط به setup همچنان ممکن است ثبت شوند. |
Init و establishment
در upstream Init، server:
- per-line state را مقداردهی اولیه میکند
- برای framing در حالت TCP یک receive stream buffer میسازد
- بلافاصله
Estرا downstream به سمت نود قبلی میفرستد
همین downstream Est سیگنال آغاز ارسال HELLO برای SpeedTestClient است.
HELLO و ACK
نخستین frame دریافتی از client باید HELLO باشد. این frame رفتار server را برای همان line تعیین میکند:
- mode
tcpیاudp - direction شامل upload، download یا bidirectional
- duration و warmup
- report interval
- payload size
- target bandwidth
- total stream count
- stream id
پس از پذیرفتن HELLO، server یک ACK در جهت downstream میفرستد. در حالت UDP،
برای HELLOهای تکراری نیز دوباره ACK ارسال میشود تا گم شدن پاسخ، client را
برای همیشه منتظر نگذارد.
server کاربردی بودن duration-ms، report-interval-ms، payload-size و تعداد کل
streamها را اعتبارسنجی میکند. payload در حالت UDP حداکثر میتواند 64952 بایت
باشد.
مسیر upload
وقتی upload فعال باشد، frameهای upstream نوع DATA با همان الگوی deterministic
تولیدشده در SpeedTestClient اعتبارسنجی میشوند.
server این آمار را نگه میدارد:
- bytes
- packets
- valid packets
- lost packets
- duplicate packets
- out-of-order packets
- validation errors
- jitter estimate
با رسیدن frame نوع END برای upload، server آمار receiver را نهایی میکند و یک
receiver REPORT در جهت downstream میفرستد. در حالت UDP، پس از پایان receiver،
ENDهای تکراری نادیده گرفته میشوند.
مسیر download
وقتی download فعال باشد، server پس از پذیرفتن HELLO ارسال frameهای downstream نوع DATA را زمانبندی میکند. payload size، warmup،
duration و target bandwidth همان مقادیری هستند که client درخواست کرده است.
در پایان download، server فریمهای زیر را میفرستد:
ENDبرای downloadREPORTمربوط به sender
در UDP، فریمهای final END و REPORT سه بار تکرار میشوند.
Framing
در حالت TCP، بایتهای ورودی در buffer_stream_t جمع و به frameهای speed-test decode میشوند.
در UDP، هر Waterwall payload buffer باید دقیقاً یک frame کامل speed-test باشد. اولین packet که HELLO با flag UDP داشته
باشد، line را وارد UDP-frame handling میکند.
header نامعتبر، نوع frame غیرمنتظره، طول ناممکن payload یا ترتیب نادرست protocol
باعث شکست line میشود. server در صورت امکان پیش از بستن آن، یک frame نوع ERROR
میفرستد.
رفتار Finish
اگر upstream پیش از پایان کامل تست بسته شود، server فقط per-line state خودش را
از بین میبرد و lineDestroy() را فراخوانی نمیکند؛ زیرا line را listener یا
adapter upstream ساخته است.
وقتی server خودش تست را کامل کند یا با خطا پایان دهد، ابتدا بایتهای نهایی لازم
برای protocol را میفرستد، سپس state خودش را از بین میبرد و downstream
Finish را میفرستد.
متادیتای نود
| ویژگی | مقدار |
|---|---|
| flag | kNodeFlagChainEnd |
| previous node | اجباری |
| next node | مجاز نیست |
| layer group | kNodeLayer4 |
required_padding_left | 0 |
اشتباههای رایج
- بعد از
SpeedTestServerنود دیگری نگذارید؛ chain end است. - بدون
SpeedTestClientمتناظر از آن استفاده نکنید. - انتظار پردازش application traffic از آن نداشته باشید.
- آن را packet-line node فرض نکنید؛ با lineهای عادی ساختهشده توسط listener یا adapter upstream کار میکند.