Esta biblioteca fornece uma biblioteca mDNS e DNS-DS de plataforma cruzada apenas de cabeçalho em C. O código-fonte mais recente está sempre disponível em
https://github.com/mjansson/mdns
Esta biblioteca é colocada em domínio público; você pode redistribuí-lo e/ou modificá-lo sem quaisquer restrições.
Criado por Mattias Jansson (@maniccoder)
Servidor Discord para discussões https://discord.gg/M8BwTQrt6c
A biblioteca faz descoberta e serviço de DNS-SD, bem como consulta e resposta mDNS de registro único e único. Não há alocações de memória feitas pela biblioteca, todos os buffers usados devem ser passados pelo chamador. Dados personalizados para uso no processamento podem ser transmitidos usando um ponteiro opaco de dados do usuário.
O arquivo executável de teste mdns.c
demonstra o uso de todos os recursos, incluindo descoberta, consulta e resposta de serviço. A documentação aqui é intencionalmente escassa, o código de exemplo está bem documentado e deve fornecer todos os detalhes.
O soquete para comunicação mDNS pode ser aberto pela biblioteca usando mdns_socket_open_ipv4
ou mdns_socket_open_ipv6
ou inicializando um soquete existente com mdns_socket_setup_ipv4
ou mdns_socket_setup_ipv6
. As funções de abertura/configuração do soquete inicializarão o soquete com associação multicast (incluindo loopback) e definido para o modo sem bloqueio.
Chame mdns_socket_close
para fechar um soquete aberto com mdns_socket_open_ipv4
ou mdns_socket_open_ipv6
.
Para abrir/configurar o soquete para consultas únicas, você pode passar um endereço de soquete de ponteiro nulo ou definir a porta no endereço de soquete passado como 0. Isso vinculará o soquete a uma porta UDP local efêmera aleatória, conforme exigido pelos RFCs para consultas únicas. Você NÃO deve vincular-se à porta 5353 ao fazer consultas únicas (consulte a RFC para obter detalhes).,
Para abrir/configurar o soquete para serviço, respondendo às consultas recebidas, você precisa passar uma estrutura de endereço de soquete com a porta definida como 5353 (definida por MDNS_PORT no cabeçalho). Você não pode escolher nenhuma outra porta ou não receberá nenhuma consulta.
Para fazer descobertas ou consultas na interface de rede padrão, você pode passar um ponteiro nulo como endereço de soquete nas funções de criação/configuração de soquete. Isso vinculará o soquete à interface de rede padrão. Caso contrário, você deverá enumerar as interfaces disponíveis e passar o endereço de soquete apropriado para a função de criação/configuração. Consulte o programa de exemplo em mdns.c
para obter um exemplo de implementação de como fazer isso para IPv4 e IPv6.
Se você deseja responder ao serviço mDNS para consultas recebidas, não precisa enumerar interfaces para responder ao serviço em todas as interfaces, pois os soquetes recebem dados de todas as interfaces. Consulte o programa de exemplo em mdns.c
para obter um exemplo de configuração de um soquete de serviço para IPv4 e IPv6.
Para enviar uma solicitação de descoberta de serviço DNS-SD, use mdns_discovery_send
. Isso enviará um único pacote multicast (registro de pergunta PTR único para _services._dns-sd._udp.local.
) solicitando uma resposta unicast.
Para ler as respostas de descoberta, use mdns_discovery_recv
. Todos os registros recebidos desde a última chamada serão canalizados para o retorno de chamada fornecido na chamada de função. O tipo de entrada será MDNS_ENTRYTYPE_ANSWER
, MDNS_ENTRYTYPE_AUTHORITY
e MDNS_ENTRYTYPE_ADDITIONAL
.
Para enviar uma consulta mDNS única para um único registro, use mdns_query_send
. Isso enviará um único pacote multicast para o registro e nome fornecidos (por exemplo, registro PTR para _http._tcp.local.
). Opcionalmente, você pode passar um ID de consulta para a consulta para filtragem posterior de respostas (mesmo que isso seja desencorajado pela RFC) ou passar 0 para ser totalmente compatível. A função retorna o ID da consulta associado a esta consulta, que, se for diferente de zero, pode ser usado para filtrar respostas em mdns_query_recv
. Se o soquete estiver vinculado à porta 5353, uma resposta multicast será solicitada; caso contrário, uma resposta unicast.
Para ler as respostas da consulta, use mdns_query_recv
. Todos os registros recebidos desde a última chamada serão canalizados para o retorno de chamada fornecido na chamada de função. Se o parâmetro query_id
for diferente de zero, a função filtrará qualquer resposta com um ID de consulta que não corresponda ao ID de consulta fornecido. O tipo de entrada será MDNS_ENTRYTYPE_ANSWER
, MDNS_ENTRYTYPE_AUTHORITY
e MDNS_ENTRYTYPE_ADDITIONAL
.
Observe que um soquete aberto para consultas únicas de uma porta efêmera não receberá respostas não solicitadas (anúncios), pois elas são enviadas como multicast na porta 5353.
Para enviar várias consultas no mesmo pacote, use mdns_multiquery_send
, que usa uma matriz e uma contagem de nomes de serviços e tipos de registro para consultar.
Para ouvir solicitações DNS-SD e consultas mDNS recebidas, o soquete pode ser aberto/configurado na interface padrão passando 0 como endereço do soquete na chamada para as funções de abertura/configuração do soquete (o soquete receberá dados de todas as interfaces de rede). Em seguida, chame mdns_socket_listen
na notificação de dados recebidos ou definindo o modo de bloqueio e chamando mdns_socket_listen
para bloquear até que os dados estejam disponíveis e analisados.
O tipo de entrada passado para o retorno de chamada será MDNS_ENTRYTYPE_QUESTION
e o tipo de registro indica com qual registro responder. O programa de exemplo responde aos registros SRV, PTR, A e AAAA. Use a função mdns_string_extract
para obter a sequência de nomes do registro de serviço solicitado.
Se o nome do registro de serviço for _services._dns-sd._udp.local.
você deve usar mdns_discovery_answer
para enviar os registros dos serviços que você fornece (DNS-SD).
Se o nome do registro de serviço for um serviço que você fornece, use mdns_query_answer_unicast
ou mdns_query_answer_multicast
dependendo do sinalizador de tipo de resposta na pergunta para enviar os detalhes do serviço de volta em resposta à consulta.
Consulte a implementação do executável de teste para obter mais detalhes sobre como lidar com os parâmetros das funções fornecidas.
Se você fornece um serviço mDNS ouvindo e respondendo a consultas na porta 5353, é recomendável enviar um anúncio na inicialização do seu serviço (como uma resposta não solicitada). Use mdns_announce_multicast
para anunciar os registros do seu serviço na inicialização e mdns_goodbye_multicast
para anunciar o fim do serviço no encerramento.
O arquivo mdns.c
contém uma implementação executável de teste usando a biblioteca para fazer consultas DNS-SD e mDNS. Compile em um executável e execute para ver as opções de linha de comando para modos de descoberta, consulta e serviço.
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
ou instale e find_package
mdns/20200130
e find_package
-> https://conan.io/center/mdns/20200130vcpkg install mdns
e find_package