From c48ae399d00892c09c32b1668fd2e6ff361b4705 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Tue, 23 Jul 2024 11:11:11 +0200 Subject: [PATCH] fix(mdns): Fix API races when removing all services Fixes **API race issue** (described in 8a690503) for API mdns_service_remove_all() --- components/mdns/mdns.c | 49 +++++++------------ .../mdns/private_include/mdns_private.h | 1 - 2 files changed, 18 insertions(+), 32 deletions(-) diff --git a/components/mdns/mdns.c b/components/mdns/mdns.c index 66c5eeb558..002306b603 100644 --- a/components/mdns/mdns.c +++ b/components/mdns/mdns.c @@ -5148,8 +5148,6 @@ static void _mdns_free_action(mdns_action_t *action) */ static void _mdns_execute_action(mdns_action_t *action) { - mdns_srv_item_t *a = NULL; - switch (action->type) { case ACTION_SYSTEM_EVENT: perform_event_action(action->data.sys_event.interface, action->data.sys_event.event_action); @@ -5169,19 +5167,6 @@ static void _mdns_execute_action(mdns_action_t *action) _mdns_server->instance = action->data.instance; _mdns_restart_all_pcbs_no_instance(); - break; - case ACTION_SERVICES_CLEAR: - _mdns_send_final_bye(false); - a = _mdns_server->services; - _mdns_server->services = NULL; - while (a) { - mdns_srv_item_t *s = a; - a = a->next; - _mdns_remove_scheduled_service_packets(s->service); - _mdns_free_service(s->service); - free(s); - } - break; case ACTION_SEARCH_ADD: _mdns_search_add(action->data.search_add.search); @@ -5226,6 +5211,7 @@ static void _mdns_execute_action(mdns_action_t *action) free((char *)action->data.delegate_hostname.hostname); free_address_list(action->data.delegate_hostname.address_list); } + xSemaphoreGive(_mdns_server->action_sema); break; case ACTION_DELEGATE_HOSTNAME_SET_ADDR: if (!_mdns_delegate_hostname_set_address(action->data.delegate_hostname.hostname, @@ -5789,6 +5775,7 @@ esp_err_t mdns_delegate_hostname_add(const char *hostname, const mdns_ip_addr_t free(action); return ESP_ERR_NO_MEM; } + xSemaphoreTake(_mdns_server->action_sema, portMAX_DELAY); return ESP_OK; } @@ -6453,27 +6440,27 @@ esp_err_t mdns_service_remove(const char *service_type, const char *proto) esp_err_t mdns_service_remove_all(void) { - if (!_mdns_server) { - return ESP_ERR_INVALID_ARG; - } MDNS_SERVICE_LOCK(); + esp_err_t ret = ESP_OK; + ESP_GOTO_ON_FALSE(_mdns_server, ESP_ERR_INVALID_ARG, done, TAG, "Invalid state"); if (!_mdns_server->services) { - MDNS_SERVICE_UNLOCK(); - return ESP_OK; + goto done; } - MDNS_SERVICE_UNLOCK(); - mdns_action_t *action = (mdns_action_t *)malloc(sizeof(mdns_action_t)); - if (!action) { - HOOK_MALLOC_FAILED; - return ESP_ERR_NO_MEM; - } - action->type = ACTION_SERVICES_CLEAR; - if (xQueueSend(_mdns_server->action_queue, &action, (TickType_t)0) != pdPASS) { - free(action); - return ESP_ERR_NO_MEM; + _mdns_send_final_bye(false); + mdns_srv_item_t *services = _mdns_server->services; + _mdns_server->services = NULL; + while (services) { + mdns_srv_item_t *s = services; + services = services->next; + _mdns_remove_scheduled_service_packets(s->service); + _mdns_free_service(s->service); + free(s); } - return ESP_OK; + +done: + MDNS_SERVICE_UNLOCK(); + return ret; } /* diff --git a/components/mdns/private_include/mdns_private.h b/components/mdns/private_include/mdns_private.h index 9b6554fd94..381bd4be43 100644 --- a/components/mdns/private_include/mdns_private.h +++ b/components/mdns/private_include/mdns_private.h @@ -187,7 +187,6 @@ typedef enum { ACTION_SYSTEM_EVENT, ACTION_HOSTNAME_SET, ACTION_INSTANCE_SET, - ACTION_SERVICES_CLEAR, ACTION_SEARCH_ADD, ACTION_SEARCH_SEND, ACTION_SEARCH_END,