open-src/xserver/xvnc/vnc-ipv6.patch
changeset 606 068c11b419c9
parent 605 e5259db5befc
child 607 261c0d718d67
equal deleted inserted replaced
605:e5259db5befc 606:068c11b419c9
     1 ## Patch from Fedora - Revision 1.2 of
       
     2 ## http://cvs.fedoraproject.org/viewcvs/rpms/vnc/devel/vnc-viewerIPv6.patch
       
     3 
       
     4 diff -up vnc-4_1_2-unixsrc/common/network/Makefile.am.ipv6 vnc-4_1_2-unixsrc/common/network/Makefile.am
       
     5 --- vnc-4_1_2-unixsrc/common/network/Makefile.am.ipv6	2008-05-29 17:53:53.000000000 +0200
       
     6 +++ vnc-4_1_2-unixsrc/common/network/Makefile.am	2008-05-29 17:53:53.000000000 +0200
       
     7 @@ -1,5 +1,7 @@
       
     8  noinst_LTLIBRARIES = libnetwork.la
       
     9  
       
    10 +libnetwork_la_CPPFLAGS = -DHAVE_IPV6
       
    11 +
       
    12  libnetwork_la_SOURCES = \
       
    13  	Socket.h \
       
    14  	TcpSocket.cxx \
       
    15 diff -up vnc-4_1_2-unixsrc/common/network/TcpSocket.cxx.ipv6 vnc-4_1_2-unixsrc/common/network/TcpSocket.cxx
       
    16 --- vnc-4_1_2-unixsrc/common/network/TcpSocket.cxx.ipv6	2008-05-29 17:53:53.000000000 +0200
       
    17 +++ vnc-4_1_2-unixsrc/common/network/TcpSocket.cxx	2008-05-29 18:18:28.000000000 +0200
       
    18 @@ -109,50 +109,100 @@ TcpSocket::TcpSocket(int sock, bool clos
       
    19  TcpSocket::TcpSocket(const char *host, int port)
       
    20    : closeFd(true)
       
    21  {
       
    22 -  int sock;
       
    23 +  int sock, err, family, ret;
       
    24 +  size_t addrlen;
       
    25 +  struct sockaddr_storage addr;
       
    26 +#ifdef HAVE_IPV6
       
    27 +  struct addrinfo *hostai, *current, hints;
       
    28 +  char errstr[256];
       
    29 +#endif
       
    30  
       
    31    // - Create a socket
       
    32    initSockets();
       
    33 -  if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
       
    34 -    throw SocketException("unable to create socket", errorNumber);
       
    35  
       
    36 -#ifndef WIN32
       
    37 -  // - By default, close the socket on exec()
       
    38 -  fcntl(sock, F_SETFD, FD_CLOEXEC);
       
    39 -#endif
       
    40 +#ifdef HAVE_IPV6
       
    41 +  memset(&hints, 0, sizeof(struct addrinfo));
       
    42 +  hints.ai_family = AF_UNSPEC;
       
    43 +  hints.ai_socktype = SOCK_STREAM;
       
    44 +  hints.ai_canonname = NULL;
       
    45 +  hints.ai_addr = NULL;
       
    46 +  hints.ai_next = NULL;
       
    47 +
       
    48 +  if (getaddrinfo(host, NULL, &hints, &hostai) != 0) {
       
    49 +    err = errorNumber;
       
    50 +    if (snprintf(errstr, 256, "unable resolve host by name (%s)",
       
    51 +	gai_strerror(err)) < 0)
       
    52 +      throw Exception("unable resolve host by name");
       
    53 +    throw Exception(errstr);
       
    54 +  }
       
    55 +
       
    56 +  for (current = hostai; current != NULL; current = hostai->ai_next) {
       
    57 +    family = current->ai_family;
       
    58 +    if (family != AF_INET && family != AF_INET6)
       
    59 +      continue;
       
    60 +
       
    61 +    addrlen = current->ai_addrlen;
       
    62 +    memcpy(&addr, current->ai_addr, addrlen);
       
    63 +
       
    64 +    if (family == AF_INET)
       
    65 +      ((struct sockaddr_in *)&addr)->sin_port = htons(port);
       
    66 +    else
       
    67 +      ((struct sockaddr_in6 *)&addr)->sin6_port = htons(port);
       
    68  
       
    69 -  // - Connect it to something
       
    70 +#else
       
    71 +    family = AF_INET;
       
    72 +    addrlen = sizeof(struct sockaddr_in);
       
    73  
       
    74 -  // Try processing the host as an IP address
       
    75 -  struct sockaddr_in addr;
       
    76 -  memset(&addr, 0, sizeof(addr));
       
    77 -  addr.sin_family = AF_INET;
       
    78 -  addr.sin_addr.s_addr = inet_addr(host);
       
    79 -  addr.sin_port = htons(port);
       
    80 -  if ((int)addr.sin_addr.s_addr == -1) {
       
    81 -    // Host was not an IP address - try resolving as DNS name
       
    82 -    struct hostent *hostinfo;
       
    83 -    hostinfo = gethostbyname(host);
       
    84 -    if (hostinfo && hostinfo->h_addr) {
       
    85 -      addr.sin_addr.s_addr = ((struct in_addr *)hostinfo->h_addr)->s_addr;
       
    86 -    } else {
       
    87 -      int e = errorNumber;
       
    88 -      closesocket(sock);
       
    89 -      throw SocketException("unable to resolve host by name", e);
       
    90 +    // Try processing the host as an IP address
       
    91 +    memset(&addr, 0, addrlen);
       
    92 +    addr.sin_family = AF_INET;
       
    93 +    addr.sin_addr.s_addr = inet_addr(host);
       
    94 +    addr.sin_port = htons(port);
       
    95 +    if ((int)addr.sin_addr.s_addr == -1) {
       
    96 +      // Host was not an IP address - try resolving as DNS name
       
    97 +      struct hostent *hostinfo;
       
    98 +      hostinfo = gethostbyname(host);
       
    99 +      if (hostinfo && hostinfo->h_addr) {
       
   100 +	addr.sin_addr.s_addr = ((struct in_addr *)hostinfo->h_addr)->s_addr;
       
   101 +      } else {
       
   102 +	err = errorNumber;
       
   103 +	strcpy(errstr, "unable to resolve host by name");
       
   104 +	goto socket_fail;
       
   105 +      }
       
   106 +    }
       
   107 +#endif
       
   108 +    sock = socket (family, SOCK_STREAM, 0);
       
   109 +    if (sock == -1) {
       
   110 +      err = errno;
       
   111 +      strcpy(errstr, "unable to create socket");
       
   112 +      goto socket_fail;
       
   113      }
       
   114 -  }
       
   115  
       
   116 -  // Attempt to connect to the remote host
       
   117 -  for (;;) {
       
   118 -    if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
       
   119 -      int e = errorNumber;
       
   120 -      if (e == EINTR)
       
   121 -        continue;
       
   122 +    // Attempt to connect to the remote host
       
   123 +    while ((ret = connect(sock, (struct sockaddr *)&addr, addrlen)) == -1) {
       
   124 +      err = errorNumber;
       
   125 +      if (err == EINTR)
       
   126 +	continue;
       
   127        closesocket(sock);
       
   128 -      throw SocketException("unable to connect to host", e);
       
   129 -    } else break;
       
   130 +      break;
       
   131 +    }
       
   132 +#ifdef HAVE_IPV6
       
   133 +    if (ret == 0)
       
   134 +      break;
       
   135 +    else
       
   136 +      continue;
       
   137 +  }
       
   138 +#endif
       
   139 +  if (ret == -1) {
       
   140 +    strcpy(errstr, "unable to connect to host");
       
   141 +    goto socket_fail;
       
   142    }
       
   143  
       
   144 +#ifndef WIN32
       
   145 +  // - By default, close the socket on exec()
       
   146 +  fcntl(sock, F_SETFD, FD_CLOEXEC);
       
   147 +#endif
       
   148 +
       
   149    // Disable Nagle's algorithm, to reduce latency
       
   150    enableNagles(sock, false);
       
   151  
       
   152 @@ -160,6 +210,14 @@ TcpSocket::TcpSocket(const char *host, i
       
   153    instream = new FdInStream(sock);
       
   154    outstream = new FdOutStream(sock);
       
   155    ownStreams = true;
       
   156 +
       
   157 +  return;
       
   158 +
       
   159 +socket_fail:
       
   160 +#ifdef HAVE_IPV6
       
   161 +  freeaddrinfo(hostai);
       
   162 +#endif
       
   163 +  throw SocketException(errstr, err);
       
   164  }
       
   165  
       
   166  TcpSocket::~TcpSocket() {