Примеры тестов POSIX Bonjour/mDNSResponder сообщают о привязке: адрес уже используется в Ubuntu, но не в Debian


person swalog    schedule 27.02.2015    source источник


Ответы (2)


Проблема связана со следующей разницей в /usr/include/asm-generic/socket.h

Рассматриваемый socket.h является частью пакета linux-libc-dev.

В Debian socket.h относится к версии 3.2.65 из linux-libc-dev и содержит закомментированную строку.

/* To add :#define SO_REUSEPORT 15 */

На Ubuntu linux-libc-dev версия 3.13.0. socket.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, что, если я правильно понимаю, должно сохранить приоритет в том порядке, в котором он был.

person swalog    schedule 27.02.2015
comment
Причина, по которой я добавляю это сюда, заключается в том, что эта проблема, а также несколько других ошибок компиляции, которые невозможно передать (смотря на вас mDNSShared/dnssd_clientshim.c), сохранялись в библиотеке bonjour в течение многих лет. Сомнительно, что отчет об ошибке своевременно исправит еще одну такую ​​​​ошибку. - person swalog; 27.02.2015

Вы сталкиваетесь с различиями между SO_REUSEADDR и SO_REUSEPORT.

SO_REUSEPORT был представлен в более поздних ядрах Linux, и похоже, что образ системы Ubuntu поддерживает его. Взгляните на этот вопрос, чтобы узнать все, что вы хотели знать о REUSADDR/REUSEPORT.

Поведенческие различия между REUSEADDR и REUSEPORT заключаются в том, что REUSEPORT накладывает больше ограничений на сокеты, пытающиеся повторно использовать один и тот же порт: все они должны иметь установленную опцию и существовать в одном и том же процессе. Это не относится к REUSEADDR.

Возможно ли, что на вашем образе Ubuntu также работает другой демон mDNS, такой как avahi? Вы можете запустить netstat для диагностики других связанных сокетов в системе, чтобы определить конфликты портов.

person Joel Cunningham    schedule 14.04.2015