mdns-sd-discovery
Access the operating system's built-in DNS-SD / mDNS stack for service discovery.
This crate provides a cross-platform async API (using Tokio) to browse DNS-SD services via native OS facilities — no bundled mDNS implementation, no extra system dependencies to install. Service registration lives in a separate crate.
Platform Support
| Platform | Backend | Minimum Version |
|---|---|---|
| macOS | native DNS-SD framework | macOS 10.12 |
| Windows | native Win32 DNS-SD API | Windows 10 |
| Linux / BSD | Avahi via D-Bus | Avahi daemon running |
- macOS and Windows link against system libraries that are always present on supported OS versions.
- Linux/FreeBSD communicate with Avahi over D-Bus — there is no binary dependency on
libavahior the Bonjour compatibility layer. Binaries will run on systems without Avahi installed but return an error when attempting to browse.
Why Use the OS Stack?
There exist various crates implementing DNS-SD/mDNS in pure Rust. Compared to these, using the operating system's DNS-SD stack has the following benefits:
- Battle-tested: OS stacks have been tested widely over many years (sometimes decades) to handle OS-dependent edge cases (sleep/wake, interface changes) properly
- Shared cache: all applications on the system share a single DNS-SD/mDNS responder & cache, reducing network traffic and keeping answers consistent.
- Smaller binary: no embedded mDNS responder; just thin FFI/D-Bus bindings.
There also exist various crates implementing a wrapper on top of the Apple DNS-SD API, which is natively available on macOS, but only on
Windows if users install Bonjour for Windows, and on Linux if the libavahi-compat-libdnssd library is installed. Compared to these, this
crate requires no additional dependencies to install for end users.
Examples
Browse for services
By default a ServiceBrowser discovers all service types on the network; filter on
DiscoveredService::service_type, or narrow to a single type with .service_type("_http._tcp").
use ;
async
Re-confirm a service is still alive
ServiceResolverBuilder resolves a single, already-known instance now, mapping
the identity fields from a previous browse event back to a connectable
DiscoveredService. A vanished instance fails with
ServiceBrowseError::ResolveFailed (rather than hanging), making it a useful
liveness probe — handy for the no-goodbye case where a host powered off or
dropped off the network without multicasting mDNS goodbye packets, so no
Removed event is delivered until the browse PTR record's (long) TTL expires.
use ;
use Duration;
async
See the examples/ directory for a full CLI tool that browses
(discover-service) services; pass --resolve NAME --type _http._tcp to probe a
single instance instead.
Platform note: on Windows, service removal (
BrowseEvent::Removed) is not currently reported; appearances and resolution are. Removal events are delivered on macOS and Linux.