From 7b85dd09e04598dcb36750dfd4f363deffff8f9f Mon Sep 17 00:00:00 2001 From: Niki Waibel Date: Fri, 6 Jun 2025 17:16:30 +0200 Subject: [PATCH] fix(libraries/asyncudp): IPv4 ONLY listenMulticast() AsyncUDP::listenMulticast() properly receives packets sent to IPv4 multicast addresses like 239.1.2.3, but it is not receiving packets sent to IPv6 multicast addresses like ff12::6ood:cafe. The root cause is a bit hidden: listen(NULL, port) would match AsyncUDP::listen(const ip_addr_t *addr, uint16_t port), which calls _udp_bind(_pcb, addr, port), which uses the lwIP API to call udp_bind(struct udp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port) at the end. If lwIP has LWIP_IPV4 enabled, it checks if ipaddr == NULL and sets it to IP4_ADDR_ANY. So an IPv6 address is never bound. This fix checks the IP address passed to AsyncUDP::listenMulticast(). If it is an IPv6 address, it constructs and passes the IPv6 any address (::); otherwise (IPv4), it constructs and passes the IPv4 any address (0.0.0.0). --- libraries/AsyncUDP/src/AsyncUDP.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/libraries/AsyncUDP/src/AsyncUDP.cpp b/libraries/AsyncUDP/src/AsyncUDP.cpp index f44cc839c97..cab9c951921 100644 --- a/libraries/AsyncUDP/src/AsyncUDP.cpp +++ b/libraries/AsyncUDP/src/AsyncUDP.cpp @@ -682,6 +682,8 @@ static esp_err_t joinMulticastGroup(const ip_addr_t *addr, bool join, tcpip_adap } bool AsyncUDP::listenMulticast(const ip_addr_t *addr, uint16_t port, uint8_t ttl, tcpip_adapter_if_t tcpip_if) { + ip_addr_t bind_addr; + if (!ip_addr_ismulticast(addr)) { return false; } @@ -690,7 +692,18 @@ bool AsyncUDP::listenMulticast(const ip_addr_t *addr, uint16_t port, uint8_t ttl return false; } - if (!listen(NULL, port)) { +#if CONFIG_LWIP_IPV6 + if (IP_IS_V6(addr)) { + IP_SET_TYPE(&bind_addr, IPADDR_TYPE_V6); + ip6_addr_set_any(&bind_addr.u_addr.ip6); + } else { +#endif + IP_SET_TYPE(&bind_addr, IPADDR_TYPE_V4); + ip4_addr_set_any(&bind_addr.u_addr.ip4); +#if CONFIG_LWIP_IPV6 + } +#endif + if (!listen(&bind_addr, port)) { return false; }