Skip to content

[server] add interface name to DNS state on Darwin#4633

Closed
siriobalmelli wants to merge 0 commit intonetbirdio:mainfrom
siriobalmelli:main
Closed

[server] add interface name to DNS state on Darwin#4633
siriobalmelli wants to merge 0 commit intonetbirdio:mainfrom
siriobalmelli:main

Conversation

@siriobalmelli
Copy link
Copy Markdown

@siriobalmelli siriobalmelli commented Oct 13, 2025

Describe your changes

Fix bug on Darwin where different instances of netbird clobber each other's DNS entries:
disambiguate 'netbirdDNSStateKeyFormat' by including the interface name.

Issue ticket number and link

Related to #446: allows proper DNS resolution when multiple server instances are run on Darwin/MacOS, each instance with its own interface and state.

Stack

Checklist

  • Is it a bug fix
  • Is a typo/documentation fix
  • Is a feature enhancement
  • It is a refactor
  • Created tests that fail without the change (if possible)

By submitting this pull request, you confirm that you have read and agree to the terms of the Contributor License Agreement.

Documentation

Select exactly one:

  • I added/updated documentation for this change
  • Documentation is not needed for this change (explain why)

It is reasonable to assume that multiple instances of netbird server can run on a Darwin machine, as long as they bind to different interfaces and have separate runtime and state directories; in this case each should push its own independent resolver record to the resolver.

This is already the case on Linux, and this bugfix brings feature parity to Darwin.

Summary by CodeRabbit

  • New Features
    • Per-interface scoping for DNS state to isolate DNS settings per network interface on macOS.
  • Bug Fixes
    • Improved DNS configuration and restoration during shutdown to prevent cross-instance conflicts and reliably restore prior settings.

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Oct 13, 2025

CLA assistant check
All committers have signed the CLA.

@sonarqubecloud
Copy link
Copy Markdown

@siriobalmelli
Copy link
Copy Markdown
Author

@nazarewk you might be interested in this; combined with nix-darwin/nix-darwin#1610 it allows participating in multiple independent overlay networks on a single nix-darwin host.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Dec 12, 2025

📝 Walkthrough

Walkthrough

Per-interface DNS state was added for Darwin: interface names are threaded into DNS state keys, host manager initialization, shutdown state, and DNS apply/cleanup logic so DNS settings and keys are scoped by network interface.

Changes

Cohort / File(s) Summary
Host manager & keying
client/internal/dns/host_darwin.go
Added interfaceName field to systemConfigurator; newHostManager now accepts interfaceName; getKeyWithInput signature changed to include iface; DNS state keys and removable/default key generation now include interface scope; local DNS handling guarded by ServerIP/Domains.
Server initialization
client/internal/dns/server_darwin.go
initialize now calls newHostManager(s.wgInterface.Name()), propagating the WireGuard interface name into host manager creation.
Unclean shutdown / state
client/internal/dns/unclean_shutdown_darwin.go
Added InterfaceName (with JSON tag) to ShutdownState; CreatedKeys JSON tag added; Cleanup() constructs host manager with stored InterfaceName and restores manager.createdKeys from persisted state before cleanup.
Tests
client/internal/dns/host_darwin_test.go
Expanded tests to validate interface-scoped key generation, host manager initialization with interfaceName, removal/cleanup behavior across interfaces, and to ensure no cross-interface key collisions.

Sequence Diagram(s)

(omitted)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • pappz

Poem

I’m a rabbit on Darwin, hopping keys by name,
Each interface fenced, no two the same.
I tuck DNS threads into tidy lanes—
Clean shutdowns remember, no cross-talk remains. 🐰✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 56.25% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding interface name to DNS state management on Darwin to disambiguate DNS entries across multiple netbird instances.
Description check ✅ Passed The description comprehensively covers all required template sections including detailed explanation of the bug fix, related issue link, proper checklist completion, and documentation justification.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sonarqubecloud
Copy link
Copy Markdown

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between abcbde2 and 8ea2c98.

📒 Files selected for processing (3)
  • client/internal/dns/host_darwin.go (10 hunks)
  • client/internal/dns/server_darwin.go (1 hunks)
  • client/internal/dns/unclean_shutdown_darwin.go (1 hunks)
🔇 Additional comments (7)
client/internal/dns/host_darwin.go (4)

58-62: LGTM! Early state initialization is a good practice.

Writing the initial state with just the interface name at the beginning of applyDNSConfig ensures that the shutdown state is recorded even if subsequent operations fail. Subsequent calls to updateState will populate CreatedKeys as DNS configuration progresses.


124-129: LGTM! State updates now include interface scoping.

The shutdown state correctly includes both the interface name and created keys, enabling proper per-interface cleanup and restoration.


192-200: Improved logic with explicit validation.

The refactored conditional now only adds local DNS when both the server IP is valid AND domains exist, making the requirements explicit. The early return with a clear log message improves code clarity.


373-375: LGTM! Helper function signature matches the updated key format.

The updated signature correctly accepts format, interface name, and key suffix, aligning with the two-placeholder format of netbirdDNSStateKeyFormat.

client/internal/dns/unclean_shutdown_darwin.go (2)

10-11: LGTM! Proper state persistence with JSON tags.

The addition of JSON tags ensures that both InterfaceName and CreatedKeys are correctly marshaled and persisted for unclean shutdown recovery.


19-26: LGTM! Cleanup now scoped to the specific interface.

The host manager is correctly initialized with the stored interface name, and the created keys are properly restored from the shutdown state before performing DNS restoration. This ensures cleanup only affects DNS entries for the specific interface.

client/internal/dns/server_darwin.go (1)

6-6: [rewritten comment]
[classification tag]

Comment thread client/internal/dns/host_darwin.go Outdated
Comment thread client/internal/dns/host_darwin.go Outdated
@siriobalmelli
Copy link
Copy Markdown
Author

Superseded by #5504, which rebases this fix onto current main and reconciles it with the domain-batching changes from #5368.

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Mar 4, 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