You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
163 lines
6.8 KiB
163 lines
6.8 KiB
From 305dad8388ea27b4d1bf1202e90ad6947ae0ab26 Mon Sep 17 00:00:00 2001 |
|
From: Pavan Balaji <balaji@anl.gov> |
|
Date: Thu, 21 Jan 2016 17:01:42 -0600 |
|
Subject: [PATCH] hydra: improve localhost detection. |
|
|
|
Be more forgiving for systems that do not resolve "localhost" or |
|
equivalent names very well (e.g., they are not added to /etc/hosts). |
|
Try them out, and if nothing works, fallback to "is not local" mode. |
|
|
|
Thanks to Orion Poplawski <orion@cora.nwra.com> for the suggestion. |
|
--- |
|
src/pm/hydra/utils/sock/sock.c | 89 +++++++++++++++++++++++------------------- |
|
1 file changed, 48 insertions(+), 41 deletions(-) |
|
|
|
diff --git a/src/pm/hydra/utils/sock/sock.c b/src/pm/hydra/utils/sock/sock.c |
|
index 86b25077aac2..dc56c767f544 100644 |
|
--- a/src/pm/hydra/utils/sock/sock.c |
|
+++ b/src/pm/hydra/utils/sock/sock.c |
|
@@ -492,7 +492,7 @@ HYD_status HYDU_sock_get_iface_ip(char *iface, char **ip) |
|
HYD_status HYDU_sock_is_local(char *host, int *is_local) |
|
{ |
|
struct hostent *ht; |
|
- char *host_ip = NULL, *local_ip = NULL, *lhost_ip = NULL; |
|
+ char *host_ip = NULL, *lhost_ip = NULL; |
|
char lhost[MAX_HOSTNAME_LEN]; |
|
struct sockaddr_in sa; |
|
struct ifaddrs *ifaddr, *ifa; |
|
@@ -516,54 +516,63 @@ HYD_status HYDU_sock_is_local(char *host, int *is_local) |
|
|
|
/* STEP 1: If "host" matches the local host name, return */ |
|
if (gethostname(lhost, MAX_HOSTNAME_LEN) < 0) { |
|
- HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "gethostname returned an error\n"); |
|
+ /* We can't figure out what my localhost name is. *sigh*. We |
|
+ * could return an error here, but we will just punt it to the |
|
+ * upper layer saying that we don't know if it is local. We |
|
+ * cannot try steps 2 and 3 either, since we don't have our |
|
+ * local hostname. */ |
|
+ goto fn_exit; |
|
} |
|
else if (!strcmp(lhost, host)) { |
|
*is_local = 1; |
|
goto fn_exit; |
|
} |
|
+ else { |
|
+ /* we have our local hostname, but that does not match the |
|
+ * provided hostname. Let's try to get our remote IP address |
|
+ * first. If we can't get that, we can give up. */ |
|
+ /* If we are unable to resolve the remote host name, it need |
|
+ * not be an error. It could mean that the user is using an |
|
+ * alias for the hostname (e.g., an ssh config alias) */ |
|
+ if ((ht = gethostbyname(host)) == NULL) |
|
+ goto fn_exit; |
|
|
|
+ memset((char *) &sa, 0, sizeof(struct sockaddr_in)); |
|
+ memcpy(&sa.sin_addr, ht->h_addr_list[0], ht->h_length); |
|
|
|
- /* STEP 2: If the IP address associated with "host" and the IP address local |
|
- * host resolves to match, return */ |
|
- |
|
- if ((ht = gethostbyname(lhost)) == NULL) { |
|
- HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "gethostbyname error on %s: %s\n", |
|
- lhost, hstrerror(h_errno)); |
|
+ /* Find the IP address of the host */ |
|
+ host_ip = HYDU_strdup((char *) inet_ntop(AF_INET, (const void *) &sa.sin_addr, buf, |
|
+ MAX_HOSTNAME_LEN)); |
|
+ HYDU_ASSERT(host_ip, status); |
|
} |
|
|
|
- memset((char *) &sa, 0, sizeof(struct sockaddr_in)); |
|
- memcpy(&sa.sin_addr, ht->h_addr_list[0], ht->h_length); |
|
- |
|
- /* Find the IP address of the host */ |
|
- lhost_ip = HYDU_strdup((char *) inet_ntop(AF_INET, (const void *) &sa.sin_addr, buf, |
|
- MAX_HOSTNAME_LEN)); |
|
- HYDU_ASSERT(lhost_ip, status); |
|
+ /* OK, if we are here, we got the remote IP. We have two ways of |
|
+ * getting the local IP: gethostbyname or getifaddrs. We'll try |
|
+ * both. */ |
|
|
|
- /* If we are unable to resolve the remote host name, it need not be an |
|
- * error. It could mean that the user is using an alias for the hostname |
|
- * (e.g., an ssh config alias) */ |
|
- if ((ht = gethostbyname(host)) == NULL) |
|
- goto fn_exit; |
|
+ /* STEP 2: Let's try the gethostbyname model */ |
|
|
|
- memset((char *) &sa, 0, sizeof(struct sockaddr_in)); |
|
- memcpy(&sa.sin_addr, ht->h_addr_list[0], ht->h_length); |
|
+ if ((ht = gethostbyname(lhost))) { |
|
+ memset((char *) &sa, 0, sizeof(struct sockaddr_in)); |
|
+ memcpy(&sa.sin_addr, ht->h_addr_list[0], ht->h_length); |
|
|
|
- /* Find the IP address of the host */ |
|
- host_ip = HYDU_strdup((char *) inet_ntop(AF_INET, (const void *) &sa.sin_addr, buf, |
|
- MAX_HOSTNAME_LEN)); |
|
- HYDU_ASSERT(host_ip, status); |
|
+ /* Find the IP address of the host */ |
|
+ lhost_ip = HYDU_strdup((char *) inet_ntop(AF_INET, (const void *) &sa.sin_addr, buf, |
|
+ MAX_HOSTNAME_LEN)); |
|
+ HYDU_ASSERT(lhost_ip, status); |
|
|
|
- /* See if the IP address of the hostname we got matches the IP address |
|
- * to which the local host resolves */ |
|
- if (!strcmp(lhost_ip, host_ip)) { |
|
- *is_local = 1; |
|
- goto fn_exit; |
|
+ /* See if the IP address of the hostname we got matches the IP |
|
+ * address to which the local host resolves */ |
|
+ if (!strcmp(lhost_ip, host_ip)) { |
|
+ *is_local = 1; |
|
+ goto fn_exit; |
|
+ } |
|
} |
|
|
|
+ /* Either gethostbyname didn't resolve or we didn't find a match. |
|
+ * Either way, let's try the getifaddr model. */ |
|
|
|
- /* STEP 3: Find all local IP addresses and try to match the host IP |
|
- * with it. */ |
|
+ /* STEP 3: Let's try the getifaddr model */ |
|
|
|
if (getifaddrs(&ifaddr) == -1) |
|
HYDU_ERR_SETANDJUMP(status, HYD_INTERNAL_ERROR, "getifaddrs failed\n"); |
|
@@ -573,21 +582,21 @@ HYD_status HYDU_sock_is_local(char *host, int *is_local) |
|
if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET) { |
|
struct sockaddr_in *sa_ptr = (struct sockaddr_in *) ifa->ifa_addr; |
|
|
|
- local_ip = HYDU_strdup((char *) |
|
+ lhost_ip = HYDU_strdup((char *) |
|
inet_ntop(AF_INET, (const void *) &(sa_ptr->sin_addr), buf, |
|
MAX_HOSTNAME_LEN)); |
|
- HYDU_ASSERT(local_ip, status); |
|
+ HYDU_ASSERT(lhost_ip, status); |
|
|
|
- /* STEP 3: For each local IP address, see if it matches the "host" |
|
+ /* For each local IP address, see if it matches the "host" |
|
* IP address */ |
|
- if (!strcmp(host_ip, local_ip)) { |
|
+ if (!strcmp(host_ip, lhost_ip)) { |
|
*is_local = 1; |
|
freeifaddrs(ifaddr); |
|
goto fn_exit; |
|
} |
|
|
|
- HYDU_FREE(local_ip); |
|
- local_ip = NULL; |
|
+ HYDU_FREE(lhost_ip); |
|
+ lhost_ip = NULL; |
|
} |
|
} |
|
|
|
@@ -596,8 +605,6 @@ HYD_status HYDU_sock_is_local(char *host, int *is_local) |
|
fn_exit: |
|
if (host_ip) |
|
HYDU_FREE(host_ip); |
|
- if (local_ip) |
|
- HYDU_FREE(local_ip); |
|
if (lhost_ip) |
|
HYDU_FREE(lhost_ip); |
|
return status; |
|
-- |
|
1.9.1 |
|
|
|
|