Index: src/api/api_lib.c
===================================================================
RCS file: /sources/lwip/lwip/src/api/api_lib.c,v
retrieving revision 1.83
diff -u -r1.83 api_lib.c
--- src/api/api_lib.c	16 Dec 2007 16:15:08 -0000	1.83
+++ src/api/api_lib.c	16 Dec 2007 16:45:32 -0000
@@ -261,16 +261,20 @@
  * Set a TCP netconn into listen mode
  *
  * @param conn the tcp netconn to set to listen mode
+ * @param backlog the listen backlog (0 = max), only used if LWIP_LISTEN_BACKLOG==1
  * @return ERR_OK if the netconn was set to listen (UDP and RAW netconns
  *         don't return any error (yet?))
  */
 err_t
-netconn_listen(struct netconn *conn)
+netconn_listen(struct netconn *conn, int backlog)
 {
   struct api_msg msg;
 
   LWIP_ERROR("netconn_listen: invalid conn", (conn != NULL), return ERR_ARG;);
 
+#if LWIP_LISTEN_BACKLOG
+  msg.msg.msg.lb.backlog = backlog;
+#endif /* LWIP_LISTEN_BACKLOG */
   msg.function = do_listen;
   msg.msg.conn = conn;
   TCPIP_APIMSG(&msg);
@@ -292,15 +296,22 @@
   LWIP_ERROR("netconn_accept: invalid acceptmbox", (conn->acceptmbox != SYS_MBOX_NULL), return NULL;);
 
 #if LWIP_SO_RCVTIMEO
-  if (sys_arch_mbox_fetch(conn->acceptmbox, (void *)&newconn, conn->recv_timeout)==SYS_ARCH_TIMEOUT) {
+  if (sys_arch_mbox_fetch(conn->acceptmbox, (void *)&newconn, conn->recv_timeout) == SYS_ARCH_TIMEOUT) {
     newconn = NULL;
-  }
+  } else
 #else
   sys_arch_mbox_fetch(conn->acceptmbox, (void *)&newconn, 0);
 #endif /* LWIP_SO_RCVTIMEO*/
+  {
+#if LWIP_LISTEN_BACKLOG
+    if (newconn != NULL) {
+      SYS_ARCH_DEC(conn->acceptmbox_count, 1);
+    }
+#endif /* LWIP_LISTEN_BACKLOG*/
 
-  /* Register event with callback */
-  API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
+    /* Register event with callback */
+    API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
+  }
 
   return newconn;
 }
Index: src/api/api_msg.c
===================================================================
RCS file: /sources/lwip/lwip/src/api/api_msg.c,v
retrieving revision 1.87
diff -u -r1.87 api_msg.c
--- src/api/api_msg.c	13 Dec 2007 23:06:50 -0000	1.87
+++ src/api/api_msg.c	16 Dec 2007 16:46:29 -0000
@@ -306,6 +306,28 @@
   tcp_err(pcb, err_tcp);
 }
 
+#if LWIP_LISTEN_BACKLOG
+/**
+ * Allow accept or not? Implements the listen backlog.
+ *
+ * @param arg should point to the netconn
+ * @param pcb the listen pcb to check
+ * @return ERR_OK if allowed, an error if not allowed (listen backlog exceeded)
+ */
+err_t
+accept_allowed_function(void *arg, struct tcp_pcb_listen *pcb)
+{
+  struct netconn *conn = (struct netconn *)arg;
+  int acceptmbox_count;
+
+  SYS_ARCH_GET(conn->acceptmbox_count, acceptmbox_count);
+  if (acceptmbox_count >= conn->backlog) {
+    return ERR_MEM;
+  }
+  return ERR_OK;
+}
+#endif /* LWIP_LISTEN_BACKLOG */
+
 /**
  * Accept callback function for TCP netconns.
  * Allocates a new netconn and posts that to conn->acceptmbox.
@@ -317,6 +339,9 @@
 {
   struct netconn *newconn;
   struct netconn *conn;
+#if LWIP_LISTEN_BACKLOG
+  int acceptmbox_count;
+#endif /* LWIP_LISTEN_BACKLOG*/
 
 #if API_MSG_DEBUG
 #if TCP_DEBUG
@@ -328,6 +353,12 @@
   LWIP_ERROR("accept_function: invalid conn->acceptmbox",
              conn->acceptmbox != SYS_MBOX_NULL, return ERR_VAL;);
 
+#if LWIP_LISTEN_BACKLOG
+  SYS_ARCH_GET(conn->acceptmbox_count, acceptmbox_count);
+  /* this should be ensured by accept_allow_function */
+  LWIP_ASSERT("listen backlog exceeded", acceptmbox_count < conn->backlog);
+#endif /* LWIP_LISTEN_BACKLOG */
+
   /* We have to set the callback here even though
    * the new socket is unknown. conn->socket is marked as -1. */
   newconn = netconn_alloc_with_proto_and_callback(conn->type, 0, conn->callback);
@@ -340,6 +371,10 @@
   /* Register event with callback */
   API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
 
+#if LWIP_LISTEN_BACKLOG
+  SYS_ARCH_INC(conn->acceptmbox_count, 1);
+#endif /* LWIP_LISTEN_BACKLOG*/
+
   sys_mbox_post(conn->acceptmbox, newconn);
   return ERR_OK;
 }
@@ -473,6 +508,10 @@
 #if LWIP_SO_RCVBUF
   conn->recv_bufsize = INT_MAX;
 #endif /* LWIP_SO_RCVBUF */
+#if LWIP_LISTEN_BACKLOG
+  conn->backlog = 0;
+  conn->acceptmbox_count = 0;
+#endif /* LWIP_LISTEN_BACKLOG */
   return conn;
 }
 
@@ -725,6 +764,15 @@
               }
             }
             if (msg->conn->err == ERR_OK) {
+#if LWIP_LISTEN_BACKLOG
+              {
+                struct tcp_pcb_listen *listen_pcb = (struct tcp_pcb_listen*)lpcb;
+                msg->conn->backlog = msg->msg.lb.backlog;
+                msg->conn->acceptmbox_count = 0;
+                listen_pcb->accept_allowed = accept_allowed_function;
+                listen_pcb->accept_allowed_arg = msg->conn;
+              }
+#endif /* LWIP_LISTEN_BACKLOG */
               msg->conn->state = NETCONN_LISTEN;
               msg->conn->pcb.tcp = lpcb;
               tcp_arg(msg->conn->pcb.tcp, msg->conn);
Index: src/api/sockets.c
===================================================================
RCS file: /sources/lwip/lwip/src/api/sockets.c,v
retrieving revision 1.110
diff -u -r1.110 sockets.c
--- src/api/sockets.c	13 Dec 2007 23:06:50 -0000	1.110
+++ src/api/sockets.c	16 Dec 2007 16:46:35 -0000
@@ -438,7 +438,7 @@
   if (!sock)
     return -1;
 
-  err = netconn_listen(sock->conn);
+  err = netconn_listen(sock->conn, backlog);
 
   if (err != ERR_OK) {
     LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d) failed, err=%d\n", s, err));
Index: src/core/tcp_in.c
===================================================================
RCS file: /sources/lwip/lwip/src/core/tcp_in.c,v
retrieving revision 1.90
diff -u -r1.90 tcp_in.c
--- src/core/tcp_in.c	16 Dec 2007 16:24:10 -0000	1.90
+++ src/core/tcp_in.c	16 Dec 2007 16:36:52 -0000
@@ -381,6 +381,13 @@
       tcphdr->dest, tcphdr->src);
   } else if (flags & TCP_SYN) {
     LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest));
+#if LWIP_LISTEN_BACKLOG
+    if (pcb->accept_allowed != NULL) {
+      if (pcb->accept_allowed(pcb->accept_allowed_arg, pcb) != ERR_OK) {
+        return ERR_ABRT;
+      }
+    }
+#endif /* LWIP_LISTEN_BACKLOG */
     npcb = tcp_alloc(pcb->prio);
     /* If a new PCB could not be created (probably due to lack of memory),
        we don't do anything, but rely on the sender will retransmit the
Index: src/include/lwip/api.h
===================================================================
RCS file: /sources/lwip/lwip/src/include/lwip/api.h,v
retrieving revision 1.38
diff -u -r1.38 api.h
--- src/include/lwip/api.h	24 Nov 2007 21:19:53 -0000	1.38
+++ src/include/lwip/api.h	16 Dec 2007 16:50:26 -0000
@@ -125,6 +125,10 @@
   sys_mbox_t acceptmbox;
   /** only used for socket layer */
   int socket;
+#if LWIP_LISTEN_BACKLOG
+  int backlog;
+  int acceptmbox_count;
+#endif /* LWIP_LISTEN_BACKLOG */
 #if LWIP_SO_RCVTIMEO
   /** timeout to wait for new data to be received
       (or connections to arrive for listening netconns) */
@@ -179,7 +183,7 @@
                                    struct ip_addr *addr,
                                    u16_t port);
 err_t             netconn_disconnect (struct netconn *conn);
-err_t             netconn_listen  (struct netconn *conn);
+err_t             netconn_listen  (struct netconn *conn, int backlog);
 struct netconn *  netconn_accept  (struct netconn *conn);
 struct netbuf *   netconn_recv    (struct netconn *conn);
 err_t             netconn_sendto  (struct netconn *conn,
Index: src/include/lwip/api_msg.h
===================================================================
RCS file: /sources/lwip/lwip/src/include/lwip/api_msg.h,v
retrieving revision 1.27
diff -u -r1.27 api_msg.h
--- src/include/lwip/api_msg.h	2 Dec 2007 15:18:08 -0000	1.27
+++ src/include/lwip/api_msg.h	13 Dec 2007 21:18:21 -0000
@@ -93,6 +93,11 @@
       enum netconn_igmp join_or_leave;
     } jl;
 #endif /* LWIP_IGMP */
+#if LWIP_LISTEN_BACKLOG
+    struct {
+      int backlog;
+    } lb;
+#endif /* LWIP_LISTEN_BACKLOG */
   } msg;
 };
 
Index: src/include/lwip/tcp.h
===================================================================
RCS file: /sources/lwip/lwip/src/include/lwip/tcp.h,v
retrieving revision 1.59
diff -u -r1.59 tcp.h
--- src/include/lwip/tcp.h	21 Nov 2007 18:37:24 -0000	1.59
+++ src/include/lwip/tcp.h	16 Dec 2007 11:04:54 -0000
@@ -411,6 +411,10 @@
    */
   err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err);
 #endif /* LWIP_CALLBACK_API */
+#if LWIP_LISTEN_BACKLOG
+  err_t (* accept_allowed)(void *arg, struct tcp_pcb_listen *pcb);
+  void *accept_allowed_arg;
+#endif /* LWIP_LISTEN_BACKLOG */
 };
 
 #if LWIP_EVENT_API
