package checker // Region is a coarse bucket for the report, not a geolocation claim (Anycast → "global"). type Resolver struct { // ID is a stable identifier, exposed in JSON/metrics. ID string // Name is the human-readable provider + flavor (shown in the report). Name string // IP is the plain-text UDP/TCP address (without port). IP string // Region tags the resolver geographically. One of: global, na, eu, asia, // ru, me, oceania, sa, africa. Region string // Filtered marks resolvers that intentionally rewrite or block answers // (malware / adult / ad / family filters). These are expected to differ // from the consensus on some zones and therefore kept out of the default // unfiltered probe set. Filtered bool // DoHURL is the RFC 8484 endpoint, when the provider publishes one. DoHURL string // DoTHost is the DNS-over-TLS server name (SNI target), when available. // DoT always runs on port 853 against this same hostname. DoTHost string } // Derived from happydomain3/web/src/lib/resolver.ts; regions are best-effort from AS paths and provider docs. var allResolvers = []Resolver{ // ── Unfiltered / Anycast global ────────────────────────────────────── {ID: "cloudflare", Name: "Cloudflare DNS", IP: "1.1.1.1", Region: "global", DoHURL: "https://cloudflare-dns.com/dns-query", DoTHost: "cloudflare-dns.com"}, {ID: "google", Name: "Google Public DNS", IP: "8.8.8.8", Region: "global", DoHURL: "https://dns.google/dns-query", DoTHost: "dns.google"}, {ID: "quad9-unfiltered", Name: "Quad9 (no blocklist)", IP: "9.9.9.10", Region: "global", DoHURL: "https://dns10.quad9.net/dns-query", DoTHost: "dns10.quad9.net"}, {ID: "opendns", Name: "OpenDNS", IP: "208.67.222.222", Region: "global"}, {ID: "he", Name: "Hurricane Electric", IP: "74.82.42.42", Region: "global"}, {ID: "dns-sb", Name: "DNS.SB", IP: "185.222.222.222", Region: "global", DoHURL: "https://doh.dns.sb/dns-query", DoTHost: "dns.sb"}, {ID: "adguard-unfiltered", Name: "AdGuard (non-filtering)", IP: "94.140.14.140", Region: "global", DoHURL: "https://unfiltered.adguard-dns.com/dns-query", DoTHost: "unfiltered.adguard-dns.com"}, // ── North America ── {ID: "level3", Name: "Level3", IP: "4.2.2.1", Region: "na"}, {ID: "verisign", Name: "Verisign", IP: "64.6.64.6", Region: "na"}, {ID: "comodo", Name: "Comodo Secure DNS", IP: "8.26.56.26", Region: "na"}, {ID: "norton", Name: "Norton ConnectSafe", IP: "199.85.126.10", Region: "na"}, {ID: "safeserve", Name: "Namecheap SafeServe", IP: "198.54.117.10", Region: "na"}, {ID: "dyn", Name: "Dyn", IP: "216.146.35.35", Region: "na"}, {ID: "neustar", Name: "Neustar / DNS Advantage", IP: "156.154.70.1", Region: "na"}, {ID: "smartviper", Name: "SmartViper", IP: "208.76.50.50", Region: "na"}, {ID: "alternate", Name: "Alternate DNS", IP: "23.253.163.53", Region: "na"}, {ID: "strongdns", Name: "StrongDNS", IP: "216.131.65.63", Region: "na"}, // ── Europe ── {ID: "dns-watch", Name: "DNS.WATCH (DE)", IP: "84.200.69.80", Region: "eu"}, {ID: "freedns", Name: "FreeDNS (AT)", IP: "37.235.1.174", Region: "eu"}, {ID: "freenom", Name: "Freenom World (NL)", IP: "80.80.80.80", Region: "eu"}, {ID: "uncensored", Name: "UncensoredDNS (DK)", IP: "91.239.100.100", Region: "eu"}, {ID: "fdn", Name: "French Data Network (FR)", IP: "80.67.169.12", Region: "eu"}, {ID: "fooldns", Name: "FoolDNS (IT)", IP: "87.118.111.215", Region: "eu"}, {ID: "puntcat", Name: "puntCAT (ES)", IP: "109.69.8.51", Region: "eu"}, {ID: "opennic", Name: "OpenNIC", IP: "185.121.177.177", Region: "eu"}, {ID: "dns4eu-unfiltered", Name: "DNS4EU (unfiltered)", IP: "86.54.11.100", Region: "eu", DoHURL: "https://unfiltered.joindns4.eu/dns-query", DoTHost: "unfiltered.joindns4.eu"}, {ID: "dns4all", Name: "DNS4ALL", IP: "194.0.5.3", Region: "eu"}, // ── Asia (East & SE) ── {ID: "ntt-jp", Name: "NTT (JP)", IP: "129.250.35.250", Region: "asia"}, {ID: "alidns", Name: "AliDNS (CN)", IP: "223.5.5.5", Region: "asia"}, {ID: "cnnic-sdns", Name: "CNNIC SDNS (CN)", IP: "1.2.4.8", Region: "asia"}, {ID: "dnspod", Name: "DNSPod (CN)", IP: "119.29.29.29", Region: "asia"}, {ID: "onedns", Name: "oneDNS (CN)", IP: "114.215.126.16", Region: "asia"}, {ID: "cloudxns", Name: "CloudXNS (CN)", IP: "124.251.124.251", Region: "asia"}, {ID: "114dns", Name: "114DNS (CN)", IP: "114.114.114.114", Region: "asia"}, {ID: "dnspai", Name: "DNSpai (CN)", IP: "101.226.4.6", Region: "asia"}, {ID: "quad101", Name: "Quad101 (TW)", IP: "101.101.101.101", Region: "asia"}, {ID: "hinet", Name: "HiNet (TW)", IP: "168.95.1.1", Region: "asia"}, // ── Russia ── {ID: "yandex", Name: "Yandex.DNS", IP: "77.88.8.8", Region: "ru", DoTHost: "common.dot.dns.yandex.net"}, // ── Middle East ── {ID: "greenteam", Name: "GreenTeam DNS (IL)", IP: "81.218.119.11", Region: "me"}, // ── Filtered (opt-in) ───────────────────────────────────────────────── {ID: "cloudflare-malware", Name: "Cloudflare (malware blocking)", IP: "1.1.1.2", Region: "global", Filtered: true, DoHURL: "https://security.cloudflare-dns.com/dns-query", DoTHost: "security.cloudflare-dns.com"}, {ID: "cloudflare-family", Name: "Cloudflare (malware + adult)", IP: "1.1.1.3", Region: "global", Filtered: true, DoHURL: "https://family.cloudflare-dns.com/dns-query", DoTHost: "family.cloudflare-dns.com"}, {ID: "quad9", Name: "Quad9 (blocklist)", IP: "9.9.9.9", Region: "global", Filtered: true, DoHURL: "https://dns.quad9.net/dns-query", DoTHost: "dns.quad9.net"}, {ID: "adguard", Name: "AdGuard (default)", IP: "94.140.14.14", Region: "global", Filtered: true, DoHURL: "https://dns.adguard-dns.com/dns-query", DoTHost: "dns.adguard-dns.com"}, {ID: "adguard-family", Name: "AdGuard (family protection)", IP: "94.140.14.15", Region: "global", Filtered: true, DoHURL: "https://family.adguard-dns.com/dns-query", DoTHost: "family.adguard-dns.com"}, {ID: "yandex-safe", Name: "Yandex Safe", IP: "77.88.8.2", Region: "ru", Filtered: true, DoTHost: "common.dot.dns.yandex.net"}, {ID: "yandex-family", Name: "Yandex Family", IP: "77.88.8.3", Region: "ru", Filtered: true, DoTHost: "common.dot.dns.yandex.net"}, {ID: "dns-advantage-threat", Name: "DNS Advantage Threat", IP: "156.154.70.2", Region: "na", Filtered: true}, {ID: "dns-advantage-family", Name: "DNS Advantage Family", IP: "156.154.70.3", Region: "na", Filtered: true}, {ID: "dns-advantage-business", Name: "DNS Advantage Business", IP: "156.154.70.4", Region: "na", Filtered: true}, {ID: "cleanbrowsing-family", Name: "CleanBrowsing Family", IP: "185.228.168.168", Region: "global", Filtered: true, DoHURL: "https://doh.cleanbrowsing.org/doh/family-filter/", DoTHost: "family-filter-dns.cleanbrowsing.org"}, {ID: "cleanbrowsing-adult", Name: "CleanBrowsing Adult", IP: "185.228.168.10", Region: "global", Filtered: true, DoHURL: "https://doh.cleanbrowsing.org/doh/adult-filter/", DoTHost: "adult-filter-dns.cleanbrowsing.org"}, {ID: "dns4eu-protective", Name: "DNS4EU Protective", IP: "86.54.11.1", Region: "eu", Filtered: true, DoHURL: "https://protective.joindns4.eu/dns-query", DoTHost: "protective.joindns4.eu"}, {ID: "dns4eu-child", Name: "DNS4EU Child Protection", IP: "86.54.11.12", Region: "eu", Filtered: true, DoHURL: "https://child.joindns4.eu/dns-query", DoTHost: "child.joindns4.eu"}, {ID: "dns4eu-adblock", Name: "DNS4EU Ad-blocking", IP: "86.54.11.13", Region: "eu", Filtered: true, DoHURL: "https://ads.joindns4.eu/dns-query", DoTHost: "ads.joindns4.eu"}, } // A non-empty allowlist takes precedence; filter and region knobs are then ignored. func selectedResolvers(includeFiltered bool, region string, allowlist []string) []Resolver { if len(allowlist) > 0 { allow := make(map[string]bool, len(allowlist)) for _, a := range allowlist { allow[a] = true } var out []Resolver for _, r := range allResolvers { if allow[r.ID] || allow[r.IP] { out = append(out, r) } } return out } var out []Resolver for _, r := range allResolvers { if r.Filtered && !includeFiltered { continue } if region != "" && region != "all" && region != r.Region { continue } out = append(out, r) } return out } func regionLabel(region string) string { switch region { case "global": return "Global / Anycast" case "na": return "North America" case "eu": return "Europe" case "asia": return "Asia" case "ru": return "Russia" case "me": return "Middle East" case "oceania": return "Oceania" case "sa": return "South America" case "africa": return "Africa" default: return region } }