fix the bug that TCP connections don't abort when IP changed

This commit is contained in:
zhangyanjiao 2018-06-07 11:24:03 +08:00
parent c77f84e788
commit b5f4bf922f
4 changed files with 66 additions and 14 deletions

View file

@ -329,6 +329,16 @@ config TCP_QUEUE_OOSEQ
Disable this option to save some RAM during TCP sessions, at the expense Disable this option to save some RAM during TCP sessions, at the expense
of increased retransmissions if segments arrive out of order. of increased retransmissions if segments arrive out of order.
config ESP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES
bool "Keep TCP connections when IP changed"
default n
help
This option is enabled when the following scenario happen:
network dropped and reconnected, IP changes is like: 192.168.0.2->0.0.0.0->192.168.0.2
Disable this option to keep consistent with the original LWIP code behavior.
choice TCP_OVERSIZE choice TCP_OVERSIZE
prompt "Pre-allocate transmit PBUF size" prompt "Pre-allocate transmit PBUF size"
default TCP_OVERSIZE_MSS default TCP_OVERSIZE_MSS

View file

@ -453,10 +453,10 @@ void
netif_set_ipaddr(struct netif *netif, const ip4_addr_t *ipaddr) netif_set_ipaddr(struct netif *netif, const ip4_addr_t *ipaddr)
{ {
ip4_addr_t new_addr = (ipaddr ? *ipaddr : *IP4_ADDR_ANY); ip4_addr_t new_addr = (ipaddr ? *ipaddr : *IP4_ADDR_ANY);
#if ESP_LWIP #if ESP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES
ip4_addr_t *last_addr = ip_2_ip4(&netif->last_ip_addr); ip4_addr_t *last_addr = ip_2_ip4(&netif->last_ip_addr);
#else #else
ip4_addr_t *last_addr = netif_ip4_addr(netif); ip4_addr_t *last_addr = ip_2_ip4(&(netif->ip_addr));
#endif #endif
/* address is actually being changed? */ /* address is actually being changed? */

View file

@ -1929,6 +1929,31 @@ tcp_eff_send_mss_impl(u16_t sendmss, const ip_addr_t *dest
} }
#endif /* TCP_CALCULATE_EFF_SEND_MSS */ #endif /* TCP_CALCULATE_EFF_SEND_MSS */
/** Helper function for tcp_netif_ip4_addr_changed() that iterates a pcb list */
static void
tcp_netif_ip_addr_changed_pcblist(const ip4_addr_t* old_addr, struct tcp_pcb* pcb_list)
{
struct tcp_pcb *pcb;
pcb = pcb_list;
while (pcb != NULL) {
/* PCB bound to current local interface address? */
if (ip4_addr_cmp(ip_2_ip4(&pcb->local_ip), old_addr)
#if LWIP_AUTOIP
/* connections to link-local addresses must persist (RFC3927 ch. 1.9) */
&& (!IP_IS_V4_VAL(pcb->local_ip) || !ip4_addr_islinklocal(ip_2_ip4(&pcb->local_ip)))
#endif /* LWIP_AUTOIP */
) {
/* this connection must be aborted */
struct tcp_pcb *next = pcb->next;
LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: aborting TCP pcb %p\n", (void *)pcb));
tcp_abort(pcb);
pcb = next;
} else {
pcb = pcb->next;
}
}
}
#if LWIP_IPV4 #if LWIP_IPV4
/** This function is called from netif.c when address is changed or netif is removed /** This function is called from netif.c when address is changed or netif is removed
* *
@ -1939,6 +1964,16 @@ void tcp_netif_ipv4_addr_changed(const ip4_addr_t* old_addr, const ip4_addr_t* n
{ {
struct tcp_pcb_listen *lpcb, *next; struct tcp_pcb_listen *lpcb, *next;
if (!ip4_addr_isany(old_addr)) {
#if ESP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES
if ((new_addr == NULL) || ((!ip4_addr_isany_val(*new_addr)) && (!ip4_addr_cmp(old_addr, new_addr)))) {
#endif
tcp_netif_ip_addr_changed_pcblist(old_addr, tcp_active_pcbs);
tcp_netif_ip_addr_changed_pcblist(old_addr, tcp_bound_pcbs);
#if ESP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES
}
#endif
if (!ip4_addr_isany(new_addr)) { if (!ip4_addr_isany(new_addr)) {
/* PCB bound to current local interface address? */ /* PCB bound to current local interface address? */
for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = next) { for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = next) {
@ -1956,6 +1991,7 @@ void tcp_netif_ipv4_addr_changed(const ip4_addr_t* old_addr, const ip4_addr_t* n
} }
} }
} }
}
#endif /* LWIP_IPV4 */ #endif /* LWIP_IPV4 */
const char* const char*

View file

@ -296,6 +296,12 @@
*/ */
#define TCP_QUEUE_OOSEQ CONFIG_TCP_QUEUE_OOSEQ #define TCP_QUEUE_OOSEQ CONFIG_TCP_QUEUE_OOSEQ
/**
* ESP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES==1: Keep TCP connection when IP changed
* scenario happens: 192.168.0.2 -> 0.0.0.0 -> 192.168.0.2 or 192.168.0.2 -> 0.0.0.0
*/
#define ESP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES CONFIG_ESP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES
/* /*
* LWIP_EVENT_API==1: The user defines lwip_tcp_event() to receive all * LWIP_EVENT_API==1: The user defines lwip_tcp_event() to receive all
* events (accept, sent, etc) that happen in the system. * events (accept, sent, etc) that happen in the system.