diff --git a/gck-rpc-module.c b/gck-rpc-module.c
index a8ff3452d1a016eba51b994149e7719b8435a3d0..713489dc6c8062921adb763c49a739d0d81cbb26 100644
--- a/gck-rpc-module.c
+++ b/gck-rpc-module.c
@@ -38,6 +38,7 @@
 #include <arpa/inet.h>
 #include <netinet/in.h>
 #include <netinet/tcp.h>
+# include <netdb.h>
 #endif
 
 #include <stdlib.h>
@@ -311,6 +312,88 @@ static CK_RV call_read(CallState * cs, unsigned char *data, size_t len)
 	return CKR_OK;
 }
 
+static int _connect_to_host_port(char *host, char *port)
+{
+	char hoststr[NI_MAXHOST], portstr[NI_MAXSERV], hostport[NI_MAXHOST + NI_MAXSERV + 1];
+	struct addrinfo *ai, *first, hints;
+	int res, sock, one = 1;
+
+	memset(&hints, 0, sizeof(struct addrinfo));
+	hints.ai_family = AF_UNSPEC;		/* Either IPv4 or IPv6 */
+	hints.ai_socktype = SOCK_STREAM;	/* Only stream oriented sockets */
+
+	if ((res = getaddrinfo(host, port, &hints, &ai)) < 0) {
+		gck_rpc_warn("couldn't resolve host '%.100s' or service '%.100s' : %.100s\n",
+			     host, port, gai_strerror(res));
+		return -1;
+	}
+
+	sock = -1;
+	first = ai;
+
+	/* Loop through the sockets returned and see if we can find one that accepts
+	 * our options and connect()
+	 */
+	while (ai) {
+		if ((res = getnameinfo(ai->ai_addr, ai->ai_addrlen,
+				       hoststr, sizeof(hoststr), portstr, sizeof(portstr),
+				       NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
+			gck_rpc_warn("couldn't call getnameinfo on pkcs11 socket (%.100s %.100s): %.100s",
+				     host, port, gai_strerror(res));
+			sock = -1;
+			continue;
+		}
+
+		snprintf(hostport, sizeof(hostport),
+			 (ai->ai_family == AF_INET6) ? "[%s]:%s" : "%s:%s", hoststr, portstr);
+
+		sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+
+		if (sock >= 0) {
+			if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
+				       (char *)&one, sizeof (one)) == -1) {
+				gck_rpc_warn("couldn't set pkcs11 "
+					     "socket protocol options (%.100s): %.100s",
+					     hostport, strerror (errno));
+				goto next;
+			}
+
+#ifndef __MINGW32__
+			/* close on exec */
+			if (fcntl(sock, F_SETFD, 1) == -1) {
+				gck_rpc_warn("couldn't secure socket (%.100s): %.100s",
+					     hostport, strerror(errno));
+				goto next;
+			}
+#endif
+
+			if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
+				close(sock);
+				warning(("couldn't connect (%.100s): %s",
+					 hostport, strerror(errno)));
+				goto next;
+			}
+
+		next:
+			close(sock);
+			sock = -1;
+		}
+		ai = ai->ai_next;
+	}
+
+	if (sock < 0) {
+		gck_rpc_warn("couldn't create pkcs11 socket (%.100s): %.100s\n",
+			     pkcs11_socket_path, strerror(errno));
+		sock = -1;
+		goto out;
+	}
+
+ out:
+	freeaddrinfo(first);
+
+	return sock;
+}
+
 static CK_RV call_connect(CallState * cs)
 {
 	struct sockaddr_un addr;
@@ -326,45 +409,20 @@ static CK_RV call_connect(CallState * cs)
 	memset(&addr, 0, sizeof(addr));
 
 	if (!strncmp("tcp://", pkcs11_socket_path, 6)) {
-		int one = 1, port;
-		char *p = NULL;
-		const char *ip;
-
-		ip = strdup(pkcs11_socket_path + 6);
-		if (ip)
-			p = strchr(ip, ':');
+		char *host, *port;
 
-		if (!p || !ip) {
-			gck_rpc_warn("invalid syntax for pkcs11 socket : %s",
+		if (! gck_rpc_parse_host_port(pkcs11_socket_path + 6, &host, &port)) {
+			gck_rpc_warn("failed parsing pkcs11 socket : %s",
 				     pkcs11_socket_path);
 			return CKR_DEVICE_ERROR;
 		}
-		*p = '\0';
-		port = strtol(p + 1, NULL, 0);
-
-		sock = socket(AF_INET, SOCK_STREAM, 0);
-
-		if (sock < 0) {
-			gck_rpc_warn("couldn't create pkcs11 socket: %s",
-				     strerror(errno));
-			return CKR_DEVICE_ERROR;
-		}
 
-		if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
-			       (char *)&one, sizeof(one)) == -1) {
-			gck_rpc_warn
-			    ("couldn't create set pkcs11 socket options : %s",
-			     strerror(errno));
+		if ((sock = _connect_to_host_port(host, port)) == -1) {
+			free(host);
 			return CKR_DEVICE_ERROR;
 		}
 
-		addr.sun_family = AF_INET;
-		if (inet_aton(ip, &((struct sockaddr_in *)&addr)->sin_addr) ==
-		    0) {
-			gck_rpc_warn("bad inet address : %s", ip);
-			return CKR_DEVICE_ERROR;
-		}
-		((struct sockaddr_in *)&addr)->sin_port = htons(port);
+		free(host);
 	} else {
 		addr.sun_family = AF_UNIX;
 		strncpy(addr.sun_path, pkcs11_socket_path,
@@ -375,22 +433,23 @@ static CK_RV call_connect(CallState * cs)
 			warning(("couldn't open socket: %s", strerror(errno)));
 			return CKR_DEVICE_ERROR;
 		}
-	}
+
 
 #ifndef __MINGW32__
-        /* close on exec */
-	if (fcntl(sock, F_SETFD, 1) == -1) {
-		close(sock);
-		warning(("couldn't secure socket: %s", strerror(errno)));
-		return CKR_DEVICE_ERROR;
-	}
+		/* close on exec */
+		if (fcntl(sock, F_SETFD, 1) == -1) {
+			close(sock);
+			warning(("couldn't secure socket: %s", strerror(errno)));
+			return CKR_DEVICE_ERROR;
+		}
 #endif
 
-	if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
-		close(sock);
-		warning(("couldn't connect to: %s: %s", pkcs11_socket_path,
-			 strerror(errno)));
-		return CKR_DEVICE_ERROR;
+		if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+			close(sock);
+			warning(("couldn't connect to: %s: %s", pkcs11_socket_path,
+				 strerror(errno)));
+			return CKR_DEVICE_ERROR;
+		}
 	}
 
 	cs->socket = sock;