Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

macos: support multiple system resolvers like C #18

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

maxfierke
Copy link

On macOS, libresolv supports multiple resolvers. This allows users, VPN clients, etc. to delegate queries for certain domains to other resolvers, in addition to the "Super Resolver" specified by /etc/resolv.conf. An example of this would be using something like dnsmasq or launchdns to resolve a Special Use Domain (described by RFC 6761) for local development like *.localhost or *.test

This is supported transparently via the gethostbyname and getaddrinfo C calls, but when replacing use of those APIs w/ Resolv, these resolutions no longer happen automatically.

If I can find a link to the respective man page on macOS about this functionality, I can post that here for review from anyone who doesn't have access to macOS.

On macOS, libresolv supports multiple resolvers. This allows users, VPN
clients, etc. to delegate queries for certain domains to other
resolvers, in addition to the "Super Resolver" specified by
/etc/resolv.conf. An example of this would be using something like
dnsmasq or launchdns to resolve a Special Use Domain (described
by RFC 6761) for local development like *.localhost or *.test

This is supported transparently via the gethostbyname and getaddrinfo C
calls, but when replacing use of those APIs w/ Resolv, these resolutions
no longer happen automatically.
@hanazuki
Copy link
Contributor

hanazuki commented Nov 26, 2023

The "Search Strategy" section of resolver(5) on MacOS 14 says that each configured resolver has an associated domain name, which is specified implicitly by the filename in /etc/resolver/* or explicitly by the domain line in the file. DNS queries are routed to the best matching resolver(s), if any, in the order of search_order, or otherwise routed to the default resolver (that is, the one configuredavailable in /etc/resolv.conf).

To make resolv work like the macOS system resolver, I suppose we need to re-implement the DNS router functionality.

if /darwin/ =~ RUBY_PLATFORM && Dir.exist?('/etc/resolver')
Dir.each_child('/etc/resolver') do |filename|
resolver = DNS::Config.parse_resolv_conf("/etc/resolver/#{filename}")
resolver[:search] = [filename] unless resolver[:search]
Copy link
Contributor

Choose a reason for hiding this comment

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

IIUC, the config filename implicitly specifies domain option, which is the key for DNS routing and is a different thing than search option or the search suffix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants