mirror of
https://github.com/espressif/esp-protocols.git
synced 2025-07-16 20:12:13 +02:00
mdns: add mdns delegation
This allows publishing mdns services for other devices. * Original commit: espressif/esp-idf@401ff56cc1
This commit is contained in:
committed by
suren-gabrielyan-espressif
parent
b62b4b3e25
commit
1eb5df9780
@ -114,6 +114,10 @@ void mdns_free(void);
|
||||
*/
|
||||
esp_err_t mdns_hostname_set(const char * hostname);
|
||||
|
||||
esp_err_t mdns_delegate_hostname_add(const char * hostname, const esp_ip_addr_t *address);
|
||||
|
||||
bool mdns_hostname_exists(const char *hostname);
|
||||
|
||||
/**
|
||||
* @brief Set the default instance name for mDNS server
|
||||
*
|
||||
@ -145,6 +149,12 @@ esp_err_t mdns_instance_name_set(const char * instance_name);
|
||||
*/
|
||||
esp_err_t mdns_service_add(const char * instance_name, const char * service_type, const char * proto, uint16_t port, mdns_txt_item_t txt[], size_t num_items);
|
||||
|
||||
|
||||
esp_err_t mdns_service_add_custom_host(const char *instance_name, const char *service_type, const char *proto,
|
||||
const char *hostname, uint16_t port, mdns_txt_item_t txt[], size_t num_items);
|
||||
|
||||
bool mdns_service_exists(const char *service_type, const char *proto, const char *hostname);
|
||||
|
||||
/**
|
||||
* @brief Remove service from mDNS server
|
||||
*
|
||||
@ -159,6 +169,8 @@ esp_err_t mdns_service_add(const char * instance_name, const char * service_type
|
||||
*/
|
||||
esp_err_t mdns_service_remove(const char * service_type, const char * proto);
|
||||
|
||||
esp_err_t mdns_service_remove_for_host(const char * service_type, const char * proto, const char *hostname);
|
||||
|
||||
/**
|
||||
* @brief Set instance name for service
|
||||
*
|
||||
@ -174,6 +186,8 @@ esp_err_t mdns_service_remove(const char * service_type, const char * proto);
|
||||
*/
|
||||
esp_err_t mdns_service_instance_name_set(const char * service_type, const char * proto, const char * instance_name);
|
||||
|
||||
esp_err_t mdns_service_instance_name_set_for_host(const char * service_type, const char * proto, const char *hostname, const char * instance_name);
|
||||
|
||||
/**
|
||||
* @brief Set service port
|
||||
*
|
||||
@ -189,6 +203,10 @@ esp_err_t mdns_service_instance_name_set(const char * service_type, const char *
|
||||
*/
|
||||
esp_err_t mdns_service_port_set(const char * service_type, const char * proto, uint16_t port);
|
||||
|
||||
|
||||
esp_err_t mdns_service_port_set_for_host(const char *service_type, const char *proto, const char *hostname,
|
||||
uint16_t port);
|
||||
|
||||
/**
|
||||
* @brief Replace all TXT items for service
|
||||
*
|
||||
@ -205,6 +223,9 @@ esp_err_t mdns_service_port_set(const char * service_type, const char * proto, u
|
||||
*/
|
||||
esp_err_t mdns_service_txt_set(const char * service_type, const char * proto, mdns_txt_item_t txt[], uint8_t num_items);
|
||||
|
||||
esp_err_t mdns_service_txt_set_for_host(const char *service_type, const char *proto, const char *hostname,
|
||||
mdns_txt_item_t txt[], uint8_t num_items);
|
||||
|
||||
/**
|
||||
* @brief Set/Add TXT item for service TXT record
|
||||
*
|
||||
@ -221,6 +242,10 @@ esp_err_t mdns_service_txt_set(const char * service_type, const char * proto, md
|
||||
*/
|
||||
esp_err_t mdns_service_txt_item_set(const char * service_type, const char * proto, const char * key, const char * value);
|
||||
|
||||
|
||||
esp_err_t mdns_service_txt_item_set_for_host(const char *service_type, const char *proto, const char *hostname,
|
||||
const char *key, const char *value);
|
||||
|
||||
/**
|
||||
* @brief Remove TXT item for service TXT record
|
||||
*
|
||||
@ -236,6 +261,9 @@ esp_err_t mdns_service_txt_item_set(const char * service_type, const char * prot
|
||||
*/
|
||||
esp_err_t mdns_service_txt_item_remove(const char * service_type, const char * proto, const char * key);
|
||||
|
||||
esp_err_t mdns_service_txt_item_remove_for_host(const char *service_type, const char *proto, const char *hostname,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* @brief Remove and free all services from mDNS server
|
||||
*
|
||||
|
@ -31,6 +31,8 @@ static const char * MDNS_DEFAULT_DOMAIN = "local";
|
||||
static const char * MDNS_SUB_STR = "_sub";
|
||||
|
||||
mdns_server_t * _mdns_server = NULL;
|
||||
static mdns_host_item_t *_mdns_host_list = NULL;
|
||||
static mdns_host_item_t _mdns_self_host;
|
||||
|
||||
static const char *TAG = "MDNS";
|
||||
|
||||
@ -43,6 +45,7 @@ static void _mdns_search_result_add_ip(mdns_search_once_t * search, const char *
|
||||
static void _mdns_search_result_add_srv(mdns_search_once_t * search, const char * hostname, uint16_t port, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
|
||||
static void _mdns_search_result_add_txt(mdns_search_once_t * search, mdns_txt_item_t * txt, size_t txt_count, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
|
||||
static mdns_result_t * _mdns_search_result_add_ptr(mdns_search_once_t * search, const char * instance, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
|
||||
static bool _mdns_append_host_list(mdns_out_answer_t ** destination, bool flush, bool bye);
|
||||
|
||||
/*
|
||||
* @brief Internal collection of mdns supported interfaces
|
||||
@ -143,6 +146,12 @@ static char * _mdns_mangle_name(char* in) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool _mdns_service_match(const mdns_service_t *srv, const char *service, const char *proto, const char *hostname)
|
||||
{
|
||||
return !strcasecmp(srv->service, service) && !strcasecmp(srv->proto, proto) &&
|
||||
(_str_null_or_empty(hostname) || !strcasecmp(srv->hostname, hostname));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief finds service from given service type
|
||||
* @param server the server
|
||||
@ -151,11 +160,11 @@ static char * _mdns_mangle_name(char* in) {
|
||||
*
|
||||
* @return the service item if found or NULL on error
|
||||
*/
|
||||
static mdns_srv_item_t * _mdns_get_service_item(const char * service, const char * proto)
|
||||
static mdns_srv_item_t * _mdns_get_service_item(const char * service, const char * proto, const char *hostname)
|
||||
{
|
||||
mdns_srv_item_t * s = _mdns_server->services;
|
||||
while (s) {
|
||||
if (!strcasecmp(s->service->service, service) && !strcasecmp(s->service->proto, proto)) {
|
||||
if (_mdns_service_match(s->service, service, proto, hostname)) {
|
||||
return s;
|
||||
}
|
||||
s = s->next;
|
||||
@ -163,6 +172,21 @@ static mdns_srv_item_t * _mdns_get_service_item(const char * service, const char
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static mdns_host_item_t *mdns_get_host_item(const char *hostname, uint8_t address_type)
|
||||
{
|
||||
if (hostname == NULL || strcasecmp(hostname, _mdns_server->hostname) == 0) {
|
||||
return &_mdns_self_host;
|
||||
}
|
||||
mdns_host_item_t *host = _mdns_host_list;
|
||||
while (host != NULL) {
|
||||
if (strcasecmp(host->hostname, hostname) == 0 && host->address.type == address_type) {
|
||||
return host;
|
||||
}
|
||||
host = host->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool _mdns_can_add_more_services(void)
|
||||
{
|
||||
mdns_srv_item_t * s = _mdns_server->services;
|
||||
@ -704,7 +728,11 @@ static uint16_t _mdns_append_srv_record(uint8_t * packet, uint16_t * index, mdns
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (service->hostname) {
|
||||
str[0] = service->hostname;
|
||||
} else {
|
||||
str[0] = _mdns_server->hostname;
|
||||
}
|
||||
str[1] = MDNS_DEFAULT_DOMAIN;
|
||||
|
||||
if (_str_null_or_empty(str[0])) {
|
||||
@ -731,20 +759,19 @@ static uint16_t _mdns_append_srv_record(uint8_t * packet, uint16_t * index, mdns
|
||||
*
|
||||
* @return length of added data: 0 on error or length on success
|
||||
*/
|
||||
static uint16_t _mdns_append_a_record(uint8_t * packet, uint16_t * index, uint32_t ip, bool flush, bool bye)
|
||||
static uint16_t _mdns_append_a_record(uint8_t * packet, uint16_t * index, const char * hostname, uint32_t ip, bool flush, bool bye)
|
||||
{
|
||||
const char * str[2];
|
||||
uint16_t record_length = 0;
|
||||
uint8_t part_length;
|
||||
|
||||
str[0] = _mdns_server->hostname;
|
||||
str[0] = hostname;
|
||||
str[1] = MDNS_DEFAULT_DOMAIN;
|
||||
|
||||
if (_str_null_or_empty(str[0])) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
part_length = _mdns_append_fqdn(packet, index, str, 2);
|
||||
if (!part_length) {
|
||||
return 0;
|
||||
@ -778,17 +805,18 @@ static uint16_t _mdns_append_a_record(uint8_t * packet, uint16_t * index, uint32
|
||||
*
|
||||
* @param packet MDNS packet
|
||||
* @param index offset in the packet
|
||||
* @param hostnamek the hostname address to add
|
||||
* @param ipv6 the IPv6 address to add
|
||||
*
|
||||
* @return length of added data: 0 on error or length on success
|
||||
*/
|
||||
static uint16_t _mdns_append_aaaa_record(uint8_t * packet, uint16_t * index, uint8_t * ipv6, bool flush, bool bye)
|
||||
static uint16_t _mdns_append_aaaa_record(uint8_t * packet, uint16_t * index, const char * hostname, uint8_t * ipv6, bool flush, bool bye)
|
||||
{
|
||||
const char * str[2];
|
||||
uint16_t record_length = 0;
|
||||
uint8_t part_length;
|
||||
|
||||
str[0] = _mdns_server->hostname;
|
||||
str[0] = hostname;
|
||||
str[1] = MDNS_DEFAULT_DOMAIN;
|
||||
|
||||
if (_str_null_or_empty(str[0])) {
|
||||
@ -908,6 +936,7 @@ static bool _ipv6_address_is_zero(esp_ip6_addr_t ip6)
|
||||
* @brief Append answer to packet
|
||||
*
|
||||
* @return number of answers added to the packet
|
||||
* XXX: create the answers here
|
||||
*/
|
||||
static uint8_t _mdns_append_answer(uint8_t * packet, uint16_t * index, mdns_out_answer_t * answer, mdns_if_t tcpip_if)
|
||||
{
|
||||
@ -930,6 +959,7 @@ static uint8_t _mdns_append_answer(uint8_t * packet, uint16_t * index, mdns_out_
|
||||
} else if (answer->type == MDNS_TYPE_SDPTR) {
|
||||
return _mdns_append_sdptr_record(packet, index, answer->service, answer->flush, answer->bye) > 0;
|
||||
} else if (answer->type == MDNS_TYPE_A) {
|
||||
if (answer->host == &_mdns_self_host) {
|
||||
esp_netif_ip_info_t if_ip_info;
|
||||
if (!_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].pcb && _mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].state != PCB_DUP) {
|
||||
return 0;
|
||||
@ -937,7 +967,7 @@ static uint8_t _mdns_append_answer(uint8_t * packet, uint16_t * index, mdns_out_
|
||||
if (esp_netif_get_ip_info(_mdns_get_esp_netif(tcpip_if), &if_ip_info)) {
|
||||
return 0;
|
||||
}
|
||||
if (_mdns_append_a_record(packet, index, if_ip_info.ip.addr, answer->flush, answer->bye) <= 0) {
|
||||
if (_mdns_append_a_record(packet, index, _mdns_server->hostname, if_ip_info.ip.addr, answer->flush, answer->bye) <= 0) {
|
||||
return 0;
|
||||
}
|
||||
if (!_mdns_if_is_dup(tcpip_if)) {
|
||||
@ -947,13 +977,21 @@ static uint8_t _mdns_append_answer(uint8_t * packet, uint16_t * index, mdns_out_
|
||||
if (esp_netif_get_ip_info(_mdns_get_esp_netif(other_if), &if_ip_info)) {
|
||||
return 1;
|
||||
}
|
||||
if (_mdns_append_a_record(packet, index, if_ip_info.ip.addr, answer->flush, answer->bye) > 0) {
|
||||
if (_mdns_append_a_record(packet, index, _mdns_server->hostname, if_ip_info.ip.addr, answer->flush, answer->bye) > 0) {
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
} else if (answer->host != NULL) {
|
||||
if (_mdns_append_a_record(packet, index, answer->host->hostname, answer->host->address.u_addr.ip4.addr, answer->flush, answer->bye) <= 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if CONFIG_LWIP_IPV6
|
||||
else if (answer->type == MDNS_TYPE_AAAA) {
|
||||
if (answer->host == &_mdns_self_host) {
|
||||
struct esp_ip6_addr if_ip6;
|
||||
if (!_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V6].pcb && _mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V6].state != PCB_DUP) {
|
||||
return 0;
|
||||
@ -964,7 +1002,7 @@ static uint8_t _mdns_append_answer(uint8_t * packet, uint16_t * index, mdns_out_
|
||||
if (_ipv6_address_is_zero(if_ip6)) {
|
||||
return 0;
|
||||
}
|
||||
if (_mdns_append_aaaa_record(packet, index, (uint8_t*)if_ip6.addr, answer->flush, answer->bye) <= 0) {
|
||||
if (_mdns_append_aaaa_record(packet, index, _mdns_server->hostname, (uint8_t*)if_ip6.addr, answer->flush, answer->bye) <= 0) {
|
||||
return 0;
|
||||
}
|
||||
if (!_mdns_if_is_dup(tcpip_if)) {
|
||||
@ -974,10 +1012,18 @@ static uint8_t _mdns_append_answer(uint8_t * packet, uint16_t * index, mdns_out_
|
||||
if (esp_netif_get_ip6_linklocal(_mdns_get_esp_netif(other_if), &if_ip6)) {
|
||||
return 1;
|
||||
}
|
||||
if (_mdns_append_aaaa_record(packet, index, (uint8_t*)if_ip6.addr, answer->flush, answer->bye) > 0) {
|
||||
if (_mdns_append_aaaa_record(packet, index, _mdns_server->hostname, (uint8_t*)if_ip6.addr, answer->flush, answer->bye) > 0) {
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
} else if (answer->host != NULL) {
|
||||
if (_mdns_append_aaaa_record(packet, index, answer->host->hostname, (uint8_t*)answer->host->address.u_addr.ip6.addr, answer->flush, answer->bye) <= 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
@ -1232,11 +1278,11 @@ static void _mdns_dealloc_answer(mdns_out_answer_t ** destination, uint16_t type
|
||||
/**
|
||||
* @brief Allocate new answer and add it to answer list (destination)
|
||||
*/
|
||||
static bool _mdns_alloc_answer(mdns_out_answer_t ** destination, uint16_t type, mdns_service_t * service, bool flush, bool bye)
|
||||
static bool _mdns_alloc_answer(mdns_out_answer_t ** destination, uint16_t type, mdns_service_t * service, mdns_host_item_t *host, bool flush, bool bye)
|
||||
{
|
||||
mdns_out_answer_t * d = *destination;
|
||||
while (d) {
|
||||
if (d->type == type && d->service == service) {
|
||||
if (d->type == type && d->service == service && d->host == host) {
|
||||
return true;
|
||||
}
|
||||
d = d->next;
|
||||
@ -1249,6 +1295,7 @@ static bool _mdns_alloc_answer(mdns_out_answer_t ** destination, uint16_t type,
|
||||
}
|
||||
a->type = type;
|
||||
a->service = service;
|
||||
a->host = host;
|
||||
a->custom_service = NULL;
|
||||
a->bye = bye;
|
||||
a->flush = flush;
|
||||
@ -1283,10 +1330,58 @@ static mdns_tx_packet_t * _mdns_alloc_packet_default(mdns_if_t tcpip_if, mdns_ip
|
||||
return packet;
|
||||
}
|
||||
|
||||
static bool _mdns_create_answer_from_service(mdns_tx_packet_t *packet, mdns_service_t *service,
|
||||
mdns_parsed_question_t *question, bool shared, bool send_flush)
|
||||
{
|
||||
mdns_host_item_t *host4 = mdns_get_host_item(service->hostname, ESP_IPADDR_TYPE_V4);
|
||||
mdns_host_item_t *host6 = mdns_get_host_item(service->hostname, ESP_IPADDR_TYPE_V6);
|
||||
if (question->type == MDNS_TYPE_PTR || question->type == MDNS_TYPE_ANY) {
|
||||
if (!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_PTR, service, NULL, false, false) ||
|
||||
!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_SRV, service, NULL, send_flush, false) ||
|
||||
!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_TXT, service, NULL, send_flush, false) ||
|
||||
!_mdns_alloc_answer(shared ? &packet->additional : &packet->answers, MDNS_TYPE_A, service, host4,
|
||||
send_flush, false) ||
|
||||
!_mdns_alloc_answer(shared ? &packet->additional : &packet->answers, MDNS_TYPE_AAAA, service, host6,
|
||||
send_flush, false)) {
|
||||
return false;
|
||||
}
|
||||
} else if (question->type == MDNS_TYPE_SRV) {
|
||||
if (!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_SRV, service, NULL, send_flush, false) ||
|
||||
!_mdns_alloc_answer(&packet->additional, MDNS_TYPE_A, service, host4, send_flush, false) ||
|
||||
!_mdns_alloc_answer(&packet->additional, MDNS_TYPE_AAAA, service, host6, send_flush, false)) {
|
||||
return false;
|
||||
}
|
||||
} else if (question->type == MDNS_TYPE_TXT) {
|
||||
if (!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_TXT, service, NULL, send_flush, false)) {
|
||||
return false;
|
||||
}
|
||||
} else if (question->type == MDNS_TYPE_SDPTR) {
|
||||
shared = true;
|
||||
if (!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_SDPTR, service, NULL, false, false)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool _mdns_create_answer_from_hostname(mdns_tx_packet_t *packet, const char *hostname, bool send_flush)
|
||||
{
|
||||
mdns_host_item_t *host4;
|
||||
mdns_host_item_t *host6;
|
||||
host4 = mdns_get_host_item(hostname, ESP_IPADDR_TYPE_V4);
|
||||
host6 = mdns_get_host_item(hostname, ESP_IPADDR_TYPE_V6);
|
||||
if (!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_A, NULL, host4, send_flush, false) ||
|
||||
!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_AAAA, NULL, host6, send_flush, false)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create answer packet to questions from parsed packet
|
||||
* XXX: reply from here
|
||||
*/
|
||||
static void _mdns_create_answer_from_parsed_packet(mdns_parsed_packet_t * parsed_packet)
|
||||
static void _mdns_create_answer_from_parsed_packet(mdns_parsed_packet_t *parsed_packet)
|
||||
{
|
||||
if (!parsed_packet->questions) {
|
||||
return;
|
||||
@ -1294,7 +1389,7 @@ static void _mdns_create_answer_from_parsed_packet(mdns_parsed_packet_t * parsed
|
||||
bool send_flush = parsed_packet->src_port == MDNS_SERVICE_PORT;
|
||||
bool unicast = false;
|
||||
bool shared = false;
|
||||
mdns_tx_packet_t * packet = _mdns_alloc_packet_default(parsed_packet->tcpip_if, parsed_packet->ip_protocol);
|
||||
mdns_tx_packet_t *packet = _mdns_alloc_packet_default(parsed_packet->tcpip_if, parsed_packet->ip_protocol);
|
||||
if (!packet) {
|
||||
return;
|
||||
}
|
||||
@ -1302,58 +1397,37 @@ static void _mdns_create_answer_from_parsed_packet(mdns_parsed_packet_t * parsed
|
||||
packet->distributed = parsed_packet->distributed;
|
||||
packet->id = parsed_packet->id;
|
||||
|
||||
mdns_parsed_question_t * q = parsed_packet->questions;
|
||||
mdns_parsed_question_t *q = parsed_packet->questions;
|
||||
while (q) {
|
||||
mdns_srv_item_t * service = NULL;
|
||||
shared = q->type == MDNS_TYPE_PTR || q->type == MDNS_TYPE_SDPTR || !parsed_packet->probe;
|
||||
if (q->service && q->proto) {
|
||||
service = _mdns_get_service_item(q->service, q->proto);
|
||||
if (!service) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (q->unicast) {
|
||||
unicast = true;
|
||||
}
|
||||
if (service) {
|
||||
if (q->type == MDNS_TYPE_PTR || q->type == MDNS_TYPE_ANY) {
|
||||
if (q->type == MDNS_TYPE_PTR || !parsed_packet->probe) {
|
||||
shared = true;
|
||||
}
|
||||
if (!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_PTR, service->service, false, false)
|
||||
|| !_mdns_alloc_answer(&packet->answers, MDNS_TYPE_SRV, service->service, send_flush, false)
|
||||
|| !_mdns_alloc_answer(&packet->answers, MDNS_TYPE_TXT, service->service, send_flush, false)
|
||||
|| !_mdns_alloc_answer(shared?&packet->additional:&packet->answers, MDNS_TYPE_A, NULL, send_flush, false)
|
||||
|| !_mdns_alloc_answer(shared?&packet->additional:&packet->answers, MDNS_TYPE_AAAA, NULL, send_flush, false)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return;
|
||||
}
|
||||
} else if (q->type == MDNS_TYPE_SRV) {
|
||||
if (!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_SRV, service->service, send_flush, false)
|
||||
|| !_mdns_alloc_answer(&packet->additional, MDNS_TYPE_A, NULL, send_flush, false)
|
||||
|| !_mdns_alloc_answer(&packet->additional, MDNS_TYPE_AAAA, NULL, send_flush, false)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return;
|
||||
}
|
||||
} else if (q->type == MDNS_TYPE_TXT) {
|
||||
if (!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_TXT, service->service, send_flush, false)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return;
|
||||
}
|
||||
} else if (q->type == MDNS_TYPE_SDPTR) {
|
||||
shared = true;
|
||||
if (!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_SDPTR, service->service, false, false)) {
|
||||
mdns_srv_item_t *service = _mdns_server->services;
|
||||
while (service) {
|
||||
if (_mdns_service_match(service->service, q->service, q->proto, q->host)) {
|
||||
if (!_mdns_create_answer_from_service(packet, service->service, q, shared, send_flush)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (q->type == MDNS_TYPE_ANY || q->type == MDNS_TYPE_A || q->type == MDNS_TYPE_AAAA) {
|
||||
if (!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_A, NULL, send_flush, false)
|
||||
|| !_mdns_alloc_answer(&packet->answers, MDNS_TYPE_AAAA, NULL, send_flush, false)) {
|
||||
service = service->next;
|
||||
}
|
||||
} else if (q->type == MDNS_TYPE_A || q->type == MDNS_TYPE_AAAA) {
|
||||
if (!_mdns_create_answer_from_hostname(packet, q->host, send_flush)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return;
|
||||
}
|
||||
} else if (q->type == MDNS_TYPE_ANY) {
|
||||
if (!_mdns_append_host_list(&packet->answers, send_flush, false)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return;
|
||||
}
|
||||
} else if (!_mdns_alloc_answer(&packet->answers, q->type, NULL, NULL, send_flush, false)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef MDNS_REPEAT_QUERY_IN_RESPONSE
|
||||
if (q->type == MDNS_TYPE_ANY || q->type == MDNS_TYPE_A || q->type == MDNS_TYPE_AAAA) {
|
||||
mdns_out_question_t * out_question = malloc(sizeof(mdns_out_question_t));
|
||||
if (out_question == NULL) {
|
||||
HOOK_MALLOC_FAILED;
|
||||
@ -1373,11 +1447,10 @@ static void _mdns_create_answer_from_parsed_packet(mdns_parsed_packet_t * parsed
|
||||
out_question->next = NULL;
|
||||
out_question->own_dynamic_memory = true;
|
||||
queueToEnd(mdns_out_question_t, packet->questions, out_question);
|
||||
#endif // MDNS_REPEAT_QUERY_IN_RESPONSE
|
||||
} else if (!_mdns_alloc_answer(&packet->answers, q->type, NULL, send_flush, false)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return;
|
||||
}
|
||||
#endif // MDNS_REPEAT_QUERY_IN_RESPONSE
|
||||
if (q->unicast) {
|
||||
unicast = true;
|
||||
}
|
||||
q = q->next;
|
||||
}
|
||||
@ -1413,6 +1486,32 @@ static bool _mdns_question_exists(mdns_out_question_t * needle, mdns_out_questio
|
||||
return false;
|
||||
}
|
||||
|
||||
bool _mdns_append_host_list(mdns_out_answer_t ** destination, bool flush, bool bye) {
|
||||
if (!_str_null_or_empty(_mdns_server->hostname)) {
|
||||
mdns_host_item_t *self_host = mdns_get_host_item(_mdns_server->hostname, ESP_IPADDR_TYPE_ANY);
|
||||
if (!_mdns_alloc_answer(destination, MDNS_TYPE_A, NULL, self_host, flush, bye)) {
|
||||
return false;
|
||||
}
|
||||
if (!_mdns_alloc_answer(destination, MDNS_TYPE_AAAA, NULL, self_host, flush, bye)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
mdns_host_item_t *host = _mdns_host_list;
|
||||
while(host != NULL) {
|
||||
if (host->address.type == ESP_IPADDR_TYPE_V4) {
|
||||
if (!_mdns_alloc_answer(destination, MDNS_TYPE_A, NULL, host, flush, bye)) {
|
||||
return false;
|
||||
}
|
||||
} else if (host->address.type == ESP_IPADDR_TYPE_V6) {
|
||||
if (!_mdns_alloc_answer(destination, MDNS_TYPE_AAAA, NULL, host, flush, bye)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
host = host->next;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create probe packet for particular services on particular PCB
|
||||
*/
|
||||
@ -1446,13 +1545,13 @@ static mdns_tx_packet_t * _mdns_create_probe_packet(mdns_if_t tcpip_if, mdns_ip_
|
||||
queueToEnd(mdns_out_question_t, packet->questions, q);
|
||||
}
|
||||
|
||||
if (!q->host || !_mdns_alloc_answer(&packet->servers, MDNS_TYPE_SRV, services[i]->service, false, false)) {
|
||||
if (!q->host || !_mdns_alloc_answer(&packet->servers, MDNS_TYPE_SRV, services[i]->service, NULL, false, false)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (include_ip && !_str_null_or_empty(_mdns_server->hostname)) {
|
||||
if (include_ip) {
|
||||
mdns_out_question_t * q = (mdns_out_question_t *)malloc(sizeof(mdns_out_question_t));
|
||||
if (!q) {
|
||||
HOOK_MALLOC_FAILED;
|
||||
@ -1473,21 +1572,12 @@ static mdns_tx_packet_t * _mdns_create_probe_packet(mdns_if_t tcpip_if, mdns_ip_
|
||||
queueToEnd(mdns_out_question_t, packet->questions, q);
|
||||
}
|
||||
|
||||
if (_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].pcb) {
|
||||
if (!_mdns_alloc_answer(&packet->servers, MDNS_TYPE_A, NULL, false, false)) {
|
||||
if (!_mdns_append_host_list(&packet->servers, false, false)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V6].pcb) {
|
||||
if (!_mdns_alloc_answer(&packet->servers, MDNS_TYPE_AAAA, NULL, false, false)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return packet;
|
||||
}
|
||||
|
||||
@ -1504,17 +1594,16 @@ static mdns_tx_packet_t * _mdns_create_announce_packet(mdns_if_t tcpip_if, mdns_
|
||||
|
||||
uint8_t i;
|
||||
for (i=0; i<len; i++) {
|
||||
if (!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_SDPTR, services[i]->service, false, false)
|
||||
|| !_mdns_alloc_answer(&packet->answers, MDNS_TYPE_PTR, services[i]->service, false, false)
|
||||
|| !_mdns_alloc_answer(&packet->answers, MDNS_TYPE_SRV, services[i]->service, true, false)
|
||||
|| !_mdns_alloc_answer(&packet->answers, MDNS_TYPE_TXT, services[i]->service, true, false)) {
|
||||
if (!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_SDPTR, services[i]->service, NULL, false, false)
|
||||
|| !_mdns_alloc_answer(&packet->answers, MDNS_TYPE_PTR, services[i]->service, NULL, false, false)
|
||||
|| !_mdns_alloc_answer(&packet->answers, MDNS_TYPE_SRV, services[i]->service, NULL, true, false)
|
||||
|| !_mdns_alloc_answer(&packet->answers, MDNS_TYPE_TXT, services[i]->service, NULL, true, false)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (include_ip) {
|
||||
if (!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_A, NULL, true, false)
|
||||
|| !_mdns_alloc_answer(&packet->answers, MDNS_TYPE_AAAA, NULL, true, false)) {
|
||||
if (!_mdns_append_host_list(&packet->servers, true, false)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return NULL;
|
||||
}
|
||||
@ -1537,16 +1626,16 @@ static mdns_tx_packet_t * _mdns_create_announce_from_probe(mdns_tx_packet_t * pr
|
||||
mdns_out_answer_t * s = probe->servers;
|
||||
while (s) {
|
||||
if (s->type == MDNS_TYPE_SRV) {
|
||||
if (!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_SDPTR, s->service, false, false)
|
||||
|| !_mdns_alloc_answer(&packet->answers, MDNS_TYPE_PTR, s->service, false, false)
|
||||
|| !_mdns_alloc_answer(&packet->answers, MDNS_TYPE_SRV, s->service, true, false)
|
||||
|| !_mdns_alloc_answer(&packet->answers, MDNS_TYPE_TXT, s->service, true, false)) {
|
||||
if (!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_SDPTR, s->service, NULL, false, false)
|
||||
|| !_mdns_alloc_answer(&packet->answers, MDNS_TYPE_PTR, s->service, NULL, false, false)
|
||||
|| !_mdns_alloc_answer(&packet->answers, MDNS_TYPE_SRV, s->service, NULL, true, false)
|
||||
|| !_mdns_alloc_answer(&packet->answers, MDNS_TYPE_TXT, s->service, NULL, true, false)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} else if (s->type == MDNS_TYPE_A || s->type == MDNS_TYPE_AAAA) {
|
||||
if (!_mdns_alloc_answer(&packet->answers, s->type, NULL, true, false)) {
|
||||
if (!_mdns_alloc_answer(&packet->answers, s->type, NULL, s->host, true, false)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return NULL;
|
||||
}
|
||||
@ -1569,14 +1658,13 @@ static void _mdns_pcb_send_bye(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protoco
|
||||
packet->flags = MDNS_FLAGS_AUTHORITATIVE;
|
||||
size_t i;
|
||||
for (i=0; i<len; i++) {
|
||||
if (!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_PTR, services[i]->service, true, true)) {
|
||||
if (!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_PTR, services[i]->service, NULL, true, true)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (include_ip && (!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_A, NULL, true, true) || !_mdns_alloc_answer(&packet->answers, MDNS_TYPE_AAAA, NULL, true, true))) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
return;
|
||||
if (include_ip) {
|
||||
_mdns_append_host_list(&packet->answers, true, true);
|
||||
}
|
||||
_mdns_dispatch_tx_packet(packet);
|
||||
_mdns_free_tx_packet(packet);
|
||||
@ -1732,18 +1820,17 @@ static void _mdns_announce_pcb(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protoco
|
||||
mdns_tx_packet_t * p = _mdns_get_next_pcb_packet(tcpip_if, ip_protocol);
|
||||
if (p) {
|
||||
for (i=0; i<len; i++) {
|
||||
if (!_mdns_alloc_answer(&p->answers, MDNS_TYPE_SDPTR, services[i]->service, false, false)
|
||||
|| !_mdns_alloc_answer(&p->answers, MDNS_TYPE_PTR, services[i]->service, false, false)
|
||||
|| !_mdns_alloc_answer(&p->answers, MDNS_TYPE_SRV, services[i]->service, true, false)
|
||||
|| !_mdns_alloc_answer(&p->answers, MDNS_TYPE_TXT, services[i]->service, true, false)) {
|
||||
if (!_mdns_alloc_answer(&p->answers, MDNS_TYPE_SDPTR, services[i]->service, NULL, false, false)
|
||||
|| !_mdns_alloc_answer(&p->answers, MDNS_TYPE_PTR, services[i]->service, NULL, false, false)
|
||||
|| !_mdns_alloc_answer(&p->answers, MDNS_TYPE_SRV, services[i]->service, NULL, true, false)
|
||||
|| !_mdns_alloc_answer(&p->answers, MDNS_TYPE_TXT, services[i]->service, NULL, true, false)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (include_ip) {
|
||||
_mdns_dealloc_answer(&p->additional, MDNS_TYPE_A, NULL);
|
||||
_mdns_dealloc_answer(&p->additional, MDNS_TYPE_AAAA, NULL);
|
||||
_mdns_alloc_answer(&p->answers, MDNS_TYPE_A, NULL, true, false);
|
||||
_mdns_alloc_answer(&p->answers, MDNS_TYPE_AAAA, NULL, true, false);
|
||||
_mdns_append_host_list(&p->answers, true, false);
|
||||
}
|
||||
_pcb->state = PCB_ANNOUNCE_1;
|
||||
}
|
||||
@ -1961,7 +2048,7 @@ static void _mdns_free_linked_txt(mdns_txt_linked_item_t *txt)
|
||||
*
|
||||
* @return pointer to the service or NULL on error
|
||||
*/
|
||||
static mdns_service_t * _mdns_create_service(const char * service, const char * proto, uint16_t port, const char * instance, size_t num_items, mdns_txt_item_t txt[])
|
||||
static mdns_service_t * _mdns_create_service(const char * service, const char * proto, const char *hostname, uint16_t port, const char * instance, size_t num_items, mdns_txt_item_t txt[])
|
||||
{
|
||||
mdns_service_t * s = (mdns_service_t *)malloc(sizeof(mdns_service_t));
|
||||
if (!s) {
|
||||
@ -1981,6 +2068,17 @@ static mdns_service_t * _mdns_create_service(const char * service, const char *
|
||||
s->txt = new_txt;
|
||||
s->port = port;
|
||||
|
||||
assert(hostname != NULL);
|
||||
if (hostname) {
|
||||
s->hostname = strndup(hostname, MDNS_NAME_BUF_LEN - 1);
|
||||
if (!s->hostname) {
|
||||
free(s);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
s->hostname = NULL;
|
||||
}
|
||||
|
||||
s->service = strndup(service, MDNS_NAME_BUF_LEN - 1);
|
||||
if (!s->service) {
|
||||
free(s);
|
||||
@ -2341,6 +2439,39 @@ static int _mdns_check_aaaa_collision(esp_ip6_addr_t * ip, mdns_if_t tcpip_if)
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool _hostname_is_ours(const char *hostname)
|
||||
{
|
||||
if (strcasecmp(hostname, _mdns_server->hostname) == 0) {
|
||||
return true;
|
||||
}
|
||||
mdns_host_item_t *host = _mdns_host_list;
|
||||
while (host != NULL) {
|
||||
if (strcasecmp(hostname, host->hostname) == 0) {
|
||||
return true;
|
||||
}
|
||||
host = host->next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool _mdns_delegate_hostname_add(const char *hostname, const esp_ip_addr_t *address)
|
||||
{
|
||||
if (_hostname_is_ours(hostname)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
mdns_host_item_t *host = (mdns_host_item_t *)malloc(sizeof(mdns_host_item_t));
|
||||
|
||||
if (host == NULL) {
|
||||
return false;
|
||||
}
|
||||
host->address = *address;
|
||||
host->hostname = hostname;
|
||||
host->next = _mdns_host_list;
|
||||
_mdns_host_list = host;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if parsed name is discovery
|
||||
*/
|
||||
@ -2369,7 +2500,7 @@ static bool _mdns_name_is_ours(mdns_name_t * name)
|
||||
if (_str_null_or_empty(name->service) && _str_null_or_empty(name->proto)) {
|
||||
if (!_str_null_or_empty(name->host)
|
||||
&& !_str_null_or_empty(_mdns_server->hostname)
|
||||
&& strcasecmp(name->host, _mdns_server->hostname) == 0)
|
||||
&& _hostname_is_ours(name->host) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -2382,7 +2513,7 @@ static bool _mdns_name_is_ours(mdns_name_t * name)
|
||||
}
|
||||
|
||||
//find the service
|
||||
mdns_srv_item_t * service = _mdns_get_service_item(name->service, name->proto);
|
||||
mdns_srv_item_t * service = _mdns_get_service_item(name->service, name->proto, name->host);
|
||||
if (!service) {
|
||||
return false;
|
||||
}
|
||||
@ -2860,7 +2991,7 @@ void mdns_parse_packet(mdns_rx_packet_t * packet)
|
||||
} else if (!name->sub && _mdns_name_is_ours(name)) {
|
||||
ours = true;
|
||||
if (name->service && name->service[0] && name->proto && name->proto[0]) {
|
||||
service = _mdns_get_service_item(name->service, name->proto);
|
||||
service = _mdns_get_service_item(name->service, name->proto, name->host);
|
||||
}
|
||||
} else {
|
||||
if (!parsed_packet->authoritative || record_type == MDNS_NS) {
|
||||
@ -2878,7 +3009,7 @@ void mdns_parse_packet(mdns_rx_packet_t * packet)
|
||||
_mdns_search_result_add_ptr(search_result, name->host, packet->tcpip_if, packet->ip_protocol);
|
||||
} else if ((discovery || ours) && !name->sub && _mdns_name_is_ours(name)) {
|
||||
if (discovery) {
|
||||
service = _mdns_get_service_item(name->service, name->proto);
|
||||
service = _mdns_get_service_item(name->service, name->proto, name->host);
|
||||
_mdns_remove_parsed_question(parsed_packet, MDNS_TYPE_SDPTR, service);
|
||||
} else if (parsed_packet->questions && !parsed_packet->probe) {
|
||||
_mdns_remove_parsed_question(parsed_packet, type, service);
|
||||
@ -3831,7 +3962,7 @@ static void _mdns_free_action(mdns_action_t * action)
|
||||
{
|
||||
switch(action->type) {
|
||||
case ACTION_HOSTNAME_SET:
|
||||
free(action->data.hostname);
|
||||
free(action->data.hostname_set.hostname);
|
||||
break;
|
||||
case ACTION_INSTANCE_SET:
|
||||
free(action->data.instance);
|
||||
@ -3892,9 +4023,10 @@ static void _mdns_execute_action(mdns_action_t * action)
|
||||
case ACTION_HOSTNAME_SET:
|
||||
_mdns_send_bye_all_pcbs_no_instance(true);
|
||||
free((char*)_mdns_server->hostname);
|
||||
_mdns_server->hostname = action->data.hostname;
|
||||
_mdns_server->hostname = action->data.hostname_set.hostname;
|
||||
_mdns_self_host.hostname = action->data.hostname_set.hostname;
|
||||
_mdns_restart_all_pcbs();
|
||||
|
||||
xTaskNotifyGive(action->data.hostname_set.calling_task);
|
||||
break;
|
||||
case ACTION_INSTANCE_SET:
|
||||
_mdns_send_bye_all_pcbs_no_instance(false);
|
||||
@ -3907,7 +4039,6 @@ static void _mdns_execute_action(mdns_action_t * action)
|
||||
action->data.srv_add.service->next = _mdns_server->services;
|
||||
_mdns_server->services = action->data.srv_add.service;
|
||||
_mdns_probe_all_pcbs(&action->data.srv_add.service, 1, false, false);
|
||||
|
||||
break;
|
||||
case ACTION_SERVICE_INSTANCE_SET:
|
||||
if (action->data.srv_instance.service->service->instance) {
|
||||
@ -4058,6 +4189,8 @@ static void _mdns_execute_action(mdns_action_t * action)
|
||||
pbuf_free(action->data.rx_handle.packet->pb);
|
||||
free(action->data.rx_handle.packet);
|
||||
break;
|
||||
case ACTION_DELEGATE_HOSTNAME_ADD:
|
||||
_mdns_delegate_hostname_add(action->data.delegate_hostname.hostname, &action->data.delegate_hostname.address);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -4461,7 +4594,40 @@ esp_err_t mdns_hostname_set(const char * hostname)
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
action->type = ACTION_HOSTNAME_SET;
|
||||
action->data.hostname = new_hostname;
|
||||
action->data.hostname_set.hostname = new_hostname;
|
||||
action->data.hostname_set.calling_task = xTaskGetCurrentTaskHandle();
|
||||
if (xQueueSend(_mdns_server->action_queue, &action, (portTickType)0) != pdPASS) {
|
||||
assert(false);
|
||||
free(new_hostname);
|
||||
free(action);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
xTaskNotifyWait(0, 0, NULL, portMAX_DELAY);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
esp_err_t mdns_delegate_hostname_add(const char * hostname, const esp_ip_addr_t *address)
|
||||
{
|
||||
if (!_mdns_server) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (_str_null_or_empty(hostname) || strlen(hostname) > (MDNS_NAME_BUF_LEN - 1)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
char * new_hostname = strndup(hostname, MDNS_NAME_BUF_LEN - 1);
|
||||
if (!new_hostname) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
mdns_action_t * action = (mdns_action_t *)malloc(sizeof(mdns_action_t));
|
||||
if (!action) {
|
||||
HOOK_MALLOC_FAILED;
|
||||
free(new_hostname);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
action->type = ACTION_DELEGATE_HOSTNAME_ADD;
|
||||
action->data.delegate_hostname.hostname = new_hostname;
|
||||
action->data.delegate_hostname.address = *address;
|
||||
if (xQueueSend(_mdns_server->action_queue, &action, (portTickType)0) != pdPASS) {
|
||||
free(new_hostname);
|
||||
free(action);
|
||||
@ -4470,6 +4636,10 @@ esp_err_t mdns_hostname_set(const char * hostname)
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
bool mdns_hostname_exists(const char *hostname) {
|
||||
return _hostname_is_ours(hostname);
|
||||
}
|
||||
|
||||
esp_err_t mdns_instance_name_set(const char * instance)
|
||||
{
|
||||
if (!_mdns_server) {
|
||||
@ -4503,7 +4673,9 @@ esp_err_t mdns_instance_name_set(const char * instance)
|
||||
* MDNS SERVICES
|
||||
* */
|
||||
|
||||
esp_err_t mdns_service_add(const char * instance, const char * service, const char * proto, uint16_t port, mdns_txt_item_t txt[], size_t num_items)
|
||||
esp_err_t mdns_service_add_custom_host(const char *instance, const char *service, const char *proto,
|
||||
const char *hostname, uint16_t port,
|
||||
mdns_txt_item_t txt[], size_t num_items)
|
||||
{
|
||||
if (!_mdns_server || _str_null_or_empty(service) || _str_null_or_empty(proto) || !port) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
@ -4513,12 +4685,12 @@ esp_err_t mdns_service_add(const char * instance, const char * service, const ch
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
mdns_srv_item_t * item = _mdns_get_service_item(service, proto);
|
||||
mdns_srv_item_t * item = _mdns_get_service_item(service, proto, hostname);
|
||||
if (item) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
mdns_service_t * s = _mdns_create_service(service, proto, port, instance, num_items, txt);
|
||||
mdns_service_t * s = _mdns_create_service(service, proto, hostname, port, instance, num_items, txt);
|
||||
if (!s) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
@ -4551,7 +4723,7 @@ esp_err_t mdns_service_add(const char * instance, const char * service, const ch
|
||||
|
||||
size_t start = xTaskGetTickCount();
|
||||
size_t timeout_ticks = pdMS_TO_TICKS(MDNS_SERVICE_ADD_TIMEOUT_MS);
|
||||
while (_mdns_get_service_item(service, proto) == NULL)
|
||||
while (_mdns_get_service_item(service, proto, hostname) == NULL)
|
||||
{
|
||||
uint32_t expired = xTaskGetTickCount() - start;
|
||||
if (expired >= timeout_ticks) {
|
||||
@ -4563,12 +4735,24 @@ esp_err_t mdns_service_add(const char * instance, const char * service, const ch
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t mdns_service_port_set(const char * service, const char * proto, uint16_t port)
|
||||
esp_err_t mdns_service_add(const char *instance, const char *service, const char *proto, uint16_t port,
|
||||
mdns_txt_item_t txt[], size_t num_items)
|
||||
{
|
||||
assert(_mdns_server->hostname != NULL);
|
||||
return mdns_service_add_custom_host(instance, service, proto, _mdns_server->hostname, port, txt, num_items);
|
||||
}
|
||||
|
||||
bool mdns_service_exists(const char *service_type, const char *proto, const char *hostname)
|
||||
{
|
||||
return _mdns_get_service_item(service_type, proto, hostname) != NULL;
|
||||
}
|
||||
|
||||
esp_err_t mdns_service_port_set_for_host(const char *service, const char *proto, const char *hostname, uint16_t port)
|
||||
{
|
||||
if (!_mdns_server || !_mdns_server->services || _str_null_or_empty(service) || _str_null_or_empty(proto) || !port) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
mdns_srv_item_t * s = _mdns_get_service_item(service, proto);
|
||||
mdns_srv_item_t * s = _mdns_get_service_item(service, proto, hostname);
|
||||
if (!s) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
@ -4588,12 +4772,17 @@ esp_err_t mdns_service_port_set(const char * service, const char * proto, uint16
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t mdns_service_txt_set(const char * service, const char * proto, mdns_txt_item_t txt[], uint8_t num_items)
|
||||
esp_err_t mdns_service_port_set(const char *service, const char *proto, uint16_t port) {
|
||||
return mdns_service_port_set_for_host(service, proto, _mdns_server->hostname, port);
|
||||
}
|
||||
|
||||
esp_err_t mdns_service_txt_set_for_host(const char *service, const char *proto, const char *hostname,
|
||||
mdns_txt_item_t txt[], uint8_t num_items)
|
||||
{
|
||||
if (!_mdns_server || !_mdns_server->services || _str_null_or_empty(service) || _str_null_or_empty(proto) || (num_items && txt == NULL)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
mdns_srv_item_t * s = _mdns_get_service_item(service, proto);
|
||||
mdns_srv_item_t * s = _mdns_get_service_item(service, proto, hostname);
|
||||
if (!s) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
@ -4624,13 +4813,17 @@ esp_err_t mdns_service_txt_set(const char * service, const char * proto, mdns_tx
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t mdns_service_txt_set(const char *service, const char *proto, mdns_txt_item_t txt[], uint8_t num_items)
|
||||
{
|
||||
return mdns_service_txt_set_for_host(service, proto, _mdns_server->hostname, txt, num_items);
|
||||
}
|
||||
|
||||
esp_err_t mdns_service_txt_item_set(const char * service, const char * proto, const char * key, const char * value)
|
||||
esp_err_t mdns_service_txt_item_set_for_host(const char * service, const char * proto, const char *hostname, const char * key, const char * value)
|
||||
{
|
||||
if (!_mdns_server || !_mdns_server->services || _str_null_or_empty(service) || _str_null_or_empty(proto) || _str_null_or_empty(key) || !value) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
mdns_srv_item_t * s = _mdns_get_service_item(service, proto);
|
||||
mdns_srv_item_t * s = _mdns_get_service_item(service, proto, hostname);
|
||||
if (!s) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
@ -4662,12 +4855,17 @@ esp_err_t mdns_service_txt_item_set(const char * service, const char * proto, co
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t mdns_service_txt_item_remove(const char * service, const char * proto, const char * key)
|
||||
esp_err_t mdns_service_txt_item_set(const char *service, const char *proto, const char *key, const char *value)
|
||||
{
|
||||
return mdns_service_txt_item_set_for_host(service, proto, _mdns_server->hostname, key, value);
|
||||
}
|
||||
|
||||
esp_err_t mdns_service_txt_item_remove_for_host(const char * service, const char * proto, const char *hostname, const char * key)
|
||||
{
|
||||
if (!_mdns_server || !_mdns_server->services || _str_null_or_empty(service) || _str_null_or_empty(proto) || _str_null_or_empty(key)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
mdns_srv_item_t * s = _mdns_get_service_item(service, proto);
|
||||
mdns_srv_item_t * s = _mdns_get_service_item(service, proto, hostname);
|
||||
if (!s) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
@ -4692,7 +4890,13 @@ esp_err_t mdns_service_txt_item_remove(const char * service, const char * proto,
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t mdns_service_instance_name_set(const char * service, const char * proto, const char * instance)
|
||||
esp_err_t mdns_service_txt_item_remove(const char *service, const char *proto, const char *key)
|
||||
{
|
||||
return mdns_service_txt_item_remove_for_host(service, proto, _mdns_server->hostname, key);
|
||||
}
|
||||
|
||||
esp_err_t mdns_service_instance_name_set_for_host(const char *service, const char *proto, const char *hostname,
|
||||
const char *instance)
|
||||
{
|
||||
if (!_mdns_server || !_mdns_server->services || _str_null_or_empty(service) || _str_null_or_empty(proto)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
@ -4700,7 +4904,7 @@ esp_err_t mdns_service_instance_name_set(const char * service, const char * prot
|
||||
if (_str_null_or_empty(instance) || strlen(instance) > (MDNS_NAME_BUF_LEN - 1)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
mdns_srv_item_t * s = _mdns_get_service_item(service, proto);
|
||||
mdns_srv_item_t * s = _mdns_get_service_item(service, proto, hostname);
|
||||
if (!s) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
@ -4726,12 +4930,17 @@ esp_err_t mdns_service_instance_name_set(const char * service, const char * prot
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t mdns_service_remove(const char * service, const char * proto)
|
||||
esp_err_t mdns_service_instance_name_set(const char *service, const char *proto, const char *instance)
|
||||
{
|
||||
return mdns_service_instance_name_set_for_host(service, proto, _mdns_server->hostname, instance);
|
||||
}
|
||||
|
||||
esp_err_t mdns_service_remove_for_host(const char * service, const char * proto, const char *hostname)
|
||||
{
|
||||
if (!_mdns_server || !_mdns_server->services || _str_null_or_empty(service) || _str_null_or_empty(proto)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
mdns_srv_item_t * s = _mdns_get_service_item(service, proto);
|
||||
mdns_srv_item_t * s = _mdns_get_service_item(service, proto, hostname);
|
||||
if (!s) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
@ -4750,6 +4959,11 @@ esp_err_t mdns_service_remove(const char * service, const char * proto)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t mdns_service_remove(const char *service_type, const char *proto)
|
||||
{
|
||||
return mdns_service_remove_for_host(service_type, proto, _mdns_server->hostname);
|
||||
}
|
||||
|
||||
esp_err_t mdns_service_remove_all(void)
|
||||
{
|
||||
if (!_mdns_server) {
|
||||
|
@ -17,8 +17,10 @@
|
||||
#include "esp_event_base.h"
|
||||
#include "esp_task.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_netif_ip_addr.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
//#define MDNS_ENABLE_DEBUG
|
||||
#define MDNS_ENABLE_DEBUG
|
||||
|
||||
#ifdef MDNS_ENABLE_DEBUG
|
||||
#define _mdns_dbg_printf(...) printf(__VA_ARGS__)
|
||||
@ -182,6 +184,7 @@ typedef enum {
|
||||
ACTION_TX_HANDLE,
|
||||
ACTION_RX_HANDLE,
|
||||
ACTION_TASK_STOP,
|
||||
ACTION_DELEGATE_HOSTNAME_ADD,
|
||||
ACTION_MAX
|
||||
} mdns_action_type_t;
|
||||
|
||||
@ -280,6 +283,7 @@ typedef struct {
|
||||
const char * instance;
|
||||
const char * service;
|
||||
const char * proto;
|
||||
const char * hostname;
|
||||
uint16_t priority;
|
||||
uint16_t weight;
|
||||
uint16_t port;
|
||||
@ -302,12 +306,19 @@ typedef struct mdns_out_question_s {
|
||||
bool own_dynamic_memory;
|
||||
} mdns_out_question_t;
|
||||
|
||||
typedef struct mdns_host_item_t {
|
||||
const char * hostname;
|
||||
esp_ip_addr_t address;
|
||||
struct mdns_host_item_t *next;
|
||||
} mdns_host_item_t;
|
||||
|
||||
typedef struct mdns_out_answer_s {
|
||||
struct mdns_out_answer_s * next;
|
||||
uint16_t type;
|
||||
uint8_t bye;
|
||||
uint8_t flush;
|
||||
mdns_service_t * service;
|
||||
mdns_host_item_t* host;
|
||||
const char * custom_instance;
|
||||
const char * custom_service;
|
||||
const char * custom_proto;
|
||||
@ -381,7 +392,10 @@ typedef struct mdns_server_s {
|
||||
typedef struct {
|
||||
mdns_action_type_t type;
|
||||
union {
|
||||
struct {
|
||||
char * hostname;
|
||||
xTaskHandle calling_task;
|
||||
} hostname_set;
|
||||
char * instance;
|
||||
struct {
|
||||
esp_event_base_t event_base;
|
||||
@ -424,6 +438,10 @@ typedef struct {
|
||||
struct {
|
||||
mdns_rx_packet_t * packet;
|
||||
} rx_handle;
|
||||
struct {
|
||||
const char * hostname;
|
||||
esp_ip_addr_t address;
|
||||
} delegate_hostname;
|
||||
} data;
|
||||
} mdns_action_t;
|
||||
|
||||
|
@ -24,34 +24,47 @@
|
||||
#define EXAMPLE_BUTTON_GPIO 0
|
||||
|
||||
static const char *TAG = "mdns-test";
|
||||
static char* generate_hostname(void);
|
||||
static char *generate_hostname(void);
|
||||
|
||||
#if CONFIG_MDNS_RESOLVE_TEST_SERVICES == 1
|
||||
static void query_mdns_host_with_gethostbyname(char * host);
|
||||
static void query_mdns_host_with_getaddrinfo(char * host);
|
||||
static void query_mdns_host_with_gethostbyname(char *host);
|
||||
static void query_mdns_host_with_getaddrinfo(char *host);
|
||||
#endif
|
||||
|
||||
static void initialise_mdns(void)
|
||||
{
|
||||
char* hostname = generate_hostname();
|
||||
printf("generate_hostname\n");
|
||||
char *hostname = generate_hostname();
|
||||
//initialize mDNS
|
||||
printf("mdns_init\n");
|
||||
ESP_ERROR_CHECK( mdns_init() );
|
||||
printf("mdns_hostname_set\n");
|
||||
//set mDNS hostname (required if you want to advertise services)
|
||||
ESP_ERROR_CHECK( mdns_hostname_set(hostname) );
|
||||
ESP_LOGI(TAG, "mdns hostname set to: [%s]", hostname);
|
||||
//set default mDNS instance name
|
||||
printf("mdns_instance_name_set\n");
|
||||
ESP_ERROR_CHECK( mdns_instance_name_set(EXAMPLE_MDNS_INSTANCE) );
|
||||
|
||||
//structure with TXT records
|
||||
mdns_txt_item_t serviceTxtData[3] = {
|
||||
{"board","esp32"},
|
||||
{"u","user"},
|
||||
{"p","password"}
|
||||
{"board", "esp32"},
|
||||
{"u", "user"},
|
||||
{"p", "password"}
|
||||
};
|
||||
|
||||
//initialize service
|
||||
printf("mdns_service_add\n");
|
||||
ESP_ERROR_CHECK( mdns_service_add("ESP32-WebServer", "_http", "_tcp", 80, serviceTxtData, 3) );
|
||||
esp_ip_addr_t addr;
|
||||
ip6_addr_t ip6_addr;
|
||||
ip6addr_aton("fe80::849b:bb01:415c:b722", &ip6_addr);
|
||||
addr.type = ESP_IPADDR_TYPE_V6;
|
||||
memcpy(addr.u_addr.ip6.addr, ip6_addr.addr, sizeof(ip6_addr.addr));
|
||||
ESP_ERROR_CHECK(mdns_delegate_hostname_add("test-device", &addr));
|
||||
ESP_ERROR_CHECK( mdns_service_add_custom_host("test0", "_http", "_tcp", "test-device", 1234, serviceTxtData, 3) );
|
||||
//add another TXT item
|
||||
printf("mdns_service_txt_item_set\n");
|
||||
ESP_ERROR_CHECK( mdns_service_txt_item_set("_http", "_tcp", "path", "/foobar") );
|
||||
//change TXT item value
|
||||
ESP_ERROR_CHECK( mdns_service_txt_item_set("_http", "_tcp", "u", "admin") );
|
||||
@ -59,33 +72,34 @@ static void initialise_mdns(void)
|
||||
}
|
||||
|
||||
/* these strings match tcpip_adapter_if_t enumeration */
|
||||
static const char * if_str[] = {"STA", "AP", "ETH", "MAX"};
|
||||
static const char *if_str[] = {"STA", "AP", "ETH", "MAX"};
|
||||
|
||||
/* these strings match mdns_ip_protocol_t enumeration */
|
||||
static const char * ip_protocol_str[] = {"V4", "V6", "MAX"};
|
||||
static const char *ip_protocol_str[] = {"V4", "V6", "MAX"};
|
||||
|
||||
static void mdns_print_results(mdns_result_t * results){
|
||||
mdns_result_t * r = results;
|
||||
mdns_ip_addr_t * a = NULL;
|
||||
static void mdns_print_results(mdns_result_t *results)
|
||||
{
|
||||
mdns_result_t *r = results;
|
||||
mdns_ip_addr_t *a = NULL;
|
||||
int i = 1, t;
|
||||
while(r){
|
||||
while (r) {
|
||||
printf("%d: Interface: %s, Type: %s\n", i++, if_str[r->tcpip_if], ip_protocol_str[r->ip_protocol]);
|
||||
if(r->instance_name){
|
||||
if (r->instance_name) {
|
||||
printf(" PTR : %s\n", r->instance_name);
|
||||
}
|
||||
if(r->hostname){
|
||||
if (r->hostname) {
|
||||
printf(" SRV : %s.local:%u\n", r->hostname, r->port);
|
||||
}
|
||||
if(r->txt_count){
|
||||
if (r->txt_count) {
|
||||
printf(" TXT : [%u] ", r->txt_count);
|
||||
for(t=0; t<r->txt_count; t++){
|
||||
printf("%s=%s; ", r->txt[t].key, r->txt[t].value?r->txt[t].value:"NULL");
|
||||
for (t = 0; t < r->txt_count; t++) {
|
||||
printf("%s=%s; ", r->txt[t].key, r->txt[t].value ? r->txt[t].value : "NULL");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
a = r->addr;
|
||||
while(a){
|
||||
if(a->addr.type == ESP_IPADDR_TYPE_V6){
|
||||
while (a) {
|
||||
if (a->addr.type == ESP_IPADDR_TYPE_V6) {
|
||||
printf(" AAAA: " IPV6STR "\n", IPV62STR(a->addr.u_addr.ip6));
|
||||
} else {
|
||||
printf(" A : " IPSTR "\n", IP2STR(&(a->addr.u_addr.ip4)));
|
||||
@ -97,17 +111,17 @@ static void mdns_print_results(mdns_result_t * results){
|
||||
|
||||
}
|
||||
|
||||
static void query_mdns_service(const char * service_name, const char * proto)
|
||||
static void query_mdns_service(const char *service_name, const char *proto)
|
||||
{
|
||||
ESP_LOGI(TAG, "Query PTR: %s.%s.local", service_name, proto);
|
||||
|
||||
mdns_result_t * results = NULL;
|
||||
mdns_result_t *results = NULL;
|
||||
esp_err_t err = mdns_query_ptr(service_name, proto, 3000, 20, &results);
|
||||
if(err){
|
||||
if (err) {
|
||||
ESP_LOGE(TAG, "Query Failed: %s", esp_err_to_name(err));
|
||||
return;
|
||||
}
|
||||
if(!results){
|
||||
if (!results) {
|
||||
ESP_LOGW(TAG, "No results found!");
|
||||
return;
|
||||
}
|
||||
@ -116,7 +130,7 @@ static void query_mdns_service(const char * service_name, const char * proto)
|
||||
mdns_query_results_free(results);
|
||||
}
|
||||
|
||||
static void query_mdns_host(const char * host_name)
|
||||
static void query_mdns_host(const char *host_name)
|
||||
{
|
||||
ESP_LOGI(TAG, "Query A: %s.local", host_name);
|
||||
|
||||
@ -124,8 +138,8 @@ static void query_mdns_host(const char * host_name)
|
||||
addr.addr = 0;
|
||||
|
||||
esp_err_t err = mdns_query_a(host_name, 2000, &addr);
|
||||
if(err){
|
||||
if(err == ESP_ERR_NOT_FOUND){
|
||||
if (err) {
|
||||
if (err == ESP_ERR_NOT_FOUND) {
|
||||
ESP_LOGW(TAG, "%s: Host was not found!", esp_err_to_name(err));
|
||||
return;
|
||||
}
|
||||
@ -174,7 +188,7 @@ static void mdns_example_task(void *pvParameters)
|
||||
query_mdns_host_with_getaddrinfo("tinytester-lwip.local");
|
||||
#endif
|
||||
|
||||
while(1) {
|
||||
while (1) {
|
||||
check_button();
|
||||
vTaskDelay(50 / portTICK_PERIOD_MS);
|
||||
}
|
||||
@ -201,7 +215,7 @@ void app_main(void)
|
||||
/** Generate host name based on sdkconfig, optionally adding a portion of MAC address to it.
|
||||
* @return host name string allocated from the heap
|
||||
*/
|
||||
static char* generate_hostname(void)
|
||||
static char *generate_hostname(void)
|
||||
{
|
||||
#ifndef CONFIG_MDNS_ADD_MAC_TO_HOSTNAME
|
||||
return strdup(CONFIG_MDNS_HOSTNAME);
|
||||
@ -221,7 +235,7 @@ static char* generate_hostname(void)
|
||||
* @brief Executes gethostbyname and displays list of resolved addresses.
|
||||
* Note: This function is used only to test advertised mdns hostnames resolution
|
||||
*/
|
||||
static void query_mdns_host_with_gethostbyname(char * host)
|
||||
static void query_mdns_host_with_gethostbyname(char *host)
|
||||
{
|
||||
struct hostent *res = gethostbyname(host);
|
||||
if (res) {
|
||||
@ -237,10 +251,10 @@ static void query_mdns_host_with_gethostbyname(char * host)
|
||||
* @brief Executes getaddrinfo and displays list of resolved addresses.
|
||||
* Note: This function is used only to test advertised mdns hostnames resolution
|
||||
*/
|
||||
static void query_mdns_host_with_getaddrinfo(char * host)
|
||||
static void query_mdns_host_with_getaddrinfo(char *host)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
struct addrinfo * res;
|
||||
struct addrinfo *res;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
@ -249,8 +263,8 @@ static void query_mdns_host_with_getaddrinfo(char * host)
|
||||
if (!getaddrinfo(host, NULL, &hints, &res)) {
|
||||
while (res) {
|
||||
ESP_LOGI(TAG, "getaddrinfo: %s resolved to: %s", host,
|
||||
res->ai_family == AF_INET?
|
||||
inet_ntoa(((struct sockaddr_in *) res->ai_addr)->sin_addr):
|
||||
res->ai_family == AF_INET ?
|
||||
inet_ntoa(((struct sockaddr_in *) res->ai_addr)->sin_addr) :
|
||||
inet_ntoa(((struct sockaddr_in6 *) res->ai_addr)->sin6_addr));
|
||||
res = res->ai_next;
|
||||
}
|
||||
|
Reference in New Issue
Block a user