Skip to content

feat: report subscription DNS routing policy in proxy import - #11

Closed
0x0021 wants to merge 1 commit into
ProjectClash:mainfrom
0x0021:feat/subscription-dns-policy
Closed

0x0021 wants to merge 1 commit into
ProjectClash:mainfrom
0x0021:feat/subscription-dns-policy

Conversation

@0x0021

@0x0021 0x0021 commented Oct 20, 2026 •

Copy link
Copy Markdown

Summary

Proxy import reduced a subscription to its proxies only. When a payload was extracted node-by-node, the airport's dns.nameserver-policy and dns.proxy-server-nameserver-policy were discarded along with the rest of the dns section, so the airport's DNS routing policy never reached the running configuration.

This adds both tables to the import report so the caller can carry them into the main configuration:

  • proxyImportReport.DNSNameServerPolicy / DNSProxyServerNameserverPolicy, both omitempty
  • extractProxyImportDNSPolicy lifts them from a decoded mihomo document
  • JSON configuration containers (mihomo-json) are decoded for their dns section too; the YAML path already holds the decoded document

No merge semantics change here. MergeOverrideForIOS already unions these maps with the user's own patch on the winning side, so the client only had to stop throwing the data away.

A payload without a dns section reports exactly what it did before, and the report encoding is unchanged for existing consumers (encodeProxyImportReport marshals the struct as a whole).

Testing

go build ./...
go vet ./
gofmt -l .
go test ./ -run 'TestProxyImport' -count=1

New tests in bind/clash/proxy_import_dns_test.go:

  • TestProxyImportCarriesDNSNameServerPolicy — YAML payload, both tables extracted
  • TestProxyImportCarriesDNSNameServerPolicyFromJSONContainer — mihomo-json payload reaches the same tables
  • TestProxyImportWithoutDNSLeavesPolicyNil — no dns section leaves both nil
  • TestProxyImportDNSMergesUnderUserOverride — end-to-end: the airport table reaches the node document, then mergeOverrideDocument unions it with a user patch so shared domains resolve to the user's entry while airport-only domains survive

go test ./ -count=1 reports two failures, TestBindClashInitStaysWithinItsBudget and TestJSONToYamlRefusesRunawayNesting. Both fail identically on the unmodified base commit (verified via git stash), so they are pre-existing and unrelated to this change.

Related client-side change: ProjectClash/Clash-Client#56

Proxy import extracted only `proxies` from a payload, so an airport's
split-DNS routing tables were dropped whenever a subscription was reduced
to its nodes. The client had no way to merge them into the main
configuration, so the DNS routing policy silently disappeared.

Surface `dns.nameserver-policy` and `dns.proxy-server-nameserver-policy` in
the import report so the caller can carry them into the main config.
Both tables are omitted when absent, so a payload without a dns section
reports exactly what it did before.
@TokenPLS

Copy link
Copy Markdown
Member

Thanks for digging into this. We're closing it because the Client no longer needs these tables from the import report.

The case that actually breaks is a subscription whose nodes' domains have to be resolved by the provider's own DNS (nameserver-policy or proxy-server-nameserver-policy sending the nodes' domains to its DoH server). The Client now detects that on import and runs such a subscription as its original configuration instead of composing it (Clash-Client e3e6472). Any other DNS policy in a subscription is replaced on purpose by the DNS of the rule scheme the user picked; a user who wants the subscription's whole DNS can import it as its original configuration.

If a subscription still resolves wrongly on the current Client, please open an issue with its dns section (addresses redacted) and we'll look at it.

@TokenPLS TokenPLS closed this Oct 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants