Потребовалось сделать в приложении анонсирование и поиск себе подобных. Причём без завязки на системный Avahi.
Выбор пал на три реализации mDNS/DNS-SD:
Первый отбросил из рассмотрения, так как показался слишком переусложнённым. Потом пошёл смотреть на libmicrodns - получилось собрать прототип очень быстро - мало кода. Но… жирный крест поставило то, что они до сих пор не исправили косяк, что нужно JOIN TO GROUP делать. Без этого анонсирование работает нормально, а вот запросы/поиск будет только на неком дефолтном, первом интерфейсе.
Пошёл на mdns. Для интеграции нужно больше кода, но почти весь можно как есть взять из примера mdns.c, библиотека без внутренних аллокаций. И очень неплохо дружится с внешними event-loop’ами, будь то libev или asio.
В общем, мой выбор - mdns.
А под катом - небольшая табличка сравнительная. Жирным - критерий преобладающий над соперником. Если ничто не выделено - нет приоритета.
Критерий | libmicrodns | mdns |
---|---|---|
Лицензия | LGPL v2.1 | Public Domain |
Уровень входа | нужно мало кода | кода нужно больше, но почти весь из примера (*) |
Асинхронное использование | нет | да (**) |
Поиск на всех интерфейсах | нет (***) | да |
Внутренние аллокации | да | нет |
Header-only | нет | да |
- (*) код берётся из примера и в целом, вполне себе пишется один раз и используется на остальных проектах. Плюс колбеки с очень развесистым набором аргументов.
- (**) возвращается
int
непосредственно полученный от вызоваsocket()
, что на том же Windows выглядит какSOCKET
, и он же -HANDLE
, плюс включенный флаг**WSA_FLAG_OVERLAPPED**
, и как следствие на том же Boost.Asio / Asio его вполне можно завернуть в UDP сокет для асинхронной обработки:
asio::ip::udp::socket sock{ioctx, asio::ip::udp::v4(), mdns_socket_open_ipv4(&sock_addr)};
asio::ip::udp::socket sock{ioctx, asio::ip::udp::v6(), mdns_socket_open_ipv6(&sock_addr)};
- https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-socket
- https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasocketa libmicrodns только в треде запускать и слушать запросы.
- (***) они почему-то не делают
IP_MULTICAST_IF
, хотя баги с прослушиванием все интерфейсов у них были, и вроде как закрыты.