open-src/xserver/xvnc/vnc-viewerIPv6.patch
changeset 606 068c11b419c9
parent 480 4d0b472bb210
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/open-src/xserver/xvnc/vnc-viewerIPv6.patch	Thu Jan 15 12:55:00 2009 -0800
@@ -0,0 +1,166 @@
+## 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() {