fix the bug that TCP connections don't abort when IP changed
This commit is contained in:
parent
c77f84e788
commit
b5f4bf922f
4 changed files with 66 additions and 14 deletions
|
@ -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
|
||||||
|
|
|
@ -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? */
|
||||||
|
|
|
@ -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,18 +1964,29 @@ 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(new_addr)) {
|
if (!ip4_addr_isany(old_addr)) {
|
||||||
/* PCB bound to current local interface address? */
|
#if ESP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES
|
||||||
for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = next) {
|
if ((new_addr == NULL) || ((!ip4_addr_isany_val(*new_addr)) && (!ip4_addr_cmp(old_addr, new_addr)))) {
|
||||||
next = lpcb->next;
|
#endif
|
||||||
/* Is this an IPv4 pcb? */
|
tcp_netif_ip_addr_changed_pcblist(old_addr, tcp_active_pcbs);
|
||||||
if (!IP_IS_V6_VAL(lpcb->local_ip)) {
|
tcp_netif_ip_addr_changed_pcblist(old_addr, tcp_bound_pcbs);
|
||||||
/* PCB bound to current local interface address? */
|
#if ESP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES
|
||||||
if ((!(ip4_addr_isany(ip_2_ip4(&lpcb->local_ip)))) &&
|
}
|
||||||
(ip4_addr_cmp(ip_2_ip4(&lpcb->local_ip), old_addr))) {
|
#endif
|
||||||
/* The PCB is listening to the old ipaddr and
|
|
||||||
* is set to listen to the new one instead */
|
if (!ip4_addr_isany(new_addr)) {
|
||||||
ip_addr_copy_from_ip4(lpcb->local_ip, *new_addr);
|
/* PCB bound to current local interface address? */
|
||||||
|
for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = next) {
|
||||||
|
next = lpcb->next;
|
||||||
|
/* Is this an IPv4 pcb? */
|
||||||
|
if (!IP_IS_V6_VAL(lpcb->local_ip)) {
|
||||||
|
/* PCB bound to current local interface address? */
|
||||||
|
if ((!(ip4_addr_isany(ip_2_ip4(&lpcb->local_ip)))) &&
|
||||||
|
(ip4_addr_cmp(ip_2_ip4(&lpcb->local_ip), old_addr))) {
|
||||||
|
/* The PCB is listening to the old ipaddr and
|
||||||
|
* is set to listen to the new one instead */
|
||||||
|
ip_addr_copy_from_ip4(lpcb->local_ip, *new_addr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in a new issue