Docs Config Resolution Flow

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:

  1. First, check whether the matched rule is a domain rule or a destination IP rule. Domain rules like DOMAIN-SUFFIX/GEOSITE go straight into resolution; destination IP rules like IP-CIDR/GEOIP also enter resolution, since the domain needs to be resolved to an IP first before it can be matched.
  2. If a domain rule matches direct, and direct-nameserver is configured: resolution goes straight through direct-nameserver, skipping the nameserver-policy/nameserver flow below.
  3. Otherwise, check whether nameserver-policy is configured: if the domain matches a policy (e.g. geosite:cn,private in the example above), it's resolved using that policy's servers; if no policy matches, or nameserver-policy isn't configured at all, it falls through to nameserver in the next step.
  4. Query using nameserver: if fallback is also configured, nameserver and fallback are queried concurrently, and both results are checked against fallback-filter (e.g. if the resolved IP matches geoip-code: CN but the domain isn't in the domain whitelist, the result may be considered polluted). If the condition is met, the fallback result is used; otherwise the nameserver result is used. If fallback isn't configured, the nameserver result is used directly.
  5. 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-nameserver is 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).