diff options
Diffstat (limited to 'libglusterfs/src')
| -rw-r--r-- | libglusterfs/src/common-utils.c | 71 | ||||
| -rw-r--r-- | libglusterfs/src/common-utils.h | 1 | 
2 files changed, 72 insertions, 0 deletions
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c index 22f13861451..75b97722513 100644 --- a/libglusterfs/src/common-utils.c +++ b/libglusterfs/src/common-utils.c @@ -2337,3 +2337,74 @@ gf_ports_reserved (char *blocked_port, gf_boolean_t *ports)  out:          return result;  } + +/* Takes in client ip{v4,v6} and returns associated hostname, if any + * Also, allocates memory for the hostname. + * Returns: 0 for success, -1 for failure + */ +int +gf_get_hostname_from_ip (char *client_ip, char **hostname) +{ +        int                      ret                          = -1; +        struct sockaddr         *client_sockaddr              = NULL; +        struct sockaddr_in       client_sock_in               = {0}; +        struct sockaddr_in6      client_sock_in6              = {0}; +        char                     client_hostname[NI_MAXHOST]  = {0}; +        char                    *client_ip_copy               = NULL; +        char                    *tmp                          = NULL; +        char                    *ip                           = NULL; + +        /* if ipv4, reverse lookup the hostname to +         * allow FQDN based rpc authentication +         */ +        if (valid_ipv4_address (client_ip, strlen (client_ip), 0) == _gf_false) { +                /* most times, we get a.b.c.d:port form, so check that */ +                client_ip_copy = gf_strdup (client_ip); +                if (!client_ip_copy) +                        goto out; + +                ip = strtok_r (client_ip_copy, ":", &tmp); +        } else { +                ip = client_ip; +        } + +        if (valid_ipv4_address (ip, strlen (ip), 0) == _gf_true) { +                client_sockaddr = (struct sockaddr *)&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; + +                client_sock_in6.sin6_family = AF_INET6; +                ret = inet_pton (AF_INET6, ip, +                                 (void *)&client_sock_in6.sin6_addr); +        } else { +                goto out; +        } + +        if (ret != 1) { +                ret = -1; +                goto out; +        } + +        ret = getnameinfo (client_sockaddr, +                           sizeof (*client_sockaddr), +                           client_hostname, sizeof (client_hostname), +                           NULL, 0, 0); +        if (ret) { +                gf_log ("common-utils", GF_LOG_ERROR, +                        "Could not lookup hostname of %s : %s", +                        client_ip, gai_strerror (ret)); +                ret = -1; +                goto out; +        } + +        *hostname = gf_strdup ((char *)client_hostname); + out: +        if (client_ip_copy) +                GF_FREE (client_ip_copy); + +        return ret; +} diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h index b89a988c62c..bbafd1fb039 100644 --- a/libglusterfs/src/common-utils.h +++ b/libglusterfs/src/common-utils.h @@ -575,5 +575,6 @@ char *generate_glusterfs_ctx_id (void);  char *gf_get_reserved_ports();  int gf_process_reserved_ports (gf_boolean_t ports[]);  gf_boolean_t gf_ports_reserved (char *blocked_port, gf_boolean_t *ports); +int gf_get_hostname_from_ip (char *client_ip, char **hostname);  #endif /* _COMMON_UTILS_H */  | 
