spamassassin-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mmarti...@apache.org
Subject svn commit: r1392699 - in /spamassassin/trunk/spamc: libspamc.c libspamc.h spamc.c
Date Tue, 02 Oct 2012 00:19:47 GMT
Author: mmartinec
Date: Tue Oct  2 00:19:47 2012
New Revision: 1392699

URL: http://svn.apache.org/viewvc?rev=1392699&view=rev
Log:
Bug 6842 - Spamc should have an option to only try v4 addresses when hostnames are specified
with -d ... implemented options -4 and -6 to spamc

Modified:
    spamassassin/trunk/spamc/libspamc.c
    spamassassin/trunk/spamc/libspamc.h
    spamassassin/trunk/spamc/spamc.c

Modified: spamassassin/trunk/spamc/libspamc.c
URL: http://svn.apache.org/viewvc/spamassassin/trunk/spamc/libspamc.c?rev=1392699&r1=1392698&r2=1392699&view=diff
==============================================================================
--- spamassassin/trunk/spamc/libspamc.c (original)
+++ spamassassin/trunk/spamc/libspamc.c Tue Oct  2 00:19:47 2012
@@ -200,10 +200,11 @@ static int _translate_connect_errno(int 
 /*
  * opensocket()
  *
- *	Given a socket type (PF_INET or PF_UNIX), try to create this socket
- *	and store the FD in the pointed-to place. If it's successful, do any
- *	other setup required to make the socket ready to use, such as setting
- *	TCP_NODELAY mode, and in any case we return EX_OK if all is well.
+ *	Given a socket family (PF_INET or PF_INET6 or PF_UNIX), try to
+ *	create this socket and store the FD in the pointed-to place.
+ *	If it's successful, do any other setup required to make the socket
+ *	ready to use, such as setting TCP_NODELAY mode, and in any case
+ *      we return EX_OK if all is well.
  *
  *	Upon failure we return one of the other EX_??? error codes.
  */
@@ -332,8 +333,11 @@ static int _opensocket(int flags, int ty
     {
 	int one = 1;
 
-	if (type == PF_INET
-	    && setsockopt(*psock, 0, TCP_NODELAY, &one, sizeof one) != 0) {
+	if ( (   type == PF_INET
+#ifdef PF_INET6
+              || type == PF_INET6
+#endif
+             ) && setsockopt(*psock, 0, TCP_NODELAY, &one, sizeof one) != 0)
{
 	    origerr = spamc_get_errno();
 	    switch (origerr) {
 	    case EBADF:
@@ -472,6 +476,7 @@ static int _try_to_connect_tcp(const str
     for (numloops = 0; numloops < connect_retries; numloops++) {
         const int hostix = numloops % tp->nhosts;
         int status, mysock;
+        int innocent = 0;
 
                 /*--------------------------------------------------------
                 * We always start by creating the socket, as we get only
@@ -521,6 +526,7 @@ static int _try_to_connect_tcp(const str
             }
             else {
               status = timeout_connect(mysock, res->ai_addr, res->ai_addrlen);
+              if (status != 0) origerr = spamc_get_errno();
             }
 
 #else
@@ -558,23 +564,24 @@ static int _try_to_connect_tcp(const str
             else {
               status = timeout_connect(mysock, (struct sockaddr *) &addrbuf,
                         sizeof(addrbuf));
+              if (status != 0) origerr = spamc_get_errno();
             }
 
 #endif
 
             if (status != 0) {
-                  origerr = spamc_get_errno();
                   closesocket(mysock);
 
-#ifndef _WIN32
-                  libspamc_log(tp->flags, LOG_ERR,
+                  innocent = origerr == ECONNREFUSED && numloops+1 < tp->nhosts;
+                  libspamc_log(tp->flags, innocent ? LOG_DEBUG : LOG_ERR,
                       "connect to spamd on %s failed, retrying (#%d of %d): %s",
-                      host, numloops+1, connect_retries, strerror(origerr));
+                      host, numloops+1, connect_retries,
+#ifdef _WIN32
+                      origerr
 #else
-                  libspamc_log(tp->flags, LOG_ERR,
-                      "connect to spamd on %s failed, retrying (#%d of %d): %d",
-                      host, numloops+1, connect_retries, origerr);
+                      strerror(origerr)
 #endif
+                  );
 
             } else {
 #ifdef DO_CONNECT_DEBUG_SYSLOGS
@@ -589,7 +596,7 @@ static int _try_to_connect_tcp(const str
             res = res->ai_next;
         }
 #endif
-        sleep(retry_sleep);
+        if (numloops+1 < connect_retries && !innocent) sleep(retry_sleep);
     } /* for(numloops...) */
 
     libspamc_log(tp->flags, LOG_ERR,
@@ -1933,8 +1940,17 @@ int transport_setup(struct transport *tp
 
     memset(&hints, 0, sizeof(hints));
     hints.ai_flags = 0;
-    hints.ai_family = PF_UNSPEC;
     hints.ai_socktype = SOCK_STREAM;
+
+    if (       (flags & SPAMC_USE_INET4) && !(flags & SPAMC_USE_INET6)) {
+      hints.ai_family = PF_INET;
+#ifdef PF_INET6
+    } else if ((flags & SPAMC_USE_INET6) && !(flags & SPAMC_USE_INET4)) {
+      hints.ai_family = PF_INET6;
+#endif
+    } else {
+      hints.ai_family = PF_UNSPEC;
+    }
 #endif
 
     switch (tp->type) {
@@ -1946,12 +1962,12 @@ int transport_setup(struct transport *tp
     case TRANSPORT_LOCALHOST:
 #ifdef SPAMC_HAS_ADDRINFO
         /* getaddrinfo(NULL) will look up the loopback address.
-         * bug 5057: unfortunately, it's the IPv6 loopback address on
-         * linux!  Be explicit, and force IPv4 using "127.0.0.1".
+         * See also bug 5057,  ::1 will be tried before 127.0.0.1
+         * unless overridden (through hints) by a command line option -4
          */
-        if ((origerr = getaddrinfo("127.0.0.1", port, &hints, &res)) != 0) {
+        if ((origerr = getaddrinfo(NULL, port, &hints, &res)) != 0) {
             libspamc_log(flags, LOG_ERR, 
-                  "getaddrinfo(127.0.0.1) failed: %s",
+                  "getaddrinfo for a loopback address failed: %s",
                   gai_strerror(origerr));
             return EX_OSERR;
         }
@@ -2073,12 +2089,20 @@ int transport_setup(struct transport *tp
                      TRANSPORT_MAX_HOSTS);
                break;
             }
-            for (addrp = res; addrp != NULL; ) {
-                tp->hosts[tp->nhosts] = addrp;
-                addrp = addrp->ai_next;     /* before NULLing ai_next */
-                tp->hosts[tp->nhosts]->ai_next = NULL;
-                tp->nhosts++;
-            }
+
+            /* treat all A or AAAA records of each host as one entry */
+            tp->hosts[tp->nhosts++] = res;
+
+            /* alternatively, treat multiple A or AAAA records
+               of one host as individual entries */
+/*          for (addrp = res; addrp != NULL; ) {
+ *              tp->hosts[tp->nhosts] = addrp;
+ *              addrp = addrp->ai_next;     /-* before NULLing ai_next *-/
+ *              tp->hosts[tp->nhosts]->ai_next = NULL;
+ *              tp->nhosts++;
+ *          }
+ */
+
 #else
             for (addrp = hp->h_addr_list; *addrp; addrp++) {
                 if (tp->nhosts == TRANSPORT_MAX_HOSTS) {

Modified: spamassassin/trunk/spamc/libspamc.h
URL: http://svn.apache.org/viewvc/spamassassin/trunk/spamc/libspamc.h?rev=1392699&r1=1392698&r2=1392699&view=diff
==============================================================================
--- spamassassin/trunk/spamc/libspamc.h (original)
+++ spamassassin/trunk/spamc/libspamc.h Tue Oct  2 00:19:47 2012
@@ -90,9 +90,12 @@
 #define SPAMC_RAW_MODE       0
 #define SPAMC_BSMTP_MODE     1
 
-#define SPAMC_USE_SSL	      (1<<27)
-#define SPAMC_SAFE_FALLBACK   (1<<28)
+#define SPAMC_USE_INET6       (1<<31)
+#define SPAMC_USE_INET4       (1<<30)
+
 #define SPAMC_CHECK_ONLY      (1<<29)
+#define SPAMC_SAFE_FALLBACK   (1<<28)
+#define SPAMC_USE_SSL         (1<<27)
 
 /* Jan 30, 2003 ym: added reporting options */
 #define SPAMC_REPORT          (1<<26)

Modified: spamassassin/trunk/spamc/spamc.c
URL: http://svn.apache.org/viewvc/spamassassin/trunk/spamc/spamc.c?rev=1392699&r1=1392698&r2=1392699&view=diff
==============================================================================
--- spamassassin/trunk/spamc/spamc.c (original)
+++ spamassassin/trunk/spamc/spamc.c Tue Oct  2 00:19:47 2012
@@ -210,6 +210,8 @@ print_usage(void)
     usg("  -z                  Compress mail message sent to spamd.\n");
 #endif
     usg("  -f                  (Now default, ignored.)\n");
+    usg("  -4                  Use IPv4 only for connecting to server.\n");
+    usg("  -6                  Use IPv6 only for connecting to server.\n");
 
     usg("\n");
 }
@@ -227,9 +229,9 @@ read_args(int argc, char **argv,
           struct transport *ptrn)
 {
 #ifndef _WIN32
-    const char *opts = "-BcrRd:e:fyp:n:t:s:u:L:C:xzSHU:ElhVKF:0:1:2";
+    const char *opts = "-BcrR46d:e:fyp:n:t:s:u:L:C:xzSHU:ElhVKF:0:1:2";
 #else
-    const char *opts = "-BcrRd:fyp:n:t:s:u:L:C:xzSHElhVKF:0:1:2";
+    const char *opts = "-BcrR46d:fyp:n:t:s:u:L:C:xzSHElhVKF:0:1:2";
 #endif
     int opt;
     int ret = EX_OK;
@@ -471,6 +473,18 @@ read_args(int argc, char **argv,
 #endif
                 break;
             }
+            case '4':
+            {
+                flags |=  SPAMC_USE_INET4;
+                flags &= ~SPAMC_USE_INET6;
+                break;
+            }
+            case '6':
+            {
+                flags |=  SPAMC_USE_INET6;
+                flags &= ~SPAMC_USE_INET4;
+                break;
+            }
             case 0:
             {
                 ptrn->connect_retries = atoi(spamc_optarg);
@@ -505,6 +519,12 @@ read_args(int argc, char **argv,
         ret = EX_USAGE;
     }
 
+    if ( !(flags & (SPAMC_USE_INET4 | SPAMC_USE_INET6)) ) {
+      /* allow any protocol family (INET or INET6) by default */
+      flags |= SPAMC_USE_INET4;
+      flags |= SPAMC_USE_INET6;
+    }
+
     /* learning action has to block some parameters */
     if (flags & SPAMC_LEARN) {
         if (flags & SPAMC_CHECK_ONLY) {



Mime
View raw message