Skip to content

Implement DnsResolver for macOS#131152

Draft
liveans wants to merge 12 commits into
dotnet:mainfrom
liveans:liveans-macos-pal-pr-129845
Draft

Implement DnsResolver for macOS#131152
liveans wants to merge 12 commits into
dotnet:mainfrom
liveans:liveans-macos-pal-pr-129845

Conversation

@liveans

@liveans liveans commented Jul 21, 2026

Copy link
Copy Markdown
Member
  • Uses DNS-SD for system-configured DNS resolution on macOS.
  • Reuses the managed resolver from Implement DnsResolver for Linux #129846 for explicit DNS servers.
  • Adds macOS-specific functional and loopback tests.

Builds on #129846. Draft until 129846 merged.

/cc @rzikm

rzikm and others added 12 commits July 9, 2026 10:41
Implements the DnsResolver PAL for the unix TFM as a managed stub
resolver. It builds and parses DNS wire messages and talks to the
configured servers over UDP (with TCP fallback on truncation) using
System.Net.Sockets. When no servers are configured, the system servers
from /etc/resolv.conf are used, falling back to loopback.

- Add internal wire primitives: message header, reader, writer,
  encoded-name (with IDN/ACE support), and per-type record parsers.
- Add DnsResolverPal.Managed.cs query engine with shared sync/async
  paths; the sync path uses blocking socket calls and returns a
  completed Task, preserving the task.IsCompleted invariant.
- Add ResolvConf.cs nameserver discovery plus parser unit tests.
- Wire the new sources into the unix ItemGroup; reference the
  System.Net.Sockets reference assembly to break the project cycle
  (Sockets references NameResolution); the implementation resolves from
  the shared framework at runtime.
- Generalize the loopback tests to run on Linux by binding an ephemeral
  port on non-Windows.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds System.Net.NameResolution.Unit.Tests covering the internal DNS
wire-format types (DnsEncodedName, DnsMessageHeader/Reader/Writer, and
typed RDATA parsing). The project links the production parsing sources
so the internal types can be exercised directly.

Also adds DnsEncodedName.GetFormattedLength() to expose the decoded
dotted-string length (already computed internally) for buffer sizing.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The managed Unix DNS stub resolver used System.Net.Sockets.Socket for UDP/TCP
queries. Because System.Net.Sockets already depends on System.Net.NameResolution
(Socket.Connect(host, port) resolves names through Dns), the emitted
NameResolution.dll carried a real metadata reference back to Sockets, closing a
dependency cycle that the shared-framework VerifyClosure task rejects. This built
locally but failed the CoreCLR/Mono runtime-pack build legs on CI.

Access Socket through a new internal DnsSocket reflection wrapper so
NameResolution no longer statically references System.Net.Sockets. The wrapper
binds the required Socket members to delegates so exceptions (e.g. SocketException)
propagate directly instead of being wrapped in TargetInvocationException, and a
DynamicDependency attribute preserves the members for trimming/AOT. SocketException,
SocketError and AddressFamily live in System.Net.Primitives and continue to be used
directly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…uccess

- Gate the loopback DNS resolver tests on IsNotBrowser and IsNotWasi in
  addition to IsNotMobile. The functional test project multi-targets
  -browser and -wasi where DnsResolverPal is Unsupported, so these
  socket-based tests would otherwise run and fail there.
- Assert success of DnsMessageReader.TryCreate/TryReadQuestion/TryReadRecord
  in the DnsRecordTypeTests GetAnswerRecord helper so malformed input
  surfaces clearly instead of failing in less obvious ways.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: f11fb54e-638e-4c9e-ad82-e5d9ff5c20e4
Copilot AI review requested due to automatic review settings July 21, 2026 14:16
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).
13 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @karelz, @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Implements a macOS-specific DnsResolverPal for System.Net.NameResolution that uses DNS-SD (DNSServiceQueryRecord) for system-configured DNS resolution while continuing to use the managed stub resolver when explicit DNS servers are provided. This extends the existing cross-platform DNS resolver work by adding an OSX PAL, shared managed wire-format handling, and corresponding tests.

Changes:

  • Add DnsResolverPal.OSX backed by DNS-SD, plus OSX interop declarations for DNSServiceQueryRecord APIs.
  • Add/enable managed DNS stub resolver + wire-format reader/writer and record parsing types for Unix/OSX builds.
  • Add new unit tests for wire-format components and expand functional/loopback tests and PAL tests (including resolv.conf parsing).

Reviewed changes

Copilot reviewed 24 out of 24 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/libraries/System.Net.NameResolution/tests/UnitTests/System.Net.NameResolution.Unit.Tests.csproj New unit test project that links managed DNS wire-format production code for testing.
src/libraries/System.Net.NameResolution/tests/UnitTests/DnsEncodedNameTests.cs Unit coverage for DNS name encoding/decoding, compression pointers, and IDN handling.
src/libraries/System.Net.NameResolution/tests/UnitTests/DnsMessageHeaderTests.cs Unit coverage for header encoding/decoding and flag/rcode/opcode round-trips.
src/libraries/System.Net.NameResolution/tests/UnitTests/DnsMessageReaderTests.cs Unit coverage for parsing questions/records and malformed buffer handling.
src/libraries/System.Net.NameResolution/tests/UnitTests/DnsMessageWriterTests.cs Unit coverage for query writing, buffer sizing, and pointer expansion behavior.
src/libraries/System.Net.NameResolution/tests/UnitTests/DnsRecordTypeTests.cs Unit coverage for typed RDATA parsing (A/AAAA/CNAME/MX/SRV/TXT/PTR/NS/SOA) and malformed cases.
src/libraries/System.Net.NameResolution/tests/PalTests/System.Net.NameResolution.Pal.Tests.csproj Adds Unix-only compilation of ResolvConf production code + tests into PAL test project.
src/libraries/System.Net.NameResolution/tests/PalTests/ResolvConfTests.cs New tests for parsing nameserver directives from resolv.conf-style content.
src/libraries/System.Net.NameResolution/tests/FunctionalTests/System.Net.NameResolution.Functional.Tests.csproj Adds OSX to functional test TFMs.
src/libraries/System.Net.NameResolution/tests/FunctionalTests/DnsResolverTest.cs Expands functional coverage to OSX and adds OSX-specific behavior/edge-case assertions via reflection hooks.
src/libraries/System.Net.NameResolution/tests/FunctionalTests/DnsResolverLoopbackTest.cs Broadens loopback tests beyond Windows and adds OSX custom-server behavior + negative cache TTL assertions for managed resolver.
src/libraries/System.Net.NameResolution/src/System/Net/ResolvConf.cs New resolv.conf nameserver parsing helper for managed resolver system-server discovery (Unix path).
src/libraries/System.Net.NameResolution/src/System/Net/DnsWireEnums.cs New internal DNS wire enums (TYPE/CLASS/OPCODE/FLAGS).
src/libraries/System.Net.NameResolution/src/System/Net/DnsSocket.cs New reflection-based socket wrapper to avoid System.Net.Sockets reference cycles for managed resolver.
src/libraries/System.Net.NameResolution/src/System/Net/DnsResolverPal.Managed.cs New managed stub resolver PAL for Unix-style explicit-server querying (UDP with TCP fallback).
src/libraries/System.Net.NameResolution/src/System/Net/DnsResolverPal.OSX.cs New macOS PAL that uses DNS-SD for system-configured resolution and defers explicit-server queries to the managed PAL.
src/libraries/System.Net.NameResolution/src/System/Net/DnsEncodedName.cs New internal wire-format DNS name representation with compression pointer support and IDN conversion.
src/libraries/System.Net.NameResolution/src/System/Net/DnsMessageHeader.cs New DNS header encode/decode implementation.
src/libraries/System.Net.NameResolution/src/System/Net/DnsMessageReader.cs New sequential DNS message reader for header/questions/records.
src/libraries/System.Net.NameResolution/src/System/Net/DnsMessageWriter.cs New DNS query writer (header + question entries).
src/libraries/System.Net.NameResolution/src/System/Net/DnsRecordParsing.cs New typed record parsing helpers for common RDATA formats.
src/libraries/System.Net.NameResolution/src/System.Net.NameResolution.csproj Adds OSX TFM and wires Unix/OSX compilation of managed resolver components + OSX PAL + required references.
src/libraries/System.Net.NameResolution/src/Resources/Strings.resx Adds a new resource string for invalid DNS names.
src/libraries/Common/src/Interop/OSX/Interop.Dnssd.cs New OSX interop declarations for DNS-SD APIs used by the macOS PAL.

Comment on lines +4 to +5
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
Comment on lines +4 to +5
using System.Buffers;
using System.Net;
{
cancellationToken.ThrowIfCancellationRequested();

Interop.Error error = Interop.Sys.Poll(fileHandle, Interop.PollEvents.POLLIN, PollTimeoutMilliseconds, out Interop.PollEvents triggered);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It might be possible to implement async resolution by doing a ReceiveAsync on an empty buffer, instead of offloading to the thread pool.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants