commit bc5cf1a2fa88fffe6671b52928635c9338cf0c00
Author: Ambroz Bizjak <ambrop7@gmail.com>
Date:   Mon Jan 18 22:40:08 2016 +0100

    lwip: Fix the backlog tracking.

diff --git a/lwip/src/core/tcp.c b/lwip/src/core/tcp.c
index da87f65..968d1da 100644
--- a/lwip/src/core/tcp.c
+++ b/lwip/src/core/tcp.c
@@ -1678,22 +1678,7 @@ tcp_pcb_purge(struct tcp_pcb *pcb)
 
 #if TCP_LISTEN_BACKLOG
     if (pcb->state == SYN_RCVD) {
-      /* Need to find the corresponding listen_pcb and decrease its accepts_pending */
-      struct tcp_pcb_listen *lpcb;
-      LWIP_ASSERT("tcp_pcb_purge: pcb->state == SYN_RCVD but tcp_listen_pcbs is NULL",
-        tcp_listen_pcbs.listen_pcbs != NULL);
-      for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
-        if ((lpcb->local_port == pcb->local_port) &&
-            IP_PCB_IPVER_EQ(pcb, lpcb) &&
-            (ip_addr_isany(&lpcb->local_ip) ||
-             ip_addr_cmp(&pcb->local_ip, &lpcb->local_ip))) {
-            /* port and address of the listen pcb match the timed-out pcb */
-            LWIP_ASSERT("tcp_pcb_purge: listen pcb does not have accepts pending",
-              lpcb->accepts_pending > 0);
-            lpcb->accepts_pending--;
-            break;
-          }
-      }
+      tcp_pcb_decrement_accepts_pending_of_listener(pcb);
     }
 #endif /* TCP_LISTEN_BACKLOG */
 
@@ -1766,6 +1751,29 @@ tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb)
   LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane());
 }
 
+#if TCP_LISTEN_BACKLOG
+void
+tcp_pcb_decrement_accepts_pending_of_listener(struct tcp_pcb *pcb)
+{
+  /* Need to find the corresponding listen_pcb and decrease its accepts_pending */
+  struct tcp_pcb_listen *lpcb;
+  LWIP_ASSERT("tcp_pcb_purge: pcb->state == SYN_RCVD but tcp_listen_pcbs is NULL",
+    tcp_listen_pcbs.listen_pcbs != NULL);
+  for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
+    if ((lpcb->local_port == pcb->local_port) &&
+        IP_PCB_IPVER_EQ(pcb, lpcb) &&
+        (ip_addr_isany(&lpcb->local_ip) ||
+         ip_addr_cmp(&pcb->local_ip, &lpcb->local_ip))) {
+        /* port and address of the listen pcb match the timed-out pcb */
+        LWIP_ASSERT("tcp_pcb_purge: listen pcb does not have accepts pending",
+          lpcb->accepts_pending > 0);
+        lpcb->accepts_pending--;
+        break;
+      }
+  }
+}
+#endif /* TCP_LISTEN_BACKLOG */
+
 /**
  * Calculates a new initial sequence number for new connections.
  *
diff --git a/lwip/src/core/tcp_in.c b/lwip/src/core/tcp_in.c
index 05fc31e..b7f6cd5 100644
--- a/lwip/src/core/tcp_in.c
+++ b/lwip/src/core/tcp_in.c
@@ -788,6 +790,9 @@ tcp_process(struct tcp_pcb *pcb)
     if (flags & TCP_ACK) {
       /* expected ACK number? */
       if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) {
+#if TCP_LISTEN_BACKLOG
+        tcp_pcb_decrement_accepts_pending_of_listener(pcb);
+#endif
         pcb->state = ESTABLISHED;
         LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
 #if LWIP_CALLBACK_API
diff --git a/lwip/src/include/lwip/tcp.h b/lwip/src/include/lwip/tcp.h
index 7c036d8..070fdec 100644
--- a/lwip/src/include/lwip/tcp.h
+++ b/lwip/src/include/lwip/tcp.h
@@ -358,14 +358,8 @@ void             tcp_err     (struct tcp_pcb *pcb, tcp_err_fn err);
 #define          tcp_nagle_enable(pcb)    ((pcb)->flags = (tcpflags_t)((pcb)->flags & ~TF_NODELAY))
 #define          tcp_nagle_disabled(pcb)  (((pcb)->flags & TF_NODELAY) != 0)
 
-#if TCP_LISTEN_BACKLOG
-#define          tcp_accepted(pcb) do { \
-  LWIP_ASSERT("pcb->state == LISTEN (called for wrong pcb?)", pcb->state == LISTEN); \
-  (((struct tcp_pcb_listen *)(pcb))->accepts_pending--); } while(0)
-#else  /* TCP_LISTEN_BACKLOG */
 #define          tcp_accepted(pcb) LWIP_ASSERT("pcb->state == LISTEN (called for wrong pcb?)", \
                                                (pcb)->state == LISTEN)
-#endif /* TCP_LISTEN_BACKLOG */
 
 void             tcp_recved  (struct tcp_pcb *pcb, u16_t len);
 err_t            tcp_bind    (struct tcp_pcb *pcb, const ip_addr_t *ipaddr,
diff --git a/lwip/src/include/lwip/tcp_impl.h b/lwip/src/include/lwip/tcp_impl.h
index 8c53cc4..6b1dc83 100644
--- a/lwip/src/include/lwip/tcp_impl.h
+++ b/lwip/src/include/lwip/tcp_impl.h
@@ -457,6 +457,10 @@ struct tcp_pcb *tcp_pcb_copy(struct tcp_pcb *pcb);
 void tcp_pcb_purge(struct tcp_pcb *pcb);
 void tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb);
 
+#if TCP_LISTEN_BACKLOG
+void tcp_pcb_decrement_accepts_pending_of_listener(struct tcp_pcb *pcb);
+#endif /* TCP_LISTEN_BACKLOG */
+
 void tcp_segs_free(struct tcp_seg *seg);
 void tcp_seg_free(struct tcp_seg *seg);
 struct tcp_seg *tcp_seg_copy(struct tcp_seg *seg);
