[exim-cvs] Support hostnames and IPv6 addresses for spamd_ad…

Etusivu
Poista viesti
Vastaa
Lähettäjä: Exim Git Commits Mailing List
Päiväys:  
Vastaanottaja: exim-cvs
Aihe: [exim-cvs] Support hostnames and IPv6 addresses for spamd_address. Bug 1259
Gitweb: http://git.exim.org/exim.git/commitdiff/2aad5761b59a709d98a7d278d83e978ac4e83c2b
Commit:     2aad5761b59a709d98a7d278d83e978ac4e83c2b
Parent:     3e60dd410992e3b732d5633e25d3cbf76d8b1e2d
Author:     Jeremy Harris <jgh146exb@???>
AuthorDate: Wed Jan 28 00:16:56 2015 +0000
Committer:  Jeremy Harris <jgh146exb@???>
CommitDate: Wed Jan 28 00:22:36 2015 +0000


    Support hostnames and IPv6 addresses for spamd_address.  Bug 1259
---
 doc/doc-docbook/spec.xfpt |    6 +++
 doc/doc-txt/ChangeLog     |    3 +-
 src/src/spam.c            |   99 +++++++++++----------------------------------
 src/src/spam.h            |    3 +-
 4 files changed, 33 insertions(+), 78 deletions(-)


diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index e34ed80..cb3d78d 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -30778,6 +30778,12 @@ condition defers.
 Unix and TCP socket specifications may be mixed in any order.
 Each element of the list is a list itself, space-separated by default
 and changeable in the usual way.
+
+For TCP socket specifications a host name or IP (v4 or v6, but
+subject to list-separator quoting rules) address can be used,
+and the port can be one or a dash-separated pair.
+In the latter case, the range is tried in strict order.
+
 Elements after the first for Unix sockets, or second for TCP socket,
 are options.
 The supported option are:
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index e06ac60..fbfe750 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -58,7 +58,8 @@ JH/15 Bug 670: The spamd_address main option (for the spam= ACL condition)
       modifiers per server.  Patch originally by <rommer@???>.


 JH/16 The spamd_address main option now supports a mixed list of local
-      and remote servers.
+      and remote servers.  Remote servers can be IPv6 addresses, and
+      specify a port-range.




diff --git a/src/src/spam.c b/src/src/spam.c
index 89be98a..76db2b6 100644
--- a/src/src/spam.c
+++ b/src/src/spam.c
@@ -263,8 +263,7 @@ start = time(NULL);
uschar *address;
uschar *spamd_address_list_ptr = spamd_address_work;
spamd_address_container * spamd_address_vector[32];
- spamd_address_container * this_spamd;
-
+ spamd_address_container * sd;

   /* Check how many spamd servers we have
      and register their addresses */
@@ -277,10 +276,9 @@ start = time(NULL);
     uschar * s;


     HDEBUG(D_acl) debug_printf("spamd: addr entry '%s'\n", address);
-    this_spamd =
-      (spamd_address_container *)store_get(sizeof(spamd_address_container));
+    sd = (spamd_address_container *)store_get(sizeof(spamd_address_container));


-    for (sublist = address, args = 0, spamd_param_init(this_spamd);
+    for (sublist = address, args = 0, spamd_param_init(sd);
      s = string_nextinlist(&sublist, &sublist_sep, NULL, 0);
      args++
      )
@@ -288,11 +286,13 @@ start = time(NULL);
     HDEBUG(D_acl) debug_printf("spamd: addr parm '%s'\n", s);
     switch (args)
     {
-    case 0:   this_spamd->hostname = s;
+    case 0:   sd->hostspec = s;
           if (*s == '/') args++;    /* local; no port */
           break;
-    case 1:   this_spamd->tcp_port = atoi(s); break;
-    default:  spamd_param(s, this_spamd);     break;
+    case 1:   sd->hostspec = string_sprintf("%s %s", sd->hostspec, s);
+          break;
+    default:  spamd_param(s, sd);
+          break;
     }
       }
     if (args < 2)
@@ -302,7 +302,7 @@ start = time(NULL);
       continue;
       }


-    spamd_address_vector[num_servers] = this_spamd;
+    spamd_address_vector[num_servers] = sd;
     if (++num_servers > 31)
       break;
     }
@@ -318,82 +318,29 @@ start = time(NULL);


   while (1)
     {
-    struct hostent *he;
-    int i;
-    BOOL is_local;
+    uschar * errstr;


     current_server = spamd_get_server(spamd_address_vector, num_servers);
-    this_spamd = spamd_address_vector[current_server];
-
-    is_local = *this_spamd->hostname == '/';
+    sd = spamd_address_vector[current_server];


-    debug_printf(is_local
-         ? "trying server %s\n" : "trying server %s, port %u\n",
-         this_spamd->hostname, this_spamd->tcp_port);
+    debug_printf("trying server %s\n", sd->hostspec);


     /* contact a spamd */
-    if (is_local)
-      {
-      if ((spamd_sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
-    {
-    log_write(0, LOG_MAIN|LOG_PANIC,
-          "%s spamd: unable to acquire socket (%s)",
-          loglabel,
-          strerror(errno));
-    goto defer;
-    }
-
-      server.sun_family = AF_UNIX;
-      Ustrcpy(server.sun_path, this_spamd->hostname);
+    if ((spamd_sock = ip_streamsocket(sd->hostspec, &errstr, 5)) >= 0)
+      break;


-      if (connect(spamd_sock, (struct sockaddr *) &server, sizeof(struct sockaddr_un)) >= 0)
-    break;                    /* connection OK */
+    log_write(0, LOG_MAIN, "%s spamd: %s", loglabel, errstr);
+    sd->is_failed = TRUE;


-      log_write(0, LOG_MAIN,
-        "%s spamd: unable to connect to UNIX socket %s (%s)",
-        loglabel, server.sun_path, strerror(errno) );
-      }
-    else
+    current_server = spamd_get_server(spamd_address_vector, num_servers);
+    if (current_server < 0)
       {
-      if ((spamd_sock = ip_socket(SOCK_STREAM, AF_INET)) < 0)
-    {
-    log_write(0, LOG_MAIN|LOG_PANIC,
-       "%s error creating IP socket for spamd", loglabel);
-    goto defer;
-    }
-
-      /*XXX should we use getaddrinfo? */
-      if (!(he = gethostbyname(CS this_spamd->hostname)))
-    log_write(0, LOG_MAIN|LOG_PANIC,
-      "%s failed to lookup host '%s'", loglabel, this_spamd->hostname);
-
-      else
-    {
-    struct in_addr in = *(struct in_addr *) he->h_addr_list[0];
-
-    if (ip_connect(spamd_sock, AF_INET, US inet_ntoa(in),
-               this_spamd->tcp_port, 5) > -1)
-      break;                /* connection OK */
-
-    log_write(0, LOG_MAIN,
-       "%s warning - spamd connection to '%s', port %u failed: %s",
-       loglabel,
-       this_spamd->hostname, this_spamd->tcp_port, strerror(errno));
-    }
-
-      (void)close(spamd_sock);
-
-      this_spamd->is_failed = TRUE;
-      current_server = spamd_get_server(spamd_address_vector, num_servers);
-      if (current_server < 0)
-    {
-    log_write(0, LOG_MAIN|LOG_PANIC, "%s all spamd servers failed",
-      loglabel);
-    goto defer;
-    }
+      log_write(0, LOG_MAIN|LOG_PANIC, "%s all spamd servers failed",
+    loglabel);
+      goto defer;
       }
     }
-    is_rspamd = this_spamd->is_rspamd;
+    is_rspamd = sd->is_rspamd;
   }


if (spamd_sock == -1)
@@ -672,3 +619,5 @@ defer:
}

#endif
+/* vi: aw ai sw=2
+*/
diff --git a/src/src/spam.h b/src/src/spam.h
index 50aed91..7ab6d2a 100644
--- a/src/src/spam.h
+++ b/src/src/spam.h
@@ -25,8 +25,7 @@

typedef struct spamd_address_container
{
- uschar * hostname;
- unsigned short tcp_port;
+ uschar * hostspec;
int is_rspamd:1;
int is_failed:1;
int is_backup:1;