fix(libraries/asyncudp): IPv4 ONLY listenMulticast() (#11444)

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).
This commit is contained in:
Niki Waibel 2025-06-10 10:55:43 +02:00 committed by GitHub
parent 0aada091e1
commit d6a76da0a5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -682,6 +682,8 @@ igmp_fail:
} }
bool AsyncUDP::listenMulticast(const ip_addr_t *addr, uint16_t port, uint8_t ttl, tcpip_adapter_if_t tcpip_if) { 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)) { if (!ip_addr_ismulticast(addr)) {
return false; return false;
} }
@ -690,7 +692,18 @@ bool AsyncUDP::listenMulticast(const ip_addr_t *addr, uint16_t port, uint8_t ttl
return false; 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; return false;
} }