Index: /trunk/src/VBox/Devices/Network/lwip-new/src/core/tcp.c
===================================================================
--- /trunk/src/VBox/Devices/Network/lwip-new/src/core/tcp.c	(revision 58554)
+++ /trunk/src/VBox/Devices/Network/lwip-new/src/core/tcp.c	(revision 58555)
@@ -601,4 +601,7 @@
   lpcb->accept_any_ip_version = 0;
 #endif /* LWIP_IPV6 */
+#if LWIP_CONNECTION_PROXY
+  lpcb->accept_on_syn = 0;
+#endif
   ipX_addr_copy(PCB_ISIPV6(pcb), lpcb->local_ip, pcb->local_ip);
   if (pcb->local_port != 0) {
@@ -1559,4 +1562,22 @@
 {
   tcp_proxy_accept_callback = accept;
+}
+
+
+/**
+ * A cross between normal accept and proxy early accept.  Like with
+ * normal accept there's a normal LISTENing pcb.  Like with proxy, the
+ * accept callback will be called on the first SYN.
+ */
+void
+tcp_accept_syn(struct tcp_pcb *pcb, tcp_accept_fn accept)
+{
+  struct tcp_pcb_listen *lpcb;
+
+  LWIP_ASSERT("invalid socket state for accept callback", pcb->state == LISTEN);
+  lpcb = (struct tcp_pcb_listen *)pcb;
+
+  lpcb->accept = accept;
+  lpcb->accept_on_syn = 1;
 }
 #endif /* LWIP_CONNECTION_PROXY */
Index: /trunk/src/VBox/Devices/Network/lwip-new/src/core/tcp_in.c
===================================================================
--- /trunk/src/VBox/Devices/Network/lwip-new/src/core/tcp_in.c	(revision 58554)
+++ /trunk/src/VBox/Devices/Network/lwip-new/src/core/tcp_in.c	(revision 58555)
@@ -569,4 +569,35 @@
       &npcb->remote_ip, PCB_ISIPV6(npcb));
 #endif /* TCP_CALCULATE_EFF_SEND_MSS */
+
+
+#if LWIP_CONNECTION_PROXY
+    /* Early accept on SYN, like we do in tcp_proxy_listen_input() */
+    if (pcb->accept_on_syn) {
+      err_t err;
+
+      /* back off to "delayed" SYN_RCVD, see comments in proxy */
+      npcb->state = SYN_RCVD_0;
+
+      /*
+       * XXX: TODO: how to pass syn pbuf?  Need to be consistent with
+       * proxy version, but can't abuse callback_arg here since it's
+       * actually used in this case.
+       */
+      /* Call the accept function. */
+      TCP_EVENT_ACCEPT(npcb, ERR_OK, err);
+      if (err != ERR_OK) {
+        /* If the accept function returns with an error, we abort
+         * the connection. */
+        /* Already aborted? */
+        if (err != ERR_ABRT) {
+          tcp_abort(npcb);
+        }
+        return ERR_ABRT;
+      }
+      /* Don't send SYN|ACK now, client will call
+       * tcp_proxy_accept_confirm(). */
+      return ERR_OK;
+    }
+#endif
 
     snmp_inc_tcppassiveopens();
Index: /trunk/src/VBox/Devices/Network/lwip-new/src/include/lwip/tcp.h
===================================================================
--- /trunk/src/VBox/Devices/Network/lwip-new/src/include/lwip/tcp.h	(revision 58554)
+++ /trunk/src/VBox/Devices/Network/lwip-new/src/include/lwip/tcp.h	(revision 58555)
@@ -301,4 +301,7 @@
   u8_t accept_any_ip_version;
 #endif /* LWIP_IPV6 */
+#if LWIP_CONNECTION_PROXY
+  u8_t accept_on_syn;
+#endif
 };
 
@@ -331,4 +334,6 @@
 void             tcp_proxy_arg(void *arg);
 void             tcp_proxy_accept(tcp_accept_fn accept);
+/* but we also provide proxy-like early accept for listening pcbs */
+void             tcp_accept_syn(struct tcp_pcb *lpcb, tcp_accept_fn accept);
 #endif
 void             tcp_recv    (struct tcp_pcb *pcb, tcp_recv_fn recv);
