POSIX Bonjour/mDNSResponder 测试示例在 Ubuntu 上报告 "bind: Address already in use",但不是 Debian

POSIX Bonjour/mDNSResponder test examples report "bind: Address already in use" on Ubuntu, but not Debian

在构建 Apple 的 mDNS 实现时,又名。 Bonjour,又名。 posix 系统的 mDNSResponder (http://www.opensource.apple.com/tarballs/mDNSResponder/) [*]

这是怎么回事?

[*] 这...只是充满了错误。为了理智,我建议使用版本 333.10 或 541,并应用来自 umondo 项目的补丁:https://github.com/tklab-tud/umundo/tree/master/contrib/archives

问题是由于 /usr/include/asm-generic/socket.h

中的以下差异造成的

有问题的 socket.hlinux-libc-dev 包的一部分。

Debian 中,socket.h 来自 linux-libc-dev 的版本 3.2.65,并且包含注释行

/* To add :#define SO_REUSEPORT 15 */

Ubuntu 上,linux-libc-dev 是版本 3.13.0socket.h。在这里,该行不再被注释掉:

#define SO_REUSEPORT    15

当然,问题不在于 linux-libc-dev,而是在 mDNSPosix.c 中使用此宏,特别是行:

#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

通过交换顺序,确定优先级 SO_REUSEADDR,不再存在套接字绑定问题。即:

#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

注意:此更改尚未在 BSD 中进行测试,如果我理解正确,可能应该保持优先级不变。

您正在 运行 了解 SO_REUSEADDR 和 SO_REUSEPORT 之间的差异。

SO_REUSEPORT 是在后来的 Linux 内核中引入的,Ubuntu 系统映像似乎支持它。查看 this 问题,了解您可能想知道的关于 REUSADDR/REUSEPORT.

的所有信息

REUSEADDR 和 REUSEPORT 之间的行为差​​异在于 REUSEPORT 对尝试重用同一端口的套接字施加了更多限制:它们都必须设置选项并存在于同一进程中。 REUSEADDR 不是这种情况。

是否有可能您的 Ubuntu 图像也 运行 正在使用另一个像 avahi 这样的 mDNS 守护进程?您可以运行 netstat 诊断系统中其他绑定的套接字以识别端口冲突