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
|
||||
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
|
||||
prompt "Pre-allocate transmit PBUF size"
|
||||
default TCP_OVERSIZE_MSS
|
||||
|
|
|
@ -453,10 +453,10 @@ void
|
|||
netif_set_ipaddr(struct netif *netif, const ip4_addr_t *ipaddr)
|
||||
{
|
||||
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);
|
||||
#else
|
||||
ip4_addr_t *last_addr = netif_ip4_addr(netif);
|
||||
ip4_addr_t *last_addr = ip_2_ip4(&(netif->ip_addr));
|
||||
#endif
|
||||
|
||||
/* 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 */
|
||||
|
||||
/** 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
|
||||
/** 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;
|
||||
|
||||
if (!ip4_addr_isany(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);
|
||||
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)) {
|
||||
/* 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
|
||||
|
||||
/**
|
||||
* 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
|
||||
* events (accept, sent, etc) that happen in the system.
|
||||
|
|
Loading…
Reference in a new issue