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
This commit is contained in:
parent
c87f0cb6ca
commit
265e983a45
1 changed files with 46 additions and 9 deletions
|
@ -1452,20 +1452,13 @@ static void _mdns_pcb_send_bye(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t i
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Send probe for particular services on particular PCB
|
||||
* @brief Send probe for additional services on particular PCB
|
||||
*/
|
||||
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)
|
||||
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)
|
||||
{
|
||||
mdns_pcb_t * pcb = &_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol];
|
||||
size_t services_final_len = len;
|
||||
|
||||
_mdns_clear_pcb_tx_queue_head(tcpip_if, ip_protocol);
|
||||
|
||||
if (_str_null_or_empty(_mdns_server->hostname)) {
|
||||
pcb->state = PCB_RUNNING;
|
||||
return;
|
||||
}
|
||||
|
||||
if (PCB_STATE_IS_PROBING(pcb)) {
|
||||
services_final_len += pcb->probe_services_len;
|
||||
}
|
||||
|
@ -1510,6 +1503,50 @@ static void _mdns_init_pcb_probe(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t
|
|||
pcb->state = PCB_PROBE_1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send probe for particular services on particular PCB
|
||||
*
|
||||
* Tests possible duplication on probing service structure and probes only for new entries.
|
||||
* - If pcb probing then add only non-probing services and restarts probing
|
||||
* - If pcb not probing, run probing for all specified services
|
||||
*/
|
||||
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)
|
||||
{
|
||||
mdns_pcb_t * pcb = &_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol];
|
||||
|
||||
_mdns_clear_pcb_tx_queue_head(tcpip_if, ip_protocol);
|
||||
|
||||
if (_str_null_or_empty(_mdns_server->hostname)) {
|
||||
pcb->state = PCB_RUNNING;
|
||||
return;
|
||||
}
|
||||
|
||||
if (PCB_STATE_IS_PROBING(pcb)) {
|
||||
// Looking for already probing services to resolve duplications
|
||||
mdns_srv_item_t * new_probe_services[len];
|
||||
int new_probe_service_len = 0;
|
||||
bool found;
|
||||
for (int j=0; j < len; ++j) {
|
||||
found = false;
|
||||
for (int i=0; i < pcb->probe_services_len; ++i) {
|
||||
if (pcb->probe_services[i] == services[j]) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
new_probe_services[new_probe_service_len++] = services[j];
|
||||
}
|
||||
}
|
||||
// init probing for newly added services
|
||||
_mdns_init_pcb_probe_new_service(tcpip_if, ip_protocol,
|
||||
new_probe_service_len?new_probe_services:NULL, new_probe_service_len, probe_ip);
|
||||
} else {
|
||||
// not probing, so init for all services
|
||||
_mdns_init_pcb_probe_new_service(tcpip_if, ip_protocol, services, len, probe_ip);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Restart the responder on particular PCB
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue