Skip to content

Commit c62b920

Browse files
committed
fix(mdns): Fix API races adding txt item for services
Fixes **API race issue** (described in 8a69050) for API mdns_service_txt_item_set_for_host_with_explicit_value_len()
1 parent a927bf3 commit c62b920

File tree

2 files changed

+43
-86
lines changed

2 files changed

+43
-86
lines changed

components/mdns/mdns.c

Lines changed: 43 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -5111,10 +5111,6 @@ static void _mdns_free_action(mdns_action_t *action)
51115111
case ACTION_SERVICE_INSTANCE_SET:
51125112
free(action->data.srv_instance.instance);
51135113
break;
5114-
case ACTION_SERVICE_TXT_SET:
5115-
free(action->data.srv_txt_set.key);
5116-
free(action->data.srv_txt_set.value);
5117-
break;
51185114
case ACTION_SERVICE_TXT_DEL:
51195115
free(action->data.srv_txt_del.key);
51205116
break;
@@ -5164,7 +5160,6 @@ static void _mdns_execute_action(mdns_action_t *action)
51645160
mdns_srv_item_t *a = NULL;
51655161
mdns_service_t *service;
51665162
char *key;
5167-
char *value;
51685163
char *subtype;
51695164
mdns_subtype_t *subtype_item;
51705165
mdns_txt_linked_item_t *txt, * t;
@@ -5197,38 +5192,6 @@ static void _mdns_execute_action(mdns_action_t *action)
51975192
action->data.srv_instance.service->service->instance = action->data.srv_instance.instance;
51985193
_mdns_probe_all_pcbs(&action->data.srv_instance.service, 1, false, false);
51995194

5200-
break;
5201-
case ACTION_SERVICE_TXT_SET:
5202-
service = action->data.srv_txt_set.service->service;
5203-
key = action->data.srv_txt_set.key;
5204-
value = action->data.srv_txt_set.value;
5205-
txt = service->txt;
5206-
while (txt) {
5207-
if (strcmp(txt->key, key) == 0) {
5208-
free((char *)txt->value);
5209-
free(key);
5210-
txt->value = value;
5211-
txt->value_len = action->data.srv_txt_set.value_len;
5212-
break;
5213-
}
5214-
txt = txt->next;
5215-
}
5216-
if (!txt) {
5217-
txt = (mdns_txt_linked_item_t *)malloc(sizeof(mdns_txt_linked_item_t));
5218-
if (!txt) {
5219-
HOOK_MALLOC_FAILED;
5220-
_mdns_free_action(action);
5221-
return;
5222-
}
5223-
txt->key = key;
5224-
txt->value = value;
5225-
txt->value_len = action->data.srv_txt_set.value_len;
5226-
txt->next = service->txt;
5227-
service->txt = txt;
5228-
}
5229-
5230-
_mdns_announce_all_pcbs(&action->data.srv_txt_set.service, 1, false);
5231-
52325195
break;
52335196
case ACTION_SERVICE_TXT_DEL:
52345197
service = action->data.srv_txt_del.service->service;
@@ -5258,7 +5221,7 @@ static void _mdns_execute_action(mdns_action_t *action)
52585221
}
52595222
free(key);
52605223

5261-
_mdns_announce_all_pcbs(&action->data.srv_txt_set.service, 1, false);
5224+
_mdns_announce_all_pcbs(&action->data.srv_txt_del.service, 1, false);
52625225

52635226
break;
52645227
case ACTION_SERVICE_SUBTYPE_ADD:
@@ -6281,51 +6244,53 @@ esp_err_t mdns_service_txt_set(const char *service, const char *proto, mdns_txt_
62816244
}
62826245

62836246
esp_err_t mdns_service_txt_item_set_for_host_with_explicit_value_len(const char *instance, const char *service, const char *proto,
6284-
const char *hostname, const char *key,
6285-
const char *value, uint8_t value_len)
6247+
const char *host, const char *key, const char *value_arg, uint8_t value_len)
62866248
{
62876249
MDNS_SERVICE_LOCK();
6288-
if (!_mdns_server || !_mdns_server->services || _str_null_or_empty(service) || _str_null_or_empty(proto) ||
6289-
_str_null_or_empty(key) || (!value && value_len)) {
6290-
MDNS_SERVICE_UNLOCK();
6291-
return ESP_ERR_INVALID_ARG;
6292-
}
6250+
esp_err_t ret = ESP_OK;
6251+
const char *hostname = host ? host : _mdns_server->hostname;
6252+
ESP_GOTO_ON_FALSE(_mdns_server && _mdns_server->services && !_str_null_or_empty(service) && !_str_null_or_empty(proto) && !_str_null_or_empty(key) &&
6253+
!((!value_arg && value_len)), ESP_ERR_INVALID_ARG, err, TAG, "Invalid state or arguments");
6254+
62936255
mdns_srv_item_t *s = _mdns_get_service_item_instance(instance, service, proto, hostname);
6294-
MDNS_SERVICE_UNLOCK();
6295-
if (!s) {
6296-
return ESP_ERR_NOT_FOUND;
6297-
}
6298-
mdns_action_t *action = (mdns_action_t *)malloc(sizeof(mdns_action_t));
6299-
if (!action) {
6300-
HOOK_MALLOC_FAILED;
6301-
return ESP_ERR_NO_MEM;
6302-
}
6256+
ESP_GOTO_ON_FALSE(s, ESP_ERR_NOT_FOUND, err, TAG, "Service doesn't exist");
63036257

6304-
action->type = ACTION_SERVICE_TXT_SET;
6305-
action->data.srv_txt_set.service = s;
6306-
action->data.srv_txt_set.key = strdup(key);
6307-
if (!action->data.srv_txt_set.key) {
6308-
free(action);
6309-
return ESP_ERR_NO_MEM;
6310-
}
6258+
mdns_service_t *srv = s->service;
6259+
char *value = NULL;
63116260
if (value_len > 0) {
6312-
action->data.srv_txt_set.value = (char *)malloc(value_len);
6313-
if (!action->data.srv_txt_set.value) {
6314-
free(action->data.srv_txt_set.key);
6315-
free(action);
6316-
return ESP_ERR_NO_MEM;
6317-
}
6318-
memcpy(action->data.srv_txt_set.value, value, value_len);
6319-
action->data.srv_txt_set.value_len = value_len;
6261+
value = (char *) malloc(value_len);
6262+
ESP_GOTO_ON_FALSE(s, ESP_ERR_NO_MEM, err, TAG, "Out of memory");
6263+
memcpy(value, value_arg, value_len);
63206264
} else {
6321-
action->data.srv_txt_set.value = NULL;
6322-
action->data.srv_txt_set.value_len = 0;
6265+
value_len = 0;
63236266
}
6324-
if (xQueueSend(_mdns_server->action_queue, &action, (TickType_t)0) != pdPASS) {
6325-
free(action->data.srv_txt_set.key);
6326-
free(action->data.srv_txt_set.value);
6327-
free(action);
6328-
return ESP_ERR_NO_MEM;
6267+
mdns_txt_linked_item_t *txt = srv->txt;
6268+
while (txt) {
6269+
if (strcmp(txt->key, key) == 0) {
6270+
free((char *)txt->value);
6271+
txt->value = value;
6272+
txt->value_len = value_len;
6273+
break;
6274+
}
6275+
txt = txt->next;
6276+
}
6277+
if (!txt) {
6278+
txt = (mdns_txt_linked_item_t *)malloc(sizeof(mdns_txt_linked_item_t));
6279+
ESP_GOTO_ON_FALSE(s, ESP_ERR_NO_MEM, err, TAG, "Out of memory");
6280+
txt->key = strdup(key);
6281+
ESP_GOTO_ON_FALSE(txt->key, ESP_ERR_NO_MEM, err, TAG, "Out of memory");
6282+
txt->value = value;
6283+
txt->value_len = value_len;
6284+
txt->next = srv->txt;
6285+
srv->txt = txt;
6286+
}
6287+
6288+
_mdns_announce_all_pcbs(&s, 1, false);
6289+
6290+
err:
6291+
MDNS_SERVICE_UNLOCK();
6292+
if (ret == ESP_ERR_NO_MEM) {
6293+
HOOK_MALLOC_FAILED;
63296294
}
63306295
return ESP_OK;
63316296
}
@@ -6343,7 +6308,7 @@ esp_err_t mdns_service_txt_item_set(const char *service, const char *proto, cons
63436308
if (!_mdns_server) {
63446309
return ESP_ERR_INVALID_STATE;
63456310
}
6346-
return mdns_service_txt_item_set_for_host_with_explicit_value_len(NULL, service, proto, _mdns_server->hostname, key,
6311+
return mdns_service_txt_item_set_for_host_with_explicit_value_len(NULL, service, proto, NULL, key,
63476312
value, strlen(value));
63486313
}
63496314

@@ -6353,8 +6318,7 @@ esp_err_t mdns_service_txt_item_set_with_explicit_value_len(const char *service,
63536318
if (!_mdns_server) {
63546319
return ESP_ERR_INVALID_STATE;
63556320
}
6356-
return mdns_service_txt_item_set_for_host_with_explicit_value_len(NULL, service, proto, _mdns_server->hostname, key,
6357-
value, value_len);
6321+
return mdns_service_txt_item_set_for_host_with_explicit_value_len(NULL, service, proto, NULL, key, value, value_len);
63586322
}
63596323

63606324
esp_err_t mdns_service_txt_item_remove_for_host(const char *instance, const char *service, const char *proto, const char *hostname,

components/mdns/private_include/mdns_private.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,6 @@ typedef enum {
188188
ACTION_HOSTNAME_SET,
189189
ACTION_INSTANCE_SET,
190190
ACTION_SERVICE_INSTANCE_SET,
191-
ACTION_SERVICE_TXT_SET,
192191
ACTION_SERVICE_TXT_DEL,
193192
ACTION_SERVICE_SUBTYPE_ADD,
194193
ACTION_SERVICES_CLEAR,
@@ -446,12 +445,6 @@ typedef struct {
446445
mdns_srv_item_t *service;
447446
char *instance;
448447
} srv_instance;
449-
struct {
450-
mdns_srv_item_t *service;
451-
char *key;
452-
char *value;
453-
uint8_t value_len;
454-
} srv_txt_set;
455448
struct {
456449
mdns_srv_item_t *service;
457450
char *key;

0 commit comments

Comments
 (0)