When building the Apple's implementation of mDNS, aka. Bonjour, aka. mDNSResponder for a posix system (http://www.opensource.apple.com/tarballs/mDNSResponder/) [*]
On a clean Ubuntu 14.04
build box (with only build-essentials, g++
), the compiled examples fail to work, and report "bind: Address already in use"
.
On a clean Debian 7
build box (with only build-essentials, g++
), the compiled examples work, and do not report "bind: Address already in use"
.
What is going on here?
[*] which... is just riddled with bugs. For sanity, I suggest using versions 333.10, or 541, and applying patches from the umondo project: https://github.com/tklab-tud/umundo/tree/master/contrib/archives
The problem is due to the following difference in /usr/include/asm-generic/socket.h
The socket.h
in question is part of the linux-libc-dev
package.
In Debian
, socket.h
is from version 3.2.65
of linux-libc-dev
, and contains contains the commented line
/* To add :#define SO_REUSEPORT 15 */
On Ubuntu
, linux-libc-dev
is version 3.13.0
. socket.h
. Here, that line is no longer commented out:
#define SO_REUSEPORT 15
Of course, the problem is not with linux-libc-dev
, but the use of this macro, in mDNSPosix.c
, in particular, the lines:
#if defined(SO_REUSEPORT)
err = setsockopt(*sktPtr, SOL_SOCKET, SO_REUSEPORT, &kOn, sizeof(kOn));
#elif defined(SO_REUSEADDR)
err = setsockopt(*sktPtr, SOL_SOCKET, SO_REUSEADDR, &kOn, sizeof(kOn));
#else
#error This platform has no way to avoid address busy errors on multicast.
#endif
By just swapping the order, to prioritize SO_REUSEADDR
, there is no longer a socket binding issue. I.e.:
#if defined(SO_REUSEADDR)
err = setsockopt(*sktPtr, SOL_SOCKET, SO_REUSEADDR, &kOn, sizeof(kOn));
#elif defined(SO_REUSEPORT)
err = setsockopt(*sktPtr, SOL_SOCKET, SO_REUSEPORT, &kOn, sizeof(kOn));
#else
#error This platform has no way to avoid address busy errors on multicast.
#endif
Note: This change has not been tested in BSD
, which, if I understand correctly, should perhaps keep the priority in the order it was.