ccTLD-aware resolvers: asking DNS where the domain lives
What is a ccTLD?
A ccTLD — country-code top-level domain — is the two-letter suffix of a domain that is tied to a country or territory: .pl (Poland), .de (Germany), .jp (Japan), .br (Brazil), .cn (China). It stands in contrast to gTLDs (generic TLDs) like .com, .org or .icu, which aren't bound to any geography. The two letters come from the ISO 3166-1 country list, and each ccTLD is run by a national registry (e.g. NASK for .pl, DENIC for .de).
Why geography matters for DNS
DNS is global, but it isn't uniform. The authoritative servers for a .jp domain, and the CDN edge it points at, usually live in or near Japan. A distant global anycast resolver can still answer, but it may be slower, may be routed to a far edge, or — in places like China behind the Great Firewall — may return filtered or poisoned answers for .cn names. Asking a resolver inside the country tends to give the fastest and most representative answer.
What the audit does
The audit (cli audit, infra/audit.py) resolves every host against three resolvers chosen by pick_resolvers (infra/dns.py):
- For a known ccTLD, it prepends a country-local resolver from
CCTLD_RESOLVERS(e.g..pl→ TPNET,.jp→ InterLink,.cn→ Alibaba DNS) and pairs it with random global resolvers as a fallback. - For a gTLD (
.com,.icu, …) there is no country to target, so it samples three distinct resolvers from the global pool (Cloudflare, Google, Quad9, OpenDNS).
allegro.pl -> [194.204.159.1 (TPNET, PL), 8.8.8.8, 1.1.1.1]
www.rakuten.co.jp -> [210.140.10.1 (InterLink, JP), 1.1.1.1, 9.9.9.9]
news773.hengmen.icu -> [9.9.9.9, 208.67.222.222, 8.8.4.4] # gTLD: three from the global pool
Two design properties
- Resilience. The local resolver may not be openly recursive for our network. That's fine: the paired global resolver still answers, and DNS consensus decides the status. A country resolver only ever adds a viewpoint — it can't break the result.
- Spread. Drawing from a pool instead of always hitting the same two operators distributes load and avoids rate-limiting when sweeping millions of hosts.
Extending coverage is a one-line change: add a tld → resolver entry to CCTLD_RESOLVERS.