## Patch from Fedora - Revision 1.2 of
## http://cvs.fedoraproject.org/viewcvs/rpms/vnc/devel/vnc-viewerIPv6.patch

diff -up vnc-4_1_2-unixsrc/common/network/Makefile.am.ipv6 vnc-4_1_2-unixsrc/common/network/Makefile.am
--- vnc-4_1_2-unixsrc/common/network/Makefile.am.ipv6	2008-05-29 17:53:53.000000000 +0200
+++ vnc-4_1_2-unixsrc/common/network/Makefile.am	2008-05-29 17:53:53.000000000 +0200
@@ -1,5 +1,7 @@
 noinst_LTLIBRARIES = libnetwork.la
 
+libnetwork_la_CPPFLAGS = -DHAVE_IPV6
+
 libnetwork_la_SOURCES = \
 	Socket.h \
 	TcpSocket.cxx \
diff -up vnc-4_1_2-unixsrc/common/network/TcpSocket.cxx.ipv6 vnc-4_1_2-unixsrc/common/network/TcpSocket.cxx
--- vnc-4_1_2-unixsrc/common/network/TcpSocket.cxx.ipv6	2008-05-29 17:53:53.000000000 +0200
+++ vnc-4_1_2-unixsrc/common/network/TcpSocket.cxx	2008-05-29 18:18:28.000000000 +0200
@@ -109,50 +109,100 @@ TcpSocket::TcpSocket(int sock, bool clos
 TcpSocket::TcpSocket(const char *host, int port)
   : closeFd(true)
 {
-  int sock;
+  int sock, err, family, ret;
+  size_t addrlen;
+  struct sockaddr_storage addr;
+#ifdef HAVE_IPV6
+  struct addrinfo *hostai, *current, hints;
+  char errstr[256];
+#endif
 
   // - Create a socket
   initSockets();
-  if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
-    throw SocketException("unable to create socket", errorNumber);
 
-#ifndef WIN32
-  // - By default, close the socket on exec()
-  fcntl(sock, F_SETFD, FD_CLOEXEC);
-#endif
+#ifdef HAVE_IPV6
+  memset(&hints, 0, sizeof(struct addrinfo));
+  hints.ai_family = AF_UNSPEC;
+  hints.ai_socktype = SOCK_STREAM;
+  hints.ai_canonname = NULL;
+  hints.ai_addr = NULL;
+  hints.ai_next = NULL;
+
+  if (getaddrinfo(host, NULL, &hints, &hostai) != 0) {
+    err = errorNumber;
+    if (snprintf(errstr, 256, "unable resolve host by name (%s)",
+	gai_strerror(err)) < 0)
+      throw Exception("unable resolve host by name");
+    throw Exception(errstr);
+  }
+
+  for (current = hostai; current != NULL; current = hostai->ai_next) {
+    family = current->ai_family;
+    if (family != AF_INET && family != AF_INET6)
+      continue;
+
+    addrlen = current->ai_addrlen;
+    memcpy(&addr, current->ai_addr, addrlen);
+
+    if (family == AF_INET)
+      ((struct sockaddr_in *)&addr)->sin_port = htons(port);
+    else
+      ((struct sockaddr_in6 *)&addr)->sin6_port = htons(port);
 
-  // - Connect it to something
+#else
+    family = AF_INET;
+    addrlen = sizeof(struct sockaddr_in);
 
-  // Try processing the host as an IP address
-  struct sockaddr_in addr;
-  memset(&addr, 0, sizeof(addr));
-  addr.sin_family = AF_INET;
-  addr.sin_addr.s_addr = inet_addr(host);
-  addr.sin_port = htons(port);
-  if ((int)addr.sin_addr.s_addr == -1) {
-    // Host was not an IP address - try resolving as DNS name
-    struct hostent *hostinfo;
-    hostinfo = gethostbyname(host);
-    if (hostinfo && hostinfo->h_addr) {
-      addr.sin_addr.s_addr = ((struct in_addr *)hostinfo->h_addr)->s_addr;
-    } else {
-      int e = errorNumber;
-      closesocket(sock);
-      throw SocketException("unable to resolve host by name", e);
+    // Try processing the host as an IP address
+    memset(&addr, 0, addrlen);
+    addr.sin_family = AF_INET;
+    addr.sin_addr.s_addr = inet_addr(host);
+    addr.sin_port = htons(port);
+    if ((int)addr.sin_addr.s_addr == -1) {
+      // Host was not an IP address - try resolving as DNS name
+      struct hostent *hostinfo;
+      hostinfo = gethostbyname(host);
+      if (hostinfo && hostinfo->h_addr) {
+	addr.sin_addr.s_addr = ((struct in_addr *)hostinfo->h_addr)->s_addr;
+      } else {
+	err = errorNumber;
+	strcpy(errstr, "unable to resolve host by name");
+	goto socket_fail;
+      }
+    }
+#endif
+    sock = socket (family, SOCK_STREAM, 0);
+    if (sock == -1) {
+      err = errno;
+      strcpy(errstr, "unable to create socket");
+      goto socket_fail;
     }
-  }
 
-  // Attempt to connect to the remote host
-  for (;;) {
-    if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
-      int e = errorNumber;
-      if (e == EINTR)
-        continue;
+    // Attempt to connect to the remote host
+    while ((ret = connect(sock, (struct sockaddr *)&addr, addrlen)) == -1) {
+      err = errorNumber;
+      if (err == EINTR)
+	continue;
       closesocket(sock);
-      throw SocketException("unable to connect to host", e);
-    } else break;
+      break;
+    }
+#ifdef HAVE_IPV6
+    if (ret == 0)
+      break;
+    else
+      continue;
+  }
+#endif
+  if (ret == -1) {
+    strcpy(errstr, "unable to connect to host");
+    goto socket_fail;
   }
 
+#ifndef WIN32
+  // - By default, close the socket on exec()
+  fcntl(sock, F_SETFD, FD_CLOEXEC);
+#endif
+
   // Disable Nagle's algorithm, to reduce latency
   enableNagles(sock, false);
 
@@ -160,6 +210,14 @@ TcpSocket::TcpSocket(const char *host, i
   instream = new FdInStream(sock);
   outstream = new FdOutStream(sock);
   ownStreams = true;
+
+  return;
+
+socket_fail:
+#ifdef HAVE_IPV6
+  freeaddrinfo(hostai);
+#endif
+  throw SocketException(errstr, err);
 }
 
 TcpSocket::~TcpSocket() {
