Zero configuration software
Implementations
This article describes implementations for the following
zero configuration technologies:
- RFC3927 for self-assigned IPv4 addresses
- mDNS for name lookup
- DNS-SD for service discovery
This is the same set of technologies implemented by default by Apple Computer on Mac OS X, since Mac OS 10.2 (till Mac OS 10.1 SLP was used for service discovery).
For this, we needed four pieces of software:
- IPv4LL code: needed for auto IP configuration
- kernel patches: needed for auto IP configuration
- mDNS software: needed for name lookup and discovery
- name lookup hooks: needed for name lookup
Self-Assigned IPv4 address (RFC3927) software
There are two possible approaches to implement self-assigned
IPv4 addresses. Best is to combine it with a DHCP client, and second-best it to put it in a stand-alone application. The advantage of combining it with a DHCP client is that is allows smooth transisition between link-local IP addresses (when no DHCP server is found) and routable IP addresses (when a DHCP server is available). Typically, for the stand-alone applications, a DHCP client is started at system boot time. If that fails (because no DHCP server could be found), the stand-alone application is run. Though this works fine for start-up, it does not deal with a situation where a DHCP server becomes available some time after system boot. Interaction between DHCP and self-assigned IP addresses is discussed in sections 1.9 and 2.11 of RFC3927, and Apple has advice on
mixing link-local and routable IP addresses∞.
RFC3927 implementations that are combined with a DHCP client are:
- Apple Darwin∞, in the bootp and Libinfo package (mostly in subpackage IPConfiguration in bootp)
- Microsoft Windows (not open source)
- Elvis Pfützenreuter has written a patch∞ for the uDHCP client/server∞
Stand-alone implementations are:
Note that the most (or even all?) of the stand-along packages originate from the same
code by Arthur van Hoff∞.
Kernel patches
Not all functionality described in RFC3927 can be handled in user-space, by the above implementations. Two following two requirements need to be handled in kernel-space (at least for relatively monolitic kernels like Linux):
- Broadcasting of ARP replies about 169.254/16 IP addresses. Normally, all ARP requests are broadcasted, and all ARP replies are unicasted. This aids timely conflict detection after network joins. See sections 2.5 and 4 of RFC 3927 for details.
- After forced reconfiguration of the IP address, existing (TCP) connections need to be closed for security reasons. See section 5 of RFC 3927 for details.
Though there is reported existing kernel patch to deal with broadcasting 169.254/16 ARP replies, we were unable to find it, and subsequently
wrote our own patch. David Daney was so kind to improve it and submit it as a
patch to the Linux kernel∞. I hope it will be implemented in the kernel anytime soon (i.e. around May 2006).
We are not aware of the status regarding closing of TCP connections after IP reconfiguration. In our opinion this problem is generic for giving up and IP address, not just IP addresses in the 169.254/16 range. So a kernel should always close existing TCP connections after an network interface stops listening to a certain IP address.
mDNS software
Like
IPv4 link-local addressing, the Multicast DNS (mDNS) and DNS Service Discovery (DNS-SD) are pioneered by Stuart Cheshire of Apple Computer. Both protocols use multicast name servers one every host to implement name lookup and service discovery,. In addition, DNS-SD can also use regular DNS servers (for, what is called "wide area bonjour" by Apple Computer). Given the very simular technical implementation, mDNS and DNS-SD are often implemented together. The most popular combination among application programmers is Apple's mDNSResponder, but more implemenations are available:
- mDNSResponder∞ (also known as Bonjour∞), an open-source implementation by Apple Computer, has interfaces for C and Java and is available on Mac OS X, Windows, and Linux. In addition, people have written interfaces in Python∞ and Ruby∞.
- Avahi∞, a free (LGPL) implementation of mDNS/DNS-SD for Linux
- Howl∞, a multiplatform mDNS/DNS-SD implementation based on Bonjour
- JmDNS∞ in Java
- Liaison∞
- mdnsd∞, embeddable Multicast DNS Daemon without DNS-SD
- pyZeroConf∞, Python service discovery
- tmdns∞, tiny multicast DNS, from the same project as ZCIP
- zeroconfd∞, developed during Google Summer of Code. There seems no download section though.
Name lookup hooks
Having the ability to use multicast DNS for name lookup on the local subnet is very convienant, but most applications to not know about multicast DNS. Of course it is possible to change applications, but it would be better to alter the UNIX socket library functions gethostbyname() and gethostbyaddr() to use multicast DNS, beside the regular DNS and optionally the /etc/hosts file. To be precise, we want the gethostby*() functions to use multicast DNS for queries regarding .local., 169.254.*.* or FE80:* addresses, and regular DNS for everything else.
There are at least two, and possible three way to do create these gethostby*() hooks.
- On Linux, the cleanest method is to change the behaviour of the Name Service Switch (which handles gethostby*() calls. Andrew White create libnss_mdns, which does exactly this thing. libnss_mdns is distributed with mDNSResponder∞ from Apple Computer.
- Secondly, you can run a name server on the localhost, listening to port 53 (and puting localhost in /etc/resolv.conf as the first name server). If it gets a link-local specific request, it will then forward this to port 5353 (multicast DNS). If not, it should return a failure, so that the next name server is used. tmdns∞ implements this solution, although the latest version (0.53) has a bug in this mechanism.
- There may be a third, poor man's solution, which is to run a regular name server on the localhost (e.g. bind) and let it forward link-local specific solutions to 224.0.0.251 port 5353. However, we never got that too work, and it's a incomplete solution, since a specific daemon also collects the answers from multiple hosts, and return them as a single reply to the original requester. Bind does not do such a thing, and only expects a single reply when it forwards requests.
Other References
This page is very simular in lay-out the the
WikiPedia ZeroConf entry∞, for the very reason that I
rewrote that entry∞ in this style in May 2005. Today the entry is less technical, so I put back some technical details here, and extended it with information regarding gethostby*() hooks and kernel patches.
More information on this wiki about
ZeroConf experiments can be found at
CategoryZeroconf.
There are no comments on this page. [Add comment]