Hello, This isn't strictly about Avahi, but I have some questions to ask and assertions I'd like to validate. What's led me down the rabbit hole of Zeroconf, mDNS, DNS-SD, and friends is out of interest in making stuff easy to use. For a specific example, GeoClue is configured to look for services of type _nmea-0183._tcp to find services providing real-time geopositioning information. This is a one-way data feed; the server simply sends a few lines of US-ASCII every second and anything sent by the client can be ignored. Using UDP over multicast would be a lot more efficient and better support the need for low latency, so I've been researching how to do this. Many of you likely already know much of what follows, but I'd like to know if I got anything wrong.
Pertinent standards such as POSIX at https://pubs.opengroup.org/onlinepubs/9799919799/functions/V2_chap02.html#tag_16_10_20_04 define much of what's needed to use IPv6 multicast, including the IPV6_JOIN_GROUP socket options. When some protocol or application always uses some fixed multicast address that can be determined ahead of time, like the one for mDNS given by https://www.iana.org/assignments/ipv6-multicast-addresses/ipv6-multicast-addresses.xhtml#xpointer(/html/body//table[@id="table-link-local"]/tbody/tr/td[text()="mDNSv6"]/..) then this may be all that is needed. However many applications only need a transient multicast address, or they're too esoteric to warrant an IANA registration (perhaps because interoperability with another implementation isn't a concern). The question then is how should one "make up" a multicast address on-the-fly? One perk of using these IANA-assigned addresses is that the protocol or purpose for some multicast group is already tied to the address. If you want to send a message using SIP to anyone on your link that's listening, just send a datagram to FF02::175. This differs when using a dynamic multicast address. Consider, for my use case, if I had a GNSS receiver getting geolocation information and wanted to share it on the local link as a server. Even if I come up with a multicast address on-the-fly for this purpose, how will clients know to find me? Fortunately this is just a service discovery problem and Avahi can solve it in the same way as for the TCP service case: I can publish _nmea-0183._udp DNS-SD information and based on the IPv6 address format it's clearly a multicast address. Therefore any prospective clients can just join the group and listen for datagrams on the port designated by the SRV record. There are, of course, other methods of announcing and discovering services than just DNS-SD. Any of those mechanisms ought to work to announce the birth of a multicast group for some use case, even in conjunction with DNS-SD, so it's easy to make such a service discoverable. That means there's only one problem for application writers left: how do you get a dynamic multicast address anyway? An application wishing to make a new group should have a convenient way to do this, but as far as I know, there's not any way for an application on GNU/Linux to do this correctly. I couldn't even find a maintained third-party library after searching. There are a couple different network protocols to solve this address allocation problem (more on those in a moment), but is there any libre code that's able to use any of them? The informational RFC 2771 (from the year 2000, before I was born!) articulates "An Abstract API for Multicast Address Allocation". This document only uses pseudocode and is intentionally programming-language-agnostic, but describes the considerations needed to make an API for application instances to get multicast addresses to call their very own. Despite its age, that document appears to still be a very good role model for what an API should look like. It also demonstrates such an API can be designed so the particular means by which an address is allocated is an implementation detail. Application writers generally aren't concerned with how an appropriate address is obtained and for the sake of portability this should be done however the operating system or environment sees fit. The most well-established scheme for multicast address allocation is MADCAP, which works in a DHCP-like way with a central server that's authoritative over the scope in question and gives out leases. This looks like the way Windows has gone, and in fact, Microsoft has a C/C++ API for this: https://learn.microsoft.com/en-us/windows/win32/api/madcapcl/ and despite the name of the header, the function names read as "multicast request address", "multicast release address", and so forth. This is more DHCP-like than SLAAC-like which one might say is ugly in the year 2025, but if that works for them (and I do believe it does in a Windows Server/Active Directory business environment with Windows machines providing compatible DHCP and MADCAP server implementations), that's good for them. That Windows API doesn't seem to have any MADCAP assumptions baked into it and instead is more generic like RFC 2771, so if it helps adoption by libre applications, maybe an API-compatible shim could be helpful? (I wonder if Winelib—which is like Cygwin in reverse, to allow compiling Windows application source code for Unix-like systems—has this.) As recently as this year the informational internet draft "Multicast Lessons Learned from Decades of Deployment Experience" has analyzed what's gone wrong and caused trouble for uptake of multicast outside specialized environments. At https://www.ietf.org/archive/id/draft-ietf-pim-multicast-lessons-learned-05.html#name-dynamic-multicast-group-add the authors make quite clear that MADCAP isn't the goal to set sight on anymore: "It was later determined that multicast addresses really should be dynamically assigned by a decentralized, and zero configuration, protocol for many of todays environments." The two strongest options for moving forward are the Zeroconf Multicast Address Allocation Protocol (ZMAAP), which has been in various drafts for decades, and the new Group Address Allocation Protocol (GAAP). Hereafter I'll focus on the former, but I do wonder where in the GNU/Linux network stack an implementation of the latter might sit. A very old draft for ZMAAP is at https://datatracker.ietf.org/doc/draft-ietf-zeroconf-zmaap/ but the only reason I mention this older version is because "An API for the Zeroconf Multicast Address Allocation Protocol (ZMAAP)" https://datatracker.ietf.org/doc/draft-ietf-zeroconf-zmaap-api/ was also jointly published. That draft builds on the "abstract API" mentioned before and actually makes it concrete with C and Java interfaces. Please correct me if I'm wrong, but to the best of my knowledge there aren't any actual implementations of this, at least not surviving ones for GNU/Linux. The document is slightly misnamed; a more accurate title would be something like "An API for Mulicast Address Allocation with Due Consideration for the Capabilities of ZMAAP". As they say, "It should be transperant [sic] to the API whether the allocations are done using ZMAAP, MADCAP or some other mechanism." From a brief skim the C API looks decent, except their data structures use some not-POSIX-like conventions. In the 25 years since the document was published a very good consensus (even with Windows) has been formed about the use of data types and modernizing the interfaces would be nice. In particular: • 'struct sockaddr' is used with the intent of holding both IPv4 and IPv6 addresses; 'struct sockaddr_storage' should be used instead • they store the address family separately from the socket address structures which is unnecessary, but also define the constants '1' for IPv4 and '2' for IPv6; the (struct sockaddr){}.sa_family member should suffice and allow using AF_INET, AF_INET6, etc. constants as usual But in general, this API is the closest thing to exactly what I need to write a nice multicast application. (Well, an actual implementation will be needed too, but don't ruin my dream…) Both that draft for ZMAAP and the one for the proposed C/Java APIs are from 2000 and long dead, but an active standards-track internet draft (yes, not expired!) for the ZMAAP protocol is available at https://datatracker.ietf.org/doc/draft-ietf-pim-ipv6-zeroconf-assignment/ and there's also a statement of exactly the problems it solves at https://datatracker.ietf.org/doc/html/draft-ietf-pim-zeroconf-mcast-addr-alloc-ps In their usage of the term, they use "zeroconf" basically as a synonym for Multicast DNS. There are other tools under the umbrella of zero configuration, and strictly speaking, the alternative Group Address Allocation Protocol (GAAP) is probably one of them. ZMAAP really should be on the radar of Avahi folks, and in fact, I think the right place for an implementation is in Avahi directly. The method involved is basically to synthesize a name under the 'eth-addr.arpa.' DNS zone and use Multicast DNS with the appropriate scope to detect collisions. Because it's a bad idea to try running multiple mDNS stacks—as remarked in avahi-daemon.conf(5)—any ZMAAP implementation will need to go through whatever daemon has taken up responsibility for mDNS, be it Avahi, systemd-resolved, or otherwise. Additionally, as I described much earlier in this mail with regards to the "service discovery problem" for applications wanting to join dynamic multicast groups that might've already been created, many multicast applications will want Avahi's help to publish DNS-SD records anyway. Lastly, for some use cases where you want everyone to converge on the same dynamic multicast group (perhaps a multiplayer video game that lets players drop in and out at any time), there could be race conditions or quirks from separating checks for an established multicast group for an application versus deciding to allocate an address and spawn your own. (For example an application may ask Avahi to "see if there's already a group for _bingo._udp, but if there's not, then I must be the first one here so let's set one up".) In conclusion, I've been puzzled trying to make a mostly-custom application using multicast and I asked "How do other libre applications pick their multicast addresses for their own usage?". The conclusion I've drawn is "They don't." I couldn't find any modern information about real-world existing practice for these sorts of problems, so I've espoused it here for future reference and so you can tell me what I got wrong. Otherwise it looks like Avahi should provide an API for multicast address allocation, concentrating on ZMAAP, and which need not match the existing and proposed APIs but may still borrow inspiration from them. I don't mean to "voluntell" the Avahi developers what to do but instead articulate a problem statement and solution idea so it can be consciously accepted or declined. Thanks, John
signature.asc
Description: This is a digitally signed message part
smime.p7s
Description: S/MIME cryptographic signature
