浏览代码

lwip: optimize TCP close

Optimize TCP close:
1. Not remove TCP pcb when IP address is changed since the lwip netconn still need the pcb
2. If the TCP connection is in TCP_FIN_WAIT_1 for too long time, remove it
Liu Zhi Fu 8 年之前
父节点
当前提交
4ad1f2b272
共有 2 个文件被更改,包括 17 次插入31 次删除
  1. 15 30
      components/lwip/core/tcp.c
  2. 2 1
      components/lwip/core/tcp_out.c

+ 15 - 30
components/lwip/core/tcp.c

@@ -149,6 +149,15 @@ tcp_tmr(void)
   }
 }
 
+void
+tcp_set_fin_wait_1(struct tcp_pcb *pcb)
+{
+  pcb->state = FIN_WAIT_1;
+#if ESP_LWIP
+  pcb->tmr = tcp_ticks;
+#endif
+}
+
 /**
  * Closes the TX side of a connection held by the PCB.
  * For tcp_close(), a RST is sent if the application didn't receive all data
@@ -233,14 +242,14 @@ tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data)
     err = tcp_send_fin(pcb);
     if (err == ERR_OK) {
       MIB2_STATS_INC(mib2.tcpattemptfails);
-      pcb->state = FIN_WAIT_1;
+      tcp_set_fin_wait_1(pcb);
     }
     break;
   case ESTABLISHED:
     err = tcp_send_fin(pcb);
     if (err == ERR_OK) {
       MIB2_STATS_INC(mib2.tcpestabresets);
-      pcb->state = FIN_WAIT_1;
+      tcp_set_fin_wait_1(pcb);
     }
     break;
   case CLOSE_WAIT:
@@ -935,7 +944,11 @@ tcp_slowtmr_start:
       }
     }
     /* Check if this PCB has stayed too long in FIN-WAIT-2 */
+#if ESP_LWIP
+    if ((pcb->state == FIN_WAIT_2) || (pcb->state == FIN_WAIT_1)) {
+#else
     if (pcb->state == FIN_WAIT_2) {
+#endif
       /* If this PCB is in FIN_WAIT_2 because of SHUT_WR don't let it time out. */
       if (pcb->flags & TF_RXCLOSED) {
         /* PCB was fully closed (either through close() or SHUT_RDWR):
@@ -1910,31 +1923,6 @@ tcp_eff_send_mss_impl(u16_t sendmss, const ip_addr_t *dest
 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
 
 #if LWIP_IPV4
-/** Helper function for tcp_netif_ipv4_addr_changed() that iterates a pcb list */
-static void
-tcp_netif_ipv4_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 (!IP_IS_V6_VAL(pcb->local_ip) && 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) */
-      && !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;
-    }
-  }
-}
-
 /** This function is called from netif.c when address is changed or netif is removed
  *
  * @param old_addr IPv4 address of the netif before change
@@ -1944,9 +1932,6 @@ void tcp_netif_ipv4_addr_changed(const ip4_addr_t* old_addr, const ip4_addr_t* n
 {
   struct tcp_pcb_listen *lpcb, *next;
 
-  tcp_netif_ipv4_addr_changed_pcblist(old_addr, tcp_active_pcbs);
-  tcp_netif_ipv4_addr_changed_pcblist(old_addr, tcp_bound_pcbs);
-
   if (!ip4_addr_isany(new_addr)) {
     /* PCB bound to current local interface address? */
     for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = next) {

+ 2 - 1
components/lwip/core/tcp_out.c

@@ -152,6 +152,7 @@ tcp_send_fin(struct tcp_pcb *pcb)
       return ERR_OK;
     }
   }
+
   /* no data, no length, flags, copy=1, no optdata */
   return tcp_enqueue_flags(pcb, TCP_FIN);
 }
@@ -1067,7 +1068,7 @@ tcp_output(struct tcp_pcb *pcb)
     seg->oversize_left = 0;
 #endif /* TCP_OVERSIZE_DBGCHECK */
     err = tcp_output_segment(seg, pcb);
-    if (err != ERR_OK) {
+    if ((err != ERR_OK) && (err != ERR_RTE)) {
       /* segment could not be sent, for whatever reason */
       pcb->flags |= TF_NAGLEMEMERR;
       return err;