مرجع API کنترل
API کنترل راهی است که پنل، اسکریپت یا کلاینت TypeScript با آن نود در حال اجرا را میخوانند و تغییر میدهند. HTTP/1.1 با بدنهٔ JSON است و veilway run آن را روی یک سوکت یونیکس سرو میکند. همهٔ مسیرها زیر /v1 هستند. GET /v1/openapi.json سند OpenAPI 3.1 را برمیگرداند.
هر که بتواند سوکت را باز کند مدیر نود است: میتواند پیکربندی در حال اجرا را (بدون رازها) بخواند، عوضش کند و همهٔ کاربران را زیر نظر بگیرد. توکن، TLS و شنوندهٔ TCP نیست. فقط مجوزهای فایل سوکت دسترسی را تعیین میکنند.
API فقط روی یونیکس ساخته میشود. جای دیگر veilway run پرچم --api و --no-api ندارد و بدون API اجرا میشود.
| مسیر | --api <path>، پیشفرض veilway.sock کنار فایل پیکربندی |
| حالت (mode) | 600: کاربری که نود با آن اجرا میشود، و root |
| خاموش کردن | --no-api |
- حالت از همان ابتدا. نود سوکت را داخل پوشهٔ تازهای با حالت
700میسازد، همانجا حالت600میدهد و بعد به مسیرش لینک میکند. پس با هر umask هرگز برای دیگران باز نیست. - سوکت کهنه. فایل سوکتی که کسی پشتش جواب نمیدهد و نودی که درست خاموش نشده جا گذاشته، جایگزین میشود. در لاگ با سطح info ثبت میشود.
- سوکت زنده. اگر پردازش دیگری روی مسیر جواب بدهد، نود راه نمیافتد و میگوید چرا.
- هر چیز دیگر. فایلی در آن مسیر که سوکت نیست هرگز پاک نمیشود. نود راه نمیافتد و مسیر را نام میبرد.
- شکست در شروع. سوکتی که ساخته نشود نود را متوقف میکند.
- خاموشی. API پیش از موتور متوقف میشود و فایل سوکت پاک میشود. سوکتی که نود دیگری در این میان مال خود کرده دستنخورده میماند.
curl --unix-socket /srv/veilway/veilway.sock http://veilway/v1/statusنام میزبان در URL هرگز جستوجو نمیشود، پس هر نامی کار میکند.
درخواستها و پاسخها
Section titled “درخواستها و پاسخها”- همهٔ بدنهها JSON هستند. درخواست دارای بدنه باید
Content-Type: application/jsonداشته باشد. - هر پاسخ ناموفق این شکل را دارد، با وضعیتی مناسب:
{"error": {"code": "stale_revision", "message": "The running config is not the one If-Match names. Read it again and apply the change to what runs now.", "details": [{"path": "revision", "message": "0f1e2d3c..."}]}}| فیلد | معنی |
|---|---|
code |
نام snake_case پایدار، برای برنامهها. |
message |
یک جملهٔ ساده، برای آدمها. |
details |
فهرستی از {"path", "message"}. برای پیکربندی ردشده، هر خطا با مسیر فیلدش. اگر چیزی برای افزودن نباشد خالی است. |
هیچ پاسخ، رویداد یا خط لاگ API مقدار رازی را نشان نمیدهد (private_key، preshared_key، transport_keys، transport_secrets، username، password، proxy_password)، فقط مسیرها را. مورد details هرگز مقداری از سند ندارد.
کدهای خطا
Section titled “کدهای خطا”| وضعیت | code |
چه زمانی |
|---|---|---|
| 400 | bad_request |
بدنه تا انتها خوانده نشد. |
| 400 | bad_json |
بدنه یک سند JSON نیست. |
| 404 | not_found |
چنین مسیری وجود ندارد. |
| 404 | user_not_found |
GET /v1/users/{name} یا ریست مصرف برای نامی که پیکربندی در حال اجرا ندارد. |
| 405 | method_not_allowed |
مسیر این متد را نمیپذیرد. |
| 408 | request_timeout |
درخواست در 30 ثانیه تمام نشد (apply و ریست مصرف را پایینتر ببینید). |
| 409 | stale_revision |
If-Match ریویژنِ در حال اجرا را نشان نمیدهد. |
| 409 | replay_absent |
ریست حافظهٔ replay روی نودی که حافظهای ندارد، چون هیچ ترنسپورت مبهمسازیشدهای اجرا نکرده است. چیزی تغییر نکرد. |
| 409 | replay_busy |
ریست حافظهٔ replay وقتی ریست قبلی هنوز معلوم نیست روی دیسک نشسته باشد، یا وقتی نود در حال توقف است. چیزی تغییر نکرد. |
| 500 | internal |
نود نتوانست پاسخش را بنویسد یا بررسی یک سند را تمام کند. |
| 500 | replay_unwritten |
ریست حافظهٔ replay که فایلش نوشته نشد. بخش همان مسیر را ببینید. |
| 500 | replay_writing |
ریست حافظهٔ replay که نوشتنش بعد از 10 ثانیه تمام نشده و هنوز ممکن است بنشیند. دوباره نخواهید. بخش همان مسیر را ببینید. |
| 413 | body_too_large |
بدنه از 4 MiB بزرگتر است. |
| 415 | unsupported_media_type |
بدنه با application/json فرستاده نشد. |
| 422 | config_invalid |
سند خطا دارد. details آنها را فهرست میکند. چیزی تغییر نکرد. |
| 422 | body_invalid |
بدنهٔ ریست مصرف JSON است ولی {"totals": true} یا {"totals": false} یا {} نیست. چیزی تغییر نکرد. |
| 422 | config_not_prepared |
سند معتبر است ولی نود نتوانست آن را آماده کند (مثلاً شنوندهای که bind نمیشود). چیزی تغییر نکرد. |
| 428 | precondition_required |
apply بدون هدر If-Match. |
| 503 | too_many_connections |
نود همین حالا 64 اتصال را سرویس میدهد. |
| 503 | too_many_streams |
نود همین حالا 32 جریان رویداد را سرویس میدهد. |
مسیرها
Section titled “مسیرها”| متد | مسیر | پاسخ |
|---|---|---|
| GET | /v1/status |
نسخه، نسل و ریویژن پیکربندی، مدت کارکرد، شمارشها |
| GET | /v1/config |
پیکربندی در حال اجرا بدون رازها، و ریویژن آن |
| POST | /v1/config/validate |
گزارش اعتبارسنجی یک سند |
| POST | /v1/config/diff |
آنچه apply یک سند تغییر میدهد، و گزارش |
| PUT | /v1/config |
سند را اعمال میکند |
| GET | /v1/users |
همهٔ کاربران |
| GET | /v1/users/{name} |
یک کاربر |
| POST | /v1/users/{name}/usage/reset |
شمارش سهمیهٔ کاربر را از نو شروع میکند و کاربر را برمیگرداند |
| POST | /v1/replay/reset |
حافظهٔ replay ترنسپورتهای مبهمسازیشده را ریست میکند و آن را برمیگرداند |
| GET | /v1/stats |
همهٔ شمارندهها با نرخ زنده |
| GET | /v1/sessions |
دستگاههای دارای نشست زنده |
| GET | /v1/exits |
هر نقطهٔ خروج با سلامت upstream آن |
| GET | /v1/inbounds |
هر ورودی با کلیدهای عمومیاش، رتبه و pin هر ترنسپورت |
| GET | /v1/links |
هر لینک نود فعال با وضعیت و شمارندههایش |
| GET | /v1/upstreams |
هر upstream فعال با وضعیت، دلیل و شمارندههایش |
| POST | /v1/upstreams/preview |
سند یک ارائهدهنده را برای بازبینی میگیرد و 600 ثانیه نگه میدارد |
| POST | /v1/upstreams/preview/{id}/decline |
جای پیشنمایش را پیش ارائهدهنده پس میدهد |
| POST | /v1/upstreams/{tag}/confirm |
جابهجایی نشانی اصلی، میزبانهای تازهٔ بهروزرسانی یا هر دو را تأیید میکند |
| POST | /v1/upstreams/{tag}/retry |
از تونل upstream میخواهد همین حالا وصل شود |
| DELETE | /v1/upstreams/{tag} |
دستگاه را از ارائهدهنده و از فایل state برمیدارد |
| GET | /v1/events |
Server-Sent Events |
| GET | /v1/openapi.json |
سند OpenAPI 3.1 |
هر مسیر میتواند 408، 503، 404 و 405 را هم مثل بالا بدهد. جدولهای زیر فقط آنچه مخصوص هر مسیر است را میآورند.
GET /v1/status
Section titled “GET /v1/status”| فیلد | نوع | معنی |
|---|---|---|
version |
string | نسخهٔ ساخت. |
generation |
integer | از 1 شروع میشود و با هر پیکربندی که اعمال شود یکی زیاد میشود. |
revision |
string | آنچه If-Match میگیرد. «ریویژنها» را ببینید. |
uptime_secs |
integer | ثانیههای گذشته از راهافتادن موتور. |
inbounds، exits، users |
integer | پیکربندی در حال اجرا چندتا دارد. |
flows |
integer | فلوهای جدول فلو در همین لحظه. |
public_addresses |
فهرست string | نشانیهای عمومی نود، همانطور که پیکربندی نام میبرد (نام میزبان یا IP، بدون پورت). اگر نباشد خالی است. |
certificates |
فهرست | گواهی هر ترنسپورت tls، یکی برای هر نشانی گوشدادن، به شکل {"listen", "pin", "self_signed", "not_before", "not_after"}. pin همان SHA-256 از SubjectPublicKeyInfo کلید است با base64 استاندارد. self_signed برای گواهیای که نود ساخته true است (آنوقت pin تنها بررسی است و با تمدید گواهی همان میماند) و برای گواهیای که از فایل cert پیکربندی خوانده شده false (زنجیره هم بررسی میشود). تا v0.3.5 فقط خودامضاها فهرست میشدند. not_before و not_after ثانیهٔ یونیکساند. اگر نباشد خالی است. |
addons |
object | {"xray": {"installed", "release"}}: آیا فایل اجرایی افزونهٔ Xray در پوشهٔ افزونهها هست، و این نود کدام نسخهٔ Xray-core را اجرا میکند. |
GET /v1/config
Section titled “GET /v1/config”{"revision", "generation", "document"} را میدهد. document پیکربندی در حال اجراست و هر راز در آن با نشانهٔ "<redacted>" عوض شده. ریویژن در هدر ETag هم میآید.
POST /v1/config/validate
Section titled “POST /v1/config/validate”بدنه: یک سند پیکربندی. چیزی تغییر نمیکند. چه سند معتبر باشد چه نه، پاسخ 200 است:
| فیلد | معنی |
|---|---|
valid |
وقتی سند خطا نداشته باشد true است. |
report |
errors و warnings (فهرستهایی از {"path", "message"})، more_errors و more_warnings (تعداد موارد بعد از 100 مورد اول هرکدام)، shadow_cut_short (بررسی قاعدههایی که قاعدهٔ قبلی پوششان میدهد در بودجهاش متوقف شد). |
بدنهٔ JSON که پیکربندی معتبر نیست 200 با valid: false میگیرد. بدنهٔ غیر JSON 400 bad_json است.
POST /v1/config/diff
Section titled “POST /v1/config/diff”بدنه: یک سند پیکربندی. چیزی تغییر نمیکند. پاسخ valid، report مثل بالا و diff دارد (برای سند نامعتبر null). برخلاف validate، قاعدههایی را که قاعدهٔ قبلی پوششان میدهد نمیجوید.
فیلد diff |
معنی |
|---|---|
inbounds، outbounds، exits، rules، users |
{"added", "changed", "removed"}، هرکدام فهرستی از تگها (برای کاربران نامها). |
dns، log، routing_default، rules_reordered، notices، public_addresses، replay |
وقتی آن بخش تغییر کرده true است. برای replay، نرخ هر مبدأ بلافاصله اعمال میشود و اندازهٔ cache از شروع بعدی نود. |
inbound_changes |
برای هر ورودی تغییرکرده: tag، restart (تونل دوباره راه میافتد و نشستهایش قطع میشوند)، transports_stopped و transports_started (اندیسها). ورودیای که فقط type، padding، transport_keys، upgrade_cookie یا upgrade_headers آن عوض شده با restart برابر false و هر دو فهرست خالی میآید. افزودن ترنسپورت udp-obfs به ورودیای که mtu نوشتهشده ندارد restart است: mtu آن از 1420 به 1390 میرود. |
user_changes |
برای هر کاربر تغییرکرده: name، devices_added، devices_removed، devices_readdressed، devices_rekeyed، devices_secrets_changed (دستگاهها با کلید عمومی) و lost_access. devices_secrets_changed دستگاههای ماندهای است که transport_secretsشان عوض شده. اتصال کنترلی که رازی را ثابت کرده که دیگر نیست بسته میشود و نشست udp-obfsای که با آن باز شده تمام میشود. |
outbound ای که username یا password آن بهجای نشانه نوشته شده باشد، هر مقداری که باشد، تغییرکرده فهرست میشود. وگرنه «تغییر نکرده» به کسی که گذرواژهای را حدس زده میگفت حدسش درست بود.
PUT /v1/config
Section titled “PUT /v1/config”بدنه: یک سند پیکربندی. هدر: If-Match با ریویژنی که تغییر روی آن ساخته شده. سند را با همان reload که SIGHUP انجام میدهد اعمال میکند و بعد در فایل پیکربندی شروع نود مینویسد.
| وضعیت | معنی |
|---|---|
| 200 | اعمال شد. |
| 409 | If-Match ریویژن در حال اجرا نیست. هدر ETag و تنها مورد details (با مسیر revision) ریویژن در حال اجرا را دارند. |
| 422 | config_invalid یا config_not_prepared. پیکربندی در حال اجرا دستنخورده است. |
| 428 | If-Match نیامده. |
پاسخ 200 این را دارد:
| فیلد | معنی |
|---|---|
revision، generation |
مال پیکربندیای که الان اعمال است. ریویژن همان ETag هم هست. |
saved |
وقتی پیکربندی اعمال شده ولی در فایل پیکربندی نوشته نشده false است، یعنی راهاندازی دوباره پیکربندی قبلی را برمیگرداند. فرستادن دوبارهٔ همین سند نوشتن را دوباره امتحان میکند. |
save_error |
دلیل شکست نوشتن، همانطور که سیستم میگوید. وقتی saved برابر true است null. |
diff |
آنچه apply اضافه، تغییر و حذف کرد، مثل /v1/config/diff. |
report |
هشدارهای پیکربندیای که الان اعمال است. |
- آنچه ذخیره میشود. نه همان بایتهایی که فرستادید: نود سندی را که الان اجرا میکند مینویسد، با رازهای واقعی بهجای هر نشانه، و با قالببندی خودش. حالت
600، فایل موقت در همان پوشه،fsync، rename و بعدfsyncپوشه. اگر مسیر پیکربندی symbolic link باشد، فایلی که به آن اشاره میکند جایگزین میشود. - مهلت نوشتن. نوشتنی که بعد از 10 ثانیه رها شده متوقف نمیشود، پس فایل ممکن است باز هم این پیکربندی را بگیرد. هرگز به پیکربندی قدیمیتر برنمیگردد.
- مهلت زمانی. 30 ثانیه خواندن و بررسی سند را میپوشاند. وقتی نود شروع به اعمال پیکربندی کرد، جواب هر قدر طول بکشد منتظر میماند. برای پیکربندیای که بعد اعمال میشود هرگز
408نمیرود. - شکست. سندی که رد شود یا آماده نشود همهچیز را همانطور که بود میگذارد. سندی که موتور در اعتبارسنجی یا آمادهسازی رد کند با رویداد
config_refusedاعلام میشود. سندی که خود API هنگام خواندن نامعتبر بیابد422میگیرد و اعلام نمیشود.
ریویژنها و If-Match
Section titled “ریویژنها و If-Match”ریویژن 64 رقم هگز است که بایتهای پیکربندی در حال اجرا را نام میبرد. هش کلیددار است با کلیدی تصادفی که نود هنگام شروع انتخاب میکند، پس کسی نمیتواند آن را از سند حساب کند و بعد از راهاندازی دوباره همان پیکربندی ریویژن دیگری دارد.
apply هدر If-Match با ریویژنی که فراخواننده خوانده میخواهد. گیومههای ETag اختیاریاند. هر ریویژن دیگر 409 stale_revision است و پاسخ ریویژن فعلی را دارد تا فراخواننده پیکربندی را دوباره بخواند و تغییرش را دوباره انجام دهد. نبودن هدر 428 precondition_required است. نود پیش از اعمال سند این بررسی را دوباره روی پیکربندی در حال اجرا انجام میدهد.
curl --unix-socket veilway.sock -X PUT http://veilway/v1/config -H 'Content-Type: application/json' -H 'If-Match: "0f1e2d3c4b5a69788796a5b4c3d2e1f00f1e2d3c4b5a69788796a5b4c3d2e1f0"' --data @config.jsonویرایش پیکربندی بدون دیدن رازها
Section titled “ویرایش پیکربندی بدون دیدن رازها”GET /v1/config هرگز رازی نمیدهد. private_key، preshared_key، username، password و proxy_password کاربر رشتهٔ "<redacted>" دارند. هر مورد transport_secrets و transport_keys یک ورودی نشانهای دارد که آن را نام میبرد: "<redacted:1a2b3c4d>" با هشت رقم hex. رقمها رازهای یک دستگاه، یا کلیدهای یک ورودی، را از هم جدا میکنند و چیزی دربارهٔ آنها نمیگویند. هر پردازهٔ نود آنها را از نو میسازد، پس بعد از راهاندازی دوباره سند را دوباره بخوانید. پنل این سند را ویرایش میکند و همانطور به validate، diff یا PUT /v1/config برمیگرداند. در سندی که به نود میرود، نشانه یعنی «مقدار در حال اجرای همان شیء را نگه دار»:
| فیلد | از کجا گرفته میشود |
|---|---|
private_key ورودی |
ورودی در حال اجرا با همان tag |
preshared_key دستگاه |
دستگاه در حال اجرا با همان public_key |
یک مورد از transport_secrets دستگاه |
رازی که این نشانه نام میبرد، از دستگاه در حال اجرا با همان public_key، هر جای فهرست که باشد. موردی که حذف شود برداشته میشود: برای پایان چرخش، نشانهٔ راز قدیمی را بردارید و دیگری را نگه دارید. برای شروع آن، راز جدید را کامل کنار نشانهٔ رازی که میماند بنویسید. |
یک مورد از transport_keys ورودی |
کلیدی که این نشانه نام میبرد، از ورودی در حال اجرا با همان tag، هر جای فهرست که باشد. چرخش مثل رازهای دستگاه است: کلید جدید را کامل پیش از نشانهٔ کلید قدیمی بنویسید و آن نشانه را بعداً بردارید. |
proxy_password کاربر |
کاربر در حال اجرا با همان name |
username و password خروجی |
outbound از نوع socks5 در حال اجرا با همان tag و همان server |
نشانهای که چنین شیئی پیدا نکند در مسیر همان فیلد خطای اعتبارسنجی است. از جمله:
- outbound ای که
serverآن عوض شده. آنوقت سند باید username و password را صریح بنویسد. - نشانهای در
transport_secretsکه هیچ رازی از آن دستگاه را نام نبرد، مثل"<redacted>"ساده یا نشانهٔ راز دستگاه دیگر. - نشانهای در
transport_keysکه هیچ کلیدی از آن ورودی را نام نبرد.
username یا password برابر نشانه در فایل پیکربندی خواندهشده از دیسک هم خطای اعتبارسنجی است.
کاربران، آمار، نشستها، خروجیها
Section titled “کاربران، آمار، نشستها، خروجیها”GET /v1/users و GET /v1/users/{name}
Section titled “GET /v1/users و GET /v1/users/{name}”فهرست {"users": [...]} را میدهد. مسیر تکی یک کاربر یا 404 user_not_found میدهد.
| فیلد | معنی |
|---|---|
name |
نام کاربر. |
enabled |
فقط وقتی پیکربندی "enabled": false بگوید false است. |
denied |
چرا کاربر همین حالا نمیتواند وصل شود: disabled، expired یا quota. برای کاربری که میتواند null است. |
expires_at |
مثل پیکربندی، یا null. |
quota_bytes، quota_period |
مثل پیکربندی، یا null. |
used_bytes |
بایتهای هر دو جهت از period_start. |
period_start |
آخرین باری که شمارش از نو شروع شد، به ثانیهٔ یونیکس. برای کاربری که هرگز quota_period نداشته، یا هنگام آخرین ریست مصرفش نداشته، 0 است. |
dns_set |
تگ مجموعهٔ DNS که کاربر را نام میبرد، وگرنه یکی از گروههایش را. اگر هیچکدام نباشد null است: پرسمانها آنوقت به مجموعهای میروند که ورودی را نام میبرد، یا به dns.servers. |
traffic |
شمارندههای طول عمر: up_bytes، up_packets، down_bytes، down_packets. up یعنی از دستگاه به نود. |
devices |
برای هر دستگاه: name، public_key، addresses، handshake_age_secs (ثانیههای گذشته از ساختهشدن نشستش، بدون نشست null). |
speed_up، speed_down |
مثل پیکربندی، به بایت بر ثانیه، یا null برای بدون محدودیت. از v0.3.6. |
limited |
آنچه محدودیتهای سرعت از زمان شروع نود انجام دادهاند: up_packets و down_packets (بستههای حذفشده بیش از نرخ: UDP، ping و TCPای که از نقطهٔ خروج netstack نمیگذرد) و paced_ms (میلیثانیههایی که streamهای TCP منتظر محدودیت ماندند، جمع روی streamها و هر دو جهت). TCP از نقطهٔ خروج netstack کند میشود و هرگز حذف نمیشود. |
کلید preshared هرگز جزو آن نیست.
POST /v1/users/{name}/usage/reset
Section titled “POST /v1/users/{name}/usage/reset”شمارش سهمیهٔ یک کاربر را از نو شروع میکند. پشت دستور veilway usage reset همین مسیر است.
| بدنه | اختیاری. {"totals": true} یا {"totals": false}. بدون بدنه یعنی false. |
used_bytes |
0 میشود. |
period_start |
آغاز دورهٔ سهمیهای میشود که ساعت نود در آن است (00:00 UTC همان روز، دوشنبه یا روز اول ماه). برای کاربر بدون quota_period برابر 0. |
traffic |
میماند. با "totals": true چهار شمارندهٔ طول عمر هم 0 میشوند. |
| وضعیت | معنی |
|---|---|
| 200 | انجام شد. بدنه همان کاربر است، دقیقاً مثل GET /v1/users/{name}. |
| 404 | user_not_found. چیزی تغییر نکرد. |
| 400، 413، 415 | bad_json، body_too_large، unsupported_media_type، برای بدنهٔ فرستادهشدهٔ غیرقابلاستفاده. چیزی تغییر نکرد. |
| 422 | body_invalid: بدنه JSON است ولی فیلدی جز totals دارد، یا totals برابر true یا false نیست. چیزی تغییر نکرد. |
- عبور از سهمیه. کاربری که بهدلیل سهمیه قطع شده بود بهمحض فرستادهشدن پاسخ میتواند دوباره وصل شود، بدون reload. کاربر غیرفعال یا منقضی همچنان رد میشود و
deniedدر پاسخ همین را میگوید. - چیز دیگری عوض نمیشود. نشستها، فلوها، پیکربندی و کاربران دیگر دستنخورده میمانند.
- فایل state. ریست پیش از پاسخ در فایل state نوشته میشود، نه در نوشتن 10 ثانیهای بعدی. اگر آن نوشتن شکست بخورد یا بیش از 5 ثانیه طول بکشد، ریست همچنان برقرار است. شکست لاگ میشود، در
state_write_failuresشمرده میشود و نوشتن دوباره امتحان میشود. - تکرار. بیخطر است: شمارش را دوباره
0میکند و چیز دیگری را عوض نمیکند. - رویدادها. یک رویداد
usage_resetفرستاده میشود، و اگر کاربر از سهمیه گذشته بود پس از آنuser_restored. - لاگ. یک خط info با نام کاربر، شمارش پیش از ریست و اینکه مجموعها صفر شدند یا نه.
- مهلت. 30 ثانیه فقط خواندن بدنه را میپوشاند. وقتی ریست شروع شد، پاسخ منتظرش میماند. برای ریستی که بعد انجام میشود هرگز
408نمیرود.
curl --unix-socket veilway.sock -X POST http://veilway/v1/users/alice/usage/resetcurl --unix-socket veilway.sock -X POST http://veilway/v1/users/alice/usage/reset -H 'Content-Type: application/json' --data '{"totals": true}'POST /v1/replay/reset
Section titled “POST /v1/replay/reset”حافظهٔ replay ترنسپورتهای مبهمسازیشده را ریست میکند. پشت دستور veilway replay reset همین مسیر است. فقط برای یک حالت است: کف حافظهٔ replay از ساعت نود جلوتر است (چون ساعت جلو رفته بوده) و نود همهٔ دستگاهها را رد میکند. مرجع پیکربندی این حالت را زیر replay توضیح میدهد.
بدنه ندارد. cache اثباتهای پذیرفتهشده خالی میشود و کف و سقف برابر ساعت نود بهاضافهٔ 60 ثانیه میشوند، حتی اگر پیشتر کمتر بوده باشند. فایل replay پیش از پاسخ و پیش از پذیرفتن اثبات بعدی نوشته میشود.
هزینهاش دو چیز است:
- هر کلاینتی 60 ثانیه رد میشود.
- اثباتی که با زمانی بالاتر از کف تازه پذیرفته شده بود فراموش میشود. هر که آن را ضبط کرده باشد، وقتی ساعت به آن زمان برسد میتواند یک بار دیگر از آن استفاده کند.
| وضعیت | معنی |
|---|---|
| 200 | انجام شد و روی دیسک است. بدنه حافظهٔ replay بعد از ریست است، همانطور که replay در /v1/stats میدهد. |
| 409 | replay_absent: نود هیچ ترنسپورت مبهمسازیشدهای اجرا نکرده و حافظهٔ replay ندارد. replay_busy: ریست قبلی هنوز معلوم نیست روی دیسک باشد، یا نود در حال توقف است. چیزی تغییر نکرد. |
| 500 | replay_unwritten: فایل replay نوشته نشد، پس ریست ممکن است روی دیسک باشد یا نباشد. نود تا وقتی کف و سقف قبلی را دوباره ننوشته، که هر ثانیه یک بار تلاش میکند، هیچ اثباتی نمیپذیرد. بعد همانها دوباره برقرارند و ریست باید دوباره خواسته شود. replay_writing: نوشتن بعد از 10 ثانیه تمام نشده است. ریست وقتی نوشتن تمام شود برقرار است، پس دوباره نخواهید: GET /v1/stats را بپرسید، که در آن replay.resets با نشستن ریست یکی بالا میرود و replay.ready تا وقتی نود هیچ اثباتی نمیپذیرد false است. |
- چیز دیگری عوض نمیشود. مصرف، سهمیهها، نشستهای باز، فلوها و پیکربندی دستنخورده میمانند.
- لاگ. یک خط warn با کف و سقف قبل و بعد، و تعداد اثباتهایی که فراموش شدند.
- مهلت. پاسخ 10 ثانیه منتظر نود میماند. نوشتنی که تا آن موقع تمام نشده باشد
replay_writingمیگیرد، نه «دوباره بخواهید»، چون ریست دوم 60 ثانیهٔ دیگر هزینه دارد. برای ریستی که بعد انجام میشود هرگز408نمیرود.
curl --unix-socket veilway.sock -X POST http://veilway/v1/replay/resetGET /v1/stats
Section titled “GET /v1/stats”یک عکس لحظهای از همهٔ شمارندهها، با نرخ به بایت بر ثانیه. نود هر ثانیه نمونه میگیرد. نرخ، رشد بین قدیمیترین و جدیدترین نمونهٔ 5 ثانیهٔ آخر است.
| فیلد | معنی |
|---|---|
window_secs |
ثانیههایی که نرخها روی آنها گرفته شد: 5 وقتی نود اینقدر کار کرده باشد، 0 پیش از نمونهٔ دوم. |
users، inbounds، exits |
فهرستهایی از {"name", "traffic", "up_bytes_per_sec", "down_bytes_per_sec"}. name نام کاربر یا تگ است. نامی که در این بازه تازه است نرخ 0 دارد. |
outbounds |
برای هر outbound پیکربندی در حال اجرا یک مورد، به همان ترتیب، با چهار فیلد یک خروجی (name تگ outbound است) بهعلاوهٔ udp، udp_down_secs، udp_flips، latency_ms، measured_at و down_reason. traffic و نرخها جمع خروجیهایی است که بکاندشان این outbound را نام میبرد. outbound ای که هیچ خروجی از آن استفاده نمیکند صفر دارد و خروجی با بکاند l3، block یا chain زیر هیچکدام نمیآید. نود برای outbound شمارندهٔ جدا ندارد، پس جمع ترافیکی را هم دارد که سیاست unsupported یک خروجی با "direct" از کنار پروکسی فرستاده است. نود برای هر خروجی، از فلوهایش، میفهمد پروکسی UDP را رله میکند یا نه، پس فیلدهای UDP آن چیزی است که خروجیهای outbound روی هم میدانند: udp تا وقتی آخرین تلاش یکی از آنها رد شده باشد false است و برای outbound ای که پروکسی SOCKS5 نیست null. udp_down_secs از تازهترین رد میشمارد. udp_flips جابهجاییهای خروجیها را جمع میکند، پس یک تغییر پروکسی که دو خروجی متوجهش شوند دو بار شمرده میشود. وضعیت هر خروجی در /v1/exits است. latency_ms مدتی است که پروکسی برای پاسخ به greeting آخرین فلوی دایلکنندهاش طول کشید و measured_at زمان آن (ثانیهٔ یونیکس). برای outbound مستقیم و تا وقتی فلویی از پروکسی استفاده نکرده، هر دو nullاند. down_reason دلیل اینکه outbound از نوع xray الان نمیتواند فلویی را حمل کند، با کلمات: افزونه نصب نیست یا اجرا نمیشود، Xray تمام شده و دوباره راه میافتد، یا نام سرور نشانیای نمیدهد که نود حق وصل شدن به آن را داشته باشد. هر خروجی روی آن با همین دلیل از کار افتاده است. تا وقتی outbound حمل میکند و برای هر outbound غیر xray برابر null است. reload آنها را از نو شروع میکند. |
drops |
بستههایی که از شروع حمل نشدند، به تفکیک نام دلیل. link_hops بستههای پیوندی را میشمارد که از پیوند چهارم میگذشتند، Chaining را ببینید. rate_limited بستههای حذفشده بیش از محدودیت سرعت کاربر را میشمارد. هر دو از v0.3.6. |
dns |
answered، refused، failed، malformed، throttled. |
flows |
فلوهای جدول فلو در همین لحظه. |
ws_stalled، ws_refused |
اتصالهای WebSocket که ارتقا را تمام نکردند و رها شدند، و آنهایی که هنگام accept رد شدند. |
state_write_failures |
نوشتنهای ناموفق فایل state مصرف از شروع. |
send_failed |
دیتاگرامهایی که نود برای دستگاهی ساخت و هیچ سوکتی نگرفت، روی همهٔ ترنسپورتهای همهٔ ورودیها. ورودی veilway هرگز تکهتکه نمیکند، پس بستهای که از ظرفیت رابط میزبان بزرگتر باشد اینجا شمرده میشود، فرستاده نمیشود و هر دقیقه یک بار در سطح info لاگ میشود. وقتی بالا میرود mtu ورودی را کم کنید. |
control |
آنچه کانال کنترل ورودیهای veilway از شروع انجام داده: اتصالهای accepted و authenticated، اتصالهای بستهشده به خاطر auth_failed، malformed، timed_out (گشایش بیش از 10 ثانیه طول کشید) و replaced (اتصال تازهتری از همان دستگاه جایش را گرفت)، درخواستهایی که پاسخ rate_limited گرفتند، exits_selected، exits_refused و exits_dropped (با بارگذاری مجدد)، probe_runs، probes_confirmed، probes_sent، probes_refused، mtus_set، byes، و open یعنی اتصالهای احرازشدهٔ همین حالا. روی نودی بدون ورودی veilway همه صفرند. |
proxies |
یک مورد برای هر ورودی پراکسی (socks5، http، mixed) پیکربندی در حال اجرا، به ترتیب آن. پایین را ببینید. روی نودی که ندارد خالی است. از v0.2.17. |
udp_obfs |
آنچه ترنسپورتهای udp-obfs از شروع انجام دادهاند و آنچه همین حالا نگه میدارند. پایین را ببینید. روی نودی بدون آن همه صفرند. |
stream |
آنچه شنوندههای جریانیِ ترنسپورتهای tls، و ترنسپورتهای ws و fronted ورودیهای veilway، از شروع انجام دادهاند و آنچه همین حالا نگه میدارند. پایین را ببینید. روی نودی بدون آنها همه صفرند. |
replay |
حافظهٔ replay ترنسپورتهای مبهمسازیشده. روی نودی که هیچکدام را اجرا نکرده null. پایین را ببینید. |
proxies. یک مورد برای هر ورودی پراکسی، با تگ ورودی در name. reload که ورودی را عوض کند شمارندههایش را از نو شروع میکند. هیچ شمارندهای نشانی، کاربر یا گذرواژهای را نام نمیبرد. بایتهای ورودی پراکسی در inbounds هم هست.
| فیلد | معنی |
|---|---|
opened، open |
اتصالهایی که ورودی از شروع گرفته، و آنهایی که همین حالا باز است. |
refused_logins |
ورودهایی که رد شد: کاربری با آن نام نیست، گذرواژه غلط است، یا ورودی آن کاربر را نمیپذیرد. |
refused_limit، refused_source، refused_busy |
اتصالهایی که در connections ورودی، در per_source یک مبدأ و در handshakes برگردانده شد. |
refused_blocked |
ورودهایی که ناشنیده رد شد چون یک مبدأ برای آن نام بیش از حد شکست خورده بود. |
refused_udp_source |
دیتاگرامهای UDP که دور ریخته شد چون از آدرس و پورتی که کلاینت برای همبستگیاش گفته بود نیامده بود. کلاینت پشت NAT که پورت را عوض میکند به همین دلیل رد میشود، پس شمارش رو به رشد با udp_any_port خاموش میگوید چرا UDP آن کار نمیکند. |
up_bytes، down_bytes |
بایتهایی که کلاینتها به مقصدشان فرستادند، و آنچه پس گرفتند. |
udp_obfs. هیچ شمارندهای نشانی، تگ یا کلیدی را نام نمیبرد. دیتاگرام دورریختهشده، به هر دلیل، جواب نگرفته است:
| فیلد | معنی |
|---|---|
pending، sessions |
همین حالا: نشستهایی که بستهٔ آغازینشان پذیرفته شده و WireGuard هنوز روی آنها احراز نشده، و نشستهای برقرارشده. sessions نشستهایی را هم که نشست تازهتری از همان مبدأ جایشان را گرفته و 10 ثانیه خواندنی میمانند میشمارد. |
tags |
تگهای دورهای در جدولهای تگ در همین حالا: سه تا برای هر راز ترنسپورتِ هر دستگاهی که میتواند وصل شود. |
opened، established |
بستههای آغازینی که پذیرفته شدند، و نشستهایی که برقرار شدند. |
waited، spent |
بستههای آغازینی که تا نوشته شدن سقف بالاتر نگه داشته شدند و بعد دوباره به قاعدهٔ replay رفتند، و بستههای آغازینی که یک حد ردشان کرد و salt آنها مصرفشده ثبت شد، تا کسی که یکی را دیده بعداً نتواند از آن استفاده کند. هر دستگاه برای این ثبتها سهمی دارد: 16 تا یکجا و بعد یکی در ثانیه. بستهٔ ردشدهٔ بیش از آن ثبت نمیشود. |
short، unknown، open_failed |
دیتاگرامهای کوتاهتر از یک بستهٔ داده. دیتاگرامهایی که بستهٔ نشستی در مبدأشان نیستند و تگشان در جدول تگ نیست: هر دیتاگرام یک غریبه اینجا شمرده میشود. و دیتاگرامهایی که تگشان در جدول هست و باز نمیشوند: فرستنده تگ این دوره را بدون راز دستگاه دارد، یا بسته در راه عوض شده است. |
sent |
بستههایی که شنوندهها برای یک سوکت ساختند. هر کدام بستهٔ دادهٔ یک نشست برقرارشده است، پس نودی که فقط غریبهها با آن حرف میزنند اینجا 0 دارد. |
window، floor، seen، cache_full |
بستههای آغازین یک دستگاه که قاعدهٔ replay رد کرد: زمانی بیش از 60 ثانیه دور از ساعت نود، زمانی روی کف یا پایینتر، بستهای که قبلاً پذیرفته شده، و هر بستهای وقتی cache پر است. window ای که برای یک دستگاه بالا میرود نشانهٔ ساعت غلط روی آن دستگاه یا روی نود است. |
limit، no_replay |
بستههای آغازین با زمانی بالاتر از سقف نوشتهشده که دور ریخته شدند، چون شنونده از پیش 64 بستهٔ دیگر نگه داشته بود یا هیچ نوشتنی ظرف 2 ثانیه تمام نشد، و آنهایی که وقتی آمدند که نود هیچ اثباتی نمیپذیرفت. |
source_devices، pool، pending_full، device_rate، source_rate |
بستههای آغازینی که یک حد ردشان کرد: مبدأ نشست 4 دستگاه دیگر را دارد، limits.sessions شنونده پر است، دستگاه 2 نشست معلق دارد، یا سهم دستگاه (16، بعد یکی در ثانیه) یا سهم مبدأ (replay.per_source) تمام شده است. |
handshakes، tunnel، unsendable |
آغاز handshake های WireGuard بیش از سهم یک نشست (3، بعد یکی در ثانیه)، دیتاگرامهایی درون یک نشست که WireGuard آنها را بستهٔ دستگاهِ همان نشست ندانست، و بستههایی که نود نتوانست بسازد. |
ended_deadline، ended_idle، ended_packets، ended_replaced، ended_displaced، ended_revoked |
نشستهایی که تمام شدند: بدون بستهٔ WireGuard تا 10 ثانیه بعد از بستهٔ آغازین، 180 ثانیه بدون فعالیت، 2^31 بستهٔ فرستادهشده، نشست تازهتری از همان مبدأ و دستگاه، نهمین نشست دستگاه، و دستگاه یا راز ترنسپورتی که پیکربندی دیگر ندارد. |
table_rebuilds، table_rebuilds_late، table_build_failures، tag_collisions |
چند بار جدول تگ برای دورهٔ تازه ساخته شد (هر 120 ثانیه برای هر ورودی)، چند بار این کار بیش از 10 ثانیه دیر شد، چند بار ساختن تمام نشد و جدول قبلی ماند، و تگهایی که کنار گذاشته شدند چون راز دیگری همان را داشت، که با رازهای تصادفی هرگز پیش نمیآید. |
stream. هیچ شمارندهای نشانی، مسیر، توکن یا کلیدی را نام نمیبرد. هر که کاربر نبوده، به هر دلیل، جواب مبدأ فریب را گرفته است، پس دلیلها فقط برای اپراتورند:
| فیلد | معنا |
|---|---|
undecided، relayed، pending، sessions |
همین حالا: اتصالهای درون دستدهی TLS یا خط درخواستشان، اتصالهایی که به مبدأ فریب رله میشوند، نشستهایی که اثباتشان پذیرفته شده و WireGuard هنوز رویشان احراز نشده، و نشستهای برقرار. |
accepted، accept_failed، broken |
اتصالهایی که شنوندهها از سیستم گرفتهاند، دفعههایی که گرفتن اتصال شکست خورده، که نشانهٔ میزبانی است که توصیفگر فایل کم آورده، و اتصالهایی که پیش از تصمیم با خطایی غیر از بستهشدن قطع شدند، مثل reset وسط خط درخواست. |
handshake_failed، handshake_slow، handshake_displaced |
دستدهیهای TLS که شکست خوردند، که در 10 ثانیه تمام نشدند، و که برای باز شدن جا در استخر تصمیمنگرفتهها بسته شدند. |
stranger_syntax، stranger_slow، stranger_closed، stranger_displaced، stranger_origin، stranger_proof |
اتصالهایی که «کاربر نیست» تشخیص داده شدند، بر پایهٔ دستهٔ دلیل: بایتی که نمیتواند جزء خط درخواست یک کاربر باشد یا خطی بلندتر از 4,096 بایت، خطی که در 10 ثانیه کامل نشد، طرفی که اول سمت خودش را بست، اتصالی که برای باز شدن جا بیدرنگ دربارهاش تصمیم گرفته شد، اتصالی که مبدأ فریبش پیش از کاملشدن خط درخواست چیزی فرستاد یا اتصال را بست، و خط درخواست کاملی که اثبات هیچ دستگاهی نیست. مسیر غلط، توکن غلط و دستگاه برداشتهشده همه در همین آخری یکسان شمرده میشوند. |
refused_window، refused_floor، refused_seen، refused_cache_full |
اثباتهای یک دستگاه که قاعدهٔ replay ردشان کرد: مهر زمانی بیش از 60 ثانیه دور از ساعت نود، مهر زمانی در کف یا زیر آن، توکنی که پیشتر پذیرفته شده، و هر اثباتی وقتی کش پر است. refused_window که بالا میرود نشانهٔ ساعت غلط روی یک دستگاه یا روی نود است. |
refused_limit، refused_no_replay |
اثباتهایی با مهر زمانی بالاتر از حدِ نوشتهشده که نوشتنشان در 2 ثانیه تمام نشد یا 64 اثبات دیگر پیش از آنها منتظر بودند، و اثباتهایی که وقتی رسیدند که نود هیچ اثباتی نمیپذیرفت. |
refused_pool، refused_pending، refused_device_rate، refused_source_rate |
اثباتهایی که یک حد ردشان کرد: limits.sessions شنونده پر است، دستگاه 2 نشست معلق دارد، یا سهم دستگاه (16 تا، بعد یکی در ثانیه) یا سهم مبدأ اتصال (replay.per_source) خرج شده. |
relays، relays_evicted، decoy_down |
اتصالهایی که به مبدأ فریب وصل و رله شدند، اتصالهای رلهشدهای که برای جا دادن به دیگری بسته شدند، و غریبههایی که بیپاسخ بسته شدند چون مبدأ در دسترس نبود. تا وقتی decoy_down بالا میرود نود از مبدأ فریبش بازشناخته میشود: مبدأ را ببینید. |
proofs_accepted، proofs_waited، head_refused، established، establish_full |
اثباتهای پذیرفتهشده، اثباتهایی که منتظر نوشتهشدن حد بالاتر ماندند، کاربرانی که سرآیند درخواستشان از حد گذشت یا upgrade به WebSocket نبود، نشستهایی که برقرار شدند، و نشستهایی که نتوانستند چون استخر نشستها بعد از اثباتشان پر شده بود. |
handshakes، tunnel، queue_full، chunks_sent |
درون نشستها: آغازگرهای دستدهی WireGuard بیش از سهم نشست (3 تا، بعد یکی در ثانیه)، دیتاگرامهایی که WireGuard بستهٔ دستگاهِ آن نشست ندانست، دیتاگرامهایی برای یک دستگاه که دور ریخته شدند چون صف ارسال اتصالش 256 تا داشت، و chunk هایی که نود فرستاد. queue_full که بالا میرود یعنی اتصالی کندتر از ترافیکی است که برایش میآید. |
ended_deadline، ended_idle، ended_packets، ended_displaced، ended_revoked، ended_closed، ended_invalid، ended_unserved |
نشستهایی که تمام شدند: هیچ بستهٔ WireGuard تا 10 ثانیه بعد از اثبات، هیچ chunk تا 300 ثانیه، تمامشدن شمارههای chunk، نهمین نشست دستگاه، دستگاهی که به هر دلیلی قطع شد یا راز ترنسپورت یا کلید ترنسپورت نودی که پیکربندی دیگر ندارد، اتصالی که بسته شد یا طرفی که نشست را بست، chunk ای که باز نشد یا فریمی که پروتکل اجازه نمیدهد، و ترنسپورتی که پیکربندی دیگر ندارد. |
upgrade_learned، upgrade_learn_failed |
چند بار فیلدهای سرآیند پاسخ upgrade از یک مبدأ فریب یاد گرفته شد، و چند بار این کار شکست خورد. تا وقتی آخرین تلاش شکست خورده، پاسخ upgrade فقط Date را از upgrade_headers دارد. شنوندهای که upgrade_headers آن هیچ فیلدی از مبدأ را نام نمیبرد، که پیشفرض ws است، از مبدأ چیزی نمیپرسد و در هیچکدام شمرده نمیشود. |
proxies، decoys، fronted |
همین حالا، روی شنوندههای ws و fronted: اتصالهای پراکسیهای مورد اعتماد، درخواستهایی روی آنها که در دست مبدأ فریباند یا بدنهشان هنوز خوانده میشود و چیزی ثابت نکردهاند، و نشستهای برقرار fronted. |
proxy_accepted، proxy_requests، proxy_unnamed، proxy_idle |
اتصالهایی که از یک پراکسی مورد اعتماد گرفته شدند، و درخواستهایی که روی آنها خوانده شدند. proxy_unnamed آن درخواستهاییاند که، روی شنوندهای با client_address_header، آن سرآیند در آنها هیچ مبدأیی را نام نبرد: خود پراکسی بهجای بازدیدکننده شمرده شد، پس حدهای هر مبدأ برای همهٔ آنها یک حد بود. وبسروری که این سرآیند را نمیگذارد اینجا دیده میشود، و veilway doctor همین دو شمارنده را میخواند. proxy_idle اتصالهاییاند که بعد از 300 ثانیه بدون درخواست بسته شدند. |
forwards، forwards_unframed، forwards_cut |
درخواستهایی که در مسیر پراکسی به مبدأ فریب داده شدند. forwards_unframed آنهاییاند که نود نتوانست پایانشان را تشخیص دهد: آنها را به شکل بایت تا پایان پاسخ مبدأ رله کرد و بعد اتصال پراکسی را بست. forwards_cut اتصالهاییاند که بیدرنگ بسته شدند چون یک مبدأ بیش از limits.decoy_requests_per_source درخواست منتظر داشت، یا همهٔ غریبهها با هم بیش از نیمی از limits.proxy_connections. |
stranger_head، stranger_session، stranger_body، stranger_unestablished |
درخواستهای مسیر پراکسی که به دلیلی که فقط همین مسیر دارد «کاربر نیست» تشخیص داده شدند: سرآیندی بلندتر از 16,384 بایت یا ناتمام بعد از 10 ثانیه، درخواست fronted ای که نشستی را با شمارهای خارج از نوبت یا هنگامی که درخواست دیگری از آن در راه است نام میبرد، درخواستی که بدنهاش دیر رسید، باز نشد یا تکراری با بایتهای دیگر بود، و درخواست آغازینی که هیچ بستهٔ WireGuard نشستش را برقرار نکرد. شمارندههای دیگر stranger_ و refused_ درخواستهای این مسیر را هم میشمارند. |
polls، poll_repeats |
درخواستهای fronted که پذیرفته شدند، با درخواستهای آغازین، و تکرارهای آخرین درخواست پذیرفتهشده که با پاسخ ذخیرهشده جواب گرفتند. |
proxy_http10 |
درخواستهای پراکسیهای مورد اعتماد که HTTP/1.0 بودند. هیچکدام نمیتواند مال کاربر باشد: وبسروری که با نود HTTP/1.0 حرف بزند همهٔ کاربران را بیرون نگه میدارد، و باید به آن گفت با HTTP/1.1 حرف بزند. |
forwards_redialed، origin_dropped |
درخواستهایی که یک بار دیگر روی اتصال تازه به مبدأ فریب فرستاده شدند، چون مبدأ اتصالی را که از درخواست قبلی مانده بود بسته بود. و اتصالهایی به مبدأ فریب که نود رهایشان کرد چون مبدأ، بی آنکه درخواستی در دستش باشد، روی آنها چیزی گفت یا آنها را بست: هیچ چیز از این به پراکسی نمیرسد و اتصال پراکسی میماند. |
replay. زمانها ثانیهٔ یونیکس روی ساعت نودند:
| فیلد | معنی |
|---|---|
ready |
وقتی هیچ اثباتی پذیرفته نمیشود false است: ریستی که هنوز معلوم نیست فایلش روی دیسک باشد. |
clock، floor، limit |
ساعت نود، زمانی که تا آن اثباتها رد میشوند، و زمانی که بالاتر از آن اثبات پیش از نوشته شدن سقف بالاتر پذیرفته نمیشود. تا وقتی نود کار میکند limit بین 10 تا 20 ثانیه از clock جلوتر است. |
disk_limit |
بالاترین سقفی که ممکن است روی دیسک باشد، که شروعِ بعد از kill آن را کف خودش میگیرد. |
entries، capacity |
اثباتهای درون cache، و replay.cache آنطور که نود با آن شروع شده. |
refusing_secs |
کف چند ثانیه از ساعت جلوتر است، به هر دلیلی. تا آن وقت اثباتهای با ساعت درست رد میشوند. بعد از شروع یا ریست تا 80، که خودش میگذرد. |
floor_ahead، refused_floor_ahead |
آیا کف طوری از ساعت جلوتر است که هیچ شروعی توضیحش نمیدهد، یعنی بیش از 80 ثانیه یا بالا رفته هنگام کار نود، که همهٔ دستگاهها را تا گذشتن ساعت از آن یا ریست حافظه رد میکند، و چند اثبات به این دلیل رد شدهاند. |
writes، write_failures، slow_writes |
نوشتنهای فایل replay که انجام شدند، که شکست خوردند، و که بیش از 2 ثانیه طول کشیدند. تا وقتی write_failures بالا میرود نود اثبات تازهای نمیپذیرد. |
limit_lowered، resets |
چند بار نود سقف خودش را بعد از ساعتی که جلو رفته بود پایین آورد، و چند بار حافظه ریست شد. |
GET /v1/sessions
Section titled “GET /v1/sessions”{"sessions": [...]}، برای هر دستگاه دارای نشست زنده روی یک ورودی یک مورد. هر مورد اینها را دارد:
user،device،public_key،inbound.transport:udp،ws،udp-obfs،tlsیاfronted، به همان نام پیکربندی، پسwsروی ورودیveilwayهمانwsبومی است. وقتی ترنسپورتی که دستگاه با آن آمده دیگر نیست، یا نشستudp-obfs،tls،wsیاfrontedآن تمام شده،null.handshake_age_secs.flows: فلوهای دستگاه روی همهٔ ورودیهایش.selected_exit: خروجیای که دستگاه روی کانال کنترل انتخاب کرده. وقتی انتخابی نکرده و از خروجی کاربرش میرودnull.control_connections: اتصالهای کنترل احرازشدهٔ دستگاه.mtu: MTU ای که دستگاه تعیین کرده. وقتی تعیین نکرده و تونلش MTU ورودی را داردnull.
نشانیای که دستگاه از آن وصل میشود هرگز جزو نشست یا هیچ پاسخی نیست، هر چه log.destinations بگوید.
GET /v1/exits
Section titled “GET /v1/exits”{"exits": [...]}.
| فیلد | معنی |
|---|---|
tag، name |
اگر پیکربندی نامی ندهد name همان تگ است. |
backend |
netstack، l3، block یا chain. |
outbound |
تگ outbound بکاند netstack، وگرنه null. |
udp |
تا آنجا که نود میداند، آیا پروکسی SOCKS5 این خروجی UDP را رله میکند. برای خروجی بدون پروکسی SOCKS5 null. |
udp_down_secs |
ثانیههای گذشته از آخرین باری که پروکسی رلهکردن UDP را رد کرد. نود هر یک دقیقه دوباره امتحان میکند. مگر وقتی udp برابر false باشد null است. |
udp_flips |
چند بار پروکسی بین رلهکردن UDP و نکردن جابهجا شد. |
interface_up |
آیا رابط بکاند l3 بالاست. تا وقتی false است، ترافیک مسیریابیشده به این خروجی «غیرقابل دسترس» جواب میگیرد و نود دوباره میکوشد رابط را بالا بیاورد: 2 ثانیه بعد، بعد هر بار با دو برابر انتظار، حداکثر دقیقهای یک بار. برای هر بکاند دیگر null. |
interface_down_secs |
ثانیههای گذشته از افتادن رابط. مگر وقتی interface_up برابر false باشد null است. |
interface_flips |
چند بار رابط بین بالا و پایین جابهجا شد. |
links |
تگ لینکهای نود یک بکاند chain که /v1/links دربارهٔ آنها گزارش میدهد. برای هر بکاند دیگر خالی است. |
link_up |
آیا یکی از آن لینکها بالاست. تا وقتی هیچکدام نباشد، ترافیک مسیریابیشده به این خروجی «غیرقابل دسترس» جواب میگیرد و راه دیگری ندارد. برای هر بکاند دیگر null. |
outbound_up |
برای خروجیای که از اتصال بیرونی wireguard میگذرد: آیا اتصال بیرونی کار میکند. فقط وقتی از کار افتاده false است: سرور 20 ثانیه به دستدهی جواب نداده یا دیتاگرامی به آن فرستاده نشده. اگر در 180 ثانیهٔ آخر دستدهی نبوده و چیزی بیجواب نیست بیکار است و true حساب میشود. تا وقتی false است خروجی کار نمیکند، دستگاههایی که خروجی انتخاب نکردهاند از routing.fallback بیرون میروند، و چیزی دورش نمیچرخد. برای هر خروجی دیگر null. |
outbound_down_secs |
چند ثانیه از افتادن اتصال بیرونی گذشته. null مگر وقتی outbound_up برابر false باشد. |
outbound_down_reason |
دلیل از کار افتادنش، با کلمه. هیچ کلیدی را نمیگوید. null مگر وقتی outbound_up برابر false باشد. |
outbound_flips |
چند بار اتصال بیرونی بین کار کردن و از کار افتادن جابهجا شد. برای هر خروجی دیگر 0. |
handshake_secs |
چند ثانیه از آخرین دستدهی با سرور گذشته. برای هر خروجی دیگر و پیش از اولین دستدهی null. |
endpoint |
نشانی و درگاهی که اتصال بیرونی الان با آن حرف میزند، یعنی همان که نامش به آن حل شده. برای هر خروجی دیگر و پیش از حل شدن نام null. |
flows |
جریانهایی که از پشتهٔ خود اتصال بیرونی باز است، TCP و UDP. برای هر خروجی دیگر null. |
latency_ms، measured_at |
مثل outbound در /v1/stats، برای outbound بکاند netstack. وگرنه null. |
load |
تنظیم load نقطهٔ خروج در پیکربندی، به شکل {"by", "busy", "very_busy"}. وقتی نقطهٔ خروج باری به برنامهها گزارش نمیکند null است. |
load_level |
سطحی که به برنامهها گفته میشود: "low"، "medium" یا "high". تا وقتی نقطهٔ خروج تنظیم load ندارد و تا وقتی نود دو بار نگاه نکرده (هر 10 ثانیه) null است. |
traffic |
شمارندهها، مثل کاربر. |
GET /v1/inbounds
Section titled “GET /v1/inbounds”{"inbounds": [...], "public_addresses": [...]}. public_addresses همان فهرست GET /v1/status است. یک مورد برای هر ورودی پیکربندی در حال اجرا، بدون کلید خصوصی.
| فیلد | معنی |
|---|---|
tag |
تگ ورودی. |
kind |
wireguard یا veilway، یعنی type ورودی. |
enabled |
برای ورودیای که پیکربندی خاموشش کرده false است: گوش نمیدهد و دستگاهی نمیپذیرد. |
public_key |
کلید عمومی WireGuard ورودی. |
transport_public_key |
نیمهٔ عمومی کلید ترنسپورت نود که پروفایل با خود دارد. برای ورودی بدون transport_keys برابر null است. |
transports |
برای هر ترنسپورت یک {"transport", "enabled", "rating"}، به ترتیب پیکربندی. enabled برای ترنسپورتی که پیکربندی خاموشش کرده false است. transport یکی از udp، ws، udp-obfs، tls یا fronted است. rating آن چیزی است که سانسورچی از اتصال یک پروفایل میتواند ببیند: protected، detectable یا unsafe. در این نسخه همهٔ ترنسپورتها detectable رتبه میگیرند. روی ترنسپورت tls که گوش میدهد سه کلید دیگر هست. pin: SHA-256 از SubjectPublicKeyInfo گواهیاش با base64 استاندارد، همان pinی که یک لینک یا پروفایل حمل میکند. key_changed_at و previous_pin: فقط وقتی نود فهمیده کلید همان نیست که پیشتر ارائه میداد، و تا 30 روز بعد از آن. key_changed_at زمان آن است (ثانیهٔ یونیکس) و previous_pin pin قدیمی. لینک یا پروفایلی که کلید قدیمی را pin کرده تا وقتی دوباره جفتسازی یا refresh نشود شکست میخورد. نود همچنان گواهی تازه را ارائه میدهد. از v0.3.6. |
GET /v1/links
Section titled “GET /v1/links”{"links": [...]}، برای هر لینک نود فعال یک مورد، بدون کلید و راز.
| فیلد | معنی |
|---|---|
tag، id |
تگ لینک و شناسهٔ آن (22 نویسه base64url). |
half |
entry وقتی این نود کاربران را دارد و بستههایشان را از راه یک خروجی با بکاند chain به لینک میفرستد. exit وقتی آنچه از لینک میرسد از این نود بیرون میرود. |
role |
listener وقتی لینک به یک ورودی این نود وصل میشود، dialler وقتی این نود به نود دیگر وصل میشود. |
state |
up (یک handshake وایرگارد در 180 ثانیهٔ گذشته کامل شده)، connecting، unreachable (هیچ کاندیدای نود دیگر پاسخ نمیدهد)، refused (نود دیگر پاسخ میدهد و اثبات را نمیپذیرد)، pin_mismatch (نود دیگر پاسخ میدهد، اما کلید گواهیاش با هیچیک از pinهای کاندیدا نمیخواند: کلید تازه دارد و لینک باید دوباره جفتسازی شود، که مشکل شبکه نیست) یا ended (24 ساعت handshake نبوده، یا این نود لینک را بهخاطر سهمیه یا انقضا قطع کرده). نودی که وصل میشود از ended به بعد روزی یک بار دوباره امتحان میکند. |
state_secs، state_flips |
ثانیههایی که لینک در state بوده، و چند بار state عوض شده. |
handshake_secs |
ثانیههای گذشته از آخرین handshake کامل تونل لینک. بدون نشست null. |
transport، transport_index، candidate_index |
روی نود وصلشونده: ترنسپورتی که روی آن است، و جای آن ترنسپورت و کاندیدایش در فهرست نود دیگر، از 0. روی نود پذیرنده همه null هستند. |
size_warning |
true وقتی سیستم در 600 ثانیهٔ گذشته یک بستهٔ بیرونی لینک را بهخاطر اندازه رد کرده، که نشان میدهد mtu لینک برای مسیر زیاد است. هر کسی روی مسیر میتواند چنین گزارشی را جعل کند، پس فقط هشدار میدهد. |
denied |
روی نیمهٔ خروج: چرا این نود لینک را قطع کرده (disabled، expired یا quota). برای لینکی که اجازهٔ کار دارد null. |
exit |
روی نیمهٔ ورود: خروجی با بکاند chain که لینک پشت آن است. |
flows |
فلوهایی که لینک حمل میکند. |
dropped |
بستههایی که از لینک بیرون آمدند و حمل نشدند. |
chained |
روی نیمهٔ خروجی: بستههایی که این نود از لینک به لینک دیگری رساند، که فقط با allow_chain پیش میآید. وگرنه 0. |
traffic |
بستههای داخلی. up آنچه این نود به لینک فرستاد، down آنچه از آن گرفت. |
Upstreamها
Section titled “Upstreamها”این مسیرها روی upstreams پیکربندی در حال اجرا کار میکنند. تگی که پیکربندی در حال اجرا نام نبرده 404 با upstream_not_found میگیرد. هیچ پاسخی کلید، راز یا لینک ندارد. صفحهٔ upstream میگوید هر گام چه میکند.
| مسیر | بدنه | پاسخ |
|---|---|---|
GET /v1/upstreams |
ندارد | {"upstreams": [...]}. هر کدام tag، state (fetching، connecting، up یا down)، reason، provider، signing_key (اثر انگشت کلیدی که سند در حال اجرا با آن امضا شده)، profile، ترنسپورت و خروجی در حال استفاده، سهمیه، اطلاعیهها، MTU، آخرین refresh، دلیل شکست refresh، جابهجایی یا میزبانهای منتظر، و شمارندهها را دارد. از v0.3.6 آنچه اپ همان موتور نشان میدهد هم دارد: engine_state (connecting، reconnecting، connected، stopped:<reason> با quota، expired، disabled یا node-stopping، یا failed؛ تا وقتی تونلی نیست null)، connected_secs، transports (نوعهایی که پروفایل در حال استفاده فهرست میکند)، profiles (همهٔ پروفایلهای سند به ترتیب امتحانشدن، هرکدام با id، name، usable و، وقتی قابل استفاده نیست، reason سادهای که هرگز آدرسی در آن نیست)، exits (حداکثر 16 نقطهٔ خروج که ارائهدهنده میدهد، هرکدام با tag، name، country، all_protocols و selected)، provider_notices (با information یا warning)، choice (profile، failover، transport و exit همانطور که پیکربندی اکنون انتخاب میکند، برای خودکار null) و، در quota، وقتی کانال کنترل باز است، period، period_start، account_expires_at، up_bytes و down_bytes. |
POST /v1/upstreams/preview |
link، private_key، device_secret و اختیاری via و allow_private |
بازبینی سند ارائهدهنده با id و expires_in_secs. وقتی 4 جا پر باشد 409 با previews_full. وقتی نشود از ارائهدهنده پرسید یا پاسخش بررسیها را رد کند 502 با provider_failed. |
POST /v1/upstreams/preview/{id}/decline |
ندارد | {"id": ...}. اگر چنین پیشنمایشی منتظر نباشد 404 با preview_not_found. |
PATCH /v1/upstreams/{tag} |
هر یک از profile، failover، transport و exit، هرکدام یک مقدار یا null |
{"tag", "revision", "generation", "live"}. فیلدی که نیاید همان میماند و null یعنی خودکار: همهٔ پروفایلها به نوبت، بدون failover، همهٔ ترنسپورتها، نقطهٔ خروج پیشفرض ارائهدهنده. هر فیلد دیگر در بدنه با 422 رد میشود، پس لینک، کلیدها، allow، allow_private و via را از این راه نمیشود عوض کرد. تغییر از همان بررسیها و همان اعمال PUT /v1/config میگذرد، روی revisionی که اکنون اجرا میشود، و در فایل پیکربندی نوشته میشود. live وقتی true است که فقط نقطهٔ خروج عوض شده: تونل میماند و نقطهٔ خروج دیگر از آن خواسته میشود. هر تغییر دیگر تونل را دوباره میسازد. 404 با upstream_not_found، 409 اگر پیکربندی در این بین دو بار جابهجا شده. از v0.3.6. |
POST /v1/upstreams/{tag}/confirm |
اختیاری move و hosts، که هر دو اگر نیایند trueاند |
{"moved": bool, "hosts": bool}، که هرکدام اگر چیزی منتظرش نبوده false است. اگر پاسخ نگه داشته نشود 500 با state_unwritten. |
POST /v1/upstreams/{tag}/retry |
ندارد | {"tag": ...}. همین حالا وصل میشود و همهٔ انتظارها را از نو شروع میکند. |
DELETE /v1/upstreams/{tag} |
ندارد | {"tag": ..., "confirmed": bool}. وقتی confirmed برابر false است، همین فراخوانی دوباره به ارائهدهنده خبر میدهد. |
رویدادها
Section titled “رویدادها”GET /v1/events جریان Server-Sent Events است (text/event-stream). هر رویداد id افزایشی، نام event و یک سند JSON بهعنوان data دارد.
| رویداد | داده |
|---|---|
config_applied |
generation، revision، diff. یک reload با SIGHUP یا یک apply. |
config_refused |
stage (validate یا prepare) و errors (تعدادشان). reload یا applyای که پیکربندی در حال اجرا را سر جایش گذاشت. |
user_cut_off |
user و reason: disabled، expired، quota یا removed. |
user_restored |
user. |
usage_reset |
user و totals (اینکه شمارندههای طول عمر هم صفر شدند یا نه). برای هر ریست مصرف فرستاده میشود. |
exit_udp_changed |
exit و udp (وضعیت تازه). |
exit_working_changed |
exit و working: پراکسی خروجی دیگر نود را راه نمیدهد، یا دوباره راه میدهد. دستگاههایی که خروجی انتخاب نکردهاند در این مدت از خروجی دیگری بیرون میروند. |
stats |
عکس لحظهای /v1/stats، هر ثانیه، فقط وقتی ساخته میشود که کسی جریان را میخواند. عکس در بافر خواننده کند یک رویداد حساب میشود. خوانندهٔ عقبمانده بهجای هر عکسی که نگرفته تازهترین عکس را میگیرد، نه عکس همان ثانیه. |
lagged |
missed. id ندارد. |
event: user_cut_offid: 42data: {"user":"alice","reason":"quota"}- خوانندههای کند. نود هرگز بیحد بافر نمیکند. خوانندهای که عقب بیفتد قدیمیترین رویدادها را از دست میدهد و
laggedبا تعداد رویدادهای ازدسترفته میگیرد، که از فاصلههای بین idها شمرده میشود. این شامل رویدادهایی است که خود نود نتوانست نگه دارد. روی نود با کاربر زیاد عکس بزرگ است، پس خوانندهای که برای هر کدام بیش از یک ثانیه لازم دارد فقط از عکسها عقب میافتد و بعد رویدادهای دیگر را هم از دست میدهد.laggedدرست پیش از رویداد بعدیِ نگهداشتهشده میآید. - نگهداشتن اتصال. هر 15 ثانیه یک خط توضیح (
: keepalive) فرستاده میشود. - اتصال کند. اتصالی که خوانندهاش 30 ثانیه چیزی برنمیدارد در حالی که نود چیزی برای فرستادن دارد بسته میشود.
- بعد از شکاف. بازپخش نیست. کلاینتی که دوباره وصل میشود باید وضعیت را از مسیرها دوباره بخواند.
محدودیتها
Section titled “محدودیتها”| محدودیت | مقدار |
|---|---|
| بدنهٔ درخواست | 4 MiB |
| خط درخواست و هدرها روی هم | 16 KiB، حداکثر 64 هدر |
| اتصال همزمان | 64. اتصال بعدی 503 too_many_connections میگیرد و بسته میشود. |
| جریان رویداد همزمان | 32، از میان همان اتصالها |
| زمان یک درخواست، از اولین بایت تا پاسخ | 30 ثانیه. همین مدت یک اتصال میتواند منتظر درخواست بعدی بماند. |
| سند پیکربندی که همزمان بررسی میشود | 2. سند سوم در مهلت درخواستش منتظر نوبت میماند. |
| رویدادهای نگهداشته برای خواننده کند | 256 |
بدنهٔ درخواست ردشده تا چهار برابر حد خوانده و دور ریخته میشود، تا کلاینتی که هنوز میفرستد بتواند دلیل رد شدن را بخواند. بعد از آن اتصال قطع میشود.
کلاینت TypeScript
Section titled “کلاینت TypeScript”@veilway/sdk (نسخهٔ 0.2.11-alpha، صفحهٔ آن) کلاینت تایپداری است که از سند OpenAPI ساخته میشود. وابستگی زمان اجرا ندارد. یک تابع fetch و یک نشانی پایه میگیرد، پس راه رسیدن به سوکت یونیکس با خود شماست. این مثال از undici استفاده میکند:
import {Agent, fetch as undiciFetch} from "undici";import {Client, VeilwayError, type Fetch} from "@veilway/sdk";
const dispatcher = new Agent({connect: {socketPath: "/srv/veilway/veilway.sock"}});const fetch: Fetch = (url, init) => undiciFetch(url, {...init, dispatcher}) as unknown as ReturnType<Fetch>;const client = new Client(fetch, "http://veilway");const running = await client.getConfig();try { await client.applyConfig({...running.document, log: {level: "debug"}}, running.revision);} catch (e) { if (e instanceof VeilwayError) console.log(e.status, e.code, e.details);}for await (const event of client.events()) { if (event.event === "user_cut_off") console.log(event.data.user, event.data.reason);}متدها: status، getConfig، validateConfig، diffConfig، applyConfig، listUsers، getUser، resetUsage، resetReplay، stats، listSessions، listExits، listInbounds، listLinks و events. هر شکستی به شکل VeilwayError با status، code، message و details پرتاب میشود. resetUsage(name, {totals: true}) مصرف یک کاربر را ریست میکند و کاربر را برمیگرداند. resetReplay() حافظهٔ replay را ریست میکند و آن را برمیگرداند؛ اول هزینهاش را زیر POST /v1/replay/reset بخوانید. events وقتی نود جریان را ببندد یا signal لغو شود تمام میشود و رویدادهای lagged را هم میدهد.
هنوز ساخته نشده
Section titled “هنوز ساخته نشده”- دسترسی از راه دور: شنوندهٔ TCP، توکن و TLS دوطرفه. فعلاً سوکت تنها راه ورود است.
- مسیر لاگها.
- قطع دستی یک نشست.
- تغییر یک کاربر، ورودی یا لینک بهتنهایی. نوشتنها فقط یک پیکربندی کامل (
PUT /v1/config)، ریست مصرف و ریست replay هستند.