summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVic Lee <llyzs@163.com>2010-06-29 20:51:08 +0800
committerJohannes Schindelin <johannes.schindelin@gmx.de>2010-07-08 10:06:17 +0200
commit68e7696a27b31034876f594f242a229ff2b74fa4 (patch)
treeaf218ea7055af0f06098cb3a1a89bc32f231cc33
parentf76c81941a001bde59a9c4df5445569d2134ab5b (diff)
downloadlibtdevnc-68e7696a.tar.gz
libtdevnc-68e7696a.zip
libvncclient: add ipv6 support
[jes: pulled the "host" declarations into the conditionally compiled blocks where that variable is used. Also fixed non-IPv6 connections.] Signed-off-by: Vic Lee <llyzs@163.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
-rw-r--r--configure.ac9
-rw-r--r--libvncclient/rfbproto.c38
-rw-r--r--libvncclient/sockets.c62
-rw-r--r--rfb/rfbclient.h1
4 files changed, 97 insertions, 13 deletions
diff --git a/configure.ac b/configure.ac
index 6516523..b7cfcc1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -697,6 +697,15 @@ if test "x$with_gnutls" != "xno"; then
fi
fi
+# IPv6
+AH_TEMPLATE(IPv6, [Enable IPv6 support])
+AC_ARG_WITH(ipv6,
+[ --without-ipv6 disable IPv6 support],,)
+if test "x$with_ipv6" != "xno"; then
+ AC_CHECK_FUNC(getaddrinfo, AC_DEFINE(IPv6,1),
+ AC_CHECK_LIB(socket, getaddrinfo, AC_DEFINE(IPv6,1)))
+fi
+
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h sys/time.h sys/timeb.h syslog.h unistd.h])
diff --git a/libvncclient/rfbproto.c b/libvncclient/rfbproto.c
index 33307d2..83ba3a5 100644
--- a/libvncclient/rfbproto.c
+++ b/libvncclient/rfbproto.c
@@ -363,8 +363,6 @@ IsUnixSocket(const char *name)
rfbBool
ConnectToRFBServer(rfbClient* client,const char *hostname, int port)
{
- unsigned int host;
-
if (client->serverPort==-1) {
/* serverHost is a file recorded by vncrec. */
const char* magic="vncLog0.0";
@@ -399,12 +397,20 @@ ConnectToRFBServer(rfbClient* client,const char *hostname, int port)
else
#endif
{
- /* serverHost is a hostname */
- if (!StringToIPAddr(hostname, &host)) {
- rfbClientLog("Couldn't convert '%s' to host address\n", hostname);
- return FALSE;
+#ifdef LIBVNCSERVER_IPv6
+ client->sock = ConnectClientToTcpAddr6(hostname, port);
+ if (client->sock == -1)
+#endif
+ {
+ unsigned int host;
+
+ /* serverHost is a hostname */
+ if (!StringToIPAddr(hostname, &host)) {
+ rfbClientLog("Couldn't convert '%s' to host address\n", hostname);
+ return FALSE;
+ }
+ client->sock = ConnectClientToTcpAddr(host, port);
}
- client->sock = ConnectClientToTcpAddr(host, port);
}
if (client->sock < 0) {
@@ -421,17 +427,23 @@ ConnectToRFBServer(rfbClient* client,const char *hostname, int port)
rfbBool ConnectToRFBRepeater(rfbClient* client,const char *repeaterHost, int repeaterPort, const char *destHost, int destPort)
{
- unsigned int host;
rfbProtocolVersionMsg pv;
int major,minor;
char tmphost[250];
- if (!StringToIPAddr(repeaterHost, &host)) {
- rfbClientLog("Couldn't convert '%s' to host address\n", repeaterHost);
- return FALSE;
- }
+#ifdef LIBVNCSERVER_IPv6
+ client->sock = ConnectClientToTcpAddr6(repeaterHost, repeaterPort);
+ if (client->sock == -1)
+#endif
+ {
+ unsigned int host;
+ if (!StringToIPAddr(repeaterHost, &host)) {
+ rfbClientLog("Couldn't convert '%s' to host address\n", repeaterHost);
+ return FALSE;
+ }
- client->sock = ConnectClientToTcpAddr(host, repeaterPort);
+ client->sock = ConnectClientToTcpAddr(host, repeaterPort);
+ }
if (client->sock < 0) {
rfbClientLog("Unable to connect to VNC repeater\n");
diff --git a/libvncclient/sockets.c b/libvncclient/sockets.c
index 598dd39..ff4fe48 100644
--- a/libvncclient/sockets.c
+++ b/libvncclient/sockets.c
@@ -337,6 +337,68 @@ ConnectClientToTcpAddr(unsigned int host, int port)
}
int
+ConnectClientToTcpAddr6(const char *hostname, int port)
+{
+#ifdef LIBVNCSERVER_IPv6
+ int sock;
+ int n;
+ struct addrinfo hints, *res, *ressave;
+ char port_s[10];
+ int one = 1;
+
+ if (!initSockets())
+ return -1;
+
+ snprintf(port_s, 10, "%d", port);
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ if ((n = getaddrinfo(hostname, port_s, &hints, &res)))
+ {
+ rfbClientErr("ConnectClientToTcpAddr6: getaddrinfo (%s)\n", gai_strerror(n));
+ return -1;
+ }
+
+ ressave = res;
+ sock = -1;
+ while (res)
+ {
+ sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (sock >= 0)
+ {
+ if (connect(sock, res->ai_addr, res->ai_addrlen) == 0)
+ break;
+ close(sock);
+ sock = -1;
+ }
+ res = res->ai_next;
+ }
+ freeaddrinfo(ressave);
+
+ if (sock == -1)
+ {
+ rfbClientErr("ConnectClientToTcpAddr6: connect\n");
+ return -1;
+ }
+
+ if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
+ (char *)&one, sizeof(one)) < 0) {
+ rfbClientErr("ConnectToTcpAddr: setsockopt\n");
+ close(sock);
+ return -1;
+ }
+
+ return sock;
+
+#else
+
+ rfbClientErr("ConnectClientToTcpAddr6: IPv6 disabled\n");
+ return -1;
+
+#endif
+}
+
+int
ConnectClientToUnixSock(const char *sockFile)
{
#ifdef WIN32
diff --git a/rfb/rfbclient.h b/rfb/rfbclient.h
index bc4ec14..b38f335 100644
--- a/rfb/rfbclient.h
+++ b/rfb/rfbclient.h
@@ -384,6 +384,7 @@ extern rfbBool WriteToRFBServer(rfbClient* client, char *buf, int n);
extern int FindFreeTcpPort(void);
extern int ListenAtTcpPort(int port);
extern int ConnectClientToTcpAddr(unsigned int host, int port);
+extern int ConnectClientToTcpAddr6(const char *hostname, int port);
extern int ConnectClientToUnixSock(const char *sockFile);
extern int AcceptTcpConnection(int listenSock);
extern rfbBool SetNonBlocking(int sock);