Fixed IPv6 support.

The TcpListener constructor now takes a 'struct sockaddr*' instead of
a string, and the createTcpListeners function creates TcpListener
instances for an address based on the results from getaddrinfo().

The XserverDesktop class now takes a list of TcpListener instances for
each of the RFB and HTTP sockets.

The TcpListener::closeFd member variable is not used and has been
removed.
diff --git a/unix/x0vncserver/x0vncserver.cxx b/unix/x0vncserver/x0vncserver.cxx
index a9b328f..2d9a066 100644
--- a/unix/x0vncserver/x0vncserver.cxx
+++ b/unix/x0vncserver/x0vncserver.cxx
@@ -477,6 +477,8 @@
   signal(SIGINT, CleanupSignalHandler);
   signal(SIGTERM, CleanupSignalHandler);
 
+  std::list<TcpListener> listeners;
+
   try {
     TXWindow::init(dpy,"x0vncserver");
     Geometry geo(DisplayWidth(dpy, DefaultScreen(dpy)),
@@ -491,13 +493,16 @@
     QueryConnHandler qcHandler(dpy, &server);
     server.setQueryConnectionHandler(&qcHandler);
 
-    TcpListener listener(NULL, (int)rfbport);
+    createTcpListeners(&listeners, 0, (int)rfbport);
     vlog.info("Listening on port %d", (int)rfbport);
 
     const char *hostsData = hostsFile.getData();
     FileTcpFilter fileTcpFilter(hostsData);
     if (strlen(hostsData) != 0)
-      listener.setFilter(&fileTcpFilter);
+      for (std::list<TcpListener>::iterator i = listeners.begin();
+           i != listeners.end();
+           i++)
+        (*i).setFilter(&fileTcpFilter);
     delete[] hostsData;
 
     PollingScheduler sched((int)pollingCycle, (int)maxProcessorUsage);
@@ -513,7 +518,11 @@
 
       FD_ZERO(&rfds);
       FD_SET(ConnectionNumber(dpy), &rfds);
-      FD_SET(listener.getFd(), &rfds);
+      for (std::list<TcpListener>::iterator i = listeners.begin();
+           i != listeners.end();
+           i++)
+        FD_SET((*i).getFd(), &rfds);
+
       server.getSockets(&sockets);
       int clients_connected = 0;
       for (i = sockets.begin(); i != sockets.end(); i++) {
@@ -558,12 +567,16 @@
       }
 
       // Accept new VNC connections
-      if (FD_ISSET(listener.getFd(), &rfds)) {
-        Socket* sock = listener.accept();
-        if (sock) {
-          server.addSocket(sock);
-        } else {
-          vlog.status("Client connection rejected");
+      for (std::list<TcpListener>::iterator i = listeners.begin();
+           i != listeners.end();
+           i++) {
+        if (FD_ISSET((*i).getFd(), &rfds)) {
+          Socket* sock = (*i).accept();
+          if (sock) {
+            server.addSocket(sock);
+          } else {
+            vlog.status("Client connection rejected");
+          }
         }
       }
 
diff --git a/unix/xserver/hw/vnc/RFBGlue.cc b/unix/xserver/hw/vnc/RFBGlue.cc
index 53d5bdb..19338fc 100644
--- a/unix/xserver/hw/vnc/RFBGlue.cc
+++ b/unix/xserver/hw/vnc/RFBGlue.cc
@@ -187,7 +187,10 @@
 int vncIsTCPPortUsed(int port)
 {
   try {
-    network::TcpListener l(NULL, port);
+    // Attempt to create TCPListeners on that port.
+    // They go out of scope immediately and are destroyed.
+    std::list<network::TcpListener> dummy;
+    network::createTcpListeners (&dummy, 0, port);
   } catch (rdr::Exception& e) {
     return 0;
   }
diff --git a/unix/xserver/hw/vnc/XserverDesktop.cc b/unix/xserver/hw/vnc/XserverDesktop.cc
index 54e09cb..165afbb 100644
--- a/unix/xserver/hw/vnc/XserverDesktop.cc
+++ b/unix/xserver/hw/vnc/XserverDesktop.cc
@@ -91,14 +91,14 @@
 
 
 XserverDesktop::XserverDesktop(int screenIndex_,
-                               network::TcpListener* listener_,
-                               network::TcpListener* httpListener_,
+                               std::list<network::TcpListener> listeners_,
+                               std::list<network::TcpListener> httpListeners_,
                                const char* name, const rfb::PixelFormat &pf,
                                int width, int height,
                                void* fbptr, int stride)
   : screenIndex(screenIndex_),
     server(0), httpServer(0),
-    listener(listener_), httpListener(httpListener_),
+    listeners(listeners_), httpListeners(httpListeners_),
     deferredUpdateTimerSet(false), directFbptr(true),
     queryConnectId(0)
 {
@@ -108,7 +108,7 @@
   setFramebuffer(width, height, fbptr, stride);
   server->setQueryConnectionHandler(this);
 
-  if (httpListener)
+  if (!httpListeners.empty ())
     httpServer = new FileHTTPServer(this);
 }
 
@@ -222,7 +222,7 @@
   }
   if (strcmp(varName, "$PORT") == 0) {
     char* str = new char[10];
-    sprintf(str, "%d", listener ? listener->getMyPort() : 0);
+    sprintf(str, "%d", listeners.empty () ? 0 : (*listeners.begin ()).getMyPort());
     return str;
   }
   if (strcmp(varName, "$WIDTH") == 0) {
@@ -393,14 +393,18 @@
 
     // Add all sockets we want read events for, after purging
     // any closed sockets.
-    if (listener)
-      FD_SET(listener->getFd(), fds);
-    if (httpListener)
-      FD_SET(httpListener->getFd(), fds);
+    for (std::list<network::TcpListener>::iterator i = listeners.begin();
+         i != listeners.end();
+         i++)
+      FD_SET((*i).getFd(), fds);
+    for (std::list<network::TcpListener>::iterator i = httpListeners.begin();
+         i != httpListeners.end();
+         i++)
+      FD_SET((*i).getFd(), fds);
 
     std::list<Socket*> sockets;
-    server->getSockets(&sockets);
     std::list<Socket*>::iterator i;
+    server->getSockets(&sockets);
     for (i = sockets.begin(); i != sockets.end(); i++) {
       int fd = (*i)->getFd();
       if ((*i)->isShutdown()) {
@@ -452,20 +456,24 @@
     // First check for file descriptors with something to do
     if (nfds >= 1) {
 
-      if (listener) {
-        if (FD_ISSET(listener->getFd(), fds)) {
-          FD_CLR(listener->getFd(), fds);
-          Socket* sock = listener->accept();
+      for (std::list<network::TcpListener>::iterator i = listeners.begin();
+           i != listeners.end();
+           i++) {
+        if (FD_ISSET((*i).getFd(), fds)) {
+          FD_CLR((*i).getFd(), fds);
+          Socket* sock = (*i).accept();
           sock->outStream().setBlocking(false);
           server->addSocket(sock);
           vlog.debug("new client, sock %d",sock->getFd());
         }
       }
 
-      if (httpListener) {
-        if (FD_ISSET(httpListener->getFd(), fds)) {
-          FD_CLR(httpListener->getFd(), fds);
-          Socket* sock = httpListener->accept();
+      for (std::list<network::TcpListener>::iterator i = httpListeners.begin();
+           i != httpListeners.end();
+           i++) {
+        if (FD_ISSET((*i).getFd(), fds)) {
+          FD_CLR((*i).getFd(), fds);
+          Socket* sock = (*i).accept();
           sock->outStream().setBlocking(false);
           httpServer->addSocket(sock);
           vlog.debug("new http client, sock %d",sock->getFd());
diff --git a/unix/xserver/hw/vnc/XserverDesktop.h b/unix/xserver/hw/vnc/XserverDesktop.h
index 7dcaa29..6909a76 100644
--- a/unix/xserver/hw/vnc/XserverDesktop.h
+++ b/unix/xserver/hw/vnc/XserverDesktop.h
@@ -50,8 +50,9 @@
                        public rfb::VNCServerST::QueryConnectionHandler {
 public:
 
-  XserverDesktop(int screenIndex, network::TcpListener* listener,
-                 network::TcpListener* httpListener_,
+  XserverDesktop(int screenIndex,
+                 std::list<network::TcpListener> listeners_,
+                 std::list<network::TcpListener> httpListeners_,
                  const char* name, const rfb::PixelFormat &pf,
                  int width, int height, void* fbptr, int stride);
   virtual ~XserverDesktop();
@@ -112,8 +113,8 @@
   int screenIndex;
   rfb::VNCServerST* server;
   rfb::HTTPServer* httpServer;
-  network::TcpListener* listener;
-  network::TcpListener* httpListener;
+  std::list<network::TcpListener> listeners;
+  std::list<network::TcpListener> httpListeners;
   bool deferredUpdateTimerSet;
   bool directFbptr;
   struct timeval dixTimeout;
diff --git a/unix/xserver/hw/vnc/vncExtInit.cc b/unix/xserver/hw/vnc/vncExtInit.cc
index 2277783..e307e31 100644
--- a/unix/xserver/hw/vnc/vncExtInit.cc
+++ b/unix/xserver/hw/vnc/vncExtInit.cc
@@ -134,33 +134,44 @@
     for (int scr = 0; scr < vncGetScreenCount(); scr++) {
 
       if (!desktop[scr]) {
-        network::TcpListener* listener = 0;
-        network::TcpListener* httpListener = 0;
+        std::list<network::TcpListener> listeners;
+        std::list<network::TcpListener> httpListeners;
         if (scr == 0 && vncInetdSock != -1) {
           if (network::TcpSocket::isSocket(vncInetdSock) &&
               !network::TcpSocket::isConnected(vncInetdSock))
           {
-            listener = new network::TcpListener(NULL, 0, 0, vncInetdSock, true);
+            listeners.push_back (network::TcpListener(vncInetdSock));
             vlog.info("inetd wait");
           }
         } else {
+          const char *addr = interface;
           int port = rfbport;
           if (port == 0) port = 5900 + atoi(vncGetDisplay());
           port += 1000 * scr;
-          if (strcasecmp(interface, "all") == 0)
-            listener = new network::TcpListener(NULL, port, localhostOnly);
+          if (strcasecmp(addr, "all") == 0)
+            addr = 0;
+          if (localhostOnly)
+            network::createLocalTcpListeners(&listeners, port);
           else
-            listener = new network::TcpListener(interface, port, localhostOnly);
+            network::createTcpListeners(&listeners, addr, port);
+
           vlog.info("Listening for VNC connections on %s interface(s), port %d",
-                    (const char*)interface, port);
+                    localhostOnly ? "local" : (const char*)interface,
+                    port);
+
           CharArray httpDirStr(httpDir.getData());
           if (httpDirStr.buf[0]) {
             port = httpPort;
             if (port == 0) port = 5800 + atoi(vncGetDisplay());
             port += 1000 * scr;
-            httpListener = new network::TcpListener(interface, port, localhostOnly);
+            if (localhostOnly)
+              network::createLocalTcpListeners(&httpListeners, port);
+            else
+              network::createTcpListeners(&httpListeners, addr, port);
+
             vlog.info("Listening for HTTP connections on %s interface(s), port %d",
-                      (const char*)interface, port);
+                      localhostOnly ? "local" : (const char*)interface,
+                      port);
           }
         }
 
@@ -168,8 +179,8 @@
         PixelFormat pf = vncGetPixelFormat(scr);
 
         desktop[scr] = new XserverDesktop(scr,
-                                          listener,
-                                          httpListener,
+                                          listeners,
+                                          httpListeners,
                                           desktopNameStr.buf,
                                           pf,
                                           vncGetScreenWidth(scr),
@@ -178,7 +189,7 @@
                                           vncFbstride[scr]);
         vlog.info("created VNC server for screen %d", scr);
 
-        if (scr == 0 && vncInetdSock != -1 && !listener) {
+        if (scr == 0 && vncInetdSock != -1 && listeners.empty()) {
           network::Socket* sock = new network::TcpSocket(vncInetdSock);
           desktop[scr]->addClient(sock, false);
           vlog.info("added inetd sock");