diff --git a/components/mdns/include/mdns.h b/components/mdns/include/mdns.h index 40ad126736..cfbdadcbfc 100644 --- a/components/mdns/include/mdns.h +++ b/components/mdns/include/mdns.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -60,6 +60,14 @@ typedef enum mdns_if_internal { MDNS_IF_MAX } mdns_if_t; +/** + * @brief mDNS query type to be explicitly set to either Unicast or Multicast + */ +typedef enum { + MDNS_QUERY_UNICAST, + MDNS_QUERY_MULTICAST, +} mdns_query_transmission_type_t; + /** * @brief mDNS query result structure */ @@ -573,13 +581,37 @@ mdns_search_once_t *mdns_query_async_new(const char *name, const char *service_t uint32_t timeout, size_t max_results, mdns_query_notify_t notifier); /** - * @brief Query mDNS for host or service + * @brief Generic mDNS query * All following query methods are derived from this one * * @param name service instance or host name (NULL for PTR queries) * @param service_type service type (_http, _arduino, _ftp etc.) (NULL for host queries) * @param proto service protocol (_tcp, _udp, etc.) (NULL for host queries) * @param type type of query (MDNS_TYPE_*) + * @param transmission_type either Unicast query, or Multicast query + * @param timeout time in milliseconds to wait for answers. + * @param max_results maximum results to be collected + * @param results pointer to the results of the query + * results must be freed using mdns_query_results_free below + * + * @return + * - ESP_OK success + * - ESP_ERR_INVALID_STATE mDNS is not running + * - ESP_ERR_NO_MEM memory error + * - ESP_ERR_INVALID_ARG timeout was not given + */ +esp_err_t mdns_query_generic(const char * name, const char * service_type, const char * proto, uint16_t type, + mdns_query_transmission_type_t transmission_type, uint32_t timeout, size_t max_results, mdns_result_t ** results); + +/** + * @brief Query mDNS for host or service + * + * Note that querying PTR types sends Multicast query, all other types send Unicast queries + * + * @param name service instance or host name (NULL for PTR queries) + * @param service_type service type (_http, _arduino, _ftp etc.) (NULL for host queries) + * @param proto service protocol (_tcp, _udp, etc.) (NULL for host queries) + * @param type type of query (MDNS_TYPE_*) * @param timeout time in milliseconds to wait for answers. * @param max_results maximum results to be collected * @param results pointer to the results of the query diff --git a/components/mdns/mdns.c b/components/mdns/mdns.c index 0faa0b509d..d3e2f82e91 100644 --- a/components/mdns/mdns.c +++ b/components/mdns/mdns.c @@ -3786,7 +3786,7 @@ static void _mdns_search_free(mdns_search_once_t * search) /** * @brief Allocate new search structure */ -static mdns_search_once_t *_mdns_search_init(const char *name, const char *service, const char *proto, uint16_t type, +static mdns_search_once_t *_mdns_search_init(const char *name, const char *service, const char *proto, uint16_t type, bool unicast, uint32_t timeout, uint8_t max_results, mdns_query_notify_t notifier) { mdns_search_once_t * search = (mdns_search_once_t *)malloc(sizeof(mdns_search_once_t)); @@ -3827,6 +3827,7 @@ static mdns_search_once_t *_mdns_search_init(const char *name, const char *servi } search->type = type; + search->unicast = unicast; search->timeout = timeout; search->num_results = 0; search->max_results = max_results; @@ -4170,7 +4171,7 @@ static mdns_search_once_t * _mdns_search_find_from(mdns_search_once_t * s, mdns_ continue; } if (s->type != MDNS_TYPE_PTR) { - if (!strcasecmp(name->host, s->instance)) { + if (s->instance && strcasecmp(name->host, s->instance) == 0) { return s; } s = s->next; @@ -4207,7 +4208,7 @@ static mdns_tx_packet_t * _mdns_create_search_packet(mdns_search_once_t * search return NULL; } q->next = NULL; - q->unicast = search->type != MDNS_TYPE_PTR; + q->unicast = search->unicast; q->type = search->type; q->host = search->instance; q->service = search->service; @@ -5610,7 +5611,7 @@ mdns_search_once_t *mdns_query_async_new(const char *name, const char *service, return NULL; } - search = _mdns_search_init(name, service, proto, type, timeout, max_results, notifier); + search = _mdns_search_init(name, service, proto, type, type != MDNS_TYPE_PTR, timeout, max_results, notifier); if (!search) { return NULL; } @@ -5623,7 +5624,7 @@ mdns_search_once_t *mdns_query_async_new(const char *name, const char *service, return search; } -esp_err_t mdns_query(const char * name, const char * service, const char * proto, uint16_t type, uint32_t timeout, size_t max_results, mdns_result_t ** results) +esp_err_t mdns_query_generic(const char * name, const char * service, const char * proto, uint16_t type, mdns_query_transmission_type_t transmission_type, uint32_t timeout, size_t max_results, mdns_result_t ** results) { mdns_search_once_t * search = NULL; @@ -5637,7 +5638,7 @@ esp_err_t mdns_query(const char * name, const char * service, const char * proto return ESP_ERR_INVALID_ARG; } - search = _mdns_search_init(name, service, proto, type, timeout, max_results, NULL); + search = _mdns_search_init(name, service, proto, type, transmission_type == MDNS_QUERY_UNICAST, timeout, max_results, NULL); if (!search) { return ESP_ERR_NO_MEM; } @@ -5654,6 +5655,11 @@ esp_err_t mdns_query(const char * name, const char * service, const char * proto return ESP_OK; } +esp_err_t mdns_query(const char * name, const char * service_type, const char * proto, uint16_t type, uint32_t timeout, size_t max_results, mdns_result_t ** results) +{ + return mdns_query_generic(name, service_type, proto, type, type != MDNS_TYPE_PTR, timeout, max_results, results); +} + esp_err_t mdns_query_ptr(const char * service, const char * proto, uint32_t timeout, size_t max_results, mdns_result_t ** results) { if (_str_null_or_empty(service) || _str_null_or_empty(proto)) { diff --git a/components/mdns/private_include/mdns_private.h b/components/mdns/private_include/mdns_private.h index a92fb8dd2a..e8af394b37 100644 --- a/components/mdns/private_include/mdns_private.h +++ b/components/mdns/private_include/mdns_private.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -368,6 +368,7 @@ typedef struct mdns_search_once_s { mdns_query_notify_t notifier; SemaphoreHandle_t done_semaphore; uint16_t type; + bool unicast; uint8_t max_results; uint8_t num_results; char * instance; diff --git a/components/mdns/test_afl_fuzz_host/mdns_di.h b/components/mdns/test_afl_fuzz_host/mdns_di.h index 12c0c56f77..79dc00f33b 100644 --- a/components/mdns/test_afl_fuzz_host/mdns_di.h +++ b/components/mdns/test_afl_fuzz_host/mdns_di.h @@ -8,15 +8,15 @@ void (*mdns_test_static_execute_action)(mdns_action_t *) = NULL; mdns_srv_item_t * (*mdns_test_static_mdns_get_service_item)(const char * service, const char * proto, const char *hostname) = NULL; -mdns_search_once_t *(*mdns_test_static_search_init)(const char *name, const char *service, const char *proto, - uint16_t type, uint32_t timeout, uint8_t max_results, +mdns_search_once_t *(*mdns_test_static_search_init)(const char *name, const char *service, const char *proto, uint16_t type, bool unicast, + uint32_t timeout, uint8_t max_results, mdns_query_notify_t notifier) = NULL; esp_err_t (*mdns_test_static_send_search_action)(mdns_action_type_t type, mdns_search_once_t * search) = NULL; void (*mdns_test_static_search_free)(mdns_search_once_t * search) = NULL; static void _mdns_execute_action(mdns_action_t * action); static mdns_srv_item_t * _mdns_get_service_item(const char * service, const char * proto, const char *hostname); -static mdns_search_once_t *_mdns_search_init(const char *name, const char *service, const char *proto, uint16_t type, +static mdns_search_once_t *_mdns_search_init(const char *name, const char *service, const char *proto, uint16_t type, bool unicast, uint32_t timeout, uint8_t max_results, mdns_query_notify_t notifier); static esp_err_t _mdns_send_search_action(mdns_action_type_t type, mdns_search_once_t * search); static void _mdns_search_free(mdns_search_once_t * search); @@ -47,7 +47,7 @@ esp_err_t mdns_test_send_search_action(mdns_action_type_t type, mdns_search_once mdns_search_once_t * mdns_test_search_init(const char * name, const char * service, const char * proto, uint16_t type, uint32_t timeout, uint8_t max_results) { - return mdns_test_static_search_init(name, service, proto, type, timeout, max_results, NULL); + return mdns_test_static_search_init(name, service, proto, type, timeout, type != MDNS_TYPE_PTR, max_results, NULL); } mdns_srv_item_t * mdns_test_mdns_get_service_item(const char * service, const char * proto)