Esta biblioteca proporciona una biblioteca mDNS y DNS-DS multiplataforma de encabezado solo en C. El código fuente más reciente siempre está disponible en
https://github.com/mjansson/mdns
Esta biblioteca es de dominio público; puedes redistribuirlo y/o modificarlo sin restricciones.
Creado por Mattias Jansson (@maniccoder)
Servidor de Discord para discusiones https://discord.gg/M8BwTQrt6c
La biblioteca realiza descubrimiento y servicio DNS-SD, así como consultas y respuestas mDNS de registro único de una sola vez. La biblioteca no realiza asignaciones de memoria; la persona que llama debe pasar todos los búferes utilizados. Los datos personalizados para su uso en el procesamiento se pueden transmitir mediante un puntero opaco de datos de usuario.
El archivo ejecutable de prueba mdns.c
demuestra el uso de todas las funciones, incluido el descubrimiento, la consulta y la respuesta del servicio. La documentación aquí es intencionalmente escasa, el código de ejemplo está bien documentado y debe proporcionar todos los detalles.
La biblioteca puede abrir el socket para la comunicación mDNS usando mdns_socket_open_ipv4
o mdns_socket_open_ipv6
, o inicializando un socket existente con mdns_socket_setup_ipv4
o mdns_socket_setup_ipv6
. Las funciones de apertura/configuración del socket inicializarán el socket con membresía de multidifusión (incluido el bucle invertido) y lo establecerán en modo sin bloqueo.
Llame mdns_socket_close
para cerrar un socket abierto con mdns_socket_open_ipv4
o mdns_socket_open_ipv6
.
Para abrir/configurar el socket para consultas de una sola vez, puede pasar una dirección de socket de puntero nulo o establecer el puerto en la dirección del socket pasada en 0. Esto vinculará el socket a un puerto UDP local efímero aleatorio según lo requieren los RFC para consultas de una sola vez. NO debe vincularse al puerto 5353 al realizar consultas únicas (consulte el RFC para obtener más detalles).
Para abrir/configurar el socket para el servicio, respondiendo a consultas entrantes, necesita pasar una estructura de dirección de socket con el puerto configurado en 5353 (definido por MDNS_PORT en el encabezado). No puede elegir ningún otro puerto o no recibirá ninguna consulta entrante.
Para realizar descubrimientos o consultas en la interfaz de red predeterminada, puede pasar un puntero nulo como dirección de socket en las funciones de creación/configuración de socket. Esto vinculará el socket a la interfaz de red predeterminada. De lo contrario, debe enumerar las interfaces disponibles y pasar la dirección de socket adecuada a la función de creación/configuración. Consulte el programa de ejemplo en mdns.c
para ver una implementación de ejemplo de cómo hacer esto tanto para IPv4 como para IPv6.
Si desea realizar una respuesta de servicio mDNS a consultas entrantes, no necesita enumerar las interfaces para realizar una respuesta de servicio en todas las interfaces, ya que los sockets reciben datos de todas las interfaces. Consulte el programa de ejemplo en mdns.c
para ver un ejemplo de configuración de un socket de servicio tanto para IPv4 como para IPv6.
Para enviar una solicitud de descubrimiento de servicio DNS-SD, utilice mdns_discovery_send
. Esto enviará un único paquete de multidifusión (registro de pregunta PTR único para _services._dns-sd._udp.local.
) solicitando una respuesta de unidifusión.
Para leer las respuestas de descubrimiento, utilice mdns_discovery_recv
. Todos los registros recibidos desde la última llamada se canalizarán a la devolución de llamada proporcionada en la llamada a la función. El tipo de entrada será uno de MDNS_ENTRYTYPE_ANSWER
, MDNS_ENTRYTYPE_AUTHORITY
y MDNS_ENTRYTYPE_ADDITIONAL
.
Para enviar una consulta mDNS única para un solo registro, utilice mdns_query_send
. Esto enviará un único paquete de multidifusión para el registro y el nombre dados (por ejemplo, registro PTR para _http._tcp.local.
). Opcionalmente, puede pasar un ID de consulta para el filtrado posterior de las respuestas (aunque el RFC no lo recomienda), o pasar 0 para que sea totalmente compatible. La función devuelve el ID de consulta asociado con esta consulta, que si es distinto de cero se puede usar para filtrar respuestas en mdns_query_recv
. Si el socket está vinculado al puerto 5353, se solicita una respuesta de multidifusión; de lo contrario, se solicita una respuesta de unidifusión.
Para leer las respuestas a una consulta, utilice mdns_query_recv
. Todos los registros recibidos desde la última llamada se canalizarán a la devolución de llamada proporcionada en la llamada a la función. Si el parámetro query_id
no es cero, la función filtrará cualquier respuesta con un ID de consulta que no coincida con el ID de consulta proporcionado. El tipo de entrada será uno de MDNS_ENTRYTYPE_ANSWER
, MDNS_ENTRYTYPE_AUTHORITY
y MDNS_ENTRYTYPE_ADDITIONAL
.
Tenga en cuenta que un socket abierto para consultas únicas desde un puerto efímero no recibirá respuestas no solicitadas (anuncios), ya que se envían como multidifusión en el puerto 5353.
Para enviar varias consultas en el mismo paquete, utilice mdns_multiquery_send
, que toma una matriz y un recuento de nombres de servicios y tipos de registros para consultar.
Para escuchar solicitudes DNS-SD entrantes y consultas mDNS, el socket se puede abrir/configurar en la interfaz predeterminada pasando 0 como dirección del socket en la llamada a las funciones de apertura/configuración del socket (el socket recibirá datos de todas las interfaces de red). Luego llame mdns_socket_listen
al recibir una notificación de datos entrantes o configurando el modo de bloqueo y llamando mdns_socket_listen
para bloquear hasta que los datos estén disponibles y analizados.
El tipo de entrada pasado a la devolución de llamada será MDNS_ENTRYTYPE_QUESTION
y el tipo de registro indica con qué registro responder. El programa de ejemplo responde a registros SRV, PTR, A y AAAA. Utilice la función mdns_string_extract
para obtener la cadena de nombre del registro de servicio que se solicitó.
Si el nombre del registro de servicio es _services._dns-sd._udp.local.
debes usar mdns_discovery_answer
para enviar los registros de los servicios que brindas (DNS-SD).
Si el nombre del registro de servicio es un servicio que usted proporciona, utilice mdns_query_answer_unicast
o mdns_query_answer_multicast
según el indicador de tipo de respuesta en la pregunta para enviar los detalles del servicio en respuesta a la consulta.
Consulte la implementación del ejecutable de prueba para obtener más detalles sobre cómo manejar los parámetros de las funciones dadas.
Si proporciona un servicio mDNS que escucha y responde consultas en el puerto 5353, se recomienda enviar un anuncio al inicio de su servicio (como una respuesta no solicitada). Utilice mdns_announce_multicast
para anunciar los registros de su servicio al inicio y mdns_goodbye_multicast
para anunciar el final del servicio al finalizar.
El archivo mdns.c
contiene una implementación ejecutable de prueba que utiliza la biblioteca para realizar consultas DNS-SD y mDNS. Compile en un ejecutable y ejecútelo para ver las opciones de la línea de comandos para los modos de descubrimiento, consulta y servicio.
cl mdns.c /Zi /Fdmdns.pdb /link /out:mdns.exe ws2_32.lib iphlpapi.lib
gcc -o mdns mdns.c
clang -o mdns mdns.c
FetchContent
o instale y find_package
mdns/20200130
y find_package
-> https://conan.io/center/mdns/20200130vcpkg install mdns
y find_package