DNS

Rules have to see a name, or see an address. Two DNS stacks give two answers.

Domain conditions eat a hostname. IP / GEOIP conditions eat a destination address. Where the name comes from, and who resolved the address, decide which stretch of the list this connection hits. When resolution is not the anomaly, do not change system DNS and in-app DNS at the same time.

  1. 01Two resolvers
  2. 02What the engine actually sees
  3. 03IPv6 makes address lines miss
  4. 04Local mapping and fake addresses

01

The system has one; the app can have another

The device already has system DNS (carrier, router, or servers you wrote in Settings). Shadowrocket can also specify its own DNS in the configuration, including encrypted queries. When both exist, which stack a given query uses follows the current configuration — it is not “average the two results.”

When system DNS and in-app DNS point at different recursors and give different addresses for the same name, GEOIP in the rules follows: the same hostname hits CN once and falls to FINAL the next. The rule file was not edited; the destination address changed.

When isolating, change one place at a time. Let system resolution work under Direct first (captive page, local visits), then start the tunnel. An in-app DNS that is wrong or unreachable makes every resolution-dependent request fail while the switch can still be on. Using Data to see whether bytes moved is faster than swapping records.

02

Some requests carry a name; some only have an address

A browser usually has both a hostname (Host / SNI) and a resolved address, so domain lines and address lines can both hit — still the first top-to-bottom hit wins.

If an app connects by IP, or omits SNI, every domain line misses and the request can only land on IP-CIDR, GEOIP, or FINAL. Then “the same site, Safari is proxied, this client is direct”: the two programs handed the engine different information. See “Where the hostname comes from” on the Rules page.

SNI says example.com, the socket is another CDN address: domain lines match example.com, GEOIP classifies the CDN address. If a domain line sits above GEOIP and already hit, GEOIP is never asked; if no domain line hit, you see the CDN’s library, not your impression of the name.

03

With only IPv4 CIDRs written, an IPv6 destination does not see that line

IP-CIDR,10.0.0.0/8,DIRECT does not cover IPv6. If the device uses fd00:: or global IPv6 to reach the same service, this line misses and the request falls until GEOIP or FINAL. Wi-Fi gave IPv6 and cellular did not: the same rule behaves differently on the two networks.

To cover both address families, add IP-CIDR6, or turn off the family you do not use in settings. Do not “add the same domain DIRECT” to fix an address-family problem — a domain line cannot help a request that has an address and no name.

04

Local mapping: rules may see an address that is not on the public net

Some configurations resolve a domain to a set of local or fake addresses first, then rewrite to the real destination inside the tunnel. Then IP-CIDR / GEOIP see the mapped address, not the site’s public address. A GEOIP country line is meaningless on those addresses; everything falls to other lines.

If the list leans heavily on GEOIP, and the resolve mode is changed to fake addresses, routing shifts as a whole. Changing resolve mode is changing the input the rules eat, not a small option. Before you change it, confirm the exit itself works with a fixed record and Proxy policy; see Data.

Hosts-style mapping on the device only affects names you wrote. Unlisted names still use current DNS. Do not expect a mapping table to replace a rule file.