feat(dns): add explicit mdns resolver - #3028
Open
hengistchan wants to merge 2 commits into
Open
Conversation
hengistchan
marked this pull request as ready for review
July 25, 2026 10:27
Author
|
Follow-up hardening is available in
The updated fork workflows are waiting for maintainer approval and have not executed any jobs yet:
Please keep the PR unmerged until both upstream workflows have actually run and passed. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #3027
Summary
This adds an explicit
mdns://DNS nameserver without changingsystem://orautomatically routing
.localnames.Root cause
Mihomo's current system resolver enumerates configured unicast DNS servers and
queries them through Mihomo's ordinary DNS client. On macOS this bypasses
mDNSResponder, so a hostname may resolve through
dscacheutil/dns-sdbutreturn
NXDOMAINthrough Mihomo.Design
mdns://in nameserver parsing and client constructiontransport
system://unchanged and does not add implicit.localroutingmDNSResponder Unix-domain IPC on macOS for A/AAAA
The portable transport:
non-point-to-point interface
destination multicast address, ingress interface index, and TTL/hop limit
and ingress interface, as required/recommended by
RFC 6762
says senders SHOULD use 255, while a packet received at the link-local
multicast destination is already known to be local
CNAME on one link cannot attach to a target record from another link
identical records are collapsed with the greatest observed TTL
timeout, reset, cancellation, or close
This also fixes CNAME targets that arrive in an earlier packet than the CNAME:
filtering is deferred until the per-interface record set has been assembled.
Negative and fallback semantics
returns a timeout error; another successful nameserver in the same policy
group may therefore win
NOERROR/NODATA with its TTLNoSuchRecordreturns NODATA andNoSuchNamereturnsNXDOMAINMihomo logs a clear diagnostic and falls back to portable multicast within
the original query deadline
if both IPC and multicast fail, the returned error contains both causes
Tests
Coverage includes:
handling
cancellation
.localqueriesincompatible-protocol fallback, and joined fallback diagnostics
Passed locally:
Running
go test ./...without the repository's macOS exclusion reproduces anunrelated
TestInboundSudoku_HTTPMaskMode/Concurrentconnection-reset failureon an untouched
origin/Alphaworktree. The CI-equivalent standard andwith_gvisorsuites pass.The full non-incremental lint command still reports existing findings in
dns/dhcp.go,dns/dot.go,dns/service.go, anddns/doq.go. Incrementallint for this PR is clean.
Build compatibility
CGO-free
with_gvisorbuilds passed for:Real verification
An isolated Mihomo instance on
127.0.0.1:10554returned:Both replies were
NOERROR, matched the macOS host resolver, and the debug logshowed
from mdns://. The existing Clash, OrbStack, routing, firewall, systemDNS, and TUN configuration were not changed.
Why
system://is unchangedsystem://is an established unicast-DNS abstraction. Adding mDNS implicitlywould change resolution order and could break private unicast-DNS deployments
that intentionally use
.local. An explicit scheme keeps the behavior opt-inand policy-controlled.
Known limitations
Mihomo's IP resolver.
dns_sd.hAPI. Incompatible protocol/transport errors now fall back with aclear diagnostic, but a future incompatible protocol may still require an
adapter update.
AAAA record. Interface metadata is retained for validation and per-interface
merging, but a returned
fe80::/10address cannot carry its zone downstream.sandboxes and containers may restrict either capability.
mdns://is a direct link-local transport; proxy selection andrespect-rulesare intentionally not applied.CI/merge gate
This PR should not be merged until the upstream Test and Build workflows have
actually run and passed. Fork workflow runs currently require a MetaCubeX
maintainer to approve execution.