دیاوهاچ net.doh
DNS رمزشده: یک حلکننده روی DNS روی HTTPS و DNS روی TLS با جایگزینی کارگزار و حافظهی TTL، DNS سادهی UDP به عنوان جایگزین، پیشتنظیمها و یک کارگزار محلی برای برنامههای دیگر.
واردسازی شبکه.دیاوهاچ
نام آرگومانها شناسهی خود کد است و معادل فارسی ندارد؛ گونهها، کلیدواژهها و نام بستهها با معادل فارسی نوشته میشوند.
DNS معمولی «نشانی این نام چیست؟» را به متن ساده روی UDP میپرسد، پس شبکهی میان شما و حلکننده هر نامی را که جستجو میکنید میخواند و میتواند پاسخ را عوض یا مسدود کند. DNS روی HTTPS (DoH) و DNS روی TLS (DoT) همین پرسش را درون یک اتصال رمزشده میفرستند. این بسته هر دو را پشتیبانی میکند، و DNS سادهی UDP را هم، و آنچه برنامه روی آن لازم دارد اضافه میکند: یک حلکننده که فهرستی از کارگزارها را به ترتیب امتحان میکند، پاسخها را به اندازهی TTLشان به یاد میسپارد و جستجوی میزبان را با فهرستی از نشانیها پاسخ میدهد. یک کارگزار محلی حلکننده را به یک کارگزار DNS محلی کوچک تبدیل میکند، تا برنامههای دیگر با اشاره دادن DNSشان به آن از آن استفاده کنند. برای دیدن اینکه تکهها در یک برنامه چگونه کنار هم مینشینند، ساختن برنامهای به سبک v2ray یا VPN را بخوانید.
ایدههای اصلی:
- یک
کارگزارمیگوید چگونه به یک کارگزار DNS برسیم:نوع دیاوهاچ پست(POST روی HTTPS)،نوع دیاوهاچ گت(GET روی HTTPS)،نوع دیاوهتی(TLS روی درگاه ۸۵۳) یانوع یو دی پی ساده(ساده).کلودفلر،گوگل،کواد نهو شکلهای DoTشان آمادهاند وکارگزار جدید،کارگزار دیاوهتی جدیدوکارگزار ساده جدیدمال خودتان را میسازند. - نشانیهای IP یک کارگزار را در
نشانیهای راهاندازبدهید. آنوقت برنامه لازم ندارد نام خود کارگزار را از پیش حل کند، که وقتی دقیقا DNS مسدود است اهمیت دارد. پرسشیک بار از یک کارگزار میپرسد.حلکننده جدیدوحلاز یک فهرست میپرسند: کارگزاری که شکست بخورد، مهلتش تمام شود یا SERVFAIL یا REFUSED بدهد برای بعدی کنار گذاشته میشود و پاسخها نگه داشته میشوند (پاسخ به اندازهی TTLش، بین حدهایتعیین حدود ماندگاری؛ پاسخ «چنین نامی نیست» برای زمان ثابتی کوتاه).- گواهیها بررسی میشوند.
ناامنآن را فقط برای آزمون خاموش میکند.
چیزهایی که آدم را گیر میاندازد:
- DNS رمزشده پرسش را از شبکه پنهان میکند، نه از حلکننده. حلکنندهای که برمیگزینید هر نامی را که جستجو میکنید میبیند. یکی را برگزینید که به آن اعتماد دارید و به یاد داشته باشید که وصل شدن به نشانی یک حلکنندهی معروف خودش دیده میشود.
- حلکنندههای مسدود. شبکه میتواند نشانی کارگزارهای DoH عمومی را ببندد. چند کارگزار به کار ببرید، یک کارگزار ساده یا خصوصی را آخر فهرست نگه دارید و برای کارگزارهای سادهی رایج در ایران
کارگزارهای ساده ایرانرا ببینید. DNS ساده خواناست و سر راه قابل تغییر است. - DNSSEC نیست. پاسخها همانطور که کارگزار داد پذیرفته میشوند؛ هیچ چیزی اینجا امضای DNSSEC را بررسی نمیکند.
- کارگزار محلی روی UDP و TCP پاسخ میدهد (همان درگاه، TCP با پیشوند طول دو بایتی) و کنترل دسترسی ندارد. وقتی میزبان خالی است روی
127.0.0.1گوش میدهد؛0.0.0.0را فقط عمداً بدهید چون سرور DNS باز روی نشانی عمومی سوءاستفاده میشود. - آنچه نگه داشتهاید آزاد کنید.
آزاد کردن پاسخ،آزاد کردن پاسخ نهاییوآزاد کردن کارگزارهاحافظه را آزاد میکنند؛حلکنندهوکارگزار محلیتا پایان برنامه زنده میمانند. - حافظه و شمارندهها میان نخها مشترکاند و حلکننده قفل خودش را دارد، پس یک حلکننده میتواند به چند نخ سرویس بدهد.
- کارگزارهای IPv6 کار میکنند. نشانی کارگزار میتواند IPv6 باشد، روی UDP، TLS یا HTTPS. کارگزارهای آماده نخست IPv4 را دارند؛
با نشانی آیپی۶،کلودفلر آیپی۶،گوگل آیپی۶وکواد نه آیپی۶نشانیهای IPv6 را میافزایند یا به کار میبرند (2606:4700:4700::1111،2001:4860:4860::8888،2620:fe::fe). کارگزار محلی میتواند روی::1یا::گوش دهد. - اتصالها بازاستفاده میشوند. DoH روی HTTPS اتصالهایش را زنده نگه میدارد و برای پرسوجوهای بعدی دوباره به کار میبرد (تا ۸ اتصال بیکار، ۳۰ ثانیه)؛ اتصال کهنه با اتصال تازه عوض و پرسوجو یک بار تکرار میشود.
اتصالهای بازاستفادهشدهشمار بازاستفادهها را میدهد وبستن اتصالهای بیکاراتصالهای بیکار را میبندد. - پیشتنظیمهای ایران تأییدنشدهاند. نشانیهای
شکن،چهارصدوسه،الکترو،راداروبگزراز فهرستهای جامعه آمده و با سایت رسمی آن سرویسها تأیید نشد. پیش از اتکا بررسیشان کنید.
استفاده از حلکننده
از فهرستی از کارگزارها یک حلکننده بسازید و از آن بپرسید. جستجوی دوم همان نام از حافظه میآید و به شبکه دست نمیزند. نمونه یک کارگزار DNS کوچک روی loopback به کار میبرد تا هرجا اجرا شود؛ با کارگزارهای واقعی از کارگزارهای پیشفرض یا فهرست خودتان استفاده کنید.
// زبان: فارسی
واردسازی فشرده سازی
واردسازی حافظه
واردسازی شبکه.دیاناس
واردسازی شبکه.دیاوهاچ
واردسازی شبکه.یو دی پی
واردسازی همگام سازی
ناپایا udp_port := 0
ناپایا queries := 0
ناپایا ready := همگام سازی.گروه انتظار جدید()
تابع record(name: رشته، rtype: صحیح، ttl: صحیح، data: رشته): دیاناس.رکورد:
برگشت دیاناس.رکورد { نام دامنه = name، نوع رکورد = rtype، رده = 1، زمان ماندگاری = ttl، داده = data }
پایان
تابع answer_for(p: تهی*، n: صحیح): فشرده سازی.بافر بایت:
queries++
question := دیاناس.کدگشایی(p، n)
asked := question.پرسشها.پرسشها.بگیر(0)
ناپایا records := وکتور {} برگردان وکتور<دیاناس.رکورد>
ناپایا rcode := 0
اگر asked.نام دامنه برابر "a.test" و asked.نوع رکورد برابر دیاناس.نوع آ:
records.بیفزا(record("a.test"، دیاناس.نوع آ، 120، "10.0.0.1"))
records.بیفزا(record("a.test"، دیاناس.نوع آ، 300، "10.0.0.2"))
وگرنه asked.نام دامنه برابر "v6.test" و asked.نوع رکورد برابر دیاناس.نوع کواداِی:
records.بیفزا(record("v6.test"، دیاناس.نوع کواداِی، 300، "2001:db8::5"))
وگرنه asked.نام دامنه برابر "txt.test" و asked.نوع رکورد برابر دیاناس.نوع تیایکستی:
records.بیفزا(record("txt.test"، دیاناس.نوع تیایکستی، 60، "hello world"))
وگرنه asked.نام دامنه برابر "alias.test":
records.بیفزا(record("alias.test"، دیاناس.نوع سینیم، 60، "target.test"))
اگر asked.نوع رکورد برابر دیاناس.نوع آ:
records.بیفزا(record("target.test"، دیاناس.نوع آ، 60، "10.9.9.9"))
پایان
وگرنه:
rcode = 3
پایان
برگشت دیاوهاچ.کدگذاری پاسخ(question.شناسه، asked.نام دامنه، asked.نوع رکورد، rcode، records)
پایان
تابع udp_server():
s := یو دی پی.پیوند(0)
udp_port = یو دی پی.درگاه(s)
همگام سازی.اتمام(ready)
buf := حافظه.تخصیص(2048 برگردان طبیعی۶۴)
ناپایا from_host := ""
ناپایا from_port := 0
تا درست:
n := یو دی پی.دریافت بایت(s، buf، 2048، from_host، from_port)
اگر n بزرگتر 0:
answer := answer_for(buf، n)
یو دی پی.ارسال بایت(s، from_host، from_port، answer.داده، answer.طول)
پایان
پایان
پایان
تابع start_mock():
همگام سازی.افزودن(ready، 1 برگردان صحیح۶۴)
_t := نخساز(udp_server)
همگام سازی.انتظار(ready)
پایان
تابع mock_server(name: رشته): دیاوهاچ.کارگزار:
ناپایا server := دیاوهاچ.کارگزار ساده جدید(name، "127.0.0.1")
server.درگاه = udp_port
برگشت server
پایان
تابع ریشه:
start_mock()
ناپایا servers := وکتور {} برگردان وکتور<دیاوهاچ.کارگزار>
servers.بیفزا(mock_server("mock"))
resolver := دیاوهاچ.حلکننده جدید(servers)
addresses := دیاوهاچ.جستجوی میزبان(resolver، "a.test")
سرچاپ "نشانیها:"، addresses.طول()، addresses.بگیر(0)
again := دیاوهاچ.جستجوی میزبان(resolver، "a.test")
سرچاپ again.طول()
stats := دیاوهاچ.آمار(resolver)
سرچاپ "از سرور"، queries، "بار پرسیده شد؛ برخورد حافظه:"، stats.برخورد حافظه
پایانبرای کار واقعی کارگزارها را به ترتیب اعتمادتان بگذارید و به هر کدام نشانیهایش را بدهید:
ناپایا servers := وکتور {} برگردان وکتور<دیاوهاچ.کارگزار>
servers.بیفزا(دیاوهاچ.کلودفلر())
servers.بیفزا(دیاوهاچ.گوگل دیاوهتی())
servers.بیفزا(دیاوهاچ.کارگزار ساده جدید("home"، "192.168.1.1"))
resolver := دیاوهاچ.حلکننده جدید(servers)
سرچاپ دیاوهاچ.جستجوی میزبان(resolver، "example.com")
DNS وقتی شبکهها دخالت میکنند
سه نوع دردسر رایج است. شبکه میتواند جستجوهای شما را بخواند: DoH یا DoT به کار ببرید. میتواند پاسخ بعضی نامها را عوض کند یا چیزی برنگرداند: DNS رمزشده تغییر سر راه را میبندد ولی مسدود کردن نشانی حلکننده را نه. میتواند خود حلکنندهها را مسدود کند: چند تا فهرست کنید، نشانیهای راهانداز را پر نگه دارید تا برای رسیدن به آنها جستجویی لازم نباشد و کارگزار سادهای را که در شبکهی شما کار میکند آخرین انتخاب بگذارید. کارگزارهای ساده ایران کارگزارهای سادهی رایج در ایران را فهرست میکند؛ ترافیکشان رمزشده نیست.
یک کارگزار محلی روی 127.0.0.1 راه بیندازید و سیستمعامل یا یک برنامه را به آن اشاره بدهید، تا هر جستجویی که میکند از حلکنندهی شما و حافظهاش بگذرد. وقتی برنامه خودش از راه پراکسی نامها را جستجو میکند، همانطور که SOCKS5 و تروجان میکنند، بگذارید پراکسی نام را حل کند تا جستجو اصلا محلی انجام نشود.
چه باید دانست
- DNS رمزشده پرسش را از شبکه پنهان میکند، نه از حلکنندهای که برمیگزینید.
نشانیهای راهاندازرا پر کنید، یا باتعیین کارگزارهای راهاندازیک راهانداز بگذارید، تا حلکننده برای پیدا کردن DNSش به DNS نیاز نداشته باشد.- کارگزارهای ناموفق کنار گذاشته میشوند؛ پاسخ «چنین نامی نیست» نهایی است و برای زمان کوتاه شکست نگه داشته میشود.
- اعتبارسنجی DNSSEC نیست. کارگزار محلی کنترل دسترسی ندارد؛ آن را به loopback ببندید.
پرسشمهلتی به میلیثانیه دارد وحلکنندهتعیین مهلت؛ آن را کوتاه نگه دارید تا یک کارگزار مسدود برنامهتان را معطل نکند.- هیچ گزارشی خودکار نوشته نمیشود.
گونهها
ورودی حافظه CacheEntry
ساختار ورودی حافظه| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| پاسخ خام | raw | فشرده سازی.بافر بایت | پاسخ نگهداریشده به شکل بایتهای سیمی DNS. |
| زمان انقضا | expires_ms | صحیح۶۴ = 0 | زمان انقضای ورودی، به شکل زمانی به میلیثانیه. |
| منفی | negative | منطقی = نادرست | درست برای پاسخ نگهداریشدهی «چنین نامی نیست» یا «دادهای نیست». |
پاسخ نهایی Answer
ساختار پاسخ نهاییحل برمیگرداند: پاسخ، و اینکه از حافظه آمد یا نه.| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| معتبر | ok | منطقی = نادرست | درست وقتی کارگزاری پاسخ قابل استفاده داد، یا حافظه داد. |
| از حافظه | cached | منطقی = نادرست | درست وقتی پاسخ از حافظه آمد بیآنکه از کارگزاری پرسیده شود. |
| منفی | negative | منطقی = نادرست | درست وقتی پاسخ میگوید نام وجود ندارد یا دادهای از آن نوع ندارد. |
| کد نتیجه | rcode | صحیح = 0 | کد پاسخ DNS: ۰ موفق، ۳ نامی که وجود ندارد. |
| زمان ماندگاری | ttl | صحیح = 0 | پاسخ چند ثانیه دیگر میتواند استفاده شود، پس از حدهای تعیین حدود ماندگاری. |
| پاسخ خام | raw | فشرده سازی.بافر بایت | پاسخ به شکل بایتهای سیمی DNS. با آزاد کردن پاسخ نهایی آزادش کنید. |
| پیام | msg | دیاناس.پیام | dns.Message رمزگشاییشده. |
| کارگزار | server | رشته = "" | نام کارگزاری که پاسخ داد، برای پاسخ حافظه خالی. |
| خطا | err | رشته = "" | چرا هیچ کارگزاری نتوانست پاسخ دهد، وقتی معتبر نادرست است. |
// زبان: فارسی
واردسازی فشرده سازی
واردسازی حافظه
واردسازی شبکه.دیاناس
واردسازی شبکه.دیاوهاچ
واردسازی شبکه.یو دی پی
واردسازی همگام سازی
ناپایا udp_port := 0
ناپایا queries := 0
ناپایا ready := همگام سازی.گروه انتظار جدید()
تابع record(name: رشته، rtype: صحیح، ttl: صحیح، data: رشته): دیاناس.رکورد:
برگشت دیاناس.رکورد { نام دامنه = name، نوع رکورد = rtype، رده = 1، زمان ماندگاری = ttl، داده = data }
پایان
تابع answer_for(p: تهی*، n: صحیح): فشرده سازی.بافر بایت:
queries++
question := دیاناس.کدگشایی(p، n)
asked := question.پرسشها.پرسشها.بگیر(0)
ناپایا records := وکتور {} برگردان وکتور<دیاناس.رکورد>
ناپایا rcode := 0
اگر asked.نام دامنه برابر "a.test" و asked.نوع رکورد برابر دیاناس.نوع آ:
records.بیفزا(record("a.test"، دیاناس.نوع آ، 120، "10.0.0.1"))
records.بیفزا(record("a.test"، دیاناس.نوع آ، 300، "10.0.0.2"))
وگرنه asked.نام دامنه برابر "v6.test" و asked.نوع رکورد برابر دیاناس.نوع کواداِی:
records.بیفزا(record("v6.test"، دیاناس.نوع کواداِی، 300، "2001:db8::5"))
وگرنه asked.نام دامنه برابر "txt.test" و asked.نوع رکورد برابر دیاناس.نوع تیایکستی:
records.بیفزا(record("txt.test"، دیاناس.نوع تیایکستی، 60، "hello world"))
وگرنه asked.نام دامنه برابر "alias.test":
records.بیفزا(record("alias.test"، دیاناس.نوع سینیم، 60، "target.test"))
اگر asked.نوع رکورد برابر دیاناس.نوع آ:
records.بیفزا(record("target.test"، دیاناس.نوع آ، 60، "10.9.9.9"))
پایان
وگرنه:
rcode = 3
پایان
برگشت دیاوهاچ.کدگذاری پاسخ(question.شناسه، asked.نام دامنه، asked.نوع رکورد، rcode، records)
پایان
تابع udp_server():
s := یو دی پی.پیوند(0)
udp_port = یو دی پی.درگاه(s)
همگام سازی.اتمام(ready)
buf := حافظه.تخصیص(2048 برگردان طبیعی۶۴)
ناپایا from_host := ""
ناپایا from_port := 0
تا درست:
n := یو دی پی.دریافت بایت(s، buf، 2048، from_host، from_port)
اگر n بزرگتر 0:
answer := answer_for(buf، n)
یو دی پی.ارسال بایت(s، from_host، from_port، answer.داده، answer.طول)
پایان
پایان
پایان
تابع start_mock():
همگام سازی.افزودن(ready، 1 برگردان صحیح۶۴)
_t := نخساز(udp_server)
همگام سازی.انتظار(ready)
پایان
تابع mock_server(name: رشته): دیاوهاچ.کارگزار:
ناپایا server := دیاوهاچ.کارگزار ساده جدید(name، "127.0.0.1")
server.درگاه = udp_port
برگشت server
پایان
تابع first(v: وکتور<رشته>): رشته:
اگر v.طول() برابر 0:
برگشت "none"
پایان
برگشت v.بگیر(0)
پایان
تابع ریشه:
start_mock()
ناپایا servers := وکتور {} برگردان وکتور<دیاوهاچ.کارگزار>
servers.بیفزا(mock_server("mock"))
resolver := دیاوهاچ.حلکننده جدید(servers)
دیاوهاچ.تعیین مهلت(resolver، 2000)
دیاوهاچ.تعیین حدود ماندگاری(resolver، 30، 3600، 15)
ناپایا a := دیاوهاچ.حل در زمان(resolver، "a.test"، دیاناس.نوع آ، 1000 برگردان صحیح۶۴)
سرچاپ a.معتبر، a.از حافظه، a.زمان ماندگاری، a.منفی، a.کد نتیجه، a.پیام.پاسخها.رکوردها.طول()، queries
ناپایا again := دیاوهاچ.حل در زمان(resolver، "a.test"، دیاناس.نوع آ، 61000 برگردان صحیح۶۴)
سرچاپ again.از حافظه، again.زمان ماندگاری، queries
ناپایا later := دیاوهاچ.حل در زمان(resolver، "a.test"، دیاناس.نوع آ، 200000 برگردان صحیح۶۴)
سرچاپ later.از حافظه، later.زمان ماندگاری، queries
دیاوهاچ.آزاد کردن پاسخ نهایی(a)
دیاوهاچ.آزاد کردن پاسخ نهایی(again)
دیاوهاچ.آزاد کردن پاسخ نهایی(later)
n1 := دیاوهاچ.حل در زمان(resolver، "nothing.test"، دیاناس.نوع آ، 500000 برگردان صحیح۶۴)
سرچاپ n1.معتبر، n1.منفی، n1.کد نتیجه، n1.زمان ماندگاری، n1.از حافظه
n2 := دیاوهاچ.حل در زمان(resolver، "nothing.test"، دیاناس.نوع آ، 505000 برگردان صحیح۶۴)
سرچاپ n2.از حافظه، n2.منفی، queries
ناپایا live := دیاوهاچ.حل(resolver، "a.test"، دیاناس.نوع آ)
سرچاپ live.معتبر، live.از حافظه
دیاوهاچ.آزاد کردن پاسخ نهایی(live)
سرچاپ first(دیاوهاچ.جستجوی آ(resolver، "a.test"))، دیاوهاچ.جستجوی آ(resolver، "a.test").طول()
سرچاپ first(دیاوهاچ.جستجوی کواداِی(resolver، "v6.test"))، first(دیاوهاچ.جستجوی تیایکستی(resolver، "txt.test"))
سرچاپ دیاوهاچ.جستجوی سینیم(resolver، "alias.test")، first(دیاوهاچ.جستجوی میزبان(resolver، "alias.test"))، first(دیاوهاچ.جستجوی میزبان(resolver، "5.6.7.8"))
stats := دیاوهاچ.آمار(resolver)
سرچاپ stats.برخورد حافظه بزرگتر 0، stats.ناکامی حافظه بزرگتر 0، stats.پرسش بالادست بزرگتر 0، stats.شکستها
سرچاپ دیاوهاچ.اندازه حافظه(resolver) بزرگتر 0
دیاوهاچ.پاک کردن حافظه(resolver)
سرچاپ دیاوهاچ.اندازه حافظه(resolver)
ناپایا dead := وکتور {} برگردان وکتور<دیاوهاچ.کارگزار>
dead.بیفزا(دیاوهاچ.کارگزار جدید("dead"، دیاوهاچ.نوع دیاوهاچ پست، "http://127.0.0.1:1/dns-query"))
broken := دیاوهاچ.حلکننده جدید(dead)
دیاوهاچ.تعیین مهلت(broken، 300)
failed := دیاوهاچ.حل(broken، "a.test"، دیاناس.نوع آ)
سرچاپ failed.معتبر، failed.خطا.طول() بزرگتر 0، دیاوهاچ.آمار(broken).شکستها
سرچاپ first(دیاوهاچ.جستجوی آ(broken، "a.test"))
ناپایا helper := وکتور {} برگردان وکتور<دیاوهاچ.کارگزار>
helper.بیفزا(mock_server("bootstrap"))
دیاوهاچ.تعیین کارگزارهای راهانداز(broken، helper)
سرچاپ "bootstrap set"
پایانآمار حلکننده ResolverStats
ساختار آمار حلکنندهآمار آنها را برمیگرداند.| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| برخورد حافظه | hits | صحیح۶۴ = 0 | پرسشهایی که از حافظه پاسخ گرفتند. |
| ناکامی حافظه | misses | صحیح۶۴ = 0 | پرسشهایی که در حافظه نبودند. |
| پرسش بالادست | upstream | صحیح۶۴ = 0 | در مجموع از چند کارگزار پرسیده شد (کارگزار ناموفق و جانشینش دو بار شمرده میشوند). |
| شکستها | failures | صحیح۶۴ = 0 | پرسشهایی که هیچ کارگزاری نتوانست پاسخ دهد. |
نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Resolver.salam
حلکننده Resolver
ساختار حلکنندهحلکننده جدید ساخته میشود؛ استفاده از چند نخ امن است.| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| وضعیت | st | State* | وضعیت درونی: کارگزارها، حافظه، حدها و شمارندهها. |
نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Resolver.salam
پاسخ Response
ساختار پاسخپرسش: پیام خام DNS، پیام رمزگشاییشده، مدت زمانش و اینکه کدام کارگزار داد.| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| معتبر | ok | منطقی = نادرست | درست وقتی پیام DNS معتبری با همان شناسه برگشت. نامی که وجود ندارد هم ok است: rcode پیام را ببینید. |
| پاسخ خام | raw | فشرده سازی.بافر بایت | پاسخ به شکل بایتهای سیمی DNS. با آزاد کردن پاسخ آزادش کنید. |
| پیام | msg | دیاناس.پیام | dns.Message رمزگشاییشده: پرسشها، پاسخها و rcode آن. |
| زمان رفتوبرگشت | rtt_ms | صحیح۶۴ = 0 | زمان رفتوبرگشت به میلیثانیه. |
| کارگزار | server | رشته = "" | نام کارگزاری که پاسخ داد. |
| خطا | err | رشته = "" | دلیل خوانا وقتی معتبر نادرست است، مثل id mismatch یا خطای اتصال. |
// زبان: فارسی
واردسازی فشرده سازی
واردسازی حافظه
واردسازی شبکه.دیاناس
واردسازی شبکه.دیاوهاچ
واردسازی شبکه.یو دی پی
واردسازی همگام سازی
ناپایا udp_port := 0
ناپایا queries := 0
ناپایا ready := همگام سازی.گروه انتظار جدید()
تابع record(name: رشته، rtype: صحیح، ttl: صحیح، data: رشته): دیاناس.رکورد:
برگشت دیاناس.رکورد { نام دامنه = name، نوع رکورد = rtype، رده = 1، زمان ماندگاری = ttl، داده = data }
پایان
تابع answer_for(p: تهی*، n: صحیح): فشرده سازی.بافر بایت:
queries++
question := دیاناس.کدگشایی(p، n)
asked := question.پرسشها.پرسشها.بگیر(0)
ناپایا records := وکتور {} برگردان وکتور<دیاناس.رکورد>
ناپایا rcode := 0
اگر asked.نام دامنه برابر "a.test" و asked.نوع رکورد برابر دیاناس.نوع آ:
records.بیفزا(record("a.test"، دیاناس.نوع آ، 120، "10.0.0.1"))
records.بیفزا(record("a.test"، دیاناس.نوع آ، 300، "10.0.0.2"))
وگرنه asked.نام دامنه برابر "v6.test" و asked.نوع رکورد برابر دیاناس.نوع کواداِی:
records.بیفزا(record("v6.test"، دیاناس.نوع کواداِی، 300، "2001:db8::5"))
وگرنه asked.نام دامنه برابر "txt.test" و asked.نوع رکورد برابر دیاناس.نوع تیایکستی:
records.بیفزا(record("txt.test"، دیاناس.نوع تیایکستی، 60، "hello world"))
وگرنه asked.نام دامنه برابر "alias.test":
records.بیفزا(record("alias.test"، دیاناس.نوع سینیم، 60، "target.test"))
اگر asked.نوع رکورد برابر دیاناس.نوع آ:
records.بیفزا(record("target.test"، دیاناس.نوع آ، 60، "10.9.9.9"))
پایان
وگرنه:
rcode = 3
پایان
برگشت دیاوهاچ.کدگذاری پاسخ(question.شناسه، asked.نام دامنه، asked.نوع رکورد، rcode، records)
پایان
تابع udp_server():
s := یو دی پی.پیوند(0)
udp_port = یو دی پی.درگاه(s)
همگام سازی.اتمام(ready)
buf := حافظه.تخصیص(2048 برگردان طبیعی۶۴)
ناپایا from_host := ""
ناپایا from_port := 0
تا درست:
n := یو دی پی.دریافت بایت(s، buf، 2048، from_host، from_port)
اگر n بزرگتر 0:
answer := answer_for(buf، n)
یو دی پی.ارسال بایت(s، from_host، from_port، answer.داده، answer.طول)
پایان
پایان
پایان
تابع start_mock():
همگام سازی.افزودن(ready، 1 برگردان صحیح۶۴)
_t := نخساز(udp_server)
همگام سازی.انتظار(ready)
پایان
تابع mock_server(name: رشته): دیاوهاچ.کارگزار:
ناپایا server := دیاوهاچ.کارگزار ساده جدید(name، "127.0.0.1")
server.درگاه = udp_port
برگشت server
پایان
تابع ریشه:
start_mock()
server := mock_server("mock")
سرچاپ server.نوع برابر دیاوهاچ.نوع یو دی پی ساده، server.درگاه برابر udp_port، server.با تی ال اس، server.نشانیهای راهانداز.بگیر(0)
ناپایا r := دیاوهاچ.پرسش(server، "a.test"، دیاناس.نوع آ، 2000)
سرچاپ r.معتبر، r.کارگزار، r.پیام.کد نتیجه، r.پیام.پاسخها.رکوردها.طول()، r.پیام.پاسخها.رکوردها.بگیر(0).داده
سرچاپ r.پاسخ خام.طول بزرگتر 12، r.خطا.طول()
دیاوهاچ.آزاد کردن پاسخ(r)
ناپایا direct := دیاوهاچ.پرسش از نشانی(server، "127.0.0.1"، "v6.test"، دیاناس.نوع کواداِی، 2000)
سرچاپ direct.معتبر، direct.پیام.پاسخها.رکوردها.بگیر(0).داده
دیاوهاچ.آزاد کردن پاسخ(direct)
ناپایا missing := دیاوهاچ.پرسش(server، "nothing.test"، دیاناس.نوع آ، 2000)
سرچاپ "missing name:"، missing.معتبر، missing.پیام.کد نتیجه، missing.پیام.پاسخها.رکوردها.طول()
دیاوهاچ.آزاد کردن پاسخ(missing)
dead := دیاوهاچ.کارگزار جدید("dead"، دیاوهاچ.نوع دیاوهاچ پست، "http://127.0.0.1:1/dns-query")
failed := دیاوهاچ.پرسش(dead، "a.test"، دیاناس.نوع آ، 500)
سرچاپ "dead server:"، failed.معتبر، failed.خطا.طول() بزرگتر 0
پایانکارگزار محلی Stub
ساختار کارگزار محلیحلکننده به برنامههای دیگر پاسخ میدهد. DNS یک برنامه را به آن اشاره بدهید تا جستجوهایش از حلکنندهی رمزشده و حافظهی شما بگذرد. با راهاندازی کارگزار محلی شروع میشود.| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| معتبر | ok | منطقی = نادرست | درست وقتی درگاه بسته شد. |
| درگاه | port | صحیح = 0 | درگاه UDP که روی آن گوش میدهد؛ وقتی ۰ خواستهاید به کار میآید. |
| میزبان | host | رشته = "" | نشانیای که stub روی آن گوش میدهد. |
| تی سی پی فعال | tcp_ok | منطقی = نادرست | درست وقتی سمت TCP stub هم گوش میدهد. |
| وضعیت | st | StubState* | وضعیت درونی. |
// زبان: فارسی
واردسازی فشرده سازی
واردسازی حافظه
واردسازی شبکه.دیاناس
واردسازی شبکه.دیاوهاچ
واردسازی شبکه.یو دی پی
واردسازی همگام سازی
ناپایا udp_port := 0
ناپایا queries := 0
ناپایا ready := همگام سازی.گروه انتظار جدید()
تابع record(name: رشته، rtype: صحیح، ttl: صحیح، data: رشته): دیاناس.رکورد:
برگشت دیاناس.رکورد { نام دامنه = name، نوع رکورد = rtype، رده = 1، زمان ماندگاری = ttl، داده = data }
پایان
تابع answer_for(p: تهی*، n: صحیح): فشرده سازی.بافر بایت:
queries++
question := دیاناس.کدگشایی(p، n)
asked := question.پرسشها.پرسشها.بگیر(0)
ناپایا records := وکتور {} برگردان وکتور<دیاناس.رکورد>
ناپایا rcode := 0
اگر asked.نام دامنه برابر "a.test" و asked.نوع رکورد برابر دیاناس.نوع آ:
records.بیفزا(record("a.test"، دیاناس.نوع آ، 120، "10.0.0.1"))
records.بیفزا(record("a.test"، دیاناس.نوع آ، 300، "10.0.0.2"))
وگرنه asked.نام دامنه برابر "v6.test" و asked.نوع رکورد برابر دیاناس.نوع کواداِی:
records.بیفزا(record("v6.test"، دیاناس.نوع کواداِی، 300، "2001:db8::5"))
وگرنه asked.نام دامنه برابر "txt.test" و asked.نوع رکورد برابر دیاناس.نوع تیایکستی:
records.بیفزا(record("txt.test"، دیاناس.نوع تیایکستی، 60، "hello world"))
وگرنه asked.نام دامنه برابر "alias.test":
records.بیفزا(record("alias.test"، دیاناس.نوع سینیم، 60، "target.test"))
اگر asked.نوع رکورد برابر دیاناس.نوع آ:
records.بیفزا(record("target.test"، دیاناس.نوع آ، 60، "10.9.9.9"))
پایان
وگرنه:
rcode = 3
پایان
برگشت دیاوهاچ.کدگذاری پاسخ(question.شناسه، asked.نام دامنه، asked.نوع رکورد، rcode، records)
پایان
تابع udp_server():
s := یو دی پی.پیوند(0)
udp_port = یو دی پی.درگاه(s)
همگام سازی.اتمام(ready)
buf := حافظه.تخصیص(2048 برگردان طبیعی۶۴)
ناپایا from_host := ""
ناپایا from_port := 0
تا درست:
n := یو دی پی.دریافت بایت(s، buf، 2048، from_host، from_port)
اگر n بزرگتر 0:
answer := answer_for(buf، n)
یو دی پی.ارسال بایت(s، from_host، from_port، answer.داده، answer.طول)
پایان
پایان
پایان
تابع start_mock():
همگام سازی.افزودن(ready، 1 برگردان صحیح۶۴)
_t := نخساز(udp_server)
همگام سازی.انتظار(ready)
پایان
تابع mock_server(name: رشته): دیاوهاچ.کارگزار:
ناپایا server := دیاوهاچ.کارگزار ساده جدید(name، "127.0.0.1")
server.درگاه = udp_port
برگشت server
پایان
تابع ریشه:
start_mock()
ناپایا servers := وکتور {} برگردان وکتور<دیاوهاچ.کارگزار>
servers.بیفزا(mock_server("mock"))
resolver := دیاوهاچ.حلکننده جدید(servers)
stub := دیاوهاچ.راهاندازی کارگزار محلی(resolver، "127.0.0.1"، 0)
سرچاپ "stub up:"، stub.معتبر، stub.درگاه بزرگتر 0
sock := یو دی پی.باز کردن()
یو دی پی.تنظیم زمان انتظار(sock، 3000)
buf := حافظه.تخصیص(2048 برگردان طبیعی۶۴)
ناپایا from_host := ""
ناپایا from_port := 0
هر name در ["a.test"، "a.test"، "nothing.test"]:
ناپایا asked := فشرده سازی.بافر بایت جدید()
فشرده سازی.افزودن بایت(asked، 0x12)
فشرده سازی.افزودن بایت(asked، 0x34)
فشرده سازی.افزودن بایت(asked، 0x01)
فشرده سازی.افزودن بایت(asked، 0x00)
فشرده سازی.افزودن بایت(asked، 0)
فشرده سازی.افزودن بایت(asked، 1)
تکرار 6:
فشرده سازی.افزودن بایت(asked، 0)
پایان
هر label در name.بشکاف("."):
فشرده سازی.افزودن بایت(asked، label.طول())
فشرده سازی.افزودن بایتها(asked، label برگردان تهی*، label.طول())
پایان
فشرده سازی.افزودن بایت(asked، 0)
فشرده سازی.افزودن بایت(asked، 0)
فشرده سازی.افزودن بایت(asked، 1)
فشرده سازی.افزودن بایت(asked، 0)
فشرده سازی.افزودن بایت(asked، 1)
یو دی پی.ارسال بایت(sock، "127.0.0.1"، stub.درگاه، asked.داده، asked.طول)
n := یو دی پی.دریافت بایت(sock، buf، 2048، from_host، from_port)
reply := دیاناس.کدگشایی(buf، n)
سرچاپ name، reply.شناسه برابر 4660، reply.کد نتیجه، reply.پاسخها.رکوردها.طول()، queries
پایان
سرچاپ "served:"، دیاوهاچ.شمار پاسخهای کارگزار محلی(stub)
دیاوهاچ.توقف کارگزار محلی(stub)
یو دی پی.بستن(sock)
پایانکارگزار Server
ساختار کارگزارکارگزار جدید، کارگزار دیاوهتی جدید و کارگزار ساده جدید آنها را میسازند.| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| نام | name | رشته = "" | نام کوتاه برای گزارشها و کارگزار. |
| نوع | kind | صحیح = 0 | نوع دیاوهاچ پست، نوع دیاوهاچ گت، نوع دیاوهتی یا نوع یو دی پی ساده. |
| نشانی | url | رشته = "" | نشانی یک نقطهی DoH، مثل https://dns.google/dns-query. |
| میزبان | host | رشته = "" | نام میزبان (برای نام TLS و سرآیند Host) یا IP. |
| درگاه | port | صحیح = 0 | درگاه: ۴۴۳ برای DoH، ۸۵۳ برای DoT، ۵۳ برای DNS ساده. |
| مسیر | path | رشته = "" | مسیر درخواست یک نقطهی DoH. |
| با تی ال اس | use_tls | منطقی = درست | درست وقتی کارگزار TLS به کار میبرد. برای DoH روی https و برای DoT درست است. |
| نشانیهای راهانداز | addrs | وکتور<رشته> | نشانیهای IP برای اتصال، تا نام خود کارگزار لازم نباشد از پیش جستجو شود. همین است که وقتی خود DNS مسدود است یک حلکنندهی رمزشده را کار میاندازد. |
| ناامن | insecure | منطقی = نادرست | درست یعنی بررسی گواهی نادیده گرفته شود. فقط برای آزمون. |
// زبان: فارسی
واردسازی شبکه.دیاوهاچ
تابع ریشه:
cloudflare := دیاوهاچ.کلودفلر()
سرچاپ cloudflare.نام، cloudflare.نوع برابر دیاوهاچ.نوع دیاوهاچ پست، cloudflare.نشانی، cloudflare.میزبان، cloudflare.درگاه، cloudflare.مسیر، cloudflare.با تی ال اس
سرچاپ cloudflare.نشانیهای راهانداز.بگیر(0)، cloudflare.نشانیهای راهانداز.بگیر(1)
سرچاپ دیاوهاچ.گوگل().میزبان، دیاوهاچ.گوگل().نشانیهای راهانداز.بگیر(0)، دیاوهاچ.کواد نه().میزبان، دیاوهاچ.کواد نه().نشانیهای راهانداز.بگیر(0)
dot := دیاوهاچ.کلودفلر دیاوهتی()
سرچاپ dot.نوع برابر دیاوهاچ.نوع دیاوهتی، dot.میزبان، dot.درگاه، dot.نشانیهای راهانداز.بگیر(0)
سرچاپ دیاوهاچ.گوگل دیاوهتی().نشانیهای راهانداز.بگیر(0)، دیاوهاچ.کواد نه دیاوهتی().میزبان
custom := دیاوهاچ.کارگزار جدید("mine"، دیاوهاچ.نوع دیاوهاچ گت، "https://dns.example.net/resolve")
سرچاپ custom.نوع برابر دیاوهاچ.نوع دیاوهاچ گت، custom.میزبان، custom.مسیر، custom.نشانیهای راهانداز.طول()
pinned := دیاوهاچ.با نشانی راهانداز(custom، "203.0.113.53")
سرچاپ pinned.نشانیهای راهانداز.طول()، custom.نشانیهای راهانداز.طول()، pinned.نشانیهای راهانداز.بگیر(0)
mine := دیاوهاچ.کارگزار دیاوهتی جدید("dot"، "dns.example.net"، "203.0.113.54")
plain := دیاوهاچ.کارگزار ساده جدید("plain"، "203.0.113.55")
سرچاپ mine.درگاه، mine.با تی ال اس، plain.درگاه، plain.نوع برابر دیاوهاچ.نوع یو دی پی ساده، plain.با تی ال اس
سرچاپ دیاوهاچ.نوع دیاوهاچ پست، دیاوهاچ.نوع دیاوهاچ گت، دیاوهاچ.نوع دیاوهتی، دیاوهاچ.نوع یو دی پی ساده
ناپایا servers := دیاوهاچ.کارگزارهای پیشفرض()
سرچاپ servers.طول()، servers.بگیر(0).نام، servers.بگیر(2).نام
iran := دیاوهاچ.کارگزارهای ساده ایران()
سرچاپ iran.طول()، iran.بگیر(0).نام، iran.بگیر(0).درگاه، iran.بگیر(0).نشانیهای راهانداز.بگیر(0)
سرچاپ دیاوهاچ.شکن().طول()، دیاوهاچ.الکترو().بگیر(0).نام، دیاوهاچ.رادار().بگیر(1).نام، دیاوهاچ.بگزر().بگیر(0).نشانیهای راهانداز.بگیر(0)
دیاوهاچ.آزاد کردن کارگزارها(servers)
پایاننشانی وب Url
ساختار نشانی وببا تی ال اس)، میزبان، درگاه و مسیر.| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| معتبر | ok | منطقی = نادرست | درست وقتی نشانی معتبر بود. |
| با تی ال اس | use_tls | منطقی = درست | برای https درست، برای http نادرست. |
| میزبان | host | رشته = "" | میزبان. |
| درگاه | port | صحیح = 0 | درگاه، یا ۴۴۳ یا ۸۰ اگر نشانی نداشته باشد. |
| مسیر | path | رشته = "" | مسیر با پرسمان، دستکم /. |
// زبان: فارسی
واردسازی فشرده سازی
واردسازی شبکه.دیاناس
واردسازی شبکه.دیاوهاچ
تابع ریشه:
سرچاپ دیاوهاچ.نشانی آیپی است("1.2.3.4")، دیاوهاچ.نشانی آیپی است("2001:db8::1")، دیاوهاچ.نشانی آیپی است("dns.google")، دیاوهاچ.نشانی آیپی است("1.2.3")
url := دیاوهاچ.تجزیه نشانی وب("https://dns.example.net/dns-query")
سرچاپ url.معتبر، url.با تی ال اس، url.میزبان، url.درگاه، url.مسیر
plain := دیاوهاچ.تجزیه نشانی وب("http://127.0.0.1:8053")
سرچاپ plain.معتبر، plain.با تی ال اس، plain.درگاه، plain.مسیر
سرچاپ دیاوهاچ.تجزیه نشانی وب("ftp://x").معتبر
ناپایا v4 := فشرده سازی.بافر بایت جدید()
سرچاپ دیاوهاچ.تجزیه آیپی۴("10.0.0.7"، v4)، v4.طول
ناپایا v6 := فشرده سازی.بافر بایت جدید()
سرچاپ دیاوهاچ.تجزیه آیپی۶("2001:db8::7"، v6)، v6.طول
سرچاپ دیاوهاچ.تجزیه آیپی۴("10.0.0"، فشرده سازی.بافر بایت جدید())
ناپایا records := وکتور {} برگردان وکتور<دیاناس.رکورد>
records.بیفزا(دیاناس.رکورد { نام دامنه = "example.test"، نوع رکورد = دیاناس.نوع آ، رده = 1، زمان ماندگاری = 300، داده = "192.0.2.7" })
wire := دیاوهاچ.کدگذاری پاسخ(4242، "example.test"، دیاناس.نوع آ، 0، records)
message := دیاناس.کدگشایی(wire.داده، wire.طول)
سرچاپ message.شناسه، message.نشانه پاسخ، message.کد نتیجه، message.پرسشها.پرسشها.طول()، message.پاسخها.رکوردها.طول()
answer := message.پاسخها.رکوردها.بگیر(0)
سرچاپ answer.نام دامنه، answer.زمان ماندگاری، answer.داده
nx := دیاوهاچ.کدگذاری پاسخ(7، "nothing.test"، دیاناس.نوع آ، 3، وکتور {} برگردان وکتور<دیاناس.رکورد>)
سرچاپ دیاناس.کدگشایی(nx.داده، nx.طول).کد نتیجه
پایانپایاها و متغیرها
نوعهای کارگزار Kind…
نوع.| نام | انگلیسی | مقدار |
|---|---|---|
| نوع دیاوهاچ پست | KindDoH | 0 |
| نوع دیاوهاچ گت | KindDoHGet | 1 |
| نوع دیاوهتی | KindDoT | 2 |
| نوع یو دی پی ساده | KindUDP | 3 |
// زبان: فارسی
واردسازی فشرده سازی
واردسازی حافظه
واردسازی شبکه.دیاناس
واردسازی شبکه.دیاوهاچ
واردسازی شبکه.تی سی پی
واردسازی رشته
واردسازی همگام سازی
ناپایا http_port := 0
ناپایا methods := ""
ناپایا ready := همگام سازی.گروه انتظار جدید()
تابع find_text(b: فشرده سازی.بافر بایت، pattern: رشته): صحیح:
n := pattern.طول()
ناپایا i := 0
تا i + n کوچکتربرابر b.طول:
ناپایا same := درست
تکرار n در j:
اگر فشرده سازی.دریافت بایت(b، i + j) نابرابر (pattern برگردان طبیعی۸*)[j] برگردان صحیح:
same = نادرست
بشکن
پایان
پایان
اگر same:
برگشت i
پایان
i++
پایان
برگشت 0 - 1
پایان
تابع text_at(b: فشرده سازی.بافر بایت، off: صحیح، n: صحیح): رشته:
buf := حافظه.تخصیص((n + 1) برگردان طبیعی۶۴)
حافظه.کپی(buf، ((b.داده برگردان صحیح۶۴) + (off برگردان صحیح۶۴)) برگردان تهی*، n برگردان طبیعی۶۴)
(buf برگردان طبیعی۸*)[n] = 0 برگردان طبیعی۸
برگشت buf برگردان رشته
پایان
تابع from_base64url(s: رشته): فشرده سازی.بافر بایت:
alphabet := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
ناپایا out := فشرده سازی.بافر بایت جدید()
ناپایا acc := 0
ناپایا bits := 0
تکرار s.طول() در i:
v := alphabet.بیاب(s.زیررشته(i، 1))
اگر v کوچکتر 0:
بشکن
پایان
acc = (acc << 6) | v
bits += 6
اگر bits بزرگتربرابر 8:
bits -= 8
فشرده سازی.افزودن بایت(out، (acc >> bits) & 255)
acc = acc & ((1 << bits) - 1)
پایان
پایان
برگشت out
پایان
تابع serve_one(c: تی سی پی.اتصال شبکه):
ناپایا raw := فشرده سازی.بافر بایت جدید()
buf := حافظه.تخصیص(4096 برگردان طبیعی۶۴)
ناپایا head_end := 0 - 1
ناپایا need := 0
تا درست:
n := تی سی پی.خواندن بایت(c، buf، 4096)
اگر n کوچکتربرابر 0:
بشکن
پایان
فشرده سازی.افزودن بایتها(raw، buf، n)
head_end = find_text(raw، "\r\n\r\n")
اگر head_end بزرگتربرابر 0:
head := رشته.کوچک(text_at(raw، 0، head_end))
at := head.بیاب("content-length:")
اگر at بزرگتربرابر 0:
rest := head.زیررشته(at + 15، head.طول() - at - 15)
ناپایا line_end := rest.بیاب("\r\n")
اگر line_end کوچکتر 0:
line_end = rest.طول()
پایان
need = رشته.پیرایش(rest.زیررشته(0، line_end)).به صحیح()
پایان
اگر raw.طول بزرگتربرابر head_end + 4 + need:
بشکن
پایان
پایان
پایان
ناپایا wire := فشرده سازی.بافر بایت جدید()
اگر text_at(raw، 0، 4) برابر "POST":
methods += "POST "
فشرده سازی.افزودن بایتها(wire، ((raw.داده برگردان صحیح۶۴) + (head_end برگردان صحیح۶۴) + 4) برگردان تهی*، need)
وگرنه:
methods += "GET "
line := text_at(raw، 0، find_text(raw، "\r\n"))
rest := line.زیررشته(line.بیاب("dns=") + 4، line.طول())
wire = from_base64url(rest.زیررشته(0، rest.بیاب(" ")))
پایان
question := دیاناس.کدگشایی(wire.داده، wire.طول)
asked := question.پرسشها.پرسشها.بگیر(0)
ناپایا records := وکتور {} برگردان وکتور<دیاناس.رکورد>
records.بیفزا(دیاناس.رکورد { نام دامنه = asked.نام دامنه، نوع رکورد = دیاناس.نوع آ، رده = 1، زمان ماندگاری = 300، داده = "192.0.2.80" })
answer := دیاوهاچ.کدگذاری پاسخ(question.شناسه، asked.نام دامنه، asked.نوع رکورد، 0، records)
head := "HTTP/1.1 200 OK\r\nContent-Type: application/dns-message\r\nConnection: close\r\nContent-Length: " + answer.طول + "\r\n\r\n"
تی سی پی.نوشتن(c، head)
تی سی پی.نوشتن بایت(c، answer.داده، answer.طول)
تی سی پی.بستن(c)
پایان
تابع http_server():
srv := تی سی پی.پیوند(0)
http_port = تی سی پی.درگاه(srv)
همگام سازی.اتمام(ready)
تا درست:
serve_one(تی سی پی.پذیرش(srv))
پایان
پایان
تابع ریشه:
همگام سازی.افزودن(ready، 1 برگردان صحیح۶۴)
_t := نخساز(http_server)
همگام سازی.انتظار(ready)
base := "http://127.0.0.1:" + http_port + "/dns-query"
post := دیاوهاچ.کارگزار جدید("post"، دیاوهاچ.نوع دیاوهاچ پست، base)
سرچاپ post.با تی ال اس، post.درگاه برابر http_port، post.مسیر
r := دیاوهاچ.پرسش(post، "web.test"، دیاناس.نوع آ، 2000)
سرچاپ r.معتبر، r.پیام.پاسخها.رکوردها.بگیر(0).داده
get := دیاوهاچ.کارگزار جدید("get"، دیاوهاچ.نوع دیاوهاچ گت، base)
g := دیاوهاچ.پرسش(get، "web.test"، دیاناس.نوع آ، 2000)
سرچاپ g.معتبر، g.پیام.پاسخها.رکوردها.بگیر(0).داده
سرچاپ methods
پایانتابعها
حلکننده جدید NewResolver
تابع حلکننده جدید(servers: وکتور<کارگزار>): حلکنندهنمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Resolver.salam
تعیین کارگزارهای راهانداز SetBootstrap
تابع تعیین کارگزارهای راهانداز(r: حلکننده، servers: وکتور<کارگزار>)نشانیهای راهانداز ندارد. باید با IP در دسترس باشند، مثلا کارگزارهای ساده.نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Resolver.salam
تعیین حدود ماندگاری SetTTLLimits
تابع تعیین حدود ماندگاری(r: حلکننده، min_ttl: صحیح، max_ttl: صحیح، neg_ttl: صحیح)نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Resolver.salam
تعیین مهلت SetTimeout
تابع تعیین مهلت(r: حلکننده، timeout_ms: صحیح)نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Resolver.salam
آمار Stats
تابع آمار(r: حلکننده): آمار حلکنندهنمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Resolver.salam
اندازه حافظه CacheSize
تابع اندازه حافظه(r: حلکننده): صحیحنمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Resolver.salam
پاک کردن حافظه ClearCache
تابع پاک کردن حافظه(r: حلکننده)نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Resolver.salam
حل در زمان ResolveAt
تابع حل در زمان(r: حلکننده، name: رشته، qtype: صحیح، now_ms: صحیح۶۴): پاسخ نهاییحل ولی با ساعت دادهشده به میلیثانیه، تا حافظه را بتوان بیانتظار آزمود.نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Resolver.salam
حل Resolve
تابع حل(r: حلکننده، name: رشته، qtype: صحیح): پاسخ نهایینمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Resolver.salam
آزاد کردن پاسخ نهایی FreeAnswer
تابع آزاد کردن پاسخ نهایی(a &: پاسخ نهایی)نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Resolver.salam
جستجوی آ LookupA
تابع جستجوی آ(r: حلکننده، name: رشته): وکتور<رشته>نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Resolver.salam
جستجوی کواداِی LookupAAAA
تابع جستجوی کواداِی(r: حلکننده، name: رشته): وکتور<رشته>نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Resolver.salam
جستجوی تیایکستی LookupTXT
تابع جستجوی تیایکستی(r: حلکننده، name: رشته): وکتور<رشته>نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Resolver.salam
جستجوی سینیم LookupCNAME
تابع جستجوی سینیم(r: حلکننده، name: رشته): رشتهنمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Resolver.salam
جستجوی میزبان LookupHost
تابع جستجوی میزبان(r: حلکننده، name: رشته): وکتور<رشته>نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Resolver.salam
پرسش از نشانی QueryAddr
تابع پرسش از نشانی(srv: کارگزار، addr: رشته، name: رشته، qtype: صحیح، timeout_ms: صحیح): پاسخنمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Query.salam
پرسش Query
تابع پرسش(srv: کارگزار، name: رشته، qtype: صحیح، timeout_ms: صحیح): پاسخنشانیهای راهانداز آن را به نوبت امتحان میکند، یا اگر ندارد نام میزبانش را حل میکند. پرسش از نشانی یک نشانی را انجام میدهد.نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Query.salam
آزاد کردن پاسخ FreeResponse
تابع آزاد کردن پاسخ(r &: پاسخ)نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Query.salam
اتصالهای بازاستفادهشده ReusedConnections
تابع اتصالهای بازاستفادهشده(): صحیح۶۴نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Http.salam
بستن اتصالهای بیکار CloseIdleConnections
تابع بستن اتصالهای بیکار()نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Http.salam
راهاندازی کارگزار محلی StartStub
تابع راهاندازی کارگزار محلی(r: حلکننده، host: رشته، port: صحیح): کارگزار محلی127.0.0.1. معتبر و برای سمت TCP tcp_ok را بررسی کنید.نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Stub.salam
شمار پاسخهای کارگزار محلی StubServed
تابع شمار پاسخهای کارگزار محلی(s: کارگزار محلی): صحیح۶۴نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Stub.salam
توقف کارگزار محلی StopStub
تابع توقف کارگزار محلی(s: کارگزار محلی)نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Stub.salam
تجزیه آیپی۴ ParseIPv4
تابع تجزیه آیپی۴(text: رشته، out &: فشرده سازی.بافر بایت): منطقینمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Parse.salam
تجزیه آیپی۶ ParseIPv6
تابع تجزیه آیپی۶(text: رشته، out &: فشرده سازی.بافر بایت): منطقینمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Parse.salam
نشانی آیپی است IsIP
تابع نشانی آیپی است(host: رشته): منطقینمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Parse.salam
تجزیه نشانی وب ParseURL
تابع تجزیه نشانی وب(raw: رشته): نشانی وبhttp:// یا https:// را تجزیه میکند.نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Parse.salam
کارگزار جدید NewServer
تابع کارگزار جدید(name: رشته، kind: صحیح، url: رشته): کارگزارنشانیهای راهانداز را اضافه کنید یا با نشانی راهانداز را به کار ببرید تا نامش نیازی به حل شدن نداشته باشد.نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Servers.salam
کارگزار دیاوهتی جدید NewDoT
تابع کارگزار دیاوهتی جدید(name: رشته، host: رشته، addr: رشته): کارگزارنمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Servers.salam
کارگزار ساده جدید NewPlain
تابع کارگزار ساده جدید(name: رشته، addr: رشته): کارگزاردرگاه را تغییر دهید.نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Servers.salam
با نشانی راهانداز WithBootstrap
تابع با نشانی راهانداز(s: کارگزار، addr: رشته): کارگزارنمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Servers.salam
با نشانی آیپی۶ WithIPv6
تابع با نشانی آیپی۶(s: کارگزار): کارگزار// زبان: فارسی
واردسازی شبکه.دیاوهاچ
تابع ریشه:
v6 := دیاوهاچ.کلودفلر آیپی۶()
سرچاپ v6.نشانیهای راهانداز.بگیر(0)، دیاوهاچ.گوگل آیپی۶().نشانیهای راهانداز.بگیر(0)، دیاوهاچ.کواد نه آیپی۶().نشانیهای راهانداز.بگیر(0)
both := دیاوهاچ.با نشانی آیپی۶(دیاوهاچ.کلودفلر())
سرچاپ both.نشانیهای راهانداز.طول()
پایانکلودفلر آیپی۶ Cloudflare6
تابع کلودفلر آیپی۶(): کارگزارنمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-IPv6.salam
گوگل آیپی۶ Google6
تابع گوگل آیپی۶(): کارگزارنمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-IPv6.salam
کواد نه آیپی۶ Quad96
تابع کواد نه آیپی۶(): کارگزارنمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-IPv6.salam
کلودفلر Cloudflare
تابع کلودفلر(): کارگزارcloudflare-dns.com)، با نشانیهای 1.1.1.1 و 1.0.0.1.نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Servers.salam
گوگل Google
تابع گوگل(): کارگزارdns.google)، با 8.8.8.8 و 8.8.4.4.نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Servers.salam
کواد نه Quad9
تابع کواد نه(): کارگزارdns.quad9.net)، با 9.9.9.9 و 149.112.112.112.نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Servers.salam
کلودفلر دیاوهتی CloudflareDoT
تابع کلودفلر دیاوهتی(): کارگزارنمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Servers.salam
گوگل دیاوهتی GoogleDoT
تابع گوگل دیاوهتی(): کارگزار// زبان: فارسی
واردسازی شبکه.دیاوهاچ
تابع ریشه:
ناپایا servers := وکتور {} برگردان وکتور<دیاوهاچ.کارگزار>
servers.بیفزا(دیاوهاچ.کلودفلر())
servers.بیفزا(دیاوهاچ.گوگل دیاوهتی())
servers.بیفزا(دیاوهاچ.کواد نه())
resolver := دیاوهاچ.حلکننده جدید(servers)
دیاوهاچ.تعیین مهلت(resolver، 3000)
answer := دیاوهاچ.حل(resolver، "example.com"، 1)
سرچاپ answer.معتبر، answer.از حافظه، answer.کارگزار، answer.زمان ماندگاری
هر ip در دیاوهاچ.جستجوی میزبان(resolver، "example.com"):
سرچاپ ip
پایان
stub := دیاوهاچ.راهاندازی کارگزار محلی(resolver، "127.0.0.1"، 5353)
سرچاپ "local resolver on port"، stub.درگاه
دیاوهاچ.توقف کارگزار محلی(stub)
پایانکواد نه دیاوهتی Quad9DoT
تابع کواد نه دیاوهتی(): کارگزارنمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Servers.salam
کارگزارهای پیشفرض DefaultServers
تابع کارگزارهای پیشفرض(): وکتور<کارگزار>حلکننده.نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Servers.salam
شکن Shecan
تابع شکن(): وکتور<کارگزار>نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Servers.salam
چهارصدوسه Server403
تابع چهارصدوسه(): وکتور<کارگزار>الکترو Electro
تابع الکترو(): وکتور<کارگزار>نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Servers.salam
رادار Radar
تابع رادار(): وکتور<کارگزار>نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Servers.salam
بگزر Begzar
تابع بگزر(): وکتور<کارگزار>نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Servers.salam
کارگزارهای ساده ایران IranPlainServers
تابع کارگزارهای ساده ایران(): وکتور<کارگزار>کارگزارهای پیشفرض را ترجیح دهید.نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Servers.salam
کدگذاری پاسخ EncodeResponse
تابع کدگذاری پاسخ(id: صحیح، name: رشته، qtype: صحیح، rcode: صحیح، records: وکتور<دیاناس.رکورد>): فشرده سازی.بافر بایتنمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Parse.salam
آزاد کردن کارگزارها FreeServers
تابع آزاد کردن کارگزارها(v &: وکتور<کارگزار>)نمونهی این مورد همراه با موارد بالاتر آمده است: net-doh-Servers.salam