Index: /trunk/src/VBox/NetworkServices/NAT/pxdns.c
===================================================================
--- /trunk/src/VBox/NetworkServices/NAT/pxdns.c	(revision 58612)
+++ /trunk/src/VBox/NetworkServices/NAT/pxdns.c	(revision 58613)
@@ -43,8 +43,11 @@
 #include "proxy.h"
 #include "proxy_pollmgr.h"
+#include "pxtcp.h"
 
 #include "lwip/sys.h"
 #include "lwip/tcpip.h"
+#include "lwip/ip_addr.h"
 #include "lwip/udp.h"
+#include "lwip/tcp.h"
 
 #ifndef RT_OS_WINDOWS
@@ -84,4 +87,6 @@
     struct udp_pcb *pcb6;
 
+    struct tcp_pcb *ltcp;
+
     size_t generation;
     size_t nresolvers;
@@ -177,4 +182,6 @@
 static void pxdns_create_resolver_sockaddrs(struct pxdns *pxdns,
                                             const char **nameservers);
+
+static err_t pxdns_accept_syn(void *arg, struct tcp_pcb *newpcb, struct pbuf *syn);
 
 static void pxdns_recv4(void *arg, struct udp_pcb *pcb, struct pbuf *p,
@@ -211,4 +218,14 @@
     LWIP_UNUSED_ARG(proxy_netif);
 
+    pxdns->ltcp = tcp_new();
+    if (pxdns->ltcp != NULL) {
+        tcp_bind_ip6(pxdns->ltcp, IP6_ADDR_ANY, 53);
+        pxdns->ltcp = tcp_listen_dual(pxdns->ltcp);
+        if (pxdns->ltcp != NULL) {
+            tcp_arg(pxdns->ltcp, pxdns);
+            tcp_accept_syn(pxdns->ltcp, pxdns_accept_syn);
+        }
+    }
+
     pxdns->pmhdl4.callback = pxdns_pmgr_pump;
     pxdns->pmhdl4.data = (void *)pxdns;
@@ -863,2 +880,41 @@
     pxdns_request_free(req);
 }
+
+
+/**
+ * TCP DNS proxy.  This kicks in for large replies that don't fit into
+ * 512 bytes of UDP payload.  Client will retry with TCP to get
+ * complete reply.
+ */
+static err_t
+pxdns_accept_syn(void *arg, struct tcp_pcb *newpcb, struct pbuf *syn)
+{
+    struct pxdns *pxdns = (struct pxdns *)arg;
+    union sockaddr_inet *si;
+    ipX_addr_t *dst;
+    u16_t dst_port;
+
+    tcp_accepted(pxdns->ltcp);
+
+    if (pxdns->nresolvers == 0) {
+        return ERR_CONN;
+    }
+
+    si = &pxdns->resolvers[0];
+
+    if (si->sa.sa_family == AF_INET6) {
+        dst = (ipX_addr_t *)&si->sin6.sin6_addr;
+        dst_port = ntohs(si->sin6.sin6_port);
+    }
+    else {
+        dst = (ipX_addr_t *)&si->sin.sin_addr;
+        dst_port = ntohs(si->sin.sin_port);
+    }
+
+    /*
+     * XXX: TODO: need to implement protocol hooks.  E.g. here if
+     * connect fails, we should try connecting to a different server.
+     */
+    return pxtcp_pcb_accept_outbound(newpcb, syn,
+               si->sa.sa_family == AF_INET6, dst, dst_port);
+}
Index: /trunk/src/VBox/NetworkServices/NAT/pxtcp.c
===================================================================
--- /trunk/src/VBox/NetworkServices/NAT/pxtcp.c	(revision 58612)
+++ /trunk/src/VBox/NetworkServices/NAT/pxtcp.c	(revision 58613)
@@ -276,6 +276,4 @@
 static void pxtcp_pcb_err(void *, err_t);
 
-static err_t pxtcp_pcb_accept_outbound(struct tcp_pcb *, struct pbuf *, int, ipX_addr_t *, u16_t);
-
 static err_t pxtcp_pcb_forward_outbound(struct pxtcp *, struct pbuf *);
 static void pxtcp_pcb_forward_outbound_close(struct pxtcp *);
@@ -1012,5 +1010,5 @@
 
 
-static err_t
+err_t
 pxtcp_pcb_accept_outbound(struct tcp_pcb *newpcb, struct pbuf *p,
                           int is_ipv6, ipX_addr_t *dst_addr, u16_t dst_port)
Index: /trunk/src/VBox/NetworkServices/NAT/pxtcp.h
===================================================================
--- /trunk/src/VBox/NetworkServices/NAT/pxtcp.h	(revision 58612)
+++ /trunk/src/VBox/NetworkServices/NAT/pxtcp.h	(revision 58613)
@@ -19,6 +19,13 @@
 #define _pxtcp_h_
 
+#include "lwip/err.h"
+#include "lwip/ip_addr.h"
+
+struct pbuf;
+struct tcp_pcb;
 struct pxtcp;
 struct fwspec;
+
+err_t pxtcp_pcb_accept_outbound(struct tcp_pcb *, struct pbuf *, int, ipX_addr_t *, u16_t);
 
 struct pxtcp *pxtcp_create_forwarded(SOCKET);
