Просмотр исходного кода

mdns: Allow for unicast PTR queries

Adresses https://github.com/espressif/esp-idf/issues/7932
David Cermak 4 лет назад
Родитель
Сommit
7eeeb01ea7

+ 25 - 2
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
  */
@@ -573,13 +573,36 @@ 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  unicast      true for Unicast query, false for 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, bool unicast, 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

+ 11 - 5
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;
@@ -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, bool unicast, 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, 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)) {

+ 2 - 1
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;

+ 4 - 4
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)