mdns: fix memory free issue when repeating the query in reply

The repeated query will be copied in the next event loop while the
memory is freed instantly. Delay the free to fix this issue.
This commit is contained in:
Jiacheng Guo 2021-04-16 15:19:34 +08:00 committed by David Cermak
parent ba15ac8634
commit 0b556de95c
2 changed files with 47 additions and 6 deletions

View File

@ -1057,7 +1057,26 @@ static void _mdns_free_tx_packet(mdns_tx_packet_t * packet)
if (!packet) { if (!packet) {
return; return;
} }
queueFree(mdns_out_question_t, packet->questions); mdns_out_question_t *q = packet->questions;
while (q) {
mdns_out_question_t *next = q->next;
if (q->own_dynamic_memory) {
if (q->host) {
free((char *)q->host);
}
if (q->service) {
free((char *)q->service);
}
if (q->proto) {
free((char *)q->proto);
}
if (q->domain) {
free((char *)q->domain);
}
}
free(q);
q = next;
}
queueFree(mdns_out_answer_t, packet->answers); queueFree(mdns_out_answer_t, packet->answers);
queueFree(mdns_out_answer_t, packet->servers); queueFree(mdns_out_answer_t, packet->servers);
queueFree(mdns_out_answer_t, packet->additional); queueFree(mdns_out_answer_t, packet->additional);
@ -1342,8 +1361,18 @@ static void _mdns_create_answer_from_parsed_packet(mdns_parsed_packet_t * parsed
_mdns_free_tx_packet(packet); _mdns_free_tx_packet(packet);
return; return;
} }
memcpy(out_question, q, sizeof(mdns_out_question_t)); out_question->type = q->type;
out_question->unicast = q->unicast;
out_question->host = q->host;
q->host = NULL;
out_question->service = q->service;
q->service = NULL;
out_question->proto = q->proto;
q->proto = NULL;
out_question->domain = q->domain;
q->domain = NULL;
out_question->next = NULL; out_question->next = NULL;
out_question->own_dynamic_memory = true;
queueToEnd(mdns_out_question_t, packet->questions, out_question); queueToEnd(mdns_out_question_t, packet->questions, out_question);
} }
#endif // MDNS_REPEAT_QUERY_IN_RESPONSE #endif // MDNS_REPEAT_QUERY_IN_RESPONSE
@ -1411,6 +1440,7 @@ static mdns_tx_packet_t * _mdns_create_probe_packet(mdns_if_t tcpip_if, mdns_ip_
q->service = services[i]->service->service; q->service = services[i]->service->service;
q->proto = services[i]->service->proto; q->proto = services[i]->service->proto;
q->domain = MDNS_DEFAULT_DOMAIN; q->domain = MDNS_DEFAULT_DOMAIN;
q->own_dynamic_memory = false;
if (!q->host || _mdns_question_exists(q, packet->questions)) { if (!q->host || _mdns_question_exists(q, packet->questions)) {
free(q); free(q);
continue; continue;
@ -1438,6 +1468,7 @@ static mdns_tx_packet_t * _mdns_create_probe_packet(mdns_if_t tcpip_if, mdns_ip_
q->service = NULL; q->service = NULL;
q->proto = NULL; q->proto = NULL;
q->domain = MDNS_DEFAULT_DOMAIN; q->domain = MDNS_DEFAULT_DOMAIN;
q->own_dynamic_memory = false;
if (_mdns_question_exists(q, packet->questions)) { if (_mdns_question_exists(q, packet->questions)) {
free(q); free(q);
} else { } else {
@ -3116,10 +3147,18 @@ clear_rx_packet:
while (parsed_packet->questions) { while (parsed_packet->questions) {
mdns_parsed_question_t * question = parsed_packet->questions; mdns_parsed_question_t * question = parsed_packet->questions;
parsed_packet->questions = parsed_packet->questions->next; parsed_packet->questions = parsed_packet->questions->next;
free(question->host); if (question->host) {
free(question->service); free(question->host);
free(question->proto); }
free(question->domain); if (question->service) {
free(question->service);
}
if (question->proto) {
free(question->proto);
}
if (question->domain) {
free(question->domain);
}
free(question); free(question);
} }
free(parsed_packet); free(parsed_packet);
@ -3649,6 +3688,7 @@ static mdns_tx_packet_t * _mdns_create_search_packet(mdns_search_once_t * search
q->service = search->service; q->service = search->service;
q->proto = search->proto; q->proto = search->proto;
q->domain = MDNS_DEFAULT_DOMAIN; q->domain = MDNS_DEFAULT_DOMAIN;
q->own_dynamic_memory = false;
queueToEnd(mdns_out_question_t, packet->questions, q); queueToEnd(mdns_out_question_t, packet->questions, q);
if (search->type == MDNS_TYPE_PTR) { if (search->type == MDNS_TYPE_PTR) {

View File

@ -299,6 +299,7 @@ typedef struct mdns_out_question_s {
const char * service; const char * service;
const char * proto; const char * proto;
const char * domain; const char * domain;
bool own_dynamic_memory;
} mdns_out_question_t; } mdns_out_question_t;
typedef struct mdns_out_answer_s { typedef struct mdns_out_answer_s {