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() { |
|