diff --git a/components/mdns/mdns.c b/components/mdns/mdns.c index cf9d0c23a8..629b91f7a6 100644 --- a/components/mdns/mdns.c +++ b/components/mdns/mdns.c @@ -3005,6 +3005,9 @@ clear_rx_packet: */ void _mdns_enable_pcb(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol) { + if (_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb && _mdns_pcb_is_ip_updated(tcpip_if, ip_protocol)) { + _mdns_pcb_deinit(tcpip_if, ip_protocol); + } if (!_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb) { if (_mdns_pcb_init(tcpip_if, ip_protocol)) { return; diff --git a/components/mdns/mdns_networking.c b/components/mdns/mdns_networking.c index 01b6344b84..2c843f7fa0 100644 --- a/components/mdns/mdns_networking.c +++ b/components/mdns/mdns_networking.c @@ -7,7 +7,6 @@ #include "mdns_networking.h" #include "esp_log.h" - extern mdns_server_t * _mdns_server; /* @@ -109,6 +108,7 @@ static void _udp_pcb_deinit(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_p } } + /** * @brief Start PCB V4 */ @@ -147,6 +147,7 @@ static esp_err_t _udp_pcb_v4_init(tcpip_adapter_if_t tcpip_if) pcb->remote_port = MDNS_SERVICE_PORT; ip_addr_copy(pcb->multicast_ip, interface_addr); ip_addr_copy(pcb->remote_ip, multicast_addr); + ip_addr_copy(_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].if_addr, interface_addr); _mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].pcb = pcb; _mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].failed_probes = 0; @@ -188,6 +189,7 @@ static esp_err_t _udp_pcb_v6_init(tcpip_adapter_if_t tcpip_if) pcb->remote_port = MDNS_SERVICE_PORT; ip_addr_copy(pcb->remote_ip, multicast_addr); + ip_addr_copy(_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V6].if_addr, interface_addr); _mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V6].pcb = pcb; _mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V6].failed_probes = 0; @@ -304,3 +306,28 @@ size_t _mdns_udp_pcb_write(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_pr } return len; } + +bool _mdns_pcb_is_ip_updated(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol) +{ + tcpip_adapter_ip_info_t if_ip_info; + if (!_mdns_server || !_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb) { + return false; + } + mdns_pcb_t pcb = _mdns_server->interfaces[tcpip_if].pcbs[ip_protocol]; + + if (ip_protocol == MDNS_IP_PROTOCOL_V4) { + if (tcpip_adapter_get_ip_info(tcpip_if, &if_ip_info) || if_ip_info.ip.addr == 0) { + return false; + } + ip_addr_t interface_addr = IPADDR4_INIT(if_ip_info.ip.addr); + return !ip_addr_cmp(&interface_addr, &pcb.if_addr); + } else if (ip_protocol == MDNS_IP_PROTOCOL_V6) { + ip_addr_t interface_addr; + interface_addr.type = IPADDR_TYPE_V6; + if (tcpip_adapter_get_ip6_linklocal(tcpip_if, &interface_addr.u_addr.ip6)) { + return false; + } + return !ip_addr_cmp(&interface_addr, &pcb.if_addr); + } + return false; +} \ No newline at end of file diff --git a/components/mdns/private_include/mdns_networking.h b/components/mdns/private_include/mdns_networking.h index 5b56f8066d..e6f0d89d98 100644 --- a/components/mdns/private_include/mdns_networking.h +++ b/components/mdns/private_include/mdns_networking.h @@ -49,4 +49,17 @@ esp_err_t _mdns_pcb_deinit(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_pr */ size_t _mdns_udp_pcb_write(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, const ip_addr_t *ip, uint16_t port, uint8_t * data, size_t len); +/** + * @brief Compares currently opened pcb's interface ip address with currently assigned tcpip address + * + * When new IP address is assigned this function can be called if current pcb uses the same IP address + * and thus can be reused. Otherwise pcb needs to be reinitialized as it is tightly coupled with it's IP + * + * @param tcpip_if interface type + * @param ip_protocol protocol type + * + * @return true if current address if different from the one used in pcb + */ +bool _mdns_pcb_is_ip_updated(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol); + #endif /* ESP_MDNS_NETWORKING_H_ */ diff --git a/components/mdns/private_include/mdns_private.h b/components/mdns/private_include/mdns_private.h index 269a5695d9..7483080418 100644 --- a/components/mdns/private_include/mdns_private.h +++ b/components/mdns/private_include/mdns_private.h @@ -297,6 +297,7 @@ typedef struct { uint8_t probe_ip; uint8_t probe_running; uint16_t failed_probes; + ip_addr_t if_addr; } mdns_pcb_t; typedef enum {