systemd-resolved-rs 0.1.1

A compatibility-oriented reimplementation of systemd-resolved
# Compatibility ledger

A checked item means a concrete implementation exists in the current tree. It
does not, by itself, establish complete upstream parity or sufficient test coverage. The project must not be
described or installed as a drop-in replacement until every release-validation
gate at the end of this document passes against the pinned upstream baseline.

## Build integrity

- [x] Rust package paths have concrete library and binary sources
- [x] C and Fortran ABI declarations agree at the repository boundary
- [x] current `main` passes Rust 1.74 and stable formatting, Clippy, tests, and release builds
- [x] Idris 2 and Agda modules pass with pinned compiler versions
- [x] Reproducible release build and package manifest are verified

## Local resolver interfaces

The pinned D-Bus signatures live in `compat/`.

- [x] UDP DNS listener on `127.0.0.53`
- [x] TCP DNS listener on `127.0.0.53`
- [x] proxy-mode UDP/TCP listener on `127.0.0.54`
- [x] `DNSStubListener=` UDP/TCP modes and independent `DNSStubListenerExtra=` sockets
- [x] generated stub and uplink `resolv.conf` files
- [x] live `org.freedesktop.resolve1` Manager and Link objects match the pinned introspection manifests
- [x] live DNS-SD registration with automatic D-Bus owner-lifetime withdrawal
- [x] DNS delegate file/drop-in loading, split-DNS/default routing, firewall-marked transports, D-Bus objects, and Varlink configuration
- [x] core `ResolveHostname`, `ResolveAddress`, `ResolveRecord`, and `ResolveService` Varlink methods
- [x] D-Bus and Varlink result provenance for synthetic, hook, cache, unicast-network, LLMNR, and mDNS answers
- [x] D-Bus and Varlink request validation plus protocol, synthesis, cache, stale, network, search, single-label, and CNAME controls
- [x] pinned D-Bus lookup argument errors, resolver-state error names, and post-CNAME service canonical filtering
- [ ] complete `io.systemd.Resolve` Varlink flags, errors, and service semantics
- [x] pinned Varlink hostname/address family errors and record class, invalid-type, zone-transfer, and obsolete-type dispatch contracts
- [x] pinned Varlink strict parameter/null-sentinel/name dispatch, UTF-8/IDNA protocol questions and DNS-SD instance escaping, post-CNAME record filtering, parallel SRV/TXT partial-success handling, service canonical-owner metadata, unrelated-answer exclusion, reply-only service flags, high-level refused-query errors, reload-aborted queries, DNSSEC RR unsupported state, maximum-attempt state, and stub-loop rejection
- [x] pinned hook IDNA-first question merging and deduplication for UTF-8/IDNA, A/AAAA, and SRV/TXT query sets across D-Bus and Varlink lookups
- [x] `io.systemd.Resolve.Monitor` Varlink interface
- [ ] complete `resolvectl` command and output compatibility
- [x] `resolvectl` per-link text/JSON configuration queries, monitor readiness/JSON output, and bounded `resolvconf` add/delete/private/exclusive compatibility
- [x] `resolvectl query` type/legend options, typed A/AAAA text and short JSON, SVCB/HTTPS ALPN and IPv4-hint formatting, and structured Varlink A/AAAA records
- [x] pinned `resolvectl query` rendering for refused record types, DNS rcodes, missing records, and DNSSEC extended errors
- [x] `resolvectl` pinned verb arity, protocol/type/class help legends, and complete named RR-type rendering
- [x] `resolvectl` systemd boolean spellings and kernel-validated main, alternative, and numeric interface identifiers
- [x] installed `systemd-resolve` and `resolvconf` multicall aliases with argv/environment detection, legacy query modes, link setters, and nonblocking delete/no-op operation
- [x] NSS policy environment, main/alternative/numeric interface scope, family filtering, canonical names, link-local scope IDs, untruncated result packing, legacy IPv6 preference, and upstream error classes
- [x] NSS signal masking, query deadline, depth-aware Varlink reply validation, malformed-schema rejection, and caller `errno` preservation
- [x] NSS compatibility mode keeps shared-memory and direct-stub extensions opt-in
- [x] glibc dynamically loads the candidate `libnss_resolve.so.2` and resolves through its Varlink path
- [ ] NSS integration parity with `nss-resolve`
- [x] `libnss_resolve.so.2` exports only the six pinned glibc NSS entry points with the upstream SONAME and hardened linkage

## DNS engine

- [x] bounded DNS name decompression with loop and forward-pointer rejection
- [x] request and response section-bound validation
- [x] A, AAAA, and PTR local answers
- [x] `/etc/hosts` forward and reverse answers
- [x] localhost, numeric-address, `_localdnsstub`, and `_localdnsproxy` synthesis
- [x] UDP forwarding with transaction and question validation
- [x] pinned question-type validation plus unicast query truncation and answer-section rejection
- [x] TCP fallback after a truncated UDP response
- [x] repeated UDP-loss fallback to TCP, TCP-loss recovery to UDP, and truncated-response transport telemetry
- [x] bounded positive and negative cache with TTL aging
- [x] RFC 2308 negative lifetime from SOA TTL and MINIMUM
- [x] optional stale-answer retention with zeroed TTLs
- [x] TSIG-bearing response cache exclusion
- [x] in-answer CNAME and DNAME redirect-chain validation
- [x] cross-transaction CNAME and DNAME follow-up for high-level lookups with loop detection and the upstream 16-redirect limit
- [x] accumulated redirect-chain record reporting and source-provenance flag merging
- [ ] complete redirect authentication, confidentiality, authority, and error parity
- [x] EDNS0/DO feature negotiation with per-server retry downgrade, exponential recovery grace periods, adaptive UDP sizing, RFC 6975 algorithm signaling, same-level SERVFAIL retry, and EDE-aware downgrade suppression
- [x] root-domain RRSIG omission detection with a persistent per-server DO clamp, allow-downgrade retry, and strict-mode failure
- [x] adaptive MTU/fragment-size advertisement and fragmented-EDNS TCP retry
- [x] upstream DNS retry budget and default timing: 24 emissions, 120-second overall deadline, 5-second UDP windows, and 10-second TCP windows
- [ ] TLS feature levels
- [x] strict DNS-over-TLS keeps EDNS0 as its packet-feature floor while allowing DNSSEC DO downgrade to TLS+EDNS0
- [x] complete resource-record validation and compression expansion
- [x] pinned v261 structured RDATA validation, class/type rejection, high-bit TTL normalization, SVCB parameter validation, and DNSSEC bitmap validation
- [x] compression-free Varlink raw export for NS, CNAME, SOA, PTR, MX, SRV, DNAME, NAPTR, RRSIG, NSEC, SVCB, and HTTPS RDATA names
- [x] concurrent identical transaction coalescing with per-client ID restoration and one-upstream regression coverage
- [x] parallel queries across equivalent scopes
- [x] reusable per-upstream UDP and TCP pools with exclusive leasing, bounded idle retention, and stale-TCP reconnect

## Secure and local-link protocols

- [ ] DNSSEC validation and trust-anchor management
- [x] pinned positive/negative trust-anchor ancestry precedence and trust-anchor record comment syntax
- [x] DNS-over-TLS opportunistic and strict modes
- [x] dual-stack LLMNR UDP/TCP resolver and responder with live forward, TCP-only reverse, truncated-UDP fallback, and anti-spoofing coverage
- [x] MulticastDNS resolver and responder
- [x] DNS-SD registration and browsing
- [x] pinned DNS-SD zero/invalid port handling and per-file load failure boundaries
- [x] pinned `BrowseServices` empty-type direct-owner semantics
- [x] DNS-SD instance-label case preservation on the wire and in browse updates
- [x] live kernel-hostname use when `/etc/hostname` is hidden or unavailable

## Routing and configuration

- [x] core `resolved.conf` list, boolean, mode, size, and duration parsing
- [x] layered `resolved.conf.d` file selection
- [x] global and fallback upstream selection
- [x] route-only and search-domain representation
- [x] `/etc/resolv.conf` uplink discovery with local-stub exclusion
- [x] SIGHUP hosts-database reload
- [x] ordered search-domain candidate expansion with route-only exclusion
- [ ] live configuration reload parity
- [x] SIGHUP reload disconnects DNS transports, flushes every protocol cache, resets non-link server state, and republishes runtime configuration
- [x] inherited per-link DNSSEC and DNS-over-TLS policy follows manager reloads while explicit D-Bus and networkd policy remains stable
- [x] reload parsing ignores invalid assignments and tokens, resets unreadable configuration to defaults, and preserves explicit fallback-server replacement semantics
- [x] per-link DNS state from D-Bus
- [x] RTNL synchronization of kernel link, address, carrier, operstate, and MTU state
- [x] live systemd-networkd managed DNS/domain/default-route/protocol/security-mode synchronization
- [x] longest-suffix routing integrated with per-link scopes
- [x] longest-suffix and explicit default-route selection integrated with independent DNS delegate scopes
- [x] default-route link inference
- [x] split-DNS parallel scope behavior
- [x] interface binding and scoped IPv6 upstreams
- [x] credential-based `network.dns` and `network.search_domains` configuration with explicit-setting precedence
- [x] exact-name static `.rr` A, AAAA, PTR, NS, CNAME, and DNAME records with drop-in precedence, `/dev/null` masking, bounded reads, and two-second rechecks
- [x] `ReadStaticRecords=` text-configuration toggle
- [ ] complete static-record diagnostics parity

## Service behavior

- [x] systemd readiness, reload, status, and stopping notifications
- [x] hardened service unit and runtime directory
- [x] privileged port operation through service capabilities
- [x] bounded Varlink framing and peer-credential checks for maintenance calls
- [x] D-Bus sender and Varlink connection lifetime tracking aborts abandoned resolver transactions without cancelling unrelated clients
- [x] action-specific Varlink PolicyKit authorization with pidfd and UID subjects
- [x] named `io.systemd.Resolve` Varlink socket activation
- [x] named `io.systemd.Resolve.Monitor` Varlink socket activation
- [ ] complete upstream socket-activation edge-case contract
- [x] named Varlink activation accepts multiple listeners and connected sockets while ignoring unrelated descriptors
- [x] watchdog keepalive
- [x] privilege-drop parity when launched directly as root
- [x] pinned service D-Bus implementation listing and XML through `--bus-introspect`
- [x] complete `systemd-resolved` help, version, bus-introspection, positional-argument, and option-error compatibility
- [x] D-Bus PolicyKit policy and authorization for the pinned v261 mutating operations

## Required release validation

- [ ] upstream `TEST-75-RESOLVED` passes unmodified
- [ ] upstream mDNS and resolver-adjacent unit suites pass unmodified
- [x] live Manager and Link D-Bus introspection matches the pinned upstream manifests
- [x] Varlink schemas and error identifiers match the pinned v261 inventory
- [ ] `resolvectl` behavioral and output corpus matches
- [ ] packet parser passes upstream and independent fuzz corpora
- [x] sanitizer, Miri, Valgrind, and race-test runs are clean
- [ ] failover, suspend/resume, network churn, VPN split-DNS, and captive-portal scenarios pass
- [ ] clean install, upgrade, rollback, and recovery procedures pass
- [ ] no unresolved high- or critical-severity security findings remain