use std::sync::LazyLock;
use super::types::DnsServer;
static DEFAULT_DNS_SERVERS: LazyLock<Vec<DnsServer>> = LazyLock::new(|| {
[
("Google", "8.8.8.8", NA, "Google"),
("Cloudflare", "1.1.1.1", NA, "Cloudflare"),
("OpenDNS", "208.67.222.222", NA, "Cisco"),
("Level3", "4.2.2.1", NA, "Lumen"),
(
"Hurricane Electric",
"74.82.42.42",
NA,
"Hurricane Electric",
),
("UltraDNS", "64.6.64.6", NA, "Vercara"),
("Control D", "76.76.2.0", NA, "Windscribe"),
("Quad9", "9.9.9.10", EU, "Quad9"),
("DNS4EU", "86.54.11.100", EU, "DNS4EU"),
("AdGuard", "94.140.14.140", EU, "AdGuard"),
("DNS.SB", "185.222.222.222", EU, "xTom"),
("CZ.NIC ODVR", "193.17.47.1", EU, "CZ.NIC"),
("Yandex", "77.88.8.8", EU, "Yandex"),
("114DNS", "114.114.114.114", AP, "114DNS"),
("DNSPod", "119.29.29.29", AP, "Tencent"),
("Volcengine", "180.184.1.1", AP, "ByteDance"),
("360 DNS", "101.226.4.6", AP, "Qihoo 360"),
("HiNet", "168.95.1.1", AP, "Chunghwa Telecom"),
("KT", "168.126.63.1", AP, "KT Corporation"),
("LG U+", "164.124.101.2", AP, "LG Uplus"),
]
.into_iter()
.map(|(name, ip, location, provider)| DnsServer::new(name, ip, location, provider))
.collect()
});
const NA: &str = "North America";
const EU: &str = "Europe";
const AP: &str = "Asia Pacific";
pub fn default_dns_servers() -> &'static [DnsServer] {
&DEFAULT_DNS_SERVERS
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_dns_servers() {
let servers = default_dns_servers();
assert!(servers.len() >= 20, "Should have at least 20 DNS servers");
let locations: Vec<&str> = servers.iter().map(|s| s.location.as_str()).collect();
for region in [NA, EU, AP] {
assert!(locations.contains(®ion), "no server in {region}");
}
}
#[test]
fn default_servers_are_unique_public_ips() {
let mut seen = std::collections::HashSet::new();
for server in default_dns_servers() {
let ip: std::net::IpAddr = server.ip.parse().expect("IP literal");
assert!(!crate::net::is_reserved_ip(ip), "{} is reserved", server.ip);
assert!(seen.insert(ip), "{} listed twice", server.ip);
}
}
}