Add parameters to force IPv4/IPv6 selection
diff --git a/common/network/TcpSocket.cxx b/common/network/TcpSocket.cxx
index f2d76bf..2545034 100644
--- a/common/network/TcpSocket.cxx
+++ b/common/network/TcpSocket.cxx
@@ -45,6 +45,7 @@
 #include <network/TcpSocket.h>
 #include <rfb/util.h>
 #include <rfb/LogWriter.h>
+#include <rfb/Configuration.h>
 
 #ifndef INADDR_NONE
 #define INADDR_NONE ((unsigned long)-1)
@@ -73,6 +74,11 @@
 
 static rfb::LogWriter vlog("TcpSocket");
 
+static rfb::BoolParameter UseIPv4("UseIPv4", "Use IPv4 for incoming and outgoing connections.", true);
+#ifdef HAVE_GETADDRINFO
+static rfb::BoolParameter UseIPv6("UseIPv6", "Use IPv6 for incoming and outgoing connections.", true);
+#endif
+
 /* Tunnelling support. */
 int network::findFreeTcpPort (void)
 {
@@ -151,8 +157,19 @@
 
   for (current = ai; current != NULL; current = current->ai_next) {
     family = current->ai_family;
-    if (family != AF_INET && family != AF_INET6)
+
+    switch (family) {
+    case AF_INET:
+      if (!UseIPv4)
+        continue;
+      break;
+    case AF_INET6:
+      if (!UseIPv6)
+        continue;
+      break;
+    default:
       continue;
+    }
 
     salen = current->ai_addrlen;
     memcpy(&sa, current->ai_addr, salen);
@@ -163,6 +180,9 @@
       sa.u.sin6.sin6_port = htons(port);
 
 #else /* HAVE_GETADDRINFO */
+    if (!UseIPv4)
+      throw Exception("Only IPv4 available but it is disabled");
+
     family = AF_INET;
     salen = sizeof(struct sockaddr_in);
 
@@ -408,6 +428,9 @@
   socklen_t sa_len;
   int fd;
 
+  if (!UseIPv6)
+    return -1;
+
   if ((fd = socket(AF_INET6, SOCK_STREAM, 0)) < 0)
     return -1;
 
@@ -458,6 +481,9 @@
   socklen_t sa_len;
   int fd;
 
+  if (!UseIPv4)
+    return -1;
+
   if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
     return -1;