Implement DnsResolver for macOS#131152
Conversation
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
|
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. |
|
Tagging subscribers to this area: @karelz, @dotnet/ncl |
There was a problem hiding this comment.
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.OSXbacked by DNS-SD, plus OSX interop declarations forDNSServiceQueryRecordAPIs. - 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.confparsing).
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. |
| using System.Diagnostics; | ||
| using System.Diagnostics.CodeAnalysis; |
| using System.Buffers; | ||
| using System.Net; |
| { | ||
| cancellationToken.ThrowIfCancellationRequested(); | ||
|
|
||
| Interop.Error error = Interop.Sys.Poll(fileHandle, Interop.PollEvents.POLLIN, PollTimeoutMilliseconds, out Interop.PollEvents triggered); |
There was a problem hiding this comment.
It might be possible to implement async resolution by doing a ReceiveAsync on an empty buffer, instead of offloading to the thread pool.
Builds on #129846. Draft until 129846 merged.
/cc @rzikm