DomainResolver
DomainResolver نودی پیشرفته برای استفاده داخلی است که پیش از عبور دادن Init، نام domain مقصد line را به IP تبدیل میکند.
در پیکربندیهای معمول لازم نیست این نود را دستی اضافه کنید. نودهای سطح بالاتری مانند TcpConnector، UdpConnector، Router، Socks5Client، VlessClient و TrojanClient در صورت نیاز آن را داخل خودشان میسازند و تنظیم میکنند. ابتدا از تنظیمات عمومی همان نودها استفاده کنید، مگر اینکه عمداً chain سفارشیای میسازید که خودش line->routing_context.dest_ctx را مقداردهی میکند.
کاری که انجام میدهد
DomainResolver فقط context آدرس مقصد را میخواند و بهروزرسانی میکند:
line->routing_context.dest_ctx
اگر مقصد از ابتدا IP باشد یا قبلاً resolve شده باشد، Init بیدرنگ عبور داده میشود. اگر مقصد نام domain باشد، درخواست DNS بهصورت async روی worker فعلی انجام میشود؛ سپس strategy انتخاب آدرس اعمال و IP برگزیده در dest_ctx نوشته میشود و در پایان Init که منتظر مانده بود عبور میکند.
این نود:
- socket باز نمیکند
- line جدید نمیسازد
- payload را تغییر نمیدهد
- بایتی از پروتکل به بافر اضافه نمیکند
src_ctxرا resolve نمیکند- نود packet line نیست
جایگاه رایج
استفاده دستی از این نود برای سناریوهای پیشرفته است. آن را پس از نودی قرار دهید که dest_ctx را روی یک domain تنظیم میکند و پیش از نودی که به IP واقعی نیاز دارد.
TcpListener -> Socks5Server -> DomainResolver -> TcpConnector
در بیشتر پیکربندیهای عادی نیازی به این کار نیست، زیرا connector یا نود پروتکل resolver داخلی خود را میسازد.
نمونه تنظیمات
{
"name": "resolve-domain",
"type": "DomainResolver",
"settings": {
"strategy": "prefer-ipv4",
"verbose": false
},
"next": "outbound"
}
فیلدها
| فیلد | نوع | اجباری | توضیح |
|---|---|---|---|
type | string | بله | باید DomainResolver باشد. |
settings | object | خیر | object تنظیمات اختیاری؛ اگر نوشته شود باید از نوع object باشد. |
next | string | معمولاً | نودی که پس از resolve شدن مقصد، Init را در جهت upstream میگیرد. |
این نود از نظر فنی میتواند Init را از upstream یا downstream بگیرد؛ با این حال در استفاده دستی معمولاً در مسیر upstream و میانه chain از نوع stream قرار میگیرد.
تنظیمات
| گزینه | پیشفرض | توضیح |
|---|---|---|
strategy | مقدار core در dns.domain-strategy | روش انتخاب نتیجه DNS. یکی از core-settings، accept-dns-returned-order، prefer-ipv4، prefer-ipv6، only-ipv4 یا only-ipv6. |
verbose | false | آغاز resolve را در لاگ debug ثبت میکند. آدرس resolveشده همچنان در logger عادی debug مربوط به DNS ثبت میشود. |
strategy میتواند string یا یکی از مقادیر داخلی مورد قبول parser مشترک domain-strategy باشد.
جریان اجرا
هنگام دریافت Init از upstream:
- state مربوط به line آماده میشود.
dest_ctxبررسی میشود- اگر نیازی به DNS نباشد،
Initدر جهت upstream بهnextمیرود. - اگر DNS لازم باشد، نود وارد state مربوط به resolving میشود و callback برمیگردد.
- پس از پایان DNS، آدرس انتخابشده در
dest_ctxنوشته میشود. Initمنتظرمانده در جهت upstream عبور داده میشود.- payloadهایی که هنگام DNS در صف ماندهاند، دوباره پخش میشوند.
در downstream نیز همین الگو برقرار است، با این تفاوت که Init منتظرمانده به نود قبلی فرستاده میشود.
Pending Payload
Payloadهایی که هنگام DNS از سمتی برسند که عملیات را آغاز کرده، در صف قرار میگیرند. سقف این صف برای هر line برابر 1 MiB است.
این سقف پس از قرار گرفتن payload در صف بررسی میشود؛ بنابراین ممکن است صف به اندازه یک بافر از حد بگذرد و سپس line بسته شود. اگر DNS شکست بخورد یا صف سرریز شود، نود state خود را از بین میبرد و تنها همان سمتی را finish میکند که line حلنشده را آغاز کرده بود.
تا پیش از رسیدن به stateِ open، callbackهای غیر از payload نادیده گرفته میشوند.
رفتار در خطا
در شرایط زیر line رد میشود:
- مقصد نه آدرس IP باشد و نه domain معتبر.
- ثبت درخواست async DNS شکست بخورد.
- DNS برای
strategyتنظیمشده هیچ آدرس قابل استفادهای برنگرداند - صف payloadهای pending از سقف تعیینشده بگذرد.
DomainResolver خودش درخواست DNS را دوباره امتحان نمیکند. این کار باید در نود سطح بالاتر یا در طراحی transport انجام شود.
مشخصات نود
| ویژگی | مقدار |
|---|---|
| مخاطب | کاربران پیشرفته و ترکیب داخلی نودها |
| جایگاه | نود پشتیبان در میانه stream |
| Layer group | Anything to anything |
| Per-line state | دارد |
| ایجاد line | خیر |
| آزاد کردن line | خیر |
| تغییر payload | خیر |
| Required left padding | 0 |