رفتن به محتوا

مرجع 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 هرگز جست‌وجو نمی‌شود، پس هر نامی کار می‌کند.

  • همهٔ بدنه‌ها 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 هرگز مقداری از سند ندارد.

وضعیت 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 جریان رویداد را سرویس می‌دهد.
متد مسیر پاسخ
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 را هم مثل بالا بدهد. جدول‌های زیر فقط آنچه مخصوص هر مسیر است را می‌آورند.

فیلد نوع معنی
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 را اجرا می‌کند.

{"revision", "generation", "document"} را می‌دهد. document پیکربندی در حال اجراست و هر راز در آن با نشانهٔ "<redacted>" عوض شده. ریویژن در هدر ETag هم می‌آید.

بدنه: یک سند پیکربندی. چیزی تغییر نمی‌کند. چه سند معتبر باشد چه نه، پاسخ 200 است:

فیلد معنی
valid وقتی سند خطا نداشته باشد true است.
report errors و warnings (فهرست‌هایی از {"path", "message"})، more_errors و more_warnings (تعداد موارد بعد از 100 مورد اول هرکدام)، shadow_cut_short (بررسی قاعده‌هایی که قاعدهٔ قبلی پوششان می‌دهد در بودجه‌اش متوقف شد).

بدنهٔ JSON که پیکربندی معتبر نیست 200 با valid: false می‌گیرد. بدنهٔ غیر JSON 400 bad_json است.

بدنه: یک سند پیکربندی. چیزی تغییر نمی‌کند. پاسخ 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 آن به‌جای نشانه نوشته شده باشد، هر مقداری که باشد، تغییرکرده فهرست می‌شود. وگرنه «تغییر نکرده» به کسی که گذرواژه‌ای را حدس زده می‌گفت حدسش درست بود.

بدنه: یک سند پیکربندی. هدر: 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 می‌گیرد و اعلام نمی‌شود.

ریویژن 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 “کاربران، آمار، نشست‌ها، خروجی‌ها”

فهرست {"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 هرگز جزو آن نیست.

شمارش سهمیهٔ یک کاربر را از نو شروع می‌کند. پشت دستور 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/reset
curl --unix-socket veilway.sock -X POST http://veilway/v1/users/alice/usage/reset -H 'Content-Type: application/json' --data '{"totals": true}'

حافظهٔ 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/reset

یک عکس لحظه‌ای از همهٔ شمارنده‌ها، با نرخ به بایت بر ثانیه. نود هر ثانیه نمونه می‌گیرد. نرخ، رشد بین قدیمی‌ترین و جدیدترین نمونهٔ 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 چند بار نود سقف خودش را بعد از ساعتی که جلو رفته بود پایین آورد، و چند بار حافظه ریست شد.

{"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 بگوید.

{"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 شمارنده‌ها، مثل کاربر.

{"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.

{"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 آنچه از آن گرفت.

این مسیرها روی 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 است، همین فراخوانی دوباره به ارائه‌دهنده خبر می‌دهد.

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_off
id: 42
data: {"user":"alice","reason":"quota"}
  • خواننده‌های کند. نود هرگز بی‌حد بافر نمی‌کند. خواننده‌ای که عقب بیفتد قدیمی‌ترین رویدادها را از دست می‌دهد و lagged با تعداد رویدادهای ازدست‌رفته می‌گیرد، که از فاصله‌های بین idها شمرده می‌شود. این شامل رویدادهایی است که خود نود نتوانست نگه دارد. روی نود با کاربر زیاد عکس بزرگ است، پس خواننده‌ای که برای هر کدام بیش از یک ثانیه لازم دارد فقط از عکس‌ها عقب می‌افتد و بعد رویدادهای دیگر را هم از دست می‌دهد. lagged درست پیش از رویداد بعدیِ نگه‌داشته‌شده می‌آید.
  • نگه‌داشتن اتصال. هر 15 ثانیه یک خط توضیح (: keepalive) فرستاده می‌شود.
  • اتصال کند. اتصالی که خواننده‌اش 30 ثانیه چیزی برنمی‌دارد در حالی که نود چیزی برای فرستادن دارد بسته می‌شود.
  • بعد از شکاف. بازپخش نیست. کلاینتی که دوباره وصل می‌شود باید وضعیت را از مسیرها دوباره بخواند.
محدودیت مقدار
بدنهٔ درخواست 4 MiB
خط درخواست و هدرها روی هم 16 KiB، حداکثر 64 هدر
اتصال همزمان 64. اتصال بعدی 503 too_many_connections می‌گیرد و بسته می‌شود.
جریان رویداد همزمان 32، از میان همان اتصال‌ها
زمان یک درخواست، از اولین بایت تا پاسخ 30 ثانیه. همین مدت یک اتصال می‌تواند منتظر درخواست بعدی بماند.
سند پیکربندی که همزمان بررسی می‌شود 2. سند سوم در مهلت درخواستش منتظر نوبت می‌ماند.
رویدادهای نگه‌داشته برای خواننده کند 256

بدنهٔ درخواست ردشده تا چهار برابر حد خوانده و دور ریخته می‌شود، تا کلاینتی که هنوز می‌فرستد بتواند دلیل رد شدن را بخواند. بعد از آن اتصال قطع می‌شود.

@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 را هم می‌دهد.

  • دسترسی از راه دور: شنوندهٔ TCP، توکن و TLS دوطرفه. فعلاً سوکت تنها راه ورود است.
  • مسیر لاگ‌ها.
  • قطع دستی یک نشست.
  • تغییر یک کاربر، ورودی یا لینک به‌تنهایی. نوشتن‌ها فقط یک پیکربندی کامل (PUT /v1/config)، ریست مصرف و ریست replay هستند.