diff options
Diffstat (limited to 'libglusterfs')
-rw-r--r-- | libglusterfs/src/common-utils.c | 28 | ||||
-rw-r--r-- | libglusterfs/src/compat.h | 4 |
2 files changed, 18 insertions, 14 deletions
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c index 18f445ae265..6a5889207d4 100644 --- a/libglusterfs/src/common-utils.c +++ b/libglusterfs/src/common-utils.c @@ -181,26 +181,16 @@ gf_rev_dns_lookup (const char *ip) { char *fqdn = NULL; int ret = 0; - struct sockaddr_in sa = {0}; - char host_addr[256] = {0, }; GF_VALIDATE_OR_GOTO ("resolver", ip, out); - sa.sin_family = AF_INET; - inet_pton (AF_INET, ip, &sa.sin_addr); - ret = getnameinfo ((struct sockaddr *)&sa, sizeof (sa), host_addr, - sizeof (host_addr), NULL, 0, 0); - + /* Get the FQDN */ + ret = gf_get_hostname_from_ip ((char *)ip, &fqdn); if (ret != 0) { gf_msg ("resolver", GF_LOG_INFO, errno, LG_MSG_RESOLVE_HOSTNAME_FAILED, "could not resolve " "hostname for %s", ip); - goto out; } - - /* Get the FQDN */ - fqdn = gf_strdup (host_addr); - out: return fqdn; } @@ -3107,11 +3097,13 @@ gf_get_hostname_from_ip (char *client_ip, char **hostname) char *client_ip_copy = NULL; char *tmp = NULL; char *ip = NULL; + size_t addr_sz = 0; /* if ipv4, reverse lookup the hostname to * allow FQDN based rpc authentication */ - if (valid_ipv4_address (client_ip, strlen (client_ip), 0) == _gf_false) { + if (!valid_ipv6_address (client_ip, strlen (client_ip), 0) && + !valid_ipv4_address (client_ip, strlen (client_ip), 0)) { /* most times, we get a.b.c.d:port form, so check that */ client_ip_copy = gf_strdup (client_ip); if (!client_ip_copy) @@ -3124,12 +3116,14 @@ gf_get_hostname_from_ip (char *client_ip, char **hostname) if (valid_ipv4_address (ip, strlen (ip), 0) == _gf_true) { client_sockaddr = (struct sockaddr *)&client_sock_in; + addr_sz = sizeof (client_sock_in); client_sock_in.sin_family = AF_INET; ret = inet_pton (AF_INET, ip, (void *)&client_sock_in.sin_addr.s_addr); } else if (valid_ipv6_address (ip, strlen (ip), 0) == _gf_true) { client_sockaddr = (struct sockaddr *) &client_sock_in6; + addr_sz = sizeof (client_sock_in6); client_sock_in6.sin6_family = AF_INET6; ret = inet_pton (AF_INET6, ip, @@ -3143,8 +3137,14 @@ gf_get_hostname_from_ip (char *client_ip, char **hostname) goto out; } + /* You cannot just use sizeof (*client_sockaddr), as per the man page + * the (getnameinfo) size must be the size of the underlying sockaddr + * struct e.g. sockaddr_in6 or sockaddr_in. Failure to do so will + * break IPv6 hostname resolution (IPv4 will work only because + * the sockaddr_in struct happens to be of the correct size). + */ ret = getnameinfo (client_sockaddr, - sizeof (*client_sockaddr), + addr_sz, client_hostname, sizeof (client_hostname), NULL, 0, 0); if (ret) { diff --git a/libglusterfs/src/compat.h b/libglusterfs/src/compat.h index 69adfbcd7fe..33388598b1e 100644 --- a/libglusterfs/src/compat.h +++ b/libglusterfs/src/compat.h @@ -463,6 +463,8 @@ int gf_mkostemp (char *tmpl, int suffixlen, int flags); #define ST_CTIM_NSEC_SET(stbuf, val) do { } while (0); #endif +#ifndef IPV6_DEFAULT + #ifndef IXDR_GET_LONG #define IXDR_GET_LONG(buf) ((long)IXDR_GET_U_INT32(buf)) #endif @@ -479,6 +481,8 @@ int gf_mkostemp (char *tmpl, int suffixlen, int flags); #define IXDR_PUT_U_LONG(buf, v) IXDR_PUT_LONG(buf, (long)(v)) #endif +#endif /* IPV6_DEFAULT */ + #if defined(__GNUC__) && !defined(RELAX_POISONING) /* Use run API, see run.h */ #include <stdlib.h> /* system(), mkostemp() */ |