Skip to content

Commit bf55daf

Browse files
committed
fix(mdns): Minor cleanup of packet parser
1 parent f33ef61 commit bf55daf

File tree

7 files changed

+571
-573
lines changed

7 files changed

+571
-573
lines changed

components/mdns/mdns_browser.c

Lines changed: 308 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,3 +318,311 @@ void mdns_browse_action(mdns_action_t *action, mdns_action_subtype_t type)
318318
}
319319

320320
}
321+
322+
/**
323+
* @brief Add result to browse, only add when the result is a new one.
324+
*/
325+
static esp_err_t _mdns_add_browse_result(mdns_browse_sync_t *sync_browse, mdns_result_t *r)
326+
{
327+
mdns_browse_result_sync_t *sync_r = sync_browse->sync_result;
328+
while (sync_r) {
329+
if (sync_r->result == r) {
330+
break;
331+
}
332+
sync_r = sync_r->next;
333+
}
334+
if (!sync_r) {
335+
// Do not find, need to add the result to the list
336+
mdns_browse_result_sync_t *new = (mdns_browse_result_sync_t *)mdns_mem_malloc(sizeof(mdns_browse_result_sync_t));
337+
338+
if (!new) {
339+
HOOK_MALLOC_FAILED;
340+
return ESP_ERR_NO_MEM;
341+
}
342+
new->result = r;
343+
new->next = sync_browse->sync_result;
344+
sync_browse->sync_result = new;
345+
}
346+
return ESP_OK;
347+
}
348+
349+
/**
350+
* @brief Called from parser to add A/AAAA data to search result
351+
*/
352+
void _mdns_browse_result_add_ip(mdns_browse_t *browse, const char *hostname, esp_ip_addr_t *ip,
353+
mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, uint32_t ttl, mdns_browse_sync_t *out_sync_browse)
354+
{
355+
if (out_sync_browse->browse == NULL) {
356+
return;
357+
} else {
358+
if (out_sync_browse->browse != browse) {
359+
return;
360+
}
361+
}
362+
mdns_result_t *r = NULL;
363+
mdns_ip_addr_t *r_a = NULL;
364+
if (browse) {
365+
r = browse->result;
366+
while (r) {
367+
if (r->ip_protocol == ip_protocol) {
368+
// Find the target result in browse result.
369+
if (r->esp_netif == _mdns_get_esp_netif(tcpip_if) && !mdns_utils_str_null_or_empty(r->hostname) && !strcasecmp(hostname, r->hostname)) {
370+
r_a = r->addr;
371+
// Check if the address has already added in result.
372+
while (r_a) {
373+
#ifdef CONFIG_LWIP_IPV4
374+
if (r_a->addr.type == ip->type && r_a->addr.type == ESP_IPADDR_TYPE_V4 && r_a->addr.u_addr.ip4.addr == ip->u_addr.ip4.addr) {
375+
break;
376+
}
377+
#endif
378+
#ifdef CONFIG_LWIP_IPV6
379+
if (r_a->addr.type == ip->type && r_a->addr.type == ESP_IPADDR_TYPE_V6 && !memcmp(r_a->addr.u_addr.ip6.addr, ip->u_addr.ip6.addr, 16)) {
380+
break;
381+
}
382+
#endif
383+
r_a = r_a->next;
384+
}
385+
if (!r_a) {
386+
// The current IP is a new one, add it to the link list.
387+
mdns_ip_addr_t *a = NULL;
388+
a = _mdns_result_addr_create_ip(ip);
389+
if (!a) {
390+
return;
391+
}
392+
a->next = r->addr;
393+
r->addr = a;
394+
if (r->ttl != ttl) {
395+
if (r->ttl == 0) {
396+
r->ttl = ttl;
397+
} else {
398+
_mdns_result_update_ttl(r, ttl);
399+
}
400+
}
401+
if (_mdns_add_browse_result(out_sync_browse, r) != ESP_OK) {
402+
return;
403+
}
404+
break;
405+
}
406+
}
407+
}
408+
r = r->next;
409+
}
410+
}
411+
}
412+
413+
static bool is_txt_item_in_list(mdns_txt_item_t txt, uint8_t txt_value_len, mdns_txt_item_t *txt_list, uint8_t *txt_value_len_list, size_t txt_count)
414+
{
415+
for (size_t i = 0; i < txt_count; i++) {
416+
if (strcmp(txt.key, txt_list[i].key) == 0) {
417+
if (txt_value_len == txt_value_len_list[i] && memcmp(txt.value, txt_list[i].value, txt_value_len) == 0) {
418+
return true;
419+
} else {
420+
// The key value is unique, so there is no need to continue searching.
421+
return false;
422+
}
423+
}
424+
}
425+
return false;
426+
}
427+
428+
/**
429+
* @brief Called from parser to add TXT data to search result
430+
*/
431+
void _mdns_browse_result_add_txt(mdns_browse_t *browse, const char *instance, const char *service, const char *proto,
432+
mdns_txt_item_t *txt, uint8_t *txt_value_len, size_t txt_count, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol,
433+
uint32_t ttl, mdns_browse_sync_t *out_sync_browse)
434+
{
435+
if (out_sync_browse->browse == NULL) {
436+
return;
437+
} else {
438+
if (out_sync_browse->browse != browse) {
439+
return;
440+
}
441+
}
442+
mdns_result_t *r = browse->result;
443+
while (r) {
444+
if (r->esp_netif == _mdns_get_esp_netif(tcpip_if) && r->ip_protocol == ip_protocol &&
445+
!mdns_utils_str_null_or_empty(r->instance_name) && !strcasecmp(instance, r->instance_name) &&
446+
!mdns_utils_str_null_or_empty(r->service_type) && !strcasecmp(service, r->service_type) &&
447+
!mdns_utils_str_null_or_empty(r->proto) && !strcasecmp(proto, r->proto)) {
448+
bool should_update = false;
449+
if (r->txt) {
450+
// Check if txt changed
451+
if (txt_count != r->txt_count) {
452+
should_update = true;
453+
} else {
454+
for (size_t txt_index = 0; txt_index < txt_count; txt_index++) {
455+
if (!is_txt_item_in_list(txt[txt_index], txt_value_len[txt_index], r->txt, r->txt_value_len, r->txt_count)) {
456+
should_update = true;
457+
break;
458+
}
459+
}
460+
}
461+
// If the result has a previous txt entry, we delete it and re-add.
462+
for (size_t i = 0; i < r->txt_count; i++) {
463+
mdns_mem_free((char *)(r->txt[i].key));
464+
mdns_mem_free((char *)(r->txt[i].value));
465+
}
466+
mdns_mem_free(r->txt);
467+
mdns_mem_free(r->txt_value_len);
468+
}
469+
r->txt = txt;
470+
r->txt_value_len = txt_value_len;
471+
r->txt_count = txt_count;
472+
if (r->ttl != ttl) {
473+
uint32_t previous_ttl = r->ttl;
474+
if (r->ttl == 0) {
475+
r->ttl = ttl;
476+
} else {
477+
_mdns_result_update_ttl(r, ttl);
478+
}
479+
if (previous_ttl != r->ttl) {
480+
should_update = true;
481+
}
482+
}
483+
if (should_update) {
484+
if (_mdns_add_browse_result(out_sync_browse, r) != ESP_OK) {
485+
return;
486+
}
487+
}
488+
return;
489+
}
490+
r = r->next;
491+
}
492+
r = (mdns_result_t *)mdns_mem_malloc(sizeof(mdns_result_t));
493+
if (!r) {
494+
HOOK_MALLOC_FAILED;
495+
goto free_txt;
496+
}
497+
memset(r, 0, sizeof(mdns_result_t));
498+
r->instance_name = mdns_mem_strdup(instance);
499+
r->service_type = mdns_mem_strdup(service);
500+
r->proto = mdns_mem_strdup(proto);
501+
if (!r->instance_name || !r->service_type || !r->proto) {
502+
mdns_mem_free(r->instance_name);
503+
mdns_mem_free(r->service_type);
504+
mdns_mem_free(r->proto);
505+
mdns_mem_free(r);
506+
return;
507+
}
508+
r->txt = txt;
509+
r->txt_value_len = txt_value_len;
510+
r->txt_count = txt_count;
511+
r->esp_netif = _mdns_get_esp_netif(tcpip_if);
512+
r->ip_protocol = ip_protocol;
513+
r->ttl = ttl;
514+
r->next = browse->result;
515+
browse->result = r;
516+
_mdns_add_browse_result(out_sync_browse, r);
517+
return;
518+
519+
free_txt:
520+
for (size_t i = 0; i < txt_count; i++) {
521+
mdns_mem_free((char *)(txt[i].key));
522+
mdns_mem_free((char *)(txt[i].value));
523+
}
524+
mdns_mem_free(txt);
525+
mdns_mem_free(txt_value_len);
526+
return;
527+
}
528+
529+
static esp_err_t _mdns_copy_address_in_previous_result(mdns_result_t *result_list, mdns_result_t *r)
530+
{
531+
while (result_list) {
532+
if (!mdns_utils_str_null_or_empty(result_list->hostname) && !mdns_utils_str_null_or_empty(r->hostname) && !strcasecmp(result_list->hostname, r->hostname) &&
533+
result_list->ip_protocol == r->ip_protocol && result_list->addr && !r->addr) {
534+
// If there is a same hostname in previous result, we need to copy the address here.
535+
r->addr = copy_address_list(result_list->addr);
536+
if (!r->addr) {
537+
return ESP_ERR_NO_MEM;
538+
}
539+
break;
540+
} else {
541+
result_list = result_list->next;
542+
}
543+
}
544+
return ESP_OK;
545+
}
546+
547+
/**
548+
* @brief Called from parser to add SRV data to search result
549+
*/
550+
void _mdns_browse_result_add_srv(mdns_browse_t *browse, const char *hostname, const char *instance, const char *service, const char *proto,
551+
uint16_t port, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, uint32_t ttl, mdns_browse_sync_t *out_sync_browse)
552+
{
553+
if (out_sync_browse->browse == NULL) {
554+
return;
555+
} else {
556+
if (out_sync_browse->browse != browse) {
557+
return;
558+
}
559+
}
560+
mdns_result_t *r = browse->result;
561+
while (r) {
562+
if (r->esp_netif == _mdns_get_esp_netif(tcpip_if) && r->ip_protocol == ip_protocol &&
563+
!mdns_utils_str_null_or_empty(r->instance_name) && !strcasecmp(instance, r->instance_name) &&
564+
!mdns_utils_str_null_or_empty(r->service_type) && !strcasecmp(service, r->service_type) &&
565+
!mdns_utils_str_null_or_empty(r->proto) && !strcasecmp(proto, r->proto)) {
566+
if (mdns_utils_str_null_or_empty(r->hostname) || strcasecmp(hostname, r->hostname)) {
567+
r->hostname = mdns_mem_strdup(hostname);
568+
r->port = port;
569+
if (!r->hostname) {
570+
HOOK_MALLOC_FAILED;
571+
return;
572+
}
573+
if (!r->addr) {
574+
esp_err_t err = _mdns_copy_address_in_previous_result(browse->result, r);
575+
if (err == ESP_ERR_NO_MEM) {
576+
return;
577+
}
578+
}
579+
if (_mdns_add_browse_result(out_sync_browse, r) != ESP_OK) {
580+
return;
581+
}
582+
}
583+
if (r->ttl != ttl) {
584+
uint32_t previous_ttl = r->ttl;
585+
if (r->ttl == 0) {
586+
r->ttl = ttl;
587+
} else {
588+
_mdns_result_update_ttl(r, ttl);
589+
}
590+
if (previous_ttl != r->ttl) {
591+
if (_mdns_add_browse_result(out_sync_browse, r) != ESP_OK) {
592+
return;
593+
}
594+
}
595+
}
596+
return;
597+
}
598+
r = r->next;
599+
}
600+
r = (mdns_result_t *)mdns_mem_malloc(sizeof(mdns_result_t));
601+
if (!r) {
602+
HOOK_MALLOC_FAILED;
603+
return;
604+
}
605+
606+
memset(r, 0, sizeof(mdns_result_t));
607+
r->hostname = mdns_mem_strdup(hostname);
608+
r->instance_name = mdns_mem_strdup(instance);
609+
r->service_type = mdns_mem_strdup(service);
610+
r->proto = mdns_mem_strdup(proto);
611+
if (!r->hostname || !r->instance_name || !r->service_type || !r->proto) {
612+
HOOK_MALLOC_FAILED;
613+
mdns_mem_free(r->hostname);
614+
mdns_mem_free(r->instance_name);
615+
mdns_mem_free(r->service_type);
616+
mdns_mem_free(r->proto);
617+
mdns_mem_free(r);
618+
return;
619+
}
620+
r->port = port;
621+
r->esp_netif = _mdns_get_esp_netif(tcpip_if);
622+
r->ip_protocol = ip_protocol;
623+
r->ttl = ttl;
624+
r->next = browse->result;
625+
browse->result = r;
626+
_mdns_add_browse_result(out_sync_browse, r);
627+
return;
628+
}

0 commit comments

Comments
 (0)