Skip to content

Commit

Permalink
fix(mdns): remove same protocol services with different instances
Browse files Browse the repository at this point in the history
  • Loading branch information
DejinChen committed May 31, 2024
1 parent 3f12ef6 commit 042533a
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 22 deletions.
109 changes: 88 additions & 21 deletions components/mdns/mdns.c
Original file line number Diff line number Diff line change
Expand Up @@ -5200,28 +5200,57 @@ static void _mdns_execute_action(mdns_action_t *action)
break;
case ACTION_SERVICE_DEL:
a = _mdns_server->services;
if (action->data.srv_del.service) {
if (_mdns_server->services == action->data.srv_del.service) {
_mdns_server->services = a->next;
_mdns_send_bye(&a, 1, false);
_mdns_remove_scheduled_service_packets(a->service);
_mdns_free_service(a->service);
free(a);
} else {
while (a->next && a->next != action->data.srv_del.service) {
a = a->next;
mdns_srv_item_t *b = a;
if (action->data.srv_del.instance) {
while (a) {
if (_mdns_service_match_instance(a->service, action->data.srv_del.instance,
action->data.srv_del.service, action->data.srv_del.proto,
action->data.srv_del.hostname)) {
if (_mdns_server->services != a) {
b->next = a->next;
} else {
_mdns_server->services = a->next;
}
_mdns_send_bye(&a, 1, false);
_mdns_remove_scheduled_service_packets(a->service);
_mdns_free_service(a->service);
free(a);
break;
}
if (a->next == action->data.srv_del.service) {
mdns_srv_item_t *b = a->next;
a->next = a->next->next;
_mdns_send_bye(&b, 1, false);
_mdns_remove_scheduled_service_packets(b->service);
_mdns_free_service(b->service);
free(b);
b = a;
a = a->next;
}
} else {
while (a) {
if (_mdns_service_match(a->service, action->data.srv_del.service, action->data.srv_del.proto,
action->data.srv_del.hostname)) {
if (_mdns_server->services != a) {
b->next = a->next;
_mdns_send_bye(&a, 1, false);
_mdns_remove_scheduled_service_packets(a->service);
_mdns_free_service(a->service);
free(a);
a = b->next;
continue;
} else {
_mdns_server->services = a->next;
_mdns_send_bye(&a, 1, false);
_mdns_remove_scheduled_service_packets(a->service);
_mdns_free_service(a->service);
free(a);
a = _mdns_server->services;
b = a;
continue;
}
}
b = a;
a = a->next;
}
}

free((char *)action->data.srv_del.instance);
free((char *)action->data.srv_del.service);
free((char *)action->data.srv_del.proto);
free((char *)action->data.srv_del.hostname);
break;
case ACTION_SERVICES_CLEAR:
_mdns_send_final_bye(false);
Expand Down Expand Up @@ -6401,6 +6430,16 @@ esp_err_t mdns_service_subtype_add_for_host(const char *instance_name, const cha
if (!s) {
return ESP_ERR_NOT_FOUND;
}

mdns_subtype_t *srv_subtype = s->service->subtype;
while (srv_subtype) {
if (strcmp(srv_subtype->subtype, subtype) == 0) {
// The same subtype has already been added
return ESP_ERR_INVALID_ARG;
}
srv_subtype = srv_subtype->next;
}

mdns_action_t *action = (mdns_action_t *)malloc(sizeof(mdns_action_t));
if (!action) {
HOOK_MALLOC_FAILED;
Expand Down Expand Up @@ -6489,12 +6528,40 @@ esp_err_t mdns_service_remove_for_host(const char *instance, const char *service
return ESP_ERR_NO_MEM;
}
action->type = ACTION_SERVICE_DEL;
action->data.srv_del.service = s;
action->data.srv_del.instance = NULL;
action->data.srv_del.hostname = NULL;
if (!_str_null_or_empty(instance)) {
action->data.srv_del.instance = strndup(instance, MDNS_NAME_BUF_LEN - 1);
if (!action->data.srv_del.instance) {
goto fail;
}
}

if (!_str_null_or_empty(hostname)) {
action->data.srv_del.hostname = strndup(hostname, MDNS_NAME_BUF_LEN - 1);
if (!action->data.srv_del.hostname) {
goto fail;
}
}

action->data.srv_del.service = strndup(service, MDNS_NAME_BUF_LEN - 1);
action->data.srv_del.proto = strndup(proto, MDNS_NAME_BUF_LEN - 1);
if (!action->data.srv_del.service || !action->data.srv_del.proto) {
goto fail;
}

if (xQueueSend(_mdns_server->action_queue, &action, (TickType_t)0) != pdPASS) {
free(action);
return ESP_ERR_NO_MEM;
goto fail;
}
return ESP_OK;

fail:
free((char *)action->data.srv_del.instance);
free((char *)action->data.srv_del.service);
free((char *)action->data.srv_del.proto);
free((char *)action->data.srv_del.hostname);
free(action);
return ESP_ERR_NO_MEM;
}

esp_err_t mdns_service_remove(const char *service_type, const char *proto)
Expand Down
5 changes: 4 additions & 1 deletion components/mdns/private_include/mdns_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,10 @@ typedef struct {
mdns_srv_item_t *service;
} srv_add;
struct {
mdns_srv_item_t *service;
char *instance;
char *service;
char *proto;
char *hostname;
} srv_del;
struct {
mdns_srv_item_t *service;
Expand Down

0 comments on commit 042533a

Please sign in to comment.