Skip to content

feat: merge subscription DNS policy into the main configuration - #56

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

When a subscription is reduced to its nodes, derivedSubscription built the node document from proxies alone. The airport's dns.nameserver-policy and dns.proxy-server-nameserver-policy were dropped there, so its DNS routing policy never reached the main configuration.

This carries both tables into the derived node document instead of discarding them:

  • ProxyImportResult gains dnsNameServerPolicy / dnsProxyServerNameserverPolicy
  • decode reads them from the kernel report, treating a missing or empty table as nil
  • derivedSubscription emits a dns section when either table is present

The merge semantics already existed: mergeOverride runs the user's patch over the node document and unions map values, with the user's side winning. So conflicting domains stay under the user's control while the airport's remaining domains are still honoured — no change to the merge layer was needed, only to what reaches it.

A payload without a dns section produces a byte-identical document to before. Validation is unaffected: validateConfigShape is a shape check, and validateDNSForIOS only requires nameserver when enable: true, which the user's merged dns provides.

Depends on the kernel-side report fields: ProjectClash/Clash#11

Node extraction kept only `proxies`, so an airport's
`dns.nameserver-policy` and `dns.proxy-server-nameserver-policy` were
dropped and its DNS routing never reached the running configuration.

Carry both tables into the derived node document instead of discarding
them. The existing override merge unions these maps with the user's own
patch taking precedence, so domains the user configured stay under their
control while the airport's remaining domains are still honoured. A
payload without a dns section produces the same document as before.
@TokenPLS

Copy link
Copy Markdown
Member

Thanks for the careful write-up. We're closing this together with ProjectClash/Clash#11.

The case that actually breaks is a subscription whose nodes' domains have to be resolved by the provider's own DNS. Since e3e6472 the Client detects that on import and runs such a subscription as its original configuration, so its DNS reaches the core as written. Any other DNS policy in a subscription is replaced on purpose by the DNS of the rule scheme the user picked; merging it in would quietly change DNS for every composed subscription that carries such a table. A user who wants the subscription's whole DNS can import it as its original configuration.

If you have a subscription that still resolves wrongly on the current Client, please open an issue with its dns section (addresses redacted).

@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