|
|
ab3a3d |
autofs-5.0.7 - fix ipv6 proximity calculation
|
|
|
ab3a3d |
|
|
|
ab3a3d |
From: Ian Kent <ikent@redhat.com>
|
|
|
ab3a3d |
|
|
|
ab3a3d |
The socket based ioctl used to get interface information only
|
|
|
ab3a3d |
return IPv4 information. Change get_proximity() function to use
|
|
|
ab3a3d |
getifaddrs(3) instead.
|
|
|
ab3a3d |
---
|
|
|
ab3a3d |
|
|
|
ab3a3d |
CHANGELOG | 1
|
|
|
ab3a3d |
modules/replicated.c | 149 ++++++++++++++------------------------------------
|
|
|
ab3a3d |
2 files changed, 42 insertions(+), 108 deletions(-)
|
|
|
ab3a3d |
|
|
|
ab3a3d |
|
|
|
ab3a3d |
diff --git a/CHANGELOG b/CHANGELOG
|
|
|
ab3a3d |
index dc38580..34c70fa 100644
|
|
|
ab3a3d |
--- a/CHANGELOG
|
|
|
ab3a3d |
+++ b/CHANGELOG
|
|
|
ab3a3d |
@@ -2,6 +2,7 @@
|
|
|
ab3a3d |
=======================
|
|
|
ab3a3d |
- fix nobind sun escaped map entries.
|
|
|
ab3a3d |
- fix use cache entry after free in lookup_prune_one_cache().
|
|
|
ab3a3d |
+- fix ipv6 proximity calculation.
|
|
|
ab3a3d |
|
|
|
ab3a3d |
25/07/2012 autofs-5.0.7
|
|
|
ab3a3d |
=======================
|
|
|
ab3a3d |
diff --git a/modules/replicated.c b/modules/replicated.c
|
|
|
ab3a3d |
index 78046c6..bd6003b 100644
|
|
|
ab3a3d |
--- a/modules/replicated.c
|
|
|
ab3a3d |
+++ b/modules/replicated.c
|
|
|
ab3a3d |
@@ -52,6 +52,7 @@
|
|
|
ab3a3d |
#include <net/if.h>
|
|
|
ab3a3d |
#include <netinet/in.h>
|
|
|
ab3a3d |
#include <netdb.h>
|
|
|
ab3a3d |
+#include <ifaddrs.h>
|
|
|
ab3a3d |
|
|
|
ab3a3d |
#include "rpc_subs.h"
|
|
|
ab3a3d |
#include "replicated.h"
|
|
|
ab3a3d |
@@ -110,58 +111,18 @@ void seed_random(void)
|
|
|
ab3a3d |
return;
|
|
|
ab3a3d |
}
|
|
|
ab3a3d |
|
|
|
ab3a3d |
-static int alloc_ifreq(struct ifconf *ifc, int sock)
|
|
|
ab3a3d |
-{
|
|
|
ab3a3d |
- int ret, lastlen = ifc_last_len, len = ifc_buf_len;
|
|
|
ab3a3d |
- char err_buf[MAX_ERR_BUF], *buf;
|
|
|
ab3a3d |
-
|
|
|
ab3a3d |
- while (1) {
|
|
|
ab3a3d |
- buf = malloc(len);
|
|
|
ab3a3d |
- if (!buf) {
|
|
|
ab3a3d |
- char *estr = strerror_r(errno, err_buf, MAX_ERR_BUF);
|
|
|
ab3a3d |
- logerr("malloc: %s", estr);
|
|
|
ab3a3d |
- return 0;
|
|
|
ab3a3d |
- }
|
|
|
ab3a3d |
-
|
|
|
ab3a3d |
- ifc->ifc_len = len;
|
|
|
ab3a3d |
- ifc->ifc_req = (struct ifreq *) buf;
|
|
|
ab3a3d |
-
|
|
|
ab3a3d |
- ret = ioctl(sock, SIOCGIFCONF, ifc);
|
|
|
ab3a3d |
- if (ret == -1) {
|
|
|
ab3a3d |
- char *estr = strerror_r(errno, err_buf, MAX_ERR_BUF);
|
|
|
ab3a3d |
- logerr("ioctl: %s", estr);
|
|
|
ab3a3d |
- free(buf);
|
|
|
ab3a3d |
- return 0;
|
|
|
ab3a3d |
- }
|
|
|
ab3a3d |
-
|
|
|
ab3a3d |
- if (ifc->ifc_len <= lastlen)
|
|
|
ab3a3d |
- break;
|
|
|
ab3a3d |
-
|
|
|
ab3a3d |
- lastlen = ifc->ifc_len;
|
|
|
ab3a3d |
- len += MAX_IFC_BUF;
|
|
|
ab3a3d |
- free(buf);
|
|
|
ab3a3d |
- }
|
|
|
ab3a3d |
-
|
|
|
ab3a3d |
- if (lastlen != ifc_last_len) {
|
|
|
ab3a3d |
- ifc_last_len = lastlen;
|
|
|
ab3a3d |
- ifc_buf_len = len;
|
|
|
ab3a3d |
- }
|
|
|
ab3a3d |
-
|
|
|
ab3a3d |
- return 1;
|
|
|
ab3a3d |
-}
|
|
|
ab3a3d |
-
|
|
|
ab3a3d |
static unsigned int get_proximity(struct sockaddr *host_addr)
|
|
|
ab3a3d |
{
|
|
|
ab3a3d |
+ struct ifaddrs *ifa = NULL;
|
|
|
ab3a3d |
+ struct ifaddrs *this;
|
|
|
ab3a3d |
struct sockaddr_in *addr, *msk_addr, *if_addr;
|
|
|
ab3a3d |
struct sockaddr_in6 *addr6, *msk6_addr, *if6_addr;
|
|
|
ab3a3d |
struct in_addr *hst_addr;
|
|
|
ab3a3d |
struct in6_addr *hst6_addr;
|
|
|
ab3a3d |
int addr_len;
|
|
|
ab3a3d |
- char buf[MAX_ERR_BUF], *ptr;
|
|
|
ab3a3d |
- struct ifconf ifc;
|
|
|
ab3a3d |
- struct ifreq *ifr, nmptr;
|
|
|
ab3a3d |
- int sock, ret, i;
|
|
|
ab3a3d |
+ char buf[MAX_ERR_BUF];
|
|
|
ab3a3d |
uint32_t mask, ha, ia, *mask6, *ha6, *ia6;
|
|
|
ab3a3d |
+ int ret;
|
|
|
ab3a3d |
|
|
|
ab3a3d |
addr = NULL;
|
|
|
ab3a3d |
addr6 = NULL;
|
|
|
ab3a3d |
@@ -170,13 +131,14 @@ static unsigned int get_proximity(struct sockaddr *host_addr)
|
|
|
ab3a3d |
mask6 = NULL;
|
|
|
ab3a3d |
ha6 = NULL;
|
|
|
ab3a3d |
ia6 = NULL;
|
|
|
ab3a3d |
+ ha = 0;
|
|
|
ab3a3d |
|
|
|
ab3a3d |
switch (host_addr->sa_family) {
|
|
|
ab3a3d |
case AF_INET:
|
|
|
ab3a3d |
addr = (struct sockaddr_in *) host_addr;
|
|
|
ab3a3d |
hst_addr = (struct in_addr *) &addr->sin_addr;
|
|
|
ab3a3d |
ha = ntohl((uint32_t) hst_addr->s_addr);
|
|
|
ab3a3d |
- addr_len = sizeof(hst_addr);
|
|
|
ab3a3d |
+ addr_len = sizeof(*hst_addr);
|
|
|
ab3a3d |
break;
|
|
|
ab3a3d |
|
|
|
ab3a3d |
case AF_INET6:
|
|
|
ab3a3d |
@@ -186,7 +148,7 @@ static unsigned int get_proximity(struct sockaddr *host_addr)
|
|
|
ab3a3d |
addr6 = (struct sockaddr_in6 *) host_addr;
|
|
|
ab3a3d |
hst6_addr = (struct in6_addr *) &addr6->sin6_addr;
|
|
|
ab3a3d |
ha6 = &hst6_addr->s6_addr32[0];
|
|
|
ab3a3d |
- addr_len = sizeof(hst6_addr);
|
|
|
ab3a3d |
+ addr_len = sizeof(*hst6_addr);
|
|
|
ab3a3d |
break;
|
|
|
ab3a3d |
#endif
|
|
|
ab3a3d |
|
|
|
ab3a3d |
@@ -194,36 +156,29 @@ static unsigned int get_proximity(struct sockaddr *host_addr)
|
|
|
ab3a3d |
return PROXIMITY_ERROR;
|
|
|
ab3a3d |
}
|
|
|
ab3a3d |
|
|
|
ab3a3d |
- sock = open_sock(AF_INET, SOCK_DGRAM, 0);
|
|
|
ab3a3d |
- if (sock < 0) {
|
|
|
ab3a3d |
+ ret = getifaddrs(&ifa;;
|
|
|
ab3a3d |
+ if (ret) {
|
|
|
ab3a3d |
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
|
ab3a3d |
- logerr("socket creation failed: %s", estr);
|
|
|
ab3a3d |
+ logerr("getifaddrs: %s", estr);
|
|
|
ab3a3d |
return PROXIMITY_ERROR;
|
|
|
ab3a3d |
}
|
|
|
ab3a3d |
|
|
|
ab3a3d |
- if (!alloc_ifreq(&ifc, sock)) {
|
|
|
ab3a3d |
- close(sock);
|
|
|
ab3a3d |
- return PROXIMITY_ERROR;
|
|
|
ab3a3d |
- }
|
|
|
ab3a3d |
-
|
|
|
ab3a3d |
- /* For each interface */
|
|
|
ab3a3d |
-
|
|
|
ab3a3d |
- /* Is the address a local interface */
|
|
|
ab3a3d |
- i = 0;
|
|
|
ab3a3d |
- ptr = (char *) &ifc.ifc_buf[0];
|
|
|
ab3a3d |
-
|
|
|
ab3a3d |
- while (ptr < (char *) ifc.ifc_req + ifc.ifc_len) {
|
|
|
ab3a3d |
- ifr = (struct ifreq *) ptr;
|
|
|
ab3a3d |
+ this = ifa;
|
|
|
ab3a3d |
+ while (this) {
|
|
|
ab3a3d |
+ if (this->ifa_flags & IFF_POINTOPOINT ||
|
|
|
ab3a3d |
+ this->ifa_addr->sa_data == NULL) {
|
|
|
ab3a3d |
+ this = this->ifa_next;
|
|
|
ab3a3d |
+ continue;
|
|
|
ab3a3d |
+ }
|
|
|
ab3a3d |
|
|
|
ab3a3d |
- switch (ifr->ifr_addr.sa_family) {
|
|
|
ab3a3d |
+ switch (this->ifa_addr->sa_family) {
|
|
|
ab3a3d |
case AF_INET:
|
|
|
ab3a3d |
if (host_addr->sa_family == AF_INET6)
|
|
|
ab3a3d |
break;
|
|
|
ab3a3d |
- if_addr = (struct sockaddr_in *) &ifr->ifr_addr;
|
|
|
ab3a3d |
+ if_addr = (struct sockaddr_in *) this->ifa_addr;
|
|
|
ab3a3d |
ret = memcmp(&if_addr->sin_addr, hst_addr, addr_len);
|
|
|
ab3a3d |
if (!ret) {
|
|
|
ab3a3d |
- close(sock);
|
|
|
ab3a3d |
- free(ifc.ifc_req);
|
|
|
ab3a3d |
+ freeifaddrs(ifa);
|
|
|
ab3a3d |
return PROXIMITY_LOCAL;
|
|
|
ab3a3d |
}
|
|
|
ab3a3d |
break;
|
|
|
ab3a3d |
@@ -234,55 +189,41 @@ static unsigned int get_proximity(struct sockaddr *host_addr)
|
|
|
ab3a3d |
#else
|
|
|
ab3a3d |
if (host_addr->sa_family == AF_INET)
|
|
|
ab3a3d |
break;
|
|
|
ab3a3d |
-
|
|
|
ab3a3d |
- if6_addr = (struct sockaddr_in6 *) &ifr->ifr_addr;
|
|
|
ab3a3d |
+ if6_addr = (struct sockaddr_in6 *) this->ifa_addr;
|
|
|
ab3a3d |
ret = memcmp(&if6_addr->sin6_addr, hst6_addr, addr_len);
|
|
|
ab3a3d |
if (!ret) {
|
|
|
ab3a3d |
- close(sock);
|
|
|
ab3a3d |
- free(ifc.ifc_req);
|
|
|
ab3a3d |
+ freeifaddrs(ifa);
|
|
|
ab3a3d |
return PROXIMITY_LOCAL;
|
|
|
ab3a3d |
}
|
|
|
ab3a3d |
#endif
|
|
|
ab3a3d |
-
|
|
|
ab3a3d |
default:
|
|
|
ab3a3d |
break;
|
|
|
ab3a3d |
}
|
|
|
ab3a3d |
-
|
|
|
ab3a3d |
- i++;
|
|
|
ab3a3d |
- ptr = (char *) &ifc.ifc_req[i];
|
|
|
ab3a3d |
+ this = this->ifa_next;
|
|
|
ab3a3d |
}
|
|
|
ab3a3d |
|
|
|
ab3a3d |
- i = 0;
|
|
|
ab3a3d |
- ptr = (char *) &ifc.ifc_buf[0];
|
|
|
ab3a3d |
-
|
|
|
ab3a3d |
- while (ptr < (char *) ifc.ifc_req + ifc.ifc_len) {
|
|
|
ab3a3d |
- ifr = (struct ifreq *) ptr;
|
|
|
ab3a3d |
-
|
|
|
ab3a3d |
- nmptr = *ifr;
|
|
|
ab3a3d |
- ret = ioctl(sock, SIOCGIFNETMASK, &nmptr);
|
|
|
ab3a3d |
- if (ret == -1) {
|
|
|
ab3a3d |
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
|
ab3a3d |
- logerr("ioctl: %s", estr);
|
|
|
ab3a3d |
- close(sock);
|
|
|
ab3a3d |
- free(ifc.ifc_req);
|
|
|
ab3a3d |
- return PROXIMITY_ERROR;
|
|
|
ab3a3d |
+ this = ifa;
|
|
|
ab3a3d |
+ while (this) {
|
|
|
ab3a3d |
+ if (this->ifa_flags & IFF_POINTOPOINT ||
|
|
|
ab3a3d |
+ this->ifa_addr->sa_data == NULL) {
|
|
|
ab3a3d |
+ this = this->ifa_next;
|
|
|
ab3a3d |
+ continue;
|
|
|
ab3a3d |
}
|
|
|
ab3a3d |
|
|
|
ab3a3d |
- switch (ifr->ifr_addr.sa_family) {
|
|
|
ab3a3d |
+ switch (this->ifa_addr->sa_family) {
|
|
|
ab3a3d |
case AF_INET:
|
|
|
ab3a3d |
if (host_addr->sa_family == AF_INET6)
|
|
|
ab3a3d |
break;
|
|
|
ab3a3d |
- if_addr = (struct sockaddr_in *) &ifr->ifr_addr;
|
|
|
ab3a3d |
+ if_addr = (struct sockaddr_in *) this->ifa_addr;
|
|
|
ab3a3d |
ia = ntohl((uint32_t) if_addr->sin_addr.s_addr);
|
|
|
ab3a3d |
|
|
|
ab3a3d |
- /* Is the address within a localiy attached subnet */
|
|
|
ab3a3d |
+ /* Is the address within a localy attached subnet */
|
|
|
ab3a3d |
|
|
|
ab3a3d |
- msk_addr = (struct sockaddr_in *) &nmptr.ifr_netmask;
|
|
|
ab3a3d |
+ msk_addr = (struct sockaddr_in *) this->ifa_netmask;
|
|
|
ab3a3d |
mask = ntohl((uint32_t) msk_addr->sin_addr.s_addr);
|
|
|
ab3a3d |
|
|
|
ab3a3d |
if ((ia & mask) == (ha & mask)) {
|
|
|
ab3a3d |
- close(sock);
|
|
|
ab3a3d |
- free(ifc.ifc_req);
|
|
|
ab3a3d |
+ freeifaddrs(ifa);
|
|
|
ab3a3d |
return PROXIMITY_SUBNET;
|
|
|
ab3a3d |
}
|
|
|
ab3a3d |
|
|
|
ab3a3d |
@@ -304,8 +245,7 @@ static unsigned int get_proximity(struct sockaddr *host_addr)
|
|
|
ab3a3d |
break;
|
|
|
ab3a3d |
|
|
|
ab3a3d |
if ((ia & mask) == (ha & mask)) {
|
|
|
ab3a3d |
- close(sock);
|
|
|
ab3a3d |
- free(ifc.ifc_req);
|
|
|
ab3a3d |
+ freeifaddrs(ifa);
|
|
|
ab3a3d |
return PROXIMITY_NET;
|
|
|
ab3a3d |
}
|
|
|
ab3a3d |
break;
|
|
|
ab3a3d |
@@ -316,35 +256,28 @@ static unsigned int get_proximity(struct sockaddr *host_addr)
|
|
|
ab3a3d |
#else
|
|
|
ab3a3d |
if (host_addr->sa_family == AF_INET)
|
|
|
ab3a3d |
break;
|
|
|
ab3a3d |
-
|
|
|
ab3a3d |
- if6_addr = (struct sockaddr_in6 *) &ifr->ifr_addr;
|
|
|
ab3a3d |
+ if6_addr = (struct sockaddr_in6 *) this->ifa_addr;
|
|
|
ab3a3d |
ia6 = &if6_addr->sin6_addr.s6_addr32[0];
|
|
|
ab3a3d |
|
|
|
ab3a3d |
/* Is the address within the network of the interface */
|
|
|
ab3a3d |
|
|
|
ab3a3d |
- msk6_addr = (struct sockaddr_in6 *) &nmptr.ifr_netmask;
|
|
|
ab3a3d |
+ msk6_addr = (struct sockaddr_in6 *) this->ifa_netmask;
|
|
|
ab3a3d |
mask6 = &msk6_addr->sin6_addr.s6_addr32[0];
|
|
|
ab3a3d |
|
|
|
ab3a3d |
if (ipv6_mask_cmp(ha6, ia6, mask6)) {
|
|
|
ab3a3d |
- close(sock);
|
|
|
ab3a3d |
- free(ifc.ifc_req);
|
|
|
ab3a3d |
+ freeifaddrs(ifa);
|
|
|
ab3a3d |
return PROXIMITY_SUBNET;
|
|
|
ab3a3d |
}
|
|
|
ab3a3d |
|
|
|
ab3a3d |
/* How do we define "local network" in ipv6? */
|
|
|
ab3a3d |
#endif
|
|
|
ab3a3d |
- break;
|
|
|
ab3a3d |
-
|
|
|
ab3a3d |
default:
|
|
|
ab3a3d |
break;
|
|
|
ab3a3d |
}
|
|
|
ab3a3d |
-
|
|
|
ab3a3d |
- i++;
|
|
|
ab3a3d |
- ptr = (char *) &ifc.ifc_req[i];
|
|
|
ab3a3d |
+ this = this->ifa_next;
|
|
|
ab3a3d |
}
|
|
|
ab3a3d |
|
|
|
ab3a3d |
- close(sock);
|
|
|
ab3a3d |
- free(ifc.ifc_req);
|
|
|
ab3a3d |
+ freeifaddrs(ifa);
|
|
|
ab3a3d |
|
|
|
ab3a3d |
return PROXIMITY_OTHER;
|
|
|
ab3a3d |
}
|