Index: /trunk/src/VBox/Devices/Network/lwip-new/src/core/tcp.c
===================================================================
--- /trunk/src/VBox/Devices/Network/lwip-new/src/core/tcp.c	(revision 58591)
+++ /trunk/src/VBox/Devices/Network/lwip-new/src/core/tcp.c	(revision 58592)
@@ -543,4 +543,19 @@
 #endif /* LWIP_CALLBACK_API */
 
+#if LWIP_CONNECTION_PROXY
+/**
+ * Default proxy accept syn callback if no accept callback is specified by the user.
+ */
+err_t
+tcp_accept_syn_null(void *arg, struct tcp_pcb *newpcb, struct pbuf *syn)
+{
+  LWIP_UNUSED_ARG(arg);
+  LWIP_UNUSED_ARG(syn);
+
+  tcp_abort(newpcb);
+  return ERR_ABRT;
+}
+#endif /* LWIP_CONNECTION_PROXY */
+
 /**
  * Set the state of the connection to be LISTEN, which means that it
@@ -1559,7 +1574,7 @@
  */ 
 void
-tcp_proxy_accept(tcp_accept_fn accept)
-{
-  tcp_proxy_accept_callback = accept;
+tcp_proxy_accept(tcp_accept_syn_fn accept_syn)
+{
+  tcp_proxy_accept_callback = accept_syn;
 }
 
@@ -1571,5 +1586,5 @@
  */
 void
-tcp_accept_syn(struct tcp_pcb *pcb, tcp_accept_fn accept)
+tcp_accept_syn(struct tcp_pcb *pcb, tcp_accept_syn_fn accept_syn)
 {
   struct tcp_pcb_listen *lpcb;
@@ -1578,5 +1593,5 @@
   lpcb = (struct tcp_pcb_listen *)pcb;
 
-  lpcb->accept = accept;
+  lpcb->accept = (tcp_accept_fn)accept_syn;
   lpcb->accept_on_syn = 1;
 }
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 58591)
+++ /trunk/src/VBox/Devices/Network/lwip-new/src/core/tcp_in.c	(revision 58592)
@@ -64,5 +64,5 @@
 
 #if LWIP_CONNECTION_PROXY
-tcp_accept_fn tcp_proxy_accept_callback = tcp_accept_null;
+tcp_accept_syn_fn tcp_proxy_accept_callback = tcp_accept_syn_null;
 #endif
 
@@ -90,9 +90,9 @@
 static void tcp_parseopt(struct tcp_pcb *pcb);
 
-static err_t tcp_listen_input(struct tcp_pcb_listen *pcb);
+static err_t tcp_listen_input(struct tcp_pcb_listen *pcb, struct pbuf *syn);
 static err_t tcp_timewait_input(struct tcp_pcb *pcb);
 
 #if LWIP_CONNECTION_PROXY
-static err_t tcp_proxy_listen_input(struct pbuf *p);
+static err_t tcp_proxy_listen_input(struct pbuf *syn);
 static void tcp_restore_pbuf(struct pbuf *p);
 
@@ -314,5 +314,5 @@
     
       LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n"));
-      tcp_listen_input(lpcb);
+      tcp_listen_input(lpcb, p);
       pbuf_free(p);
       return;
@@ -498,5 +498,5 @@
  */
 static err_t
-tcp_listen_input(struct tcp_pcb_listen *pcb)
+tcp_listen_input(struct tcp_pcb_listen *pcb, struct pbuf *syn)
 {
   struct tcp_pcb *npcb;
@@ -572,4 +572,5 @@
     /* Early accept on SYN, like we do in tcp_proxy_listen_input() */
     if (pcb->accept_on_syn) {
+      tcp_accept_syn_fn accept_syn;
       err_t err;
 
@@ -578,10 +579,18 @@
 
       /*
-       * 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 syn function.  Note, that it comes from the
+       * listening pcb and we reset the normal accept callback of the
+       * new pcb.  The latter should be set by the client along with
+       * other callbacks if necessary.
        */
-      /* Call the accept function. */
-      TCP_EVENT_ACCEPT(npcb, ERR_OK, err);
+      accept_syn = (tcp_accept_syn_fn)npcb->accept;
+      npcb->accept = tcp_accept_null;
+
+      /* TCP_EVENT_ACCEPT_SYN */
+      if (accept_syn != NULL)
+        err = (*accept_syn)(npcb->callback_arg, npcb, syn);
+      else
+        err = ERR_ARG;
+
       if (err != ERR_OK) {
         /* If the accept function returns with an error, we abort
@@ -645,5 +654,5 @@
  */
 static err_t
-tcp_proxy_listen_input(struct pbuf *p)
+tcp_proxy_listen_input(struct pbuf *syn)
 {
   struct tcp_pcb *npcb;
@@ -700,5 +709,5 @@
     npcb->callback_arg = /* pcb->callback_arg */ NULL;
 #if LWIP_CALLBACK_API
-    npcb->accept = /* pcb->accept */ tcp_proxy_accept_callback;
+    npcb->accept = /* pcb->accept */ tcp_accept_null;
 #endif /* LWIP_CALLBACK_API */
     /* inherit socket options */
@@ -733,9 +742,12 @@
      */
 
-    tcp_restore_pbuf(p);
-    npcb->callback_arg = (void *)p;
- 
-    /* Call the accept function. */
-    TCP_EVENT_ACCEPT(npcb, ERR_OK, err);
+    tcp_restore_pbuf(syn);
+
+    /* TCP_EVENT_ACCEPT_SYN */
+    if (tcp_proxy_accept_callback != NULL)
+      err = (*tcp_proxy_accept_callback)(NULL, npcb, syn);
+    else
+      err = ERR_ARG;
+
     if (err != ERR_OK) {
         /* If the accept function returns with an error, we abort
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 58591)
+++ /trunk/src/VBox/Devices/Network/lwip-new/src/include/lwip/tcp.h	(revision 58592)
@@ -61,4 +61,16 @@
  */
 typedef err_t (*tcp_accept_fn)(void *arg, struct tcp_pcb *newpcb, err_t err);
+
+#if LWIP_CONNECTION_PROXY
+/** Function prototype for tcp accept callback functions. Called when
+ * a new connection is about to be accepted by the proxy or on a
+ * listening pcb that requested proxy-like accept on syn.
+ *
+ * @param arg Additional argument to pass to the callback function (@see tcp_arg())
+ * @param newpcb The new connection pcb
+ * @param syn The pbuf with the SYN segment (may be used to reply with ICMP).
+ */
+typedef err_t (*tcp_accept_syn_fn)(void *arg, struct tcp_pcb *newpcb, struct pbuf *syn);
+#endif /* LWIP_CONNECTION_PROXY */
 
 /** Function prototype for tcp receive callback functions. Called when data has
@@ -333,7 +345,7 @@
 /* when proxied connection is accepted there's no listening pcb */
 void             tcp_proxy_arg(void *arg);
-void             tcp_proxy_accept(tcp_accept_fn accept);
+void             tcp_proxy_accept(tcp_accept_syn_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);
+void             tcp_accept_syn(struct tcp_pcb *lpcb, tcp_accept_syn_fn accept);
 #endif
 void             tcp_recv    (struct tcp_pcb *pcb, tcp_recv_fn recv);
Index: /trunk/src/VBox/Devices/Network/lwip-new/src/include/lwip/tcp_impl.h
===================================================================
--- /trunk/src/VBox/Devices/Network/lwip-new/src/include/lwip/tcp_impl.h	(revision 58591)
+++ /trunk/src/VBox/Devices/Network/lwip-new/src/include/lwip/tcp_impl.h	(revision 58592)
@@ -314,5 +314,5 @@
 
 #if LWIP_CONNECTION_PROXY
-extern tcp_accept_fn tcp_proxy_accept_callback;
+extern tcp_accept_syn_fn tcp_proxy_accept_callback;
 #endif
 
@@ -489,4 +489,8 @@
 #endif /* LWIP_CALLBACK_API */
 
+#if LWIP_CONNECTION_PROXY
+err_t tcp_accept_syn_null(void *arg, struct tcp_pcb *newpcb, struct pbuf *syn);
+#endif /* LWIP_CONNECTION_PROXY */
+
 #if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG
 void tcp_debug_print(struct tcp_hdr *tcphdr);
Index: /trunk/src/VBox/NetworkServices/NAT/pxtcp.c
===================================================================
--- /trunk/src/VBox/NetworkServices/NAT/pxtcp.c	(revision 58591)
+++ /trunk/src/VBox/NetworkServices/NAT/pxtcp.c	(revision 58592)
@@ -268,5 +268,5 @@
 
 /* tcp pcb callbacks */
-static err_t pxtcp_pcb_heard(void *, struct tcp_pcb *, err_t); /* global */
+static err_t pxtcp_pcb_heard(void *, struct tcp_pcb *, struct pbuf *); /* global */
 static err_t pxtcp_pcb_accept(void *, struct tcp_pcb *, err_t);
 static err_t pxtcp_pcb_connected(void *, struct tcp_pcb *, err_t);
@@ -1003,11 +1003,9 @@
  */
 static err_t
-pxtcp_pcb_heard(void *arg, struct tcp_pcb *newpcb, err_t error)
-{
-    struct pbuf *p = (struct pbuf *)arg;
-
-    LWIP_UNUSED_ARG(error);     /* always ERR_OK */
-
-    return pxtcp_pcb_accept_outbound(newpcb, p,
+pxtcp_pcb_heard(void *arg, struct tcp_pcb *newpcb, struct pbuf *syn)
+{
+    LWIP_UNUSED_ARG(arg);
+
+    return pxtcp_pcb_accept_outbound(newpcb, syn,
                PCB_ISIPV6(newpcb), &newpcb->local_ip, newpcb->local_port);
 }
