Skip to content

fix(server): SO_REUSEPORT to coexist with mDNSResponder on macOS Sequoia - #250

Open
eejd wants to merge 1 commit into
zerotier:mainfrom
eejd:fix/macos-sequoia-reuseport
Open

fix(server): SO_REUSEPORT to coexist with mDNSResponder on macOS Sequoia#250
eejd wants to merge 1 commit into
zerotier:mainfrom
eejd:fix/macos-sequoia-reuseport

Conversation

@eejd

@eejd eejd commented May 31, 2026

Copy link
Copy Markdown

On macOS Sequoia (Darwin 25+), mDNSResponder permanently binds *:53 (UDP+TCP) as a unicast DNS proxy. It is SIP-protected and cannot be removed via launchctl. zeronsd already binds to the specific ZeroTier interface IP (not INADDR_ANY), but mDNSResponder's exclusive wildcard binding blocks, causing zeronsd to appear to load but not respond to any requests as it cannot acquire the port 53 for the ZeroTier IP.

Fix: use socket2 to create the UDP and TCP sockets with SO_REUSEPORT before handing them to trust_dns_server. On BSD/macOS, SO_REUSEPORT allows a new socket to coexist with an existing binding on the same port; the more-specific IP address match (zeronsd's ZT interface IP) takes priority over the wildcard (*) for incoming packets. mDNSResponder continues to operate normally on port 5353 (mDNS).

SO_REUSEPORT is supported on macOS 10.4+ and is harmless on Linux, where it can also improve multi-process deployment. The socket2 crate (already a transitive dependency via tokio) provides the cross-platform socket option API.

Fixes: macOS issue where zeronsd starts and loads records but never serves DNS (trust_dns_server bind fails silently, leaving DNS queries unanswered). Related: #199 (macOS port 53 binding failure, reported 2022)

…Sequoia

On macOS Sequoia (Darwin 25+), mDNSResponder permanently binds *:53 (UDP+TCP)
as a unicast DNS proxy. It is SIP-protected and cannot be removed via launchctl.
zeronsd already binds to the specific ZeroTier interface IP (not INADDR_ANY), but
mDNSResponder's exclusive wildcard binding blocks it regardless.

Fix: use socket2 to create the UDP and TCP sockets with SO_REUSEPORT before
handing them to trust_dns_server. On BSD/macOS, SO_REUSEPORT allows a new socket
to coexist with an existing binding on the same port; the more-specific IP address
match (zeronsd's ZT interface IP) takes priority over the wildcard (*) for incoming
packets. mDNSResponder continues to operate normally on port 5353 (mDNS).

SO_REUSEPORT is supported on macOS 10.4+ and is harmless on Linux, where it can
also improve multi-process deployment. The socket2 crate (already a transitive
dependency via tokio) provides the cross-platform socket option API.

Fixes: macOS issue where zeronsd starts and loads records but never serves DNS
(trust_dns_server bind fails silently, leaving DNS queries unanswered).
Related: zerotier#199 (macOS port 53 binding failure, reported 2022)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

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