Ian Kent 3d12a7
autofs-5.0.6 - fix ipv6 rpc calls
Ian Kent 3d12a7
Ian Kent 3d12a7
From: Ian Kent <ikent@redhat.com>
Ian Kent 3d12a7
Ian Kent 3d12a7
There is a mistake in the way autofs uses libtirpc. Two IPv6 compatibiliy
Ian Kent 3d12a7
functions were thought to be included when in fact they were not and would
Ian Kent 3d12a7
not actually work with IPv6 anyway.
Ian Kent 3d12a7
Ian Kent 3d12a7
To fix that the libtirpc interface code needed to be re-written. Portmap
Ian Kent 3d12a7
(using libtirpc calls) is still used to get service port numbers, rather
Ian Kent 3d12a7
than rpcbind.
Ian Kent 3d12a7
---
Ian Kent 3d12a7
Ian Kent 3d12a7
 CHANGELOG            |    1 
Ian Kent 3d12a7
 lib/rpc_subs.c       |  370 ++++++++++++++++++++-------------------------------
Ian Kent 3d12a7
 modules/replicated.c |    8 -
Ian Kent 3d12a7
 3 files changed, 155 insertions(+), 224 deletions(-)
Ian Kent 3d12a7
Ian Kent 3d12a7
Ian Kent 3d12a7
--- autofs-5.0.6.orig/CHANGELOG
Ian Kent 3d12a7
+++ autofs-5.0.6/CHANGELOG
Ian Kent 3d12a7
@@ -14,6 +14,7 @@
Ian Kent 3d12a7
 - fix fix map source check in file lookup.
Ian Kent 3d12a7
 - add disable move mount configure option.
Ian Kent 3d12a7
 - fix ipv6 name lookup check.
Ian Kent 3d12a7
+- fix ipv6 rpc calls.
Ian Kent 3d12a7
 
Ian Kent 3d12a7
 28/06/2011 autofs-5.0.6
Ian Kent 3d12a7
 -----------------------
Ian Kent 3d12a7
--- autofs-5.0.6.orig/lib/rpc_subs.c
Ian Kent 3d12a7
+++ autofs-5.0.6/lib/rpc_subs.c
Ian Kent 3d12a7
@@ -62,89 +62,6 @@ static const rpcvers_t mount_vers[] = {
Ian Kent 3d12a7
 static int connect_nb(int, struct sockaddr *, socklen_t, struct timeval *);
Ian Kent 3d12a7
 inline void dump_core(void);
Ian Kent 3d12a7
 
Ian Kent 3d12a7
-static CLIENT *rpc_clntudp_create(struct sockaddr *addr, struct conn_info *info, int *fd)
Ian Kent 3d12a7
-{
Ian Kent 3d12a7
-	struct sockaddr_in *in4_raddr;
Ian Kent 3d12a7
-	struct sockaddr_in6 *in6_raddr;
Ian Kent 3d12a7
-	CLIENT *client = NULL;
Ian Kent 3d12a7
-
Ian Kent 3d12a7
-	switch (addr->sa_family) {
Ian Kent 3d12a7
-	case AF_INET:
Ian Kent 3d12a7
-		in4_raddr = (struct sockaddr_in *) addr;
Ian Kent 3d12a7
-		in4_raddr->sin_port = htons(info->port);
Ian Kent 3d12a7
-		client = clntudp_bufcreate(in4_raddr,
Ian Kent 3d12a7
-					   info->program, info->version,
Ian Kent 3d12a7
-					   info->timeout, fd,
Ian Kent 3d12a7
-					   info->send_sz, info->recv_sz);
Ian Kent 3d12a7
-		break;
Ian Kent 3d12a7
-
Ian Kent 3d12a7
-	case AF_INET6:
Ian Kent 3d12a7
-#ifndef INET6
Ian Kent 3d12a7
-		/* Quiet compile warning */
Ian Kent 3d12a7
-		in6_raddr = NULL;
Ian Kent 3d12a7
-#else
Ian Kent 3d12a7
-		in6_raddr = (struct sockaddr_in6 *) addr;
Ian Kent 3d12a7
-		in6_raddr->sin6_port = htons(info->port);
Ian Kent 3d12a7
-		client = clntudp6_bufcreate(in6_raddr,
Ian Kent 3d12a7
-					    info->program, info->version,
Ian Kent 3d12a7
-					    info->timeout, fd,
Ian Kent 3d12a7
-					    info->send_sz, info->recv_sz);
Ian Kent 3d12a7
-#endif
Ian Kent 3d12a7
-		break;
Ian Kent 3d12a7
-
Ian Kent 3d12a7
-	default:
Ian Kent 3d12a7
-		break;
Ian Kent 3d12a7
-	}
Ian Kent 3d12a7
-
Ian Kent 3d12a7
-	return client;
Ian Kent 3d12a7
-}
Ian Kent 3d12a7
-
Ian Kent 3d12a7
-static CLIENT *rpc_clnttcp_create(struct sockaddr *addr, struct conn_info *info, int *fd)
Ian Kent 3d12a7
-{
Ian Kent 3d12a7
-	struct sockaddr_in *in4_raddr;
Ian Kent 3d12a7
-	struct sockaddr_in6 *in6_raddr;
Ian Kent 3d12a7
-	CLIENT *client = NULL;
Ian Kent 3d12a7
-	socklen_t slen;
Ian Kent 3d12a7
-
Ian Kent 3d12a7
-	switch (addr->sa_family) {
Ian Kent 3d12a7
-	case AF_INET:
Ian Kent 3d12a7
-		in4_raddr = (struct sockaddr_in *) addr;
Ian Kent 3d12a7
-		in4_raddr->sin_port = htons(info->port);
Ian Kent 3d12a7
-		slen = sizeof(struct sockaddr_in);
Ian Kent 3d12a7
-
Ian Kent 3d12a7
-		if (connect_nb(*fd, addr, slen, &info->timeout) < 0)
Ian Kent 3d12a7
-			break;
Ian Kent 3d12a7
-
Ian Kent 3d12a7
-		client = clnttcp_create(in4_raddr,
Ian Kent 3d12a7
-					info->program, info->version, fd,
Ian Kent 3d12a7
-					info->send_sz, info->recv_sz);
Ian Kent 3d12a7
-		break;
Ian Kent 3d12a7
-
Ian Kent 3d12a7
-	case AF_INET6:
Ian Kent 3d12a7
-#ifndef INET6
Ian Kent 3d12a7
-		/* Quiet compile warning */
Ian Kent 3d12a7
-		in6_raddr = NULL;
Ian Kent 3d12a7
-#else
Ian Kent 3d12a7
-		in6_raddr = (struct sockaddr_in6 *) addr;
Ian Kent 3d12a7
-		in6_raddr->sin6_port = htons(info->port);
Ian Kent 3d12a7
-		slen = sizeof(struct sockaddr_in6);
Ian Kent 3d12a7
-
Ian Kent 3d12a7
-		if (connect_nb(*fd, addr, slen, &info->timeout) < 0)
Ian Kent 3d12a7
-			break;
Ian Kent 3d12a7
-
Ian Kent 3d12a7
-		client = clnttcp6_create(in6_raddr,
Ian Kent 3d12a7
-					 info->program, info->version, fd,
Ian Kent 3d12a7
-					 info->send_sz, info->recv_sz);
Ian Kent 3d12a7
-#endif
Ian Kent 3d12a7
-		break;
Ian Kent 3d12a7
-
Ian Kent 3d12a7
-	default:
Ian Kent 3d12a7
-		break;
Ian Kent 3d12a7
-	}
Ian Kent 3d12a7
-
Ian Kent 3d12a7
-	return client;
Ian Kent 3d12a7
-}
Ian Kent 3d12a7
-
Ian Kent 3d12a7
 /*
Ian Kent 3d12a7
  *  Perform a non-blocking connect on the socket fd.
Ian Kent 3d12a7
  *
Ian Kent 3d12a7
@@ -232,12 +149,12 @@ done:
Ian Kent 3d12a7
 	return ret;
Ian Kent 3d12a7
 }
Ian Kent 3d12a7
 
Ian Kent 3d12a7
+#ifndef WITH_LIBTIRPC
Ian Kent 3d12a7
 static CLIENT *rpc_do_create_client(struct sockaddr *addr, struct conn_info *info, int *fd)
Ian Kent 3d12a7
 {
Ian Kent 3d12a7
 	CLIENT *client = NULL;
Ian Kent 3d12a7
-	struct sockaddr *laddr;
Ian Kent 3d12a7
 	struct sockaddr_in in4_laddr;
Ian Kent 3d12a7
-	struct sockaddr_in6 in6_laddr;
Ian Kent 3d12a7
+	struct sockaddr_in in4_raddr;
Ian Kent 3d12a7
 	int type, proto;
Ian Kent 3d12a7
 	socklen_t slen;
Ian Kent 3d12a7
 
Ian Kent 3d12a7
@@ -252,48 +169,41 @@ static CLIENT *rpc_do_create_client(stru
Ian Kent 3d12a7
 	 * layer, it would bind to a reserved port, which has been shown
Ian Kent 3d12a7
 	 * to exhaust the reserved port range in some situations.
Ian Kent 3d12a7
 	 */
Ian Kent 3d12a7
-	switch (addr->sa_family) {
Ian Kent 3d12a7
-	case AF_INET:
Ian Kent 3d12a7
-		in4_laddr.sin_family = AF_INET;
Ian Kent 3d12a7
-		in4_laddr.sin_port = htons(0);
Ian Kent 3d12a7
-		in4_laddr.sin_addr.s_addr = htonl(INADDR_ANY);
Ian Kent 3d12a7
-		slen = sizeof(struct sockaddr_in);
Ian Kent 3d12a7
-		laddr = (struct sockaddr *) &in4_laddr;
Ian Kent 3d12a7
-		break;
Ian Kent 3d12a7
-
Ian Kent 3d12a7
-	case AF_INET6:
Ian Kent 3d12a7
-#ifndef INET6
Ian Kent 3d12a7
-		/* Quiet compiler */
Ian Kent 3d12a7
-		in6_laddr.sin6_family = AF_INET6;
Ian Kent 3d12a7
-		return NULL;
Ian Kent 3d12a7
-#else
Ian Kent 3d12a7
-		in6_laddr.sin6_family = AF_INET6;
Ian Kent 3d12a7
-		in6_laddr.sin6_port = htons(0);
Ian Kent 3d12a7
-		in6_laddr.sin6_addr = in6addr_any;
Ian Kent 3d12a7
-		slen = sizeof(struct sockaddr_in6);
Ian Kent 3d12a7
-		laddr = (struct sockaddr *) &in6_laddr;
Ian Kent 3d12a7
-		break;
Ian Kent 3d12a7
-#endif
Ian Kent 3d12a7
-	default:
Ian Kent 3d12a7
-		return NULL;
Ian Kent 3d12a7
-	}
Ian Kent 3d12a7
+	in4_laddr.sin_family = AF_INET;
Ian Kent 3d12a7
+	in4_laddr.sin_port = htons(0);
Ian Kent 3d12a7
+	in4_laddr.sin_addr.s_addr = htonl(INADDR_ANY);
Ian Kent 3d12a7
+	slen = sizeof(struct sockaddr_in);
Ian Kent 3d12a7
 
Ian Kent 3d12a7
 	if (!info->client) {
Ian Kent 3d12a7
+		struct sockaddr *laddr;
Ian Kent 3d12a7
+
Ian Kent 3d12a7
 		*fd = open_sock(addr->sa_family, type, proto);
Ian Kent 3d12a7
 		if (*fd < 0)
Ian Kent 3d12a7
 			return NULL;
Ian Kent 3d12a7
 
Ian Kent 3d12a7
+		laddr = (struct sockaddr *) &in4_laddr;
Ian Kent 3d12a7
 		if (bind(*fd, laddr, slen) < 0)
Ian Kent 3d12a7
 			return NULL;
Ian Kent 3d12a7
 	}
Ian Kent 3d12a7
 
Ian Kent 3d12a7
+	in4_raddr = (struct sockaddr_in *) addr;
Ian Kent 3d12a7
+	in4_raddr->sin_port = htons(info->port);
Ian Kent 3d12a7
+
Ian Kent 3d12a7
 	switch (info->proto->p_proto) {
Ian Kent 3d12a7
 	case IPPROTO_UDP:
Ian Kent 3d12a7
-		client = rpc_clntudp_create(addr, info, fd);
Ian Kent 3d12a7
+		client = clntudp_bufcreate(in4_raddr,
Ian Kent 3d12a7
+					   info->program, info->version,
Ian Kent 3d12a7
+					   info->timeout, fd,
Ian Kent 3d12a7
+					   info->send_sz, info->recv_sz);
Ian Kent 3d12a7
 		break;
Ian Kent 3d12a7
 
Ian Kent 3d12a7
 	case IPPROTO_TCP:
Ian Kent 3d12a7
-		client = rpc_clnttcp_create(addr, info, fd);
Ian Kent 3d12a7
+		if (connect_nb(*fd, addr, slen, &info->timeout) < 0)
Ian Kent 3d12a7
+			break;
Ian Kent 3d12a7
+
Ian Kent 3d12a7
+		client = clnttcp_create(in4_raddr,
Ian Kent 3d12a7
+					info->program, info->version, fd,
Ian Kent 3d12a7
+					info->send_sz, info->recv_sz);
Ian Kent 3d12a7
 		break;
Ian Kent 3d12a7
 
Ian Kent 3d12a7
 	default:
Ian Kent 3d12a7
@@ -302,20 +212,126 @@ static CLIENT *rpc_do_create_client(stru
Ian Kent 3d12a7
 
Ian Kent 3d12a7
 	return client;
Ian Kent 3d12a7
 }
Ian Kent 3d12a7
+#else
Ian Kent 3d12a7
+struct netconfig *find_netconf(void *handle, char *family, char *proto)
Ian Kent 3d12a7
+{
Ian Kent 3d12a7
+	struct netconfig *nconf;
Ian Kent 3d12a7
+
Ian Kent 3d12a7
+	while ((nconf = getnetconfig(handle))) {
Ian Kent 3d12a7
+		if ((strcmp(nconf->nc_protofmly, family) == 0) &&
Ian Kent 3d12a7
+		    (strcmp(nconf->nc_proto, proto) == 0))
Ian Kent 3d12a7
+			break;
Ian Kent 3d12a7
+	}
Ian Kent 3d12a7
+
Ian Kent 3d12a7
+	return nconf;
Ian Kent 3d12a7
+}
Ian Kent 3d12a7
+
Ian Kent 3d12a7
+static CLIENT *rpc_do_create_client(struct sockaddr *addr, struct conn_info *info, int *fd)
Ian Kent 3d12a7
+{
Ian Kent 3d12a7
+	CLIENT *client = NULL;
Ian Kent 3d12a7
+	struct sockaddr_in in4_laddr;
Ian Kent 3d12a7
+	struct sockaddr_in6 in6_laddr;
Ian Kent 3d12a7
+	struct sockaddr *laddr = NULL;
Ian Kent 3d12a7
+	struct netconfig *nconf;
Ian Kent 3d12a7
+	struct netbuf nb_addr;
Ian Kent 3d12a7
+	int type, proto;
Ian Kent 3d12a7
+	char *nc_family, *nc_proto;
Ian Kent 3d12a7
+	void *handle;
Ian Kent 3d12a7
+	size_t slen;
Ian Kent 3d12a7
+
Ian Kent 3d12a7
+	proto = info->proto->p_proto;
Ian Kent 3d12a7
+	if (proto == IPPROTO_UDP) {
Ian Kent 3d12a7
+		type = SOCK_DGRAM;
Ian Kent 3d12a7
+		nc_proto = NC_UDP;
Ian Kent 3d12a7
+	} else {
Ian Kent 3d12a7
+		type = SOCK_STREAM;
Ian Kent 3d12a7
+		nc_proto = NC_TCP;
Ian Kent 3d12a7
+	}
Ian Kent 3d12a7
+
Ian Kent 3d12a7
+	/*
Ian Kent 3d12a7
+	 * bind to any unused port.  If we left this up to the rpc
Ian Kent 3d12a7
+	 * layer, it would bind to a reserved port, which has been shown
Ian Kent 3d12a7
+	 * to exhaust the reserved port range in some situations.
Ian Kent 3d12a7
+	 */
Ian Kent 3d12a7
+	if (addr->sa_family == AF_INET) {
Ian Kent 3d12a7
+		struct sockaddr_in *in4_raddr = (struct sockaddr_in *) addr;
Ian Kent 3d12a7
+		in4_laddr.sin_family = AF_INET;
Ian Kent 3d12a7
+		in4_laddr.sin_port = htons(0);
Ian Kent 3d12a7
+		in4_laddr.sin_addr.s_addr = htonl(INADDR_ANY);
Ian Kent 3d12a7
+		laddr = (struct sockaddr *) &in4_laddr;
Ian Kent 3d12a7
+		in4_raddr->sin_port = htons(info->port);
Ian Kent 3d12a7
+		slen = sizeof(struct sockaddr_in);
Ian Kent 3d12a7
+		nc_family = NC_INET;
Ian Kent 3d12a7
+	} else if (addr->sa_family == AF_INET6) {
Ian Kent 3d12a7
+		struct sockaddr_in6 *in6_raddr = (struct sockaddr_in6 *) addr;
Ian Kent 3d12a7
+		in6_laddr.sin6_family = AF_INET6;
Ian Kent 3d12a7
+		in6_laddr.sin6_port = htons(0);
Ian Kent 3d12a7
+		in6_laddr.sin6_addr = in6addr_any;
Ian Kent 3d12a7
+		laddr = (struct sockaddr *) &in6_laddr;
Ian Kent 3d12a7
+		in6_raddr->sin6_port = htons(info->port);
Ian Kent 3d12a7
+		slen = sizeof(struct sockaddr_in6);
Ian Kent 3d12a7
+		nc_family = NC_INET6;
Ian Kent 3d12a7
+	} else
Ian Kent 3d12a7
+		return NULL;
Ian Kent 3d12a7
+
Ian Kent 3d12a7
+	handle = setnetconfig();
Ian Kent 3d12a7
+	if (!handle)
Ian Kent 3d12a7
+		return NULL;
Ian Kent 3d12a7
+
Ian Kent 3d12a7
+	nconf = find_netconf(handle, nc_family, nc_proto);
Ian Kent 3d12a7
+	if (!nconf) {
Ian Kent 3d12a7
+		endnetconfig(handle);
Ian Kent 3d12a7
+		return NULL;
Ian Kent 3d12a7
+	}
Ian Kent 3d12a7
+
Ian Kent 3d12a7
+	/*
Ian Kent 3d12a7
+	 * bind to any unused port.  If we left this up to the rpc layer,
Ian Kent 3d12a7
+	 * it would bind to a reserved port, which has been shown to
Ian Kent 3d12a7
+	 * exhaust the reserved port range in some situations.
Ian Kent 3d12a7
+	 */
Ian Kent 3d12a7
+	if (!info->client) {
Ian Kent 3d12a7
+		*fd = open_sock(addr->sa_family, type, proto);
Ian Kent 3d12a7
+		if (*fd < 0) {
Ian Kent 3d12a7
+			endnetconfig(handle);
Ian Kent 3d12a7
+			return NULL;
Ian Kent 3d12a7
+		}
Ian Kent 3d12a7
+
Ian Kent 3d12a7
+		if (bind(*fd, laddr, slen) < 0) {
Ian Kent 3d12a7
+			endnetconfig(handle);
Ian Kent 3d12a7
+			return NULL;
Ian Kent 3d12a7
+		}
Ian Kent 3d12a7
+	}
Ian Kent 3d12a7
+
Ian Kent 3d12a7
+	nb_addr.maxlen = nb_addr.len = slen;
Ian Kent 3d12a7
+	nb_addr.buf = addr;
Ian Kent 3d12a7
+
Ian Kent 3d12a7
+	if (info->proto->p_proto == IPPROTO_TCP) {
Ian Kent 3d12a7
+		if (connect_nb(*fd, addr, slen, &info->timeout) < 0) {
Ian Kent 3d12a7
+			endnetconfig(handle);
Ian Kent 3d12a7
+			return NULL;
Ian Kent 3d12a7
+		}
Ian Kent 3d12a7
+	}
Ian Kent 3d12a7
+
Ian Kent 3d12a7
+	client = clnt_tli_create(*fd, nconf, &nb_addr,
Ian Kent 3d12a7
+				 info->program, info->version,
Ian Kent 3d12a7
+				 info->send_sz, info->recv_sz);
Ian Kent 3d12a7
+
Ian Kent 3d12a7
+	endnetconfig(handle);
Ian Kent 3d12a7
+
Ian Kent 3d12a7
+	return client;
Ian Kent 3d12a7
+}
Ian Kent 3d12a7
+#endif
Ian Kent 3d12a7
 
Ian Kent 3d12a7
 /*
Ian Kent 3d12a7
- * Create a UDP RPC client
Ian Kent 3d12a7
+ * Create an RPC client
Ian Kent 3d12a7
  */
Ian Kent 3d12a7
-static CLIENT *create_udp_client(struct conn_info *info)
Ian Kent 3d12a7
+static CLIENT *create_client(struct conn_info *info)
Ian Kent 3d12a7
 {
Ian Kent 3d12a7
 	CLIENT *client = NULL;
Ian Kent 3d12a7
 	struct addrinfo *ai, *haddr;
Ian Kent 3d12a7
 	struct addrinfo hints;
Ian Kent 3d12a7
 	int fd, ret;
Ian Kent 3d12a7
 
Ian Kent 3d12a7
-	if (info->proto->p_proto != IPPROTO_UDP)
Ian Kent 3d12a7
-		return NULL;
Ian Kent 3d12a7
-
Ian Kent 3d12a7
 	fd = RPC_ANYSOCK;
Ian Kent 3d12a7
 
Ian Kent 3d12a7
 	if (info->client) {
Ian Kent 3d12a7
@@ -355,6 +371,11 @@ static CLIENT *create_udp_client(struct
Ian Kent 3d12a7
 
Ian Kent 3d12a7
 	haddr = ai;
Ian Kent 3d12a7
 	while (haddr) {
Ian Kent 3d12a7
+		if (haddr->ai_protocol != info->proto->p_proto) {
Ian Kent 3d12a7
+			haddr = haddr->ai_next;
Ian Kent 3d12a7
+			continue;
Ian Kent 3d12a7
+		}
Ian Kent 3d12a7
+
Ian Kent 3d12a7
 		client = rpc_do_create_client(haddr->ai_addr, info, &fd;;
Ian Kent 3d12a7
 		if (client)
Ian Kent 3d12a7
 			break;
Ian Kent 3d12a7
@@ -408,7 +429,7 @@ int rpc_udp_getclient(struct conn_info *
Ian Kent 3d12a7
 	info->program = program;
Ian Kent 3d12a7
 	info->version = version;
Ian Kent 3d12a7
 
Ian Kent 3d12a7
-	client = create_udp_client(info);
Ian Kent 3d12a7
+	client = create_client(info);
Ian Kent 3d12a7
 
Ian Kent 3d12a7
 	if (!client)
Ian Kent 3d12a7
 		return 0;
Ian Kent 3d12a7
@@ -428,92 +449,6 @@ void rpc_destroy_udp_client(struct conn_
Ian Kent 3d12a7
 	return;
Ian Kent 3d12a7
 }
Ian Kent 3d12a7
 
Ian Kent 3d12a7
-/*
Ian Kent 3d12a7
- * Create a TCP RPC client using non-blocking connect
Ian Kent 3d12a7
- */
Ian Kent 3d12a7
-static CLIENT *create_tcp_client(struct conn_info *info)
Ian Kent 3d12a7
-{
Ian Kent 3d12a7
-	CLIENT *client = NULL;
Ian Kent 3d12a7
-	struct addrinfo *ai, *haddr;
Ian Kent 3d12a7
-	struct addrinfo hints;
Ian Kent 3d12a7
-	int fd, ret;
Ian Kent 3d12a7
-
Ian Kent 3d12a7
-	if (info->proto->p_proto != IPPROTO_TCP)
Ian Kent 3d12a7
-		return NULL;
Ian Kent 3d12a7
-
Ian Kent 3d12a7
-	fd = RPC_ANYSOCK;
Ian Kent 3d12a7
-
Ian Kent 3d12a7
-	if (info->client) {
Ian Kent 3d12a7
-		if (!clnt_control(info->client, CLGET_FD, (char *) &fd)) {
Ian Kent 3d12a7
-			fd = RPC_ANYSOCK;
Ian Kent 3d12a7
-			clnt_destroy(info->client);
Ian Kent 3d12a7
-			info->client = NULL;
Ian Kent 3d12a7
-		} else {
Ian Kent 3d12a7
-			clnt_control(info->client, CLSET_FD_NCLOSE, NULL);
Ian Kent 3d12a7
-			clnt_destroy(info->client);
Ian Kent 3d12a7
-		}
Ian Kent 3d12a7
-	}
Ian Kent 3d12a7
-
Ian Kent 3d12a7
-	if (info->addr) {
Ian Kent 3d12a7
-		client = rpc_do_create_client(info->addr, info, &fd;;
Ian Kent 3d12a7
-		if (client)
Ian Kent 3d12a7
-			goto done;
Ian Kent 3d12a7
-
Ian Kent 3d12a7
-		if (!info->client) {
Ian Kent 3d12a7
-			close(fd);
Ian Kent 3d12a7
-			fd = RPC_ANYSOCK;
Ian Kent 3d12a7
-		}
Ian Kent 3d12a7
-	}
Ian Kent 3d12a7
-
Ian Kent 3d12a7
-	memset(&hints, 0, sizeof(hints));
Ian Kent 3d12a7
-	hints.ai_flags = AI_ADDRCONFIG;
Ian Kent 3d12a7
-	hints.ai_family = AF_UNSPEC;
Ian Kent 3d12a7
-	hints.ai_socktype = SOCK_STREAM;
Ian Kent 3d12a7
-
Ian Kent 3d12a7
-	ret = getaddrinfo(info->host, NULL, &hints, &ai;;
Ian Kent 3d12a7
-	if (ret) {
Ian Kent 3d12a7
-		error(LOGOPT_ANY,
Ian Kent 3d12a7
-		      "hostname lookup failed: %s", gai_strerror(ret));
Ian Kent 3d12a7
-		info->client = NULL;
Ian Kent 3d12a7
-		goto out_close;
Ian Kent 3d12a7
-	}
Ian Kent 3d12a7
-
Ian Kent 3d12a7
-	haddr = ai;
Ian Kent 3d12a7
-	while (haddr) {
Ian Kent 3d12a7
-		client = rpc_do_create_client(haddr->ai_addr, info, &fd;;
Ian Kent 3d12a7
-		if (client)
Ian Kent 3d12a7
-			break;
Ian Kent 3d12a7
-
Ian Kent 3d12a7
-		if (!info->client && fd != RPC_ANYSOCK) {
Ian Kent 3d12a7
-			close(fd);
Ian Kent 3d12a7
-			fd = RPC_ANYSOCK;
Ian Kent 3d12a7
-		}
Ian Kent 3d12a7
-
Ian Kent 3d12a7
-		haddr = haddr->ai_next;
Ian Kent 3d12a7
-	}
Ian Kent 3d12a7
-
Ian Kent 3d12a7
-	freeaddrinfo(ai);
Ian Kent 3d12a7
-
Ian Kent 3d12a7
-	if (!client) {
Ian Kent 3d12a7
-		info->client = NULL;
Ian Kent 3d12a7
-		goto out_close;
Ian Kent 3d12a7
-	}
Ian Kent 3d12a7
-done:
Ian Kent 3d12a7
-	/* Close socket fd on destroy, as is default for rpcowned fds */
Ian Kent 3d12a7
-	if  (!clnt_control(client, CLSET_FD_CLOSE, NULL)) {
Ian Kent 3d12a7
-		clnt_destroy(client);
Ian Kent 3d12a7
-		info->client = NULL;
Ian Kent 3d12a7
-		goto out_close;
Ian Kent 3d12a7
-	}
Ian Kent 3d12a7
-
Ian Kent 3d12a7
-	return client;
Ian Kent 3d12a7
-
Ian Kent 3d12a7
-out_close:
Ian Kent 3d12a7
-	if (fd != -1)
Ian Kent 3d12a7
-		close(fd);
Ian Kent 3d12a7
-	return NULL;
Ian Kent 3d12a7
-}
Ian Kent 3d12a7
-
Ian Kent 3d12a7
 int rpc_tcp_getclient(struct conn_info *info,
Ian Kent 3d12a7
 		      unsigned int program, unsigned int version)
Ian Kent 3d12a7
 {
Ian Kent 3d12a7
@@ -533,7 +468,7 @@ int rpc_tcp_getclient(struct conn_info *
Ian Kent 3d12a7
 	info->program = program;
Ian Kent 3d12a7
 	info->version = version;
Ian Kent 3d12a7
 
Ian Kent 3d12a7
-	client = create_tcp_client(info);
Ian Kent 3d12a7
+	client = create_client(info);
Ian Kent 3d12a7
 
Ian Kent 3d12a7
 	if (!client)
Ian Kent 3d12a7
 		return 0;
Ian Kent 3d12a7
@@ -593,12 +528,9 @@ int rpc_portmap_getclient(struct conn_in
Ian Kent 3d12a7
 	info->close_option = option;
Ian Kent 3d12a7
 	info->client = NULL;
Ian Kent 3d12a7
 
Ian Kent 3d12a7
-	if (pe_proto->p_proto == IPPROTO_TCP) {
Ian Kent 3d12a7
+	if (pe_proto->p_proto == IPPROTO_TCP)
Ian Kent 3d12a7
 		info->timeout.tv_sec = PMAP_TOUT_TCP;
Ian Kent 3d12a7
-		client = create_tcp_client(info);
Ian Kent 3d12a7
-	} else
Ian Kent 3d12a7
-		client = create_udp_client(info);
Ian Kent 3d12a7
-
Ian Kent 3d12a7
+	client = create_client(info);
Ian Kent 3d12a7
 	if (!client)
Ian Kent 3d12a7
 		return 0;
Ian Kent 3d12a7
 
Ian Kent 3d12a7
@@ -635,11 +567,7 @@ unsigned short rpc_portmap_getport(struc
Ian Kent 3d12a7
 		pmap_info.send_sz = RPCSMALLMSGSIZE;
Ian Kent 3d12a7
 		pmap_info.recv_sz = RPCSMALLMSGSIZE;
Ian Kent 3d12a7
 
Ian Kent 3d12a7
-		if (proto == IPPROTO_TCP)
Ian Kent 3d12a7
-			client = create_tcp_client(&pmap_info);
Ian Kent 3d12a7
-		else
Ian Kent 3d12a7
-			client = create_udp_client(&pmap_info);
Ian Kent 3d12a7
-
Ian Kent 3d12a7
+		client = create_client(&pmap_info);
Ian Kent 3d12a7
 		if (!client)
Ian Kent 3d12a7
 			return 0;
Ian Kent 3d12a7
 	}
Ian Kent 3d12a7
@@ -700,10 +628,8 @@ int rpc_ping_proto(struct conn_info *inf
Ian Kent 3d12a7
 		if (info->proto->p_proto == IPPROTO_UDP) {
Ian Kent 3d12a7
 			info->send_sz = UDPMSGSIZE;
Ian Kent 3d12a7
 			info->recv_sz = UDPMSGSIZE;
Ian Kent 3d12a7
-			client = create_udp_client(info);
Ian Kent 3d12a7
-		} else
Ian Kent 3d12a7
-			client = create_tcp_client(info);
Ian Kent 3d12a7
-
Ian Kent 3d12a7
+		}
Ian Kent 3d12a7
+		client = create_client(info);
Ian Kent 3d12a7
 		if (!client)
Ian Kent 3d12a7
 			return 0;
Ian Kent 3d12a7
 	}
Ian Kent 3d12a7
@@ -857,10 +783,8 @@ static int rpc_get_exports_proto(struct
Ian Kent 3d12a7
 	if (info->proto->p_proto == IPPROTO_UDP) {
Ian Kent 3d12a7
 		info->send_sz = UDPMSGSIZE;
Ian Kent 3d12a7
 		info->recv_sz = UDPMSGSIZE;
Ian Kent 3d12a7
-		client = create_udp_client(info);
Ian Kent 3d12a7
-	} else
Ian Kent 3d12a7
-		client = create_tcp_client(info);
Ian Kent 3d12a7
-
Ian Kent 3d12a7
+	}
Ian Kent 3d12a7
+	client = create_client(info);
Ian Kent 3d12a7
 	if (!client)
Ian Kent 3d12a7
 		return 0;
Ian Kent 3d12a7
 
Ian Kent 3d12a7
--- autofs-5.0.6.orig/modules/replicated.c
Ian Kent 3d12a7
+++ autofs-5.0.6/modules/replicated.c
Ian Kent 3d12a7
@@ -1095,7 +1095,13 @@ static int add_new_host(struct host **li
Ian Kent 3d12a7
 	if (prx == PROXIMITY_ERROR)
Ian Kent 3d12a7
 		return 0;
Ian Kent 3d12a7
 
Ian Kent 3d12a7
-	addr_len = sizeof(struct sockaddr);
Ian Kent 3d12a7
+	if (host_addr->ai_addr->sa_family == AF_INET)
Ian Kent 3d12a7
+		addr_len = INET_ADDRSTRLEN;
Ian Kent 3d12a7
+	else if (host_addr->ai_addr->sa_family == AF_INET6)
Ian Kent 3d12a7
+		addr_len = INET6_ADDRSTRLEN;
Ian Kent 3d12a7
+	else
Ian Kent 3d12a7
+		return 0;
Ian Kent 3d12a7
+
Ian Kent 3d12a7
 	new = new_host(host, host_addr->ai_addr, addr_len, prx, weight, options);
Ian Kent 3d12a7
 	if (!new)
Ian Kent 3d12a7
 		return 0;