From de691c61abb850fee2e4d33113000aad77be6494 Mon Sep 17 00:00:00 2001 From: Dushnilin Date: Wed, 2 Sep 2026 17:29:51 +0300 Subject: [PATCH] feat(dns): prioritize encrypted DoH as primary DNS with verified UDP bootstrap resolution --- tachyon/files/usr/lib/dns/benchmark.uc | 84 ++++++++++++++------------ tests/dns_benchmark.sh | 12 ++++ 2 files changed, 58 insertions(+), 38 deletions(-) diff --git a/tachyon/files/usr/lib/dns/benchmark.uc b/tachyon/files/usr/lib/dns/benchmark.uc index 333f3fe5..98879a4b 100644 --- a/tachyon/files/usr/lib/dns/benchmark.uc +++ b/tachyon/files/usr/lib/dns/benchmark.uc @@ -27,6 +27,7 @@ const CANDIDATE_SERVERS = [ // --- Yandex DNS --- { id: "yandex_udp", provider: "Yandex", type: "udp", address: "77.88.8.8", ip: "77.88.8.8", tag: "Primary" }, { id: "yandex_udp2", provider: "Yandex", type: "udp", address: "77.88.8.1", ip: "77.88.8.1", tag: "Secondary" }, + { id: "yandex_doh", provider: "Yandex", type: "doh", address: "https://common.dot.yandex.net/dns-query", ip: "77.88.8.8", tag: "DoH Basic" }, // --- Cloudflare DNS --- { id: "cloudflare_udp", provider: "Cloudflare", type: "udp", address: "1.1.1.1", ip: "1.1.1.1", tag: "Primary" }, @@ -40,7 +41,7 @@ const CANDIDATE_SERVERS = [ // --- AdGuard DNS --- { id: "adguard_udp", provider: "AdGuard", type: "udp", address: "94.140.14.14", ip: "94.140.14.14", tag: "Default" }, - { id: "adguard_doh", provider: "AdGuard", type: "doh", address: "https://dns.adguard-dns.com/dns-query", ip: "94.140.14.14", tag: "DoH Encrypted" }, + { id: "adguard_doh", provider: "AdGuard", type: "doh", address: "https://dns.adguard-dns.com/dns-query", ip: "94.140.14.14", tag: "DoH AdBlock" }, // --- Comss.one DNS --- { id: "comss_udp", provider: "Comss.one", type: "udp", address: "92.223.109.31", ip: "92.223.109.31", tag: "Anti-Censorship" }, @@ -52,9 +53,15 @@ const CANDIDATE_SERVERS = [ // --- Quad9 --- { id: "quad9_udp", provider: "Quad9", type: "udp", address: "9.9.9.9", ip: "9.9.9.9", tag: "Primary" }, + { id: "quad9_doh", provider: "Quad9", type: "doh", address: "https://dns.quad9.net/dns-query", ip: "9.9.9.9", tag: "DoH Secure" }, // --- Mullvad DNS --- - { id: "mullvad_udp", provider: "Mullvad", type: "udp", address: "194.242.2.2", ip: "194.242.2.2", tag: "Privacy" } + { id: "mullvad_udp", provider: "Mullvad", type: "udp", address: "194.242.2.2", ip: "194.242.2.2", tag: "Privacy" }, + { id: "mullvad_doh", provider: "Mullvad", type: "doh", address: "https://dns.mullvad.net/dns-query", ip: "194.242.2.2", tag: "DoH Privacy" }, + + // --- OpenDNS --- + { id: "opendns_udp", provider: "OpenDNS", type: "udp", address: "208.67.222.222", ip: "208.67.222.222", tag: "Standard" }, + { id: "opendns_doh", provider: "OpenDNS", type: "doh", address: "https://doh.opendns.com/dns-query", ip: "208.67.222.222", tag: "DoH Encrypted" } ]; const TEST_DOMAINS = [ @@ -324,56 +331,57 @@ function compute_recommendation(results) { }; } - // Find fastest UDP and fastest DoH - let fastest_udp = null; - let second_udp = null; - let fastest_doh = null; + let working_udp = []; + let working_doh = []; for (let r in working) { - if (r.type == "udp") { - if (fastest_udp == null) - fastest_udp = r; - else if (second_udp == null && r.provider != fastest_udp.provider) - second_udp = r; - } else if (r.type == "doh") { - if (fastest_doh == null) - fastest_doh = r; - } + if (r.type == "udp") + push(working_udp, r); + else if (r.type == "doh") + push(working_doh, r); } - if (fastest_udp == null && length(working) > 0) - fastest_udp = working[0]; - if (second_udp == null) { - for (let r in working) { - if (r.type == "udp" && r.id != fastest_udp.id) { - second_udp = r; + working_udp = sort(working_udp, function(a, b) { return a.score - b.score; }); + working_doh = sort(working_doh, function(a, b) { return a.score - b.score; }); + + let fastest_udp = length(working_udp) > 0 ? working_udp[0] : working[0]; + let second_udp = null; + if (length(working_udp) > 1) { + for (let u in working_udp) { + if (u.provider != fastest_udp.provider) { + second_udp = u; break; } } + if (second_udp == null) + second_udp = working_udp[1]; } if (second_udp == null) - second_udp = { address: "1.1.1.1", ip: "1.1.1.1", provider: "Cloudflare" }; - - // Choose Primary DNS: - // Prefer DoH if latency is good (< 85ms and <= 1.6x of fastest UDP) for security & anti-hijacking - let selected_type = "udp"; - let selected_dns_server = [ fastest_udp.address ]; - let reason = "Selected fastest UDP server (" + fastest_udp.provider + " " + fastest_udp.latency + "ms)"; - - if (fastest_doh != null && fastest_doh.latency <= 85) { - let udp_lat = fastest_udp ? fastest_udp.latency : 100; - if (fastest_doh.latency <= (udp_lat * 1.6) + 15) { - selected_type = "doh"; - selected_dns_server = [ fastest_doh.address ]; - reason = "Selected fast encrypted DoH (" + fastest_doh.provider + " " + fastest_doh.latency + "ms) for maximum privacy and anti-censorship"; - } - } + second_udp = { address: "1.1.1.1", ip: "1.1.1.1", provider: "Cloudflare", latency: 50 }; let bootstrap_ip = fastest_udp.ip || fastest_udp.address || "77.88.8.8"; let fallback_ip = second_udp.ip || second_udp.address || "1.1.1.1"; + let selected_type = "udp"; + let selected_dns_server = [ fastest_udp.address ]; + let reason = "Selected fastest UDP server (" + fastest_udp.provider + " " + fastest_udp.latency + "ms) as fallback because encrypted DoH is unavailable"; + + // ALWAYS PRIORITIZE ENCRYPTED DoH AS PRIMARY DNS + // Encrypted DNS prevents ISP interception, DNS hijacking, poisoning, and MITM. + // Bootstrap DNS resolves the DoH hostname, while DoH handles all encrypted user traffic. + if (length(working_doh) > 0) { + let best_doh = working_doh[0]; + if (best_doh.lossPct <= 25 && best_doh.latency < 350) { + selected_type = "doh"; + selected_dns_server = [ best_doh.address ]; + reason = "Selected encrypted DoH (" + best_doh.provider + " " + best_doh.latency + "ms) for maximum privacy and anti-censorship, with " + fastest_udp.provider + " (" + bootstrap_ip + ") bootstrap DNS"; + } + } + let upstream_mode = "sequential"; - if (fastest_udp.latency < 50 && second_udp.latency < 60) + if (length(working_doh) > 1 && working_doh[0].latency < 70 && working_doh[1].latency < 90) + upstream_mode = "parallel"; + else if (fastest_udp.latency < 40 && second_udp.latency < 50) upstream_mode = "parallel"; return { diff --git a/tests/dns_benchmark.sh b/tests/dns_benchmark.sh index 9907cf09..928e51ca 100644 --- a/tests/dns_benchmark.sh +++ b/tests/dns_benchmark.sh @@ -106,6 +106,18 @@ if (rec_c.dns_type != "udp" || rec_c.dns_server[0] != "77.88.8.8" || rec_c.dns_f exit(5); } +// Scenario D: DoH latency higher than UDP, but working -> DoH must STILL be chosen as primary for encryption +let results_d = [ + { id: "yandex_udp", provider: "Yandex", type: "udp", address: "77.88.8.8", ip: "77.88.8.8", latency: 15, lossPct: 0, status: "excellent", score: 15 }, + { id: "cf_udp", provider: "Cloudflare", type: "udp", address: "1.1.1.1", ip: "1.1.1.1", latency: 20, lossPct: 0, status: "excellent", score: 20 }, + { id: "cf_doh", provider: "Cloudflare", type: "doh", address: "https://cloudflare-dns.com/dns-query", ip: "1.1.1.1", latency: 95, lossPct: 0, status: "good", score: 95 } +]; +let rec_d = benchmark.compute_recommendation(results_d); +if (rec_d.dns_type != "doh" || rec_d.dns_server[0] != "https://cloudflare-dns.com/dns-query" || rec_d.bootstrap_dns_server[0] != "77.88.8.8") { + print("ERR: Scenario D failed to prioritize encrypted DoH over UDP\n"); + exit(6); +} + print("OK\n"); exit(0); UCODE