پرش به مطلب اصلی

بخش ۱: تنظیمات هسته

WaterWall هنگام راه‌اندازی، تنظیمات اولیه‌ی خود را از فایل core.json می‌خواند. تنظیمات سراسری process، مانند log‌ها، تعداد worker‌ها، پروفایل حافظه، MTU، تنظیم اختیاری BBR در Linux، مسیر library‌های خارجی، DNS resolver مشترک و فهرست فایل‌های config node‌ها، در این فایل قرار می‌گیرند.

خود node‌های تونل مستقیماً در این فایل تعریف نمی‌شوند. chain‌های تونل در فایل‌هایی قرار دارند که زیر configs فهرست شده‌اند.

نکات مهم هنگام راه‌اندازی​

اگر مسیر config را با آرگومان CLI یا متغیر محیطی تغییر نداده باشید، WaterWall فایل ./core.json را از working directory خود می‌خواند. چیدمان معمول فایل‌ها:

waterwall/
WaterWall
core.json
configs/
server.json

WaterWall را از همین دایرکتوری اجرا کنید:

cd ~/waterwall
./WaterWall

برای انتخاب منبع دیگری برای JSON هسته، می‌توانید از هر یک از شکل‌های معادل زیر در CLI استفاده کنید:

-c:PATH
--c:PATH
-config:PATH
--config:PATH
config:PATH

وجود : الزامی است. مقدار PATH می‌تواند یک مسیر نسبی از working directory یا یک مسیر مطلق باشد. مقدار ویژه‌ی stdin باعث می‌شود JSON هسته از ورودی استاندارد خوانده شود:

./WaterWall --config:/etc/waterwall/core.json
./WaterWall --config:stdin < core.json

متغیر محیطی WW_CORE_JSON_INPUT نیز همین مسیرها یا مقدار stdin را می‌پذیرد. ترتیب اولویت انتخاب ورودی چنین است:

CLI option > WW_CORE_JSON_INPUT > ./core.json

محتوای core.json باید JSON معتبر باشد؛ بنابراین در آن comment‌هایی با // ننویسید. قابلیت comment نوشتن و جایگزینی variable که در ادامه توضیح می‌دهیم، فقط در loader فایل‌های config node‌ها پشتیبانی می‌شود، نه در parser تنظیمات هسته.

انتخاب منبع دیگری برای JSON هسته، working directory مربوط به process را تغییر نمی‌دهد. همه‌ی مسیرهای داخل core.json دقیقاً با همان شکلی که نوشته شده‌اند به بخش مربوط داده می‌شوند؛ بنابراین مسیرهای نسبی، از جمله اعضای configs، همچنان نسبت به دایرکتوری اجرای WaterWall محاسبه می‌شوند، نه نسبت به محل فایل JSON هسته.

ساختار سطح اول​

{
"log": {},
"misc": {},
"dns": {},
"configs": []
}
فیلدنوعالزامیکاربرد
configsآرایه‌ای از string‌هابلهفایل‌های config node‌ها که باید parse و اجرا شوند.
logobjectخیرمسیر و فایل log، سطح log و خروجی console.
miscobjectخیرتعداد worker‌ها، پروفایل حافظه، MTU، تنظیم BBR در Linux و مسیر library‌ها.
dnsobjectخیرDNS resolver مشترک و async و سیاست پیش‌فرض انتخاب آدرس domain.

وجود configs الزامی است و باید دست‌کم یک مسیر string در آن باشد. بخش‌های دیگر اختیاری‌اند، اما در محیط production بهتر است misc و dns.domain-strategy را صریحاً مشخص کنید.

گزینه‌ی domain-strategy را در ریشه‌ی core.json قرار ندهید:

{
"domain-strategy": "prefer-ipv4"
}

این ساختار هنگام راه‌اندازی رد می‌شود. شکل درست آن چنین است:

{
"dns": {
"domain-strategy": "prefer-ipv4"
}
}

configs​

بخش configs مشخص می‌کند WaterWall پس از آماده‌شدن runtime هسته، کدام فایل‌های config node را load کند.

{
"configs": [
"configs/server.json",
"configs/reverse.json"
]
}

قواعد:

حالترفتار
configs وجود نداردراه‌اندازی با خطا متوقف می‌شود.
آرایه خالی استراه‌اندازی با خطا متوقف می‌شود.
هیچ عضو string در آرایه نیستراه‌اندازی با خطا متوقف می‌شود.
مسیرها نسبی‌اندنسبت به working directory مربوط به process resolve می‌شوند.
چند فایل وجود داردپس از parse شدن تنظیمات هسته، node manager آن‌ها را load می‌کند.

برای راه‌اندازی‌های کوچک یک فایل کافی است. برای راه‌اندازی‌های بزرگ‌تر می‌توانید گروه‌های مختلف chain را در چند فایل جدا قرار دهید.

log​

بخش log چهار logger سراسری process را تنظیم می‌کند.

loggerکاربرد
internalجزئیات سطح پایین runtime و اطلاعات تشخیصی داخلی.
coreراه‌اندازی، parse کردن config و log‌های سطح manager.
networklog‌های شبکه و runtime تونل‌ها.
dnslog‌های DNS resolver مشترک و async.

هر logger فیلدهای یکسانی می‌پذیرد:

فیلدنوعمقدار پیش‌فرضتوضیح
loglevelstring"INFO"پایین‌ترین سطحی که این logger ثبت می‌کند.
filestringمختص همان loggerنام فایلی که به log.path افزوده می‌شود.
consolebooleantrueخروجی این logger در console نیز چاپ شود.

log.path دایرکتوری پایه برای ساخت مسیر فایل‌های log است. مقدار پیش‌فرض آن "log/" است. WaterWall در صورت نیاز این دایرکتوری را هنگام راه‌اندازی می‌سازد.

مقادیر پیش‌فرض:

فیلدمقدار پیش‌فرض
log.path"log/"
log.internal.loglevel"INFO"
log.internal.file"internal.log"
log.internal.consoletrue
log.core.loglevel"INFO"
log.core.file"core.log"
log.core.consoletrue
log.network.loglevel"INFO"
log.network.file"network.log"
log.network.consoletrue
log.dns.loglevel"INFO"
log.dns.file"dns.log"
log.dns.consoletrue

سطح‌های قابل‌قبول برای log:

VERBOSE, DEBUG, INFO, WARN, ERROR, FATAL, SILENT

logger پیش از اعمال مقدار، آن را به حروف بزرگ تبدیل می‌کند؛ بنابراین در این لایه "debug" و "DEBUG" تفاوتی ندارند.

برای نمایش همه‌ی سطح‌های log در یک اجرا، گزینه‌ی --verbose را اضافه کنید:

./WaterWall --verbose
./WaterWall --verbose --config:/etc/waterwall/core.json

شکل‌های معادل این گزینه --log، -log، -verbose، --showlog، -showlog و --debug-log هستند. در هر اجرا فقط یکی از این شکل‌ها را مشخص کنید.

این گزینه خروجی console را فعال می‌کند و سطح logger‌های internal، core، network و dns را روی VERBOSE قرار می‌دهد؛ بنابراین تنظیمات loglevel و console حتی در حالت SILENT بازنویسی می‌شوند. فایل‌های log فعال نیز پیام‌های اضافی را دریافت می‌کنند. مسیر فایل‌ها و غیرفعال‌بودن خروجی فایل همچنان از config پیروی می‌کنند. این تغییر پیش از مقداردهی اولیه‌ی logger‌ها فقط در حافظه اعمال می‌شود و فایل core.json را تغییر نمی‌دهد. گزینه‌ی -v همچنان نسخه را چاپ می‌کند. گزینه‌ی --verbose را فقط یک بار مشخص کنید؛ ترکیب آن با درخواست نمایش نسخه یا بازیابی Windows مجاز نیست.

نمونه:

{
"log": {
"path": "logs/",
"internal": {
"loglevel": "INFO",
"file": "internal.log",
"console": false
},
"core": {
"loglevel": "INFO",
"file": "core.log",
"console": true
},
"network": {
"loglevel": "WARN",
"file": "network.log",
"console": true
},
"dns": {
"loglevel": "DEBUG",
"file": "dns.log",
"console": true
}
}
}

پیشنهادهای عملی:

موقعیتپیشنهاد
نصب اولیه یا debugخروجی console برای core، network و dns را فعال نگه دارید.
محیط production با اتصال‌های زیادبرای network از INFO یا WARN استفاده کنید؛ سطح‌های پرحجم را فقط هنگام debug فعال کنید.
عیب‌یابی DNSموقتاً log.dns.loglevel را روی "DEBUG" بگذارید.
سرویس بلندمدتحتی اگر خروجی console غیرفعال است، ثبت log در فایل را فعال نگه دارید.

misc​

بخش misc اندازه‌ی منابع runtime و نحوه‌ی load library‌ها را در سطح process کنترل می‌کند.

{
"misc": {
"workers": 4,
"ram-profile": "server",
"mtu": 1500,
"tcp-tune": true,
"try-enabling-bbr": true,
"libs-path": "libs/"
}
}
فیلدنوعمقدار پیش‌فرضاعتبارسنجی و رفتار
workersintegerتعداد هسته‌های CPUمقدار 0 یا منفی به تعداد هسته‌های CPU برمی‌گردد. مقادیر بیشتر از 254 به 254 کاهش می‌یابند.
ram-profilestring یا integer"server"اندازه‌ی memory pool‌ها و پیش‌فرض node‌های وابسته به پروفایل را انتخاب می‌کند. عدد باید یک عدد صحیح در بازه‌ی 0..6 باشد. مقدار نامعتبر راه‌اندازی را متوقف می‌کند.
mtuinteger1500مقدار سراسری MTU که تونل‌های بدون مقدار اختصاصی آن را به ارث می‌برند. باید یک عدد صحیح در بازه‌ی 68..65535 باشد. مقدار نامعتبر راه‌اندازی را متوقف می‌کند.
tcp-tunebooleantrue در Linux؛ در بقیه‌ی سیستم‌ها falseتنظیم هنگام راه‌اندازی هسته با سقف ثابت 128 MiB برای socket و تنظیم خودکار buffer‌های TCP.
try-enabling-bbrbooleantrueفقط در Linux: اگر kernel از BBR پشتیبانی کند، WaterWall تلاش می‌کند TCP BBR را فعال کند؛ موفقیت این کار تضمین‌شده نیست.
libs-pathstring"libs/"دایرکتوری load library‌های خارجی تونل.

مقادیر پیش‌فرض بالا در هر سه حالت اعمال می‌شوند: چه misc موجود باشد، چه خالی و چه به‌کلی حذف شده باشد - از جمله mtu و ram-profile که پیش‌تر با حذف این بخش بدون مقدار می‌ماندند. مقدار نامعتبر هرگز با پیش‌فرض جایگزین نمی‌شود؛ برنامه با خطایی که نام همان فیلد را نشان می‌دهد متوقف می‌شود. با این حال برای رفتار قابل‌پیش‌بینی بهتر است کل بخش misc را صریح بنویسید.

workers​

گزینه‌ی workers تعداد worker thread‌هایی را مشخص می‌کند که WaterWall می‌سازد.

نوع استفادهنقطه‌ی شروع مناسب
client کوچک یا محیط تست1 یا 2
VPS عمومیبرابر با تعداد هسته‌های CPU
سرور پرترافیکابتدا تعداد هسته‌های CPU؛ سپس تنظیم بر اساس معیارهای CPU و latency

worker بیشتر همیشه بهتر نیست. هر worker یک event loop و بخشی از منابع مختص خود را دارد. مقادیر بسیار بزرگ به 254 محدود می‌شوند.

ram-profile​

مقادیر string:

مقدارپروفایل داخلیکاربرد معمول
"server"پروفایل حافظه‌ی L2پروفایل پیش‌فرض سمت server با pool‌های بزرگ‌تر.
"client"پروفایل حافظه‌ی M1پروفایل عمومی سمت client.
"client-larger"پروفایل حافظه‌ی M2پروفایل بزرگ‌تر سمت client.
"minimal"پروفایل حافظه‌ی S1پروفایل با حداقل مصرف حافظه.
"ultralow"پروفایل حافظه‌ی S1نام مستعار "minimal".

parser پیش از تطبیق، مقدار string را به حروف کوچک تبدیل می‌کند. در config‌های جدید بهتر است از مقدارهای string استفاده کنید.

مقادیر integer قدیمی نیز همچنان پذیرفته می‌شوند:

مقدارپروفایل
0 یا 1پروفایل حافظه‌ی S1
2پروفایل حافظه‌ی S2
3پروفایل حافظه‌ی M1
4پروفایل حافظه‌ی M2
5پروفایل حافظه‌ی L1
6پروفایل حافظه‌ی L2

این پروفایل پیش‌فرض بعضی تنظیمات حساس به حافظه را نیز انتخاب می‌کند. به‌طور مشخص، اگر detached-buffer-limit و detached-child-limit در MuxClient یا MuxServer نوشته نشوند، مقدار آن‌ها از حداقل S1 تا حداکثر L2 افزایش می‌یابد؛ تنظیم صریح node همچنان اولویت دارد. مقدار دقیق هر پروفایل در راهنمای node‌های Mux آمده است.

هر مقدار عددی یا string نامعتبر، راه‌اندازی را متوقف می‌کند.

mtu​

misc.mtu فقط پیش‌فرض زمان ساخت node‌هاست. هر node مقدار خود را اعتبارسنجی و ثابت ذخیره می‌کند؛ override یک node، هسته یا node‌های دیگر را تغییر نمی‌دهد. این مقدار MTU اجباری مشترک همهٔ node‌ها یا اندازه‌گیری MTU مسیر نیست.

مگر آنکه توپولوژی شما مقدار دیگری لازم داشته باشد، از 1500 استفاده کنید. تونل‌های packet، دستگاه‌های TUN، لایه‌های encapsulation و chain‌های شبیه VPN ممکن است برای جلوگیری از fragmentation به MTU مؤثر کوچک‌تری نیاز داشته باشند.

parser مقدار را به‌صورت عدد صحیح در بازه‌ی 68..65535 اعتبارسنجی می‌کند: 68 حداقل MTU برای IPv4 در RFC 791 است و 65535 بزرگ‌ترین مقداری است که این فیلد می‌تواند نگه دارد. مقدار خارج از بازه، کسری یا از نوع نادرست راه‌اندازی را متوقف می‌کند و با پیش‌فرض جایگزین نمی‌شود.

splice​

مقدار پیش‌فرض splice برابر true است؛ مقدار false مسیر عادی TCP را فعال می‌کند. splice فقط در پلتفرم‌ها و chainهایی استفاده می‌شود که همهٔ نودهای آن از این قابلیت پشتیبانی کنند.

در Linux پشتیبانی‌شده، WaterWall هنگام راه‌اندازی تلاش می‌کند مقدار fs.pipe-user-pages-soft را تا بودجهٔ 512 MiB، تبدیل‌شده به تعداد pageهای سیستم، افزایش دهد. اگر fs.pipe-user-pages-hard غیرصفر باشد، هدف از آن بیشتر نمی‌شود. این تنظیم‌ها مصرف مجموع pipeهای هر کاربر را در سطح سیستم محدود می‌کنند. مقدار soft نامحدود (0) یا بزرگ‌تر از هدف حفظ می‌شود. شکست این تنظیم مانع راه‌اندازی نیست؛ مقدار hard و fs.pipe-max-size تغییر نمی‌کنند و تنظیم دائمی نوشته نمی‌شود. افزایش موفق پس از خروج برنامه هم باقی می‌ماند.

پس از نهایی‌شدن chainهای همهٔ configهای راه‌اندازی و پیش از اجرای hookهای prepare/start یا آغاز تولید داده، bufferهای کامل splice با padding ثابتِ برابر با بیشترین نیاز chainها و pipeهای با ظرفیت کامل 1 MiB ساخته می‌شوند. سقف مجموع ظرفیت برای فرایند 512 MiB است. تعداد pipeها از floor((RLIMIT_NOFILE.soft - open_descriptors) / 8) هم بیشتر نمی‌شود؛ هر pipe دو descriptor دارد و بنابراین این مجموعه حداکثر یک‌چهارم سهم باقی‌ماندهٔ descriptorهای فرایند را مصرف می‌کند و باقی را برای منابع config و runtime نگه می‌دارد. شمارش از /proc/self/fd به‌صورت محافظه‌کارانه descriptor موقت خودِ شمارش را هم شامل می‌شود؛ اگر حد یا شمارش در دسترس نباشد، مجموعه خالی می‌ماند. محدودیت‌های kernel و خطای تخصیص ممکن است تعداد واقعی را کمتر کنند. تعداد و ظرفیت واقعی در log راه‌اندازی ثبت می‌شود. این بودجهٔ ظرفیت pipe است و به معنی رزرو 512 MiB حافظهٔ فیزیکی برای payload نیست.

هر worker حداکثر هشت buffer خالی splice را در cache محلی نگه می‌دارد. اگر cache خالی باشد، از masterpool مشترک buffer می‌گیرد. اگر هر دو خالی باشند، درخواست مقدار NULL برمی‌گرداند و caller معمولاً از buffer عادی استفاده می‌کند، حتی اگر cache مربوط به worker دیگری هنوز pipe آزاد داشته باشد. pipeهای سالم تا shutdown حفظ می‌شوند؛ هنگام ترافیک pipe تازه ساخته یا بزرگ نمی‌شود و pipe کوچک‌تر هم پذیرفته نمی‌شود. pipe غیرقابل‌استفاده بدون جایگزین کنار گذاشته می‌شود. splice: false هم تنظیم محدودیت pipe و هم ساخت این مجموعه را غیرفعال می‌کند.

tcp-tune​

این گزینه در Linux بومی به‌صورت پیش‌فرض true است و در سیستم‌های دیگر، از جمله Android و Cygwin، false است. این پیش‌فرض برای misc خالی یا حذف‌شده هم اعمال می‌شود. فقط boolean پذیرفته می‌شود. مقدار false این مرحله‌ی راه‌اندازی هسته را غیرفعال می‌کند؛ این گزینه مستقل از splice و try-enabling-bbr است. مقدار صریح true در سیستم‌های دیگر پذیرفته می‌شود، ولی هیچ تنظیمی انجام نمی‌دهد.

پس از آماده‌شدن log‌های runtime و پیش از بارگذاری config نودها، WaterWall دقیقاً چهار مقدار ثابت زیر را مستقل از پروفایل حافظه اعمال می‌کند:

تنظیممقدار
net.core.rmem_max134217728 (128 MiB)
net.core.wmem_max134217728 (128 MiB)
net.ipv4.tcp_rmem4096 87380 134217728
net.ipv4.tcp_wmem4096 87380 134217728

این مرحله net.core.netdev_max_backlog و net.core.somaxconn را تغییر نمی‌دهد. وجود MuxClient یا MuxServer در chain باعث می‌شود نودهای TcpListener و TcpConnector برای گزینه‌های حذف‌شده‌ی ارسال و دریافت، اندازه‌ی 16 MiB را صریحاً درخواست کنند؛ این رفتار مستقل از tcp-tune و موفقیت اجرای sysctl است. در نبود Mux، گزینه‌های حذف‌شده به kernel واگذار می‌شوند. مقادیر صریح large-send-buffer و large-recv-buffer، از جمله تنظیمات هر مقصد TcpConnector، در هر دو حالت اولویت دارند.

اگر اجرای دستوری ناموفق باشد، یک warning ثبت می‌شود و اجرای بقیه‌ی دستورها ادامه پیدا می‌کند. نداشتن مجوز یا نبودن sysctl راه‌اندازی را متوقف نمی‌کند. تغییرات موفق در تنظیمات زنده‌ی kernel اعمال می‌شوند و پس از خروج برگردانده نمی‌شوند؛ WaterWall آن‌ها را در /etc/sysctl.conf ذخیره نمی‌کند.

RawSocket مرحله‌ی تنظیم جداگانه‌ای با گزینه‌ی skip-sysctl برای backlogها و سایر پارامترهای TCP دارد. نوشتن چهار تنظیم buffer بالا فقط در مرحله‌ی راه‌اندازی هسته با tcp-tune انجام می‌شود.

try-enabling-bbr​

وقتی این گزینه در Linux برابر true باشد، WaterWall الگوریتم فعلی کنترل ازدحام TCP و مقدار net.ipv4.tcp_available_congestion_control را بررسی می‌کند. اگر kernel در حال اجرا bbr را در فهرست پشتیبانی‌شده داشته باشد و BBR از قبل فعال نباشد، WaterWall مقادیر فعلی sysctl را برای net.core.default_qdisc=fq و net.ipv4.tcp_congestion_control=bbr اعمال می‌کند.

این فقط تلاشی برای تنظیم بهتر سیستم هنگام راه‌اندازی است و موفقیت آن تضمین‌شده نیست. WaterWall نه kernel نصب می‌کند و نه /etc/sysctl.conf را تغییر می‌دهد. اگر نمی‌خواهید تلاش برای فعال‌سازی BBR انجام شود، این گزینه را روی false بگذارید. گزینه‌ی tcp-tune مرحله‌ی جداگانه‌ی تنظیم مقادیر ثابت buffer‌های socket و TCP را کنترل می‌کند.

libs-path​

libs-path دایرکتوری library‌های خارجی تونل را مشخص می‌کند.

در بیشتر راه‌اندازی‌ها از node‌های داخلی استفاده می‌شود و این مقدار را می‌توان بدون تغییر گذاشت:

{
"misc": {
"libs-path": "libs/"
}
}

فقط زمانی آن را تغییر دهید که عمداً library مربوط به node‌های خارجی را از دایرکتوری دیگری load می‌کنید.

dns​

بخش dns، resolver مشترک و async مبتنی بر c-ares را که worker‌های WaterWall به کار می‌برند تنظیم می‌کند. همچنین سیاست پیش‌فرض انتخاب آدرس domain برای node‌های connector در همین بخش تعیین می‌شود.

اگر dns حذف شده یا خالی باشد:

تنظیممقدار پیش‌فرض
گزینه‌های resolverمقادیر پیش‌فرض c-ares در WaterWall
dns.domain-strategy"prefer-ipv4"
timeout-ms1000
max-timeout-ms5000
tries2
query-cache-max-ttl1800
server-failover.retry-chance10
server-failover.retry-delay-ms5000

سایر گزینه‌های رفتاری DNS فقط در صورت تعریف‌شدن به c-ares فرستاده می‌شوند. در صورت حذف آن‌ها، رفتارشان را c-ares و تنظیمات resolver سیستم‌عامل تعیین می‌کند.

dns.domain-strategy​

domain-strategy مشخص می‌کند وقتی DNS رکورد IPv4، IPv6 یا هر دو را برمی‌گرداند، WaterWall کدام آدرس را انتخاب کند.

این مقدار پیش‌فرض هسته برای node‌هایی است که سیاست جداگانه‌ای ندارند. TcpConnector و UdpConnector می‌توانند در settings خود آن را override کنند. هر مقصد در ورودی‌های وزن‌دار TcpConnector.addresses نیز می‌تواند سیاست مخصوص خود را داشته باشد.

مقادیر string معتبر:

مقداررفتار
"prefer-ipv4"در صورت وجود، نخستین آدرس IPv4 انتخاب می‌شود؛ در غیر این صورت IPv6 به کار می‌رود. این مقدار پیش‌فرض هسته است.
"prefer-ipv6"در صورت وجود، نخستین آدرس IPv6 انتخاب می‌شود؛ در غیر این صورت IPv4 به کار می‌رود.
"only-ipv4"فقط نتیجه‌های IPv4 پذیرفته می‌شوند. اگر آدرس IPv4 برنگردد، نتیجه برای آن اتصال قابل‌استفاده نیست.
"only-ipv6"فقط نتیجه‌های IPv6 پذیرفته می‌شوند. اگر آدرس IPv6 برنگردد، نتیجه برای آن اتصال قابل‌استفاده نیست.
"accept-dns-returned-order"نخستین آدرس قابل‌استفاده با همان ترتیبی که DNS برگردانده انتخاب می‌شود.

تطبیق string‌ها به بزرگی و کوچکی حروف حساس نیست.

مقادیر integer قدیمی:

مقدارسیاست
0accept-dns-returned-order
1prefer-ipv4
2prefer-ipv6
3only-ipv4
4only-ipv6

نمونه:

{
"dns": {
"domain-strategy": "prefer-ipv4"
}
}

راهنمای عملی:

محیطسیاست
بیشتر VPS‌های مبتنی بر IPv4"prefer-ipv4"
شبکه‌ای که IPv6 در آن اولویت دارد"prefer-ipv6"
سرور یا قواعد firewall مختص IPv4"only-ipv4"
راه‌اندازی فقط با IPv6"only-ipv6"
به ترتیب اعلام‌شده‌ی resolver اعتماد دارید"accept-dns-returned-order"

زمان‌بندی و cache مربوط به resolver​

فیلدنوعمقدار پیش‌فرضاعتبارسنجیمفهوم
timeout-msinteger1000بزرگ‌تر از 0timeout اولیه‌ی query مربوط به DNS بر حسب میلی‌ثانیه.
max-timeout-msinteger5000بزرگ‌تر از 0بیشترین timeout برای query مربوط به DNS پس از retry‌ها.
triesinteger2بزرگ‌تر از 0تعداد دفعات تلاش برای query.
query-cache-max-ttlinteger18000 یا بیشترحداکثر TTL مربوط به DNS cache بر حسب ثانیه.

نمونه:

{
"dns": {
"timeout-ms": 750,
"max-timeout-ms": 3000,
"tries": 2,
"query-cache-max-ttl": 600
}
}

timeout کوتاه‌تر باعث می‌شود شکست resolve شدن domain زودتر مشخص شود، اما در شبکه‌های کند یا دارای packet loss می‌تواند قابلیت اطمینان را کاهش دهد. TTL کوتاه‌تر cache هم باعث می‌شود تغییرات DNS زودتر دیده شوند، ولی ترافیک resolver را بیشتر می‌کند.

گزینه‌های رفتاری resolver​

این گزینه‌ها اختیاری‌اند. اگر حذف شوند، مقادیر پیش‌فرض c-ares اعمال خواهد شد.

فیلدنوعاعتبارسنجیمفهوم
ndotsintegerاز 0 تا 15تعداد نقطه‌های لازم پیش از آنکه c-ares نام را absolute در نظر بگیرد.
udp-portintegerاز 1 تا 65535پورت UDP سرور DNS.
tcp-portintegerاز 1 تا 65535پورت TCP سرور DNS.
socket-send-buffer-sizeintegerبزرگ‌تر از 0اندازه‌ی send buffer مربوط به socketِ DNS.
socket-receive-buffer-sizeintegerبزرگ‌تر از 0اندازه‌ی receive buffer مربوط به socketِ DNS.
edns-packet-sizeintegerاز 1 تا 65535اندازه‌ی packet مربوط به EDNS.
udp-max-queriesinteger0 یا بیشترمحدودیت query‌های UDP در c-ares.
rotatebooleanمقدار booleanچرخش میان server‌های c-ares را فعال یا غیرفعال می‌کند.

نمونه:

{
"dns": {
"ndots": 1,
"udp-port": 53,
"tcp-port": 53,
"socket-send-buffer-size": 262144,
"socket-receive-buffer-size": 262144,
"edns-packet-size": 1232,
"udp-max-queries": 0,
"rotate": true
}
}

تا وقتی دلیل مشخصی ندارید، این گزینه‌ها را تغییر ندهید. برای بیشتر کاربران، servers، domain-strategy و گزینه‌های زمان‌بندی کافی‌اند.

گزینه‌های search و source​

فیلدنوعاعتبارسنجیمفهوم
domainsآرایه‌ای از string‌هاآرایه و string‌ها نباید خالی باشندsearch domain‌هایی که به c-ares داده می‌شوند.
lookupsstringفقط b و f، بدون کاراکتر تکراریترتیب lookup source‌ها؛ b یعنی DNS و f یعنی فایل hosts.
resolvconf-pathstringstring غیرخالیمسیر سفارشی resolv.conf.
hosts-pathstringstring غیرخالیمسیر سفارشی فایل hosts.
sortliststringstring غیرخالیمقدار sortlist مربوط به c-ares.
serversstring یا آرایه‌ای از string‌هاغیرخالی؛ اعضای آرایه نباید کاما داشته باشندسرورهای DNS که به c-ares داده می‌شوند.

servers می‌تواند یک string با قالب CSV مورد قبول c-ares یا یک آرایه باشد. اگر آرایه باشد، WaterWall اعضای آن را پیش از فرستادن به c-ares با کاما به هم متصل می‌کند.

نمونه:

{
"dns": {
"servers": [
"1.1.1.1",
"8.8.8.8"
],
"lookups": "bf",
"domains": [
"example.com"
],
"resolvconf-path": "/etc/resolv.conf",
"hosts-path": "/etc/hosts",
"sortlist": "10.0.0.0/8"
}
}

مقادیر lookups:

مقدارمفهوم
"b"فقط DNS.
"f"فقط فایل hosts.
"bf"ابتدا DNS و سپس فایل hosts بررسی شود.
"fb"ابتدا فایل hosts و سپس DNS بررسی شود.

source‌های lookup را تکرار نکنید؛ مقادیر "bb"، "ff" و "bfb" رد می‌شوند.

dns.flags​

flags گزینه‌های flag پشتیبانی‌شده‌ی c-ares را تنظیم می‌کند و چهار شکل نوشتاری دارد.

bitmask عددی:

{
"dns": {
"flags": 0
}
}

نام یک flag:

{
"dns": {
"flags": "edns"
}
}

آرایه‌ای از نام flag‌ها:

{
"dns": {
"flags": [
"edns",
"dns0x20"
]
}
}

object با مقدارهای boolean:

{
"dns": {
"flags": {
"edns": true,
"dns0x20": true,
"use-vc": false
}
}
}

در شکل object، مقدار true یک flag را فعال می‌کند و false آن را غیرفعال باقی می‌گذارد.

نام flag‌های پشتیبانی‌شده:

نامflag در c-ares
"usevc"ARES_FLAG_USEVC
"use-vc"ARES_FLAG_USEVC
"tcp"ARES_FLAG_USEVC
"primary"ARES_FLAG_PRIMARY
"igntc"ARES_FLAG_IGNTC
"ignore-truncated"ARES_FLAG_IGNTC
"norecurse"ARES_FLAG_NORECURSE
"no-recurse"ARES_FLAG_NORECURSE
"stayopen"ARES_FLAG_STAYOPEN
"stay-open"ARES_FLAG_STAYOPEN
"no-search"ARES_FLAG_NOSEARCH
"no-aliases"ARES_FLAG_NOALIASES
"nocheckresp"ARES_FLAG_NOCHECKRESP
"no-check-response"ARES_FLAG_NOCHECKRESP
"edns"ARES_FLAG_EDNS
"no-default-server"ARES_FLAG_NO_DFLT_SVR
"no-dflt-svr"ARES_FLAG_NO_DFLT_SVR
"dns0x20"ARES_FLAG_DNS0x20

وجود نام ناشناخته برای flag، راه‌اندازی را متوقف می‌کند. bitmask‌های عددی نیز فقط می‌توانند bit‌های پشتیبانی‌شده‌ی c-ares را در خود داشته باشند.

dns.server-failover​

بخش server-failover گزینه‌های failover سرور را در c-ares تنظیم می‌کند.

فیلدنوعمقدار پیش‌فرضاعتبارسنجیمفهوم
retry-chanceinteger10از 0 تا 65535مقدار احتمال retry در c-ares.
retry-delay-msinteger50000 یا بیشترفاصله‌ی زمانی تا تلاش دوباره برای سرور DNS ناموفق.

نمونه:

{
"dns": {
"server-failover": {
"retry-chance": 25,
"retry-delay-ms": 2000
}
}
}

اگر server-failover وجود داشته باشد، باید یک object باشد. فیلدهای داخل آن اختیاری‌اند و فیلدهای حذف‌شده مقدار پیش‌فرض خود را حفظ می‌کنند.

نمونه‌ی کامل ساختار​

نمونه‌ی زیر همه‌ی بخش‌های فعلی مستندشده‌ی هسته و بیشتر فیلدهای DNS را نشان می‌دهد. از آن به‌عنوان مرجع استفاده کنید، نه توصیه‌ای برای تغییر همه‌ی مقادیر DNS.

{
"log": {
"path": "log/",
"internal": {
"loglevel": "INFO",
"file": "internal.log",
"console": true
},
"core": {
"loglevel": "INFO",
"file": "core.log",
"console": true
},
"network": {
"loglevel": "INFO",
"file": "network.log",
"console": true
},
"dns": {
"loglevel": "INFO",
"file": "dns.log",
"console": true
}
},
"misc": {
"workers": 4,
"ram-profile": "server",
"mtu": 1500,
"try-enabling-bbr": true,
"libs-path": "libs/"
},
"dns": {
"domain-strategy": "prefer-ipv4",
"timeout-ms": 1000,
"max-timeout-ms": 5000,
"tries": 2,
"query-cache-max-ttl": 1800,
"ndots": 1,
"udp-port": 53,
"tcp-port": 53,
"socket-send-buffer-size": 262144,
"socket-receive-buffer-size": 262144,
"edns-packet-size": 1232,
"udp-max-queries": 0,
"flags": [
"edns",
"dns0x20"
],
"rotate": true,
"domains": [
"example.com"
],
"lookups": "bf",
"resolvconf-path": "/etc/resolv.conf",
"hosts-path": "/etc/hosts",
"sortlist": "10.0.0.0/8",
"servers": [
"1.1.1.1",
"8.8.8.8"
],
"server-failover": {
"retry-chance": 10,
"retry-delay-ms": 5000
}
},
"configs": [
"configs/server.json"
]
}

نمونه‌ی حداقلی و کاربردی​

برای بیشتر کاربران، شروع با این نمونه‌ی کوچک‌تر مناسب‌تر است:

{
"log": {
"path": "logs/",
"core": {
"loglevel": "INFO",
"file": "core.log",
"console": true
},
"network": {
"loglevel": "INFO",
"file": "network.log",
"console": true
},
"dns": {
"loglevel": "INFO",
"file": "dns.log",
"console": true
},
"internal": {
"loglevel": "INFO",
"file": "internal.log",
"console": true
}
},
"misc": {
"workers": 4,
"ram-profile": "server",
"mtu": 1500,
"try-enabling-bbr": true,
"libs-path": "libs/"
},
"dns": {
"domain-strategy": "prefer-ipv4"
},
"configs": [
"configs/server.json"
]
}

نمونه‌ی تنظیم‌شده برای DNS​

اگر می‌خواهید سرورهای DNS را صریحاً مشخص کنید و رفتار resolver را سریع‌تر عیب‌یابی کنید، نمونه‌ی زیر نقطه‌ی شروع مناسبی است:

{
"log": {
"path": "logs/",
"core": {
"loglevel": "INFO",
"file": "core.log",
"console": true
},
"network": {
"loglevel": "WARN",
"file": "network.log",
"console": false
},
"dns": {
"loglevel": "DEBUG",
"file": "dns.log",
"console": true
},
"internal": {
"loglevel": "INFO",
"file": "internal.log",
"console": false
}
},
"misc": {
"workers": 8,
"ram-profile": "client-larger",
"mtu": 1500,
"try-enabling-bbr": true,
"libs-path": "libs/"
},
"dns": {
"domain-strategy": "prefer-ipv4",
"servers": [
"1.1.1.1",
"8.8.8.8"
],
"timeout-ms": 1000,
"max-timeout-ms": 5000,
"tries": 2,
"query-cache-max-ttl": 600,
"lookups": "bf",
"flags": [
"edns",
"dns0x20"
],
"rotate": true,
"server-failover": {
"retry-chance": 10,
"retry-delay-ms": 5000
}
},
"configs": [
"configs/server.json",
"configs/reverse.json"
]
}

خطاهای رایج هنگام راه‌اندازی​

اشتباهنتیجهراه‌حل
در core.json از comment‌های // استفاده شده استخطای parse در JSONcomment‌ها را از core.json حذف کنید.
configs وجود ندارد یا خالی استراه‌اندازی متوقف می‌شودمسیر دست‌کم یک فایل config را اضافه کنید.
مسیر موجود در configs نسبت به دایرکتوری دیگری نوشته شده استفایل config خوانده نمی‌شودWaterWall را از working directory موردنظر اجرا کنید یا مسیرها را اصلاح کنید.
domain-strategy در ریشه قرار داردراه‌اندازی متوقف می‌شودآن را به dns.domain-strategy منتقل کنید.
dns یک object نیستراه‌اندازی متوقف می‌شودبرای dns از object استفاده کنید یا آن را حذف کنید.
dns.flags نام ناشناخته‌ای داردراه‌اندازی متوقف می‌شودیکی از نام‌های مستندشده را به کار ببرید.
در misc.ram-profile اشتباه تایپی وجود داردراه‌اندازی متوقف می‌شوداز server، client، client-larger، minimal یا ultralow استفاده کنید.
تعداد worker‌ها بیش‌ازحد زیاد استمقدار به 254 کاهش می‌یابدتعداد واقع‌بینانه‌ای برای worker‌ها انتخاب کنید.

ابتدا چه چیزهایی را تنظیم کنیم؟​

در شروع، فقط روی این موارد تمرکز کنید:

هدففیلد
اجرای chain‌های درستconfigs
کنترل مصرف CPUmisc.workers
انتخاب رفتار حافظه برای server یا clientmisc.ram-profile
داشتن log‌های کاربردیlog.network.loglevel، log.dns.loglevel
اولویت‌دادن به IPv4 یا IPv6dns.domain-strategy
استفاده از resolver‌های مشخصdns.servers

تا زمانی که دلیل مشخصی برای تغییر گزینه‌های پیشرفته‌ی DNS ندارید، آن‌ها را به حال خود بگذارید. مقادیر پیش‌فرض عمداً برای کاربردهای معمول محافظه‌کارانه انتخاب شده‌اند.