Andrew Tunnell-Jones / Log
2019-10-03

DNS-SD APIs

This is a round up of the common DNS-SD APIs. Standalone embedded implementations such as JmDNS aren't included, the focus here is on platform APIs.

Android

Android has had the Network Service Discovery API since Android Jelly Bean 4.1 (API 16). However, TXT accessors have only worked since the Nougat (API 24) release which may be an issue for some applications. The API is built on Apple's open source mDNSResponder project so it is possible to work around this limitation by starting the NSD service and then using Apple's Java (or C dns_sd.h) API instead.

iOS and macOS

Apple as the progenitor of DNS-SD naturally have a number of APIs available. From low to high they are:

The MultipeerConnectivity and Network frameworks integrate DNS-SD as well.

Unix

Avahi is commonly available on most open source UNIX platforms. It offers C and DBUS APIs, for which there are bindings available in most programming languages. Avahi also offers a dns_sd.h compatible shim which, while it doesn't offer the full API or behave exactly as the original does, can be good enough for simple applications.

The mDNSResponder project's mdnsd and associated dns_sd.h API isn't as common as Avahi but is still often available, particularly on the BSD platforms.

Windows

Apple Bonjour, often installed with iTunes or Bonjour Print Services for Windows, was the only common(-ish) API available prior to Windows 10. An SDK makes the dns_sd.h API available to developers, however somewhat awkwardly, developers cannot redistribute Bonjour itself and so need to ask their users to install Apple's software along with their own.

Over the course of Windows 10 Microsoft have added several APIs. I'm not that familiar with the Windows world but as I understand it, there is the now deprecated Windows.Networking.ServiceDiscovery.Dnssd and the Windows.Devices.Enumeration APIs available to UWP apps. I haven't looked at either of these in any detail.

Since SDK 10.0.18362.0 windns.h also offers a DNS-SD API. It has a few shortcomings though. First, registering a service requires specifying a hostname and the only way to obtain the system's mDNS hostname is to do a reverse lookup. Clumsy, but workable. More of an issue is that browse callbacks are only invoked once instead of whenever a service appears or disappears from the network. This could be worked around with a query, however multicast queries do not seem to be consistently updated as RRSets change. It's difficult to recommend building on this API today. Hopefully it'll improve in a future release.