diff --git a/CHANGELOG b/CHANGELOG index bc3a0fad..77f898c8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,6 +6,9 @@ HISTORY ++ New features: + 2015-02-22: patch by TabascoEye + * netif.c, udp.h/.c: fixed bug #40753 (re-bind UDP pcbs on change of IP address) + 2015-02-22: chrysn, Simon Goldschmidt * *.*: Changed nearly all functions taking 'ip(X)_addr_t' pointer to take const pointers (changed user callbacks: raw_recv_fn, udp_recv_fn; changed diff --git a/src/core/netif.c b/src/core/netif.c index 328694c4..822bc836 100644 --- a/src/core/netif.c +++ b/src/core/netif.c @@ -390,9 +390,11 @@ netif_set_ipaddr(struct netif *netif, const ip_addr_t *ipaddr) #if LWIP_TCP struct tcp_pcb *pcb; struct tcp_pcb_listen *lpcb; +#endif /* LWIP_TCP */ /* address is actually being changed? */ if (ipaddr && (ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0) { +#if LWIP_TCP /* extern struct tcp_pcb *tcp_active_pcbs; defined by tcp.h */ LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: netif address being changed\n")); pcb = tcp_active_pcbs; @@ -422,8 +424,12 @@ netif_set_ipaddr(struct netif *netif, const ip_addr_t *ipaddr) ip_addr_set(ipX_2_ip(&lpcb->local_ip), ipaddr); } } +#endif /* LWIP_TCP */ +#if LWIP_UDP + udp_netif_ipv4_addr_changed(&netif->ip_addr, ipaddr); +#endif /* LWIP_UDP */ } -#endif + snmp_delete_ipaddridx_tree(netif); snmp_delete_iprteidx_tree(0,netif); /* set new IP address to netif */ diff --git a/src/core/udp.c b/src/core/udp.c index ed9bb28e..01ff470d 100644 --- a/src/core/udp.c +++ b/src/core/udp.c @@ -1151,6 +1151,26 @@ udp_new_ip6(void) } #endif /* LWIP_IPV6 */ +/** This function is called from netif.c when address is changed + * + * @param old_addr IPv4 address of the netif before change + * @param new_addr IPv4 address of the netif after change + */ +void udp_netif_ipv4_addr_changed(const ip_addr_t* old_addr, const ip_addr_t* new_addr) +{ + struct udp_pcb* upcb; + + for (upcb = udp_pcbs; upcb != NULL; upcb = upcb->next) { + /* PCB bound to current local interface address? */ + if ((!(ip_addr_isany(ipX_2_ip(&upcb->local_ip)))) && + (ip_addr_cmp(ipX_2_ip(&upcb->local_ip), old_addr))) { + /* The PCB is bound to the old ipaddr and + * is set to bound to the new one instead */ + ip_addr_set(ipX_2_ip(&upcb->local_ip), new_addr); + } + } +} + #if UDP_DEBUG /** * Print UDP header information for debug purposes. diff --git a/src/include/lwip/udp.h b/src/include/lwip/udp.h index 22a6f658..0cd3b98d 100644 --- a/src/include/lwip/udp.h +++ b/src/include/lwip/udp.h @@ -221,6 +221,8 @@ void udp_debug_print(struct udp_hdr *udphdr); #define udp_debug_print(udphdr) #endif +void udp_netif_ipv4_addr_changed(const ip_addr_t* old_addr, const ip_addr_t* new_addr); + #ifdef __cplusplus } #endif