Blame SOURCES/0001-hydra-improve-localhost-detection.patch

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