Resolution Flow
There are quite a few DNS-related fields, and it's easy to lose track of which one takes priority. Let's walk through the whole resolution chain with an example.
Example Config
config.yaml YAML
dns: nameserver: - https://doh.pub/dns-query fallback: - https://8.8.8.8/dns-query direct-nameserver: - system nameserver-policy: "geosite:cn,private": - https://doh.pub/dns-query - https://dns.alidns.com/dns-query fallback-filter: geoip: true geoip-code: CN geosite: - gfw ipcidr: - 240.0.0.0/4 domain: - '+.google.com' rules: - DOMAIN-SUFFIX,google.com,PROXY - GEOIP,CN,DIRECT - MATCH,PROXY
Full Flow
This only covers how the dns module itself processes requests, split into two paths by traffic type:
- First, check whether the matched rule is a domain rule or a destination IP rule. Domain rules like
DOMAIN-SUFFIX/GEOSITEgo straight into resolution; destination IP rules likeIP-CIDR/GEOIPalso enter resolution, since the domain needs to be resolved to an IP first before it can be matched. - If a domain rule matches direct, and
direct-nameserveris configured: resolution goes straight throughdirect-nameserver, skipping the nameserver-policy/nameserver flow below. - Otherwise, check whether
nameserver-policyis configured: if the domain matches a policy (e.g.geosite:cn,privatein the example above), it's resolved using that policy's servers; if no policy matches, ornameserver-policyisn't configured at all, it falls through tonameserverin the next step. - Query using
nameserver: iffallbackis also configured,nameserverandfallbackare queried concurrently, and both results are checked againstfallback-filter(e.g. if the resolved IP matchesgeoip-code: CNbut the domain isn't in thedomainwhitelist, the result may be considered polluted). If the condition is met, thefallbackresult is used; otherwise thenameserverresult is used. Iffallbackisn't configured, thenameserverresult is used directly. - Once an IP is resolved, it goes through rule matching again: if the domain rule already matched a proxy, the domain along with the resolved result is sent to the proxy (the proxy server may re-resolve it independently); if a destination IP rule matches direct and
direct-nameserveris configured, it's resolved again through that before connecting directly; otherwise the already-resolved IP is used to connect directly.
Re-resolving via direct-nameserver currently only applies to TCP connections; newer core versions have also extended this to UDP connections (fake-ip mode via TUN inbound only).