Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
Please login to access the resource
openSUSE:11.4:Update
autofs
autofs-5.0.6-fix-ipv6-rpc-calls.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File autofs-5.0.6-fix-ipv6-rpc-calls.patch of Package autofs
commit f8ea2a5762f65b1e45c21aa3676bf18bb5e37680 Author: Ian Kent <ikent@redhat.com> Date: Thu Dec 1 18:35:12 2011 +0800 autofs-5.0.6 - fix ipv6 rpc calls There is a mistake in the way autofs uses libtirpc. Two IPv6 compatibiliy functions were thought to be included when in fact they were not and would not actually work with IPv6 anyway. To fix that the libtirpc interface code needed to be re-written. Portmap (using libtirpc calls) is still used to get service port numbers, rather than rpcbind. Index: autofs-5.0.5/CHANGELOG =================================================================== --- autofs-5.0.5.orig/CHANGELOG +++ autofs-5.0.5/CHANGELOG @@ -90,6 +90,7 @@ - fix submount shutdown race. - fix fix map source check in file lookup. - fix ipv6 name lookup check. +- fix ipv6 rpc calls. 03/09/2009 autofs-5.0.5 ----------------------- Index: autofs-5.0.5/lib/rpc_subs.c =================================================================== --- autofs-5.0.5.orig/lib/rpc_subs.c +++ autofs-5.0.5/lib/rpc_subs.c @@ -62,89 +62,6 @@ static const rpcvers_t mount_vers[] = { static int connect_nb(int, struct sockaddr *, socklen_t, struct timeval *); inline void dump_core(void); -static CLIENT *rpc_clntudp_create(struct sockaddr *addr, struct conn_info *info, int *fd) -{ - struct sockaddr_in *in4_raddr; - struct sockaddr_in6 *in6_raddr; - CLIENT *client = NULL; - - switch (addr->sa_family) { - case AF_INET: - in4_raddr = (struct sockaddr_in *) addr; - in4_raddr->sin_port = htons(info->port); - client = clntudp_bufcreate(in4_raddr, - info->program, info->version, - info->timeout, fd, - info->send_sz, info->recv_sz); - break; - - case AF_INET6: -#ifndef INET6 - /* Quiet compile warning */ - in6_raddr = NULL; -#else - in6_raddr = (struct sockaddr_in6 *) addr; - in6_raddr->sin6_port = htons(info->port); - client = clntudp6_bufcreate(in6_raddr, - info->program, info->version, - info->timeout, fd, - info->send_sz, info->recv_sz); -#endif - break; - - default: - break; - } - - return client; -} - -static CLIENT *rpc_clnttcp_create(struct sockaddr *addr, struct conn_info *info, int *fd) -{ - struct sockaddr_in *in4_raddr; - struct sockaddr_in6 *in6_raddr; - CLIENT *client = NULL; - socklen_t slen; - - switch (addr->sa_family) { - case AF_INET: - in4_raddr = (struct sockaddr_in *) addr; - in4_raddr->sin_port = htons(info->port); - slen = sizeof(struct sockaddr_in); - - if (connect_nb(*fd, addr, slen, &info->timeout) < 0) - break; - - client = clnttcp_create(in4_raddr, - info->program, info->version, fd, - info->send_sz, info->recv_sz); - break; - - case AF_INET6: -#ifndef INET6 - /* Quiet compile warning */ - in6_raddr = NULL; -#else - in6_raddr = (struct sockaddr_in6 *) addr; - in6_raddr->sin6_port = htons(info->port); - slen = sizeof(struct sockaddr_in6); - - if (connect_nb(*fd, addr, slen, &info->timeout) < 0) - break; - - client = clnttcp6_create(in6_raddr, - info->program, info->version, fd, - info->send_sz, info->recv_sz); -#endif - break; - - default: - break; - } - - return client; -} - /* * Perform a non-blocking connect on the socket fd. * @@ -232,12 +149,12 @@ done: return ret; } +#ifndef WITH_LIBTIRPC static CLIENT *rpc_do_create_client(struct sockaddr *addr, struct conn_info *info, int *fd) { CLIENT *client = NULL; - struct sockaddr *laddr; struct sockaddr_in in4_laddr; - struct sockaddr_in6 in6_laddr; + struct sockaddr_in in4_raddr; int type, proto; socklen_t slen; @@ -252,48 +169,41 @@ static CLIENT *rpc_do_create_client(stru * layer, it would bind to a reserved port, which has been shown * to exhaust the reserved port range in some situations. */ - switch (addr->sa_family) { - case AF_INET: - in4_laddr.sin_family = AF_INET; - in4_laddr.sin_port = htons(0); - in4_laddr.sin_addr.s_addr = htonl(INADDR_ANY); - slen = sizeof(struct sockaddr_in); - laddr = (struct sockaddr *) &in4_laddr; - break; - - case AF_INET6: -#ifndef INET6 - /* Quiet compiler */ - in6_laddr.sin6_family = AF_INET6; - return NULL; -#else - in6_laddr.sin6_family = AF_INET6; - in6_laddr.sin6_port = htons(0); - in6_laddr.sin6_addr = in6addr_any; - slen = sizeof(struct sockaddr_in6); - laddr = (struct sockaddr *) &in6_laddr; - break; -#endif - default: - return NULL; - } + in4_laddr.sin_family = AF_INET; + in4_laddr.sin_port = htons(0); + in4_laddr.sin_addr.s_addr = htonl(INADDR_ANY); + slen = sizeof(struct sockaddr_in); if (!info->client) { + struct sockaddr *laddr; + *fd = open_sock(addr->sa_family, type, proto); if (*fd < 0) return NULL; + laddr = (struct sockaddr *) &in4_laddr; if (bind(*fd, laddr, slen) < 0) return NULL; } + in4_raddr = (struct sockaddr_in *) addr; + in4_raddr->sin_port = htons(info->port); + switch (info->proto->p_proto) { case IPPROTO_UDP: - client = rpc_clntudp_create(addr, info, fd); + client = clntudp_bufcreate(in4_raddr, + info->program, info->version, + info->timeout, fd, + info->send_sz, info->recv_sz); break; case IPPROTO_TCP: - client = rpc_clnttcp_create(addr, info, fd); + if (connect_nb(*fd, addr, slen, &info->timeout) < 0) + break; + + client = clnttcp_create(in4_raddr, + info->program, info->version, fd, + info->send_sz, info->recv_sz); break; default: @@ -302,20 +212,126 @@ static CLIENT *rpc_do_create_client(stru return client; } +#else +struct netconfig *find_netconf(void *handle, char *family, char *proto) +{ + struct netconfig *nconf; + + while ((nconf = getnetconfig(handle))) { + if ((strcmp(nconf->nc_protofmly, family) == 0) && + (strcmp(nconf->nc_proto, proto) == 0)) + break; + } + + return nconf; +} + +static CLIENT *rpc_do_create_client(struct sockaddr *addr, struct conn_info *info, int *fd) +{ + CLIENT *client = NULL; + struct sockaddr_in in4_laddr; + struct sockaddr_in6 in6_laddr; + struct sockaddr *laddr = NULL; + struct netconfig *nconf; + struct netbuf nb_addr; + int type, proto; + char *nc_family, *nc_proto; + void *handle; + size_t slen; + + proto = info->proto->p_proto; + if (proto == IPPROTO_UDP) { + type = SOCK_DGRAM; + nc_proto = NC_UDP; + } else { + type = SOCK_STREAM; + nc_proto = NC_TCP; + } + + /* + * bind to any unused port. If we left this up to the rpc + * layer, it would bind to a reserved port, which has been shown + * to exhaust the reserved port range in some situations. + */ + if (addr->sa_family == AF_INET) { + struct sockaddr_in *in4_raddr = (struct sockaddr_in *) addr; + in4_laddr.sin_family = AF_INET; + in4_laddr.sin_port = htons(0); + in4_laddr.sin_addr.s_addr = htonl(INADDR_ANY); + laddr = (struct sockaddr *) &in4_laddr; + in4_raddr->sin_port = htons(info->port); + slen = sizeof(struct sockaddr_in); + nc_family = NC_INET; + } else if (addr->sa_family == AF_INET6) { + struct sockaddr_in6 *in6_raddr = (struct sockaddr_in6 *) addr; + in6_laddr.sin6_family = AF_INET6; + in6_laddr.sin6_port = htons(0); + in6_laddr.sin6_addr = in6addr_any; + laddr = (struct sockaddr *) &in6_laddr; + in6_raddr->sin6_port = htons(info->port); + slen = sizeof(struct sockaddr_in6); + nc_family = NC_INET6; + } else + return NULL; + + handle = setnetconfig(); + if (!handle) + return NULL; + + nconf = find_netconf(handle, nc_family, nc_proto); + if (!nconf) { + endnetconfig(handle); + return NULL; + } + + /* + * bind to any unused port. If we left this up to the rpc layer, + * it would bind to a reserved port, which has been shown to + * exhaust the reserved port range in some situations. + */ + if (!info->client) { + *fd = open_sock(addr->sa_family, type, proto); + if (*fd < 0) { + endnetconfig(handle); + return NULL; + } + + if (bind(*fd, laddr, slen) < 0) { + endnetconfig(handle); + return NULL; + } + } + + nb_addr.maxlen = nb_addr.len = slen; + nb_addr.buf = addr; + + if (info->proto->p_proto == IPPROTO_TCP) { + if (connect_nb(*fd, addr, slen, &info->timeout) < 0) { + endnetconfig(handle); + return NULL; + } + } + + client = clnt_tli_create(*fd, nconf, &nb_addr, + info->program, info->version, + info->send_sz, info->recv_sz); + + endnetconfig(handle); + + return client; +} +#endif /* - * Create a UDP RPC client + * Create an RPC client */ -static CLIENT *create_udp_client(struct conn_info *info) +static CLIENT *create_client(struct conn_info *info) { CLIENT *client = NULL; struct addrinfo *ai, *haddr; struct addrinfo hints; int fd, ret; - if (info->proto->p_proto != IPPROTO_UDP) - return NULL; - fd = RPC_ANYSOCK; if (info->client) { @@ -355,6 +371,11 @@ static CLIENT *create_udp_client(struct haddr = ai; while (haddr) { + if (haddr->ai_protocol != info->proto->p_proto) { + haddr = haddr->ai_next; + continue; + } + client = rpc_do_create_client(haddr->ai_addr, info, &fd); if (client) break; @@ -408,7 +429,7 @@ int rpc_udp_getclient(struct conn_info * info->program = program; info->version = version; - client = create_udp_client(info); + client = create_client(info); if (!client) return 0; @@ -428,92 +449,6 @@ void rpc_destroy_udp_client(struct conn_ return; } -/* - * Create a TCP RPC client using non-blocking connect - */ -static CLIENT *create_tcp_client(struct conn_info *info) -{ - CLIENT *client = NULL; - struct addrinfo *ai, *haddr; - struct addrinfo hints; - int fd, ret; - - if (info->proto->p_proto != IPPROTO_TCP) - return NULL; - - fd = RPC_ANYSOCK; - - if (info->client) { - if (!clnt_control(info->client, CLGET_FD, (char *) &fd)) { - fd = RPC_ANYSOCK; - clnt_destroy(info->client); - info->client = NULL; - } else { - clnt_control(info->client, CLSET_FD_NCLOSE, NULL); - clnt_destroy(info->client); - } - } - - if (info->addr) { - client = rpc_do_create_client(info->addr, info, &fd); - if (client) - goto done; - - if (!info->client) { - close(fd); - fd = RPC_ANYSOCK; - } - } - - memset(&hints, 0, sizeof(hints)); - hints.ai_flags = AI_ADDRCONFIG; - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - - ret = getaddrinfo(info->host, NULL, &hints, &ai); - if (ret) { - error(LOGOPT_ANY, - "hostname lookup failed: %s", gai_strerror(ret)); - info->client = NULL; - goto out_close; - } - - haddr = ai; - while (haddr) { - client = rpc_do_create_client(haddr->ai_addr, info, &fd); - if (client) - break; - - if (!info->client && fd != RPC_ANYSOCK) { - close(fd); - fd = RPC_ANYSOCK; - } - - haddr = haddr->ai_next; - } - - freeaddrinfo(ai); - - if (!client) { - info->client = NULL; - goto out_close; - } -done: - /* Close socket fd on destroy, as is default for rpcowned fds */ - if (!clnt_control(client, CLSET_FD_CLOSE, NULL)) { - clnt_destroy(client); - info->client = NULL; - goto out_close; - } - - return client; - -out_close: - if (fd != -1) - close(fd); - return NULL; -} - int rpc_tcp_getclient(struct conn_info *info, unsigned int program, unsigned int version) { @@ -533,7 +468,7 @@ int rpc_tcp_getclient(struct conn_info * info->program = program; info->version = version; - client = create_tcp_client(info); + client = create_client(info); if (!client) return 0; @@ -593,12 +528,9 @@ int rpc_portmap_getclient(struct conn_in info->close_option = option; info->client = NULL; - if (pe_proto->p_proto == IPPROTO_TCP) { + if (pe_proto->p_proto == IPPROTO_TCP) info->timeout.tv_sec = PMAP_TOUT_TCP; - client = create_tcp_client(info); - } else - client = create_udp_client(info); - + client = create_client(info); if (!client) return 0; @@ -635,11 +567,7 @@ unsigned short rpc_portmap_getport(struc pmap_info.send_sz = RPCSMALLMSGSIZE; pmap_info.recv_sz = RPCSMALLMSGSIZE; - if (proto == IPPROTO_TCP) - client = create_tcp_client(&pmap_info); - else - client = create_udp_client(&pmap_info); - + client = create_client(&pmap_info); if (!client) return 0; } @@ -700,10 +628,8 @@ int rpc_ping_proto(struct conn_info *inf if (info->proto->p_proto == IPPROTO_UDP) { info->send_sz = UDPMSGSIZE; info->recv_sz = UDPMSGSIZE; - client = create_udp_client(info); - } else - client = create_tcp_client(info); - + } + client = create_client(info); if (!client) return 0; } @@ -857,10 +783,8 @@ static int rpc_get_exports_proto(struct if (info->proto->p_proto == IPPROTO_UDP) { info->send_sz = UDPMSGSIZE; info->recv_sz = UDPMSGSIZE; - client = create_udp_client(info); - } else - client = create_tcp_client(info); - + } + client = create_client(info); if (!client) return 0; Index: autofs-5.0.5/modules/replicated.c =================================================================== --- autofs-5.0.5.orig/modules/replicated.c +++ autofs-5.0.5/modules/replicated.c @@ -1093,7 +1093,13 @@ static int add_new_host(struct host **li if (prx == PROXIMITY_ERROR) return 0; - addr_len = sizeof(struct sockaddr); + if (host_addr->ai_addr->sa_family == AF_INET) + addr_len = INET_ADDRSTRLEN; + else if (host_addr->ai_addr->sa_family == AF_INET6) + addr_len = INET6_ADDRSTRLEN; + else + return 0; + new = new_host(host, host_addr->ai_addr, addr_len, prx, weight, options); if (!new) return 0;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor