mdns: add mdns delegation

This allows publishing mdns services for other devices.


* Original commit: espressif/esp-idf@401ff56cc1
This commit is contained in:
Jiacheng Guo
2021-03-30 13:19:01 +08:00
committed by suren-gabrielyan-espressif
parent b62b4b3e25
commit 1eb5df9780
4 changed files with 494 additions and 220 deletions

View File

@ -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
*

View File

@ -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;
}
str[0] = _mdns_server->hostname;
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,54 +959,71 @@ 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) {
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;
}
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) {
return 0;
}
if (!_mdns_if_is_dup(tcpip_if)) {
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;
}
if (esp_netif_get_ip_info(_mdns_get_esp_netif(tcpip_if), &if_ip_info)) {
return 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)) {
return 1;
}
mdns_if_t other_if = _mdns_get_other_if (tcpip_if);
if (esp_netif_get_ip_info(_mdns_get_esp_netif(other_if), &if_ip_info)) {
return 1;
}
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;
}
}
mdns_if_t other_if = _mdns_get_other_if (tcpip_if);
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) {
return 2;
}
return 1;
}
#if CONFIG_LWIP_IPV6
else if (answer->type == MDNS_TYPE_AAAA) {
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;
}
if (esp_netif_get_ip6_linklocal(_mdns_get_esp_netif(tcpip_if), &if_ip6)) {
return 0;
}
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) {
return 0;
}
if (!_mdns_if_is_dup(tcpip_if)) {
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;
}
if (esp_netif_get_ip6_linklocal(_mdns_get_esp_netif(tcpip_if), &if_ip6)) {
return 0;
}
if (_ipv6_address_is_zero(if_ip6)) {
return 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)) {
return 1;
}
mdns_if_t other_if = _mdns_get_other_if (tcpip_if);
if (esp_netif_get_ip6_linklocal(_mdns_get_esp_netif(other_if), &if_ip6)) {
return 1;
}
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;
}
}
mdns_if_t other_if = _mdns_get_other_if (tcpip_if);
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) {
return 2;
}
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,82 +1397,60 @@ 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;
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;
}
}
service = service->next;
}
}
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_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)) {
_mdns_free_tx_packet(packet);
return;
}
#ifdef MDNS_REPEAT_QUERY_IN_RESPONSE
mdns_out_question_t * out_question = malloc(sizeof(mdns_out_question_t));
if (out_question == NULL) {
HOOK_MALLOC_FAILED;
_mdns_free_tx_packet(packet);
return;
}
out_question->type = q->type;
out_question->unicast = q->unicast;
out_question->host = q->host;
q->host = NULL;
out_question->service = q->service;
q->service = NULL;
out_question->proto = q->proto;
q->proto = NULL;
out_question->domain = q->domain;
q->domain = NULL;
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)) {
} 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;
_mdns_free_tx_packet(packet);
return;
}
out_question->type = q->type;
out_question->unicast = q->unicast;
out_question->host = q->host;
q->host = NULL;
out_question->service = q->service;
q->service = NULL;
out_question->proto = q->proto;
q->proto = NULL;
out_question->domain = q->domain;
q->domain = NULL;
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
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,18 +1572,9 @@ 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)) {
_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;
}
if (!_mdns_append_host_list(&packet->servers, false, false)) {
_mdns_free_tx_packet(packet);
return NULL;
}
}
@ -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) {

View File

@ -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 {
char * hostname;
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;