Skip to content

Commit 985e691

Browse files
mdns: fix possible crash when probing on particular interface with duplicated service instances due to naming conflicts on network
Issue: MDNS server initially sends probing packets to resolve naming confilicts with already registered service instances. In case of a conflict, instance name is altered and probing restarts. Original instance however wasnnot removed from the structure and upon service removal only one entry was removed and a dangling service might have been kept in the structure to bring about a crash. Resolution: Keep only one instance of a service in the probing structure. Closes IDF-498 * Original commit: espressif/esp-idf@265e983
1 parent 75deebb commit 985e691

File tree

1 file changed

+46
-9
lines changed

1 file changed

+46
-9
lines changed

components/mdns/mdns.c

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1452,20 +1452,13 @@ static void _mdns_pcb_send_bye(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t i
14521452
}
14531453

14541454
/**
1455-
* @brief Send probe for particular services on particular PCB
1455+
* @brief Send probe for additional services on particular PCB
14561456
*/
1457-
static void _mdns_init_pcb_probe(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, mdns_srv_item_t ** services, size_t len, bool probe_ip)
1457+
static void _mdns_init_pcb_probe_new_service(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, mdns_srv_item_t ** services, size_t len, bool probe_ip)
14581458
{
14591459
mdns_pcb_t * pcb = &_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol];
14601460
size_t services_final_len = len;
14611461

1462-
_mdns_clear_pcb_tx_queue_head(tcpip_if, ip_protocol);
1463-
1464-
if (_str_null_or_empty(_mdns_server->hostname)) {
1465-
pcb->state = PCB_RUNNING;
1466-
return;
1467-
}
1468-
14691462
if (PCB_STATE_IS_PROBING(pcb)) {
14701463
services_final_len += pcb->probe_services_len;
14711464
}
@@ -1510,6 +1503,50 @@ static void _mdns_init_pcb_probe(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t
15101503
pcb->state = PCB_PROBE_1;
15111504
}
15121505

1506+
/**
1507+
* @brief Send probe for particular services on particular PCB
1508+
*
1509+
* Tests possible duplication on probing service structure and probes only for new entries.
1510+
* - If pcb probing then add only non-probing services and restarts probing
1511+
* - If pcb not probing, run probing for all specified services
1512+
*/
1513+
static void _mdns_init_pcb_probe(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, mdns_srv_item_t ** services, size_t len, bool probe_ip)
1514+
{
1515+
mdns_pcb_t * pcb = &_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol];
1516+
1517+
_mdns_clear_pcb_tx_queue_head(tcpip_if, ip_protocol);
1518+
1519+
if (_str_null_or_empty(_mdns_server->hostname)) {
1520+
pcb->state = PCB_RUNNING;
1521+
return;
1522+
}
1523+
1524+
if (PCB_STATE_IS_PROBING(pcb)) {
1525+
// Looking for already probing services to resolve duplications
1526+
mdns_srv_item_t * new_probe_services[len];
1527+
int new_probe_service_len = 0;
1528+
bool found;
1529+
for (int j=0; j < len; ++j) {
1530+
found = false;
1531+
for (int i=0; i < pcb->probe_services_len; ++i) {
1532+
if (pcb->probe_services[i] == services[j]) {
1533+
found = true;
1534+
break;
1535+
}
1536+
}
1537+
if (!found) {
1538+
new_probe_services[new_probe_service_len++] = services[j];
1539+
}
1540+
}
1541+
// init probing for newly added services
1542+
_mdns_init_pcb_probe_new_service(tcpip_if, ip_protocol,
1543+
new_probe_service_len?new_probe_services:NULL, new_probe_service_len, probe_ip);
1544+
} else {
1545+
// not probing, so init for all services
1546+
_mdns_init_pcb_probe_new_service(tcpip_if, ip_protocol, services, len, probe_ip);
1547+
}
1548+
}
1549+
15131550
/**
15141551
* @brief Restart the responder on particular PCB
15151552
*/

0 commit comments

Comments
 (0)