]> Pileus Git - ~andy/fetchmail/commitdiff
Multihome handling.
authorEric S. Raymond <esr@thyrsus.com>
Sat, 2 Oct 1999 11:50:01 +0000 (11:50 -0000)
committerEric S. Raymond <esr@thyrsus.com>
Sat, 2 Oct 1999 11:50:01 +0000 (11:50 -0000)
svn path=/trunk/; revision=2629

NEWS
socket.c

diff --git a/NEWS b/NEWS
index f371982a1839ad79f5235257b0367e71cb05cb13..efe07e0f7b5a0e7f15a7ff6ac29bd2f65eccdc1e 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,8 @@
 
 (The `lines' figures total .c, .h, .l, and .y files under version control.)
 
+* Joe Loughry <loughry@uswest.net> sent a patch to handle multihomed machines.
+
 fetchmail-5.1.0 (Wed Sep 29 11:52:06 EDT 1999), 17827 lines:
 * Added workaround, fetchmailconf warning, and FAQ about Novell GroupWise.
 * Consistently show dummy arguments on manual page.
index c852e641e42e0be80d4fa96ae6aebc1da5be667a..c09257234215d09ad69d2e5b3969791c502127b3 100644 (file)
--- a/socket.c
+++ b/socket.c
@@ -152,7 +152,7 @@ int SockOpen(const char *host, int clientPort, const char *options,
 #ifndef HAVE_INET_ATON
     unsigned long inaddr;
 #endif /* HAVE_INET_ATON */
-    struct sockaddr_in ad;
+    struct sockaddr_in ad, **pptr;
     struct hostent *hp;
 
 #ifdef HAVE_SOCKETPAIR
@@ -195,30 +195,35 @@ int SockOpen(const char *host, int clientPort, const char *options,
            return -1;
        }
        /*
-        * FIXME: make this work for multihomed hosts.
-        * We're toast if we get back multiple addresses and h_addrs[0]
-        * (aka h_addr) is not one we can actually connect to; this happens
-        * with multi-homed boxen.
+        * Try all addresses of a possibly multihomed host until we get
+        * a successful connect or until we run out of addresses.
         */
-        memcpy(&ad.sin_addr, hp->h_addr, hp->h_length);
-    }
-    ad.sin_port = htons(clientPort);
-    
-    sock = socket(AF_INET, SOCK_STREAM, 0);
-    if (sock < 0)
-    {
-       h_errno = 0;
-        return -1;
-    }
-    if (connect(sock, (struct sockaddr *) &ad, sizeof(ad)) < 0)
-    {
-       int olderr = errno;
-       close(sock);
-       h_errno = 0;
-       errno = olderr;
-        return -1;
+       pptr = (struct sockaddr_in **)hp->h_addr_list;
+       for(; *pptr != NULL; pptr++)
+       {
+           sock = socket(AF_INET, SOCK_STREAM, 0);
+           if (sock < 0)
+           {
+               h_errno = 0;
+               return -1;
+           }
+           ad.sin_port = htons(clientPort);
+           memcpy(&ad.sin_addr, *pptr, sizeof(struct in_addr));
+           if (connect(sock, (struct sockaddr *) &ad, sizeof(ad)) == 0)
+               break; /* success */
+           close(sock);
+           memset(&ad, 0, sizeof(ad));
+           ad.sin_family = AF_INET;
+       }
+       if(*pptr == NULL)
+       {
+           int olderr = errno;
+           close(sock);
+           h_errno = 0;
+           errno = olderr;
+           return -1;
+       }
     }
-
     return(sock);
 }
 #endif /* INET6 */