This is an old revision of the document!
MulticastDNS mdnsd
Status: Able to receive and cache records.
Parts completed
- Low level stack, both IPv4 and IPv6 (multicast join/leave, buffer management, packet (de)construction).
- Automatic interface add/remove, address add/remove, link state aware.
- Record cache.
Goals
- Implement all MUST and SHOULD parts of draft-cheshire-dnsext-multicastdns.txt
- Should pass Apples Bonjour Conformance Test
- Expose a low-level client API through local UNIX sockets.
- Should handle interface addition/removal automatically.
- Should handle ip-address addition/removal automatically.
- Must support IPv6
Design
This is the overall principle, clients (programs) performs queries through a local unix socket to the responder daemon which in turn performs these queries on the network and provides a cache of previously asked records.
[Other mDNS responders] <--network (mdns protocol)--> [responderd] <--unix sockets--> [clients]
The responder itself is multi-threaded using a simple work-queue scheme. This has the advantage that threads can be completely disabled on systems where libpthread or threads in general aren't desired (small embedded systems in particular), while at the same time has the ability to take advantage of modern multicore processors.
This is some ugly ascii to demonstrate the general data flow with in the application
__________
--> [work queue] <---------[event dispatcher] <--I/O ready signal--- | |
| ___|_____ | NETWORK |
----| Workers | <--------------------- read from fdX----------------- | |
|w0,w1,wn | | |
|_________| ------------------> [output queue] --- write fdX ---> |__________|
The event dispatcher is implemented on top of kqueue(), it's used both for I/O ready signals and general timers. The purpose of the output queue is to aggregate several responses into one mdns packet (multicast allows packet sizes as large as the MTU of the network with an upper limit of 9000 bytes).
Static configuration
Configuration of “static” hosts will be done using /etc/responderd.conf (other name?)
This is an example of what an configuration file could look like. All variables are expanded and auto-updated when something changes. interface * should be read as “for every interface”. interface ath0 means “only interface ath0”. All resources are claimed unique on the network except those inside a “shared” section.
interface * {
"$(hostname).local." A $(ifaddr)
$(ifaddr) PTR "$(hostname).local."
"$(hostname).local" HINFO "$(cpu) ! FreeBSD $(osrelease) $(arch)"
shared {
"$(hostname).local" TXT "foo"
}
}
interface ath0 {
"$(hostname).local." AAAA $(ifaddr)
$(ifaddr6) PTR "$(hostname).local."
}
Too complicated? Or should the configuration be in XML?