diff --git a/src/core/udp.c b/src/core/udp.c index fc820282..747fd7d5 100644 --- a/src/core/udp.c +++ b/src/core/udp.c @@ -997,11 +997,13 @@ udp_bind(struct udp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port) { /* port matches that of PCB in list and REUSEADDR not set -> reject */ if ((ipcb->local_port == port) && - (IP_GET_TYPE(&ipcb->local_ip) == IP_GET_TYPE(ipaddr)) && + ((IP_GET_TYPE(&ipcb->local_ip) == IP_GET_TYPE(ipaddr)) && /* IP address matches or any IP used? */ (ip_addr_cmp(&ipcb->local_ip, ipaddr) || ip_addr_isany(ipaddr) || - ip_addr_isany(&ipcb->local_ip))) { + ip_addr_isany(&ipcb->local_ip))) || + (IP_GET_TYPE(&ipcb->local_ip) == IPADDR_TYPE_ANY) || + (IP_GET_TYPE(ipaddr) == IPADDR_TYPE_ANY)) { /* other PCB already binds to this local IP and port */ LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: local port %"U16_F" already bound by another pcb\n", port)); diff --git a/test/unit/udp/test_udp.c b/test/unit/udp/test_udp.c index 56e14b81..a9a6b25b 100644 --- a/test/unit/udp/test_udp.c +++ b/test/unit/udp/test_udp.c @@ -377,7 +377,7 @@ START_TEST(test_udp_bind) udp_remove(pcb1); udp_remove(pcb2); - /* bind on same port using SAME IPv4 address type */ + /* bind on same port using SAME IPv6 address type */ ip_addr_set_any_val(1, ip1); ip_addr_set_any_val(1, ip2); @@ -440,6 +440,22 @@ START_TEST(test_udp_bind) udp_remove(pcb1); udp_remove(pcb2); + + /* bind on same port using ANY + IPv4 */ + ip1 = *IP_ANY_TYPE; + IP_ADDR4(&ip2, 1, 2, 3, 4); + + pcb1 = udp_new_ip_type(IPADDR_TYPE_ANY); + pcb2 = udp_new_ip_type(IPADDR_TYPE_V4); + + err1 = udp_bind(pcb1, &ip1, 2105); + err2 = udp_bind(pcb2, &ip2, 2105); + + fail_unless(err1 == ERR_OK); + fail_unless(err2 == ERR_USE); + + udp_remove(pcb1); + udp_remove(pcb2); } END_TEST