Networking

NAVIGATION
CATEGORIES
REFERRENCE
LINKS
Home » Development Group »» Networking
  • possible change to spamd_address behaviour

    0 answers - 5046 bytes - related search similar search Add To My Delicious Add To My Stumble Upon Add To My Google Mark Add To My Facebook Add To My Digg

    Hi,
    In the interests of load-balancing and redundancy, we found it would be
    helpful if there was more control over how the list of spamd servers in
    spamd_addresses is used. The attached patch adds an MX-style priority as
    an optional third argument to each ip/port combination, so that it is
    possible to offload spam checking to a server or group of servers. and
    fall back onto another server should none of these be contactable.
    The general idea is that as spam processing becomes a greater drain on
    system resources, it becomes practical to offload this burden onto a
    dedicated machine (which can then become a cluster of machines once the
    load becomes too high). This leaves the MX server free to concentrate on
    mail delivery and processing ACL checks. However in the event of a
    failure of the offload server, it would be useful to be able to fall
    back onto a backup running elsewhere, for example on localhost.
    This patch preserves the usual spamd_address behaviour at each level of
    priority; the default priority for a server is 10 and a random(ish)
    server will be chosen to begin with, then the list cycles in order.
    I have tested it a little to ensure the functionality is correct, and
    would be interested in any feedback and comments on the idea. The patch
    is against the 4.63 source tree.
    Cheers,
    diff -ur exim-4.63/src/spam.c exim-4.63-spam-mx/src/spam.c
    exim-4.63/src/spam.cMon Jul 31 15:19:48 2006
    exim-4.63-spam-mx/src/spam.cTue Aug 22 16:46:08 2006
    @@ -20,6 +20,18 @@
    uschar prev_user_name[128] = "";
    int spam_ok = 0;
    int spam_rc = 0;
    +int rand_server = 0;
    +int num_servers = 0;
    +
    +int sort_by_prio(const void *ia, const void *ib) {
    + spamd_address_container * const *a = ia;
    + const spamd_address_container * const *b = ib;
    + if ((*a)->priority - (*b)->priority)
    + return (*a)->priority - (*b)->priority;
    + /* pseudo-randomisation of equal priorities
    + * will only change once per second, as before */
    + return ((*a)->pos + rand_server)%num_servers - ((*b)->pos + rand_server)%num_servers;
    +}
    int spam(uschar **listptr) {
    int sep = 0;
    @@ -92,14 +104,14 @@
    /* socket does not start with '/' -network socket */
    if (*spamd_address != '/') {
    time_t now = time(NULL);
    - int num_servers = 0;
    int current_server = 0;
    - int start_server = 0;
    uschar *address = NULL;
    uschar *spamd_address_list_ptr = spamd_address;
    uschar address_buffer[256];
    spamd_address_container * spamd_address_vector[32];
    + num_servers = 0;
    +
    /* Check how many spamd servers we have
    and register their addresses */
    while ((address = string_nextinlist(&spamd_address_list_ptr, &sep,
    @@ -108,9 +120,17 @@
    spamd_address_container *this_spamd =
    (spamd_address_container *)store_get(sizeof(spamd_address_container));
    +
    + /* set a default spamd priority of 10 */
    + this_spamd->priority = 10;
    + /* store current server number for randomisation purposes */
    + this_spamd->pos = num_servers;
    /* grok spamd address and port */
    - if( sscanf(CS address, "%s %u", this_spamd->tcp_addr, &(this_spamd->tcp_port)) != 2 ) {
    + if( sscanf(CS address, "%s %u %i",
    + this_spamd->tcp_addr,
    + &(this_spamd->tcp_port),
    + &(this_spamd->priority)) < 2 ) {
    log_write(0, LG_MAIN,
    "spam acl condition: warning - invalid spamd address: '%s'", address);
    continue;
    @@ -130,13 +150,15 @@
    return DEFER;
    };
    - current_server = start_server = (int)now % num_servers;
    + rand_server = (int)now % num_servers;
    + qsort(spamd_address_vector, num_servers, sizeof(*spamd_address_vector), sort_by_prio);
    while (1) {
    - debug_printf("trying server %s, port %u\n",
    + debug_printf("trying server %s, port %u, priority %d\n",
    spamd_address_vector[current_server]->tcp_addr,
    - spamd_address_vector[current_server]->tcp_port);
    + spamd_address_vector[current_server]->tcp_port,
    + spamd_address_vector[current_server]->priority);
    /* contact a spamd */
    if ( (spamd_sock = ip_socket(SCK_STREAM, AF_INET)) < 0) {
    @@ -161,9 +183,7 @@
    spamd_address_vector[current_server]->tcp_port,
    strerror(errno));
    current_server++;
    - if (current_server >= num_servers)
    - current_server = 0;
    - if (current_server == start_server) {
    + if (current_server == num_servers) {
    log_write(0, LG_MAIN|LG_PANIC, "spam acl condition: all spamd servers failed");
    (void)fclose(mbox_file);
    (void)close(spamd_sock);
    diff -ur exim-4.63/src/spam.h exim-4.63-spam-mx/src/spam.h
    exim-4.63/src/spam.hMon Jul 31 15:19:48 2006
    exim-4.63-spam-mx/src/spam.hTue Aug 22 13:35:20 2006
    @@ -25,6 +25,8 @@
    typedef struct spamd_address_container {
    uschar tcp_addr[24];
    unsigned int tcp_port;
    + int priority;
    + int pos;
    } spamd_address_container;
    #endif

Re: possible change to spamd_address behaviour


max 4000 letters.
Your nickname that display:
In order to stop the spam: 3 + 3 =
SPONSORED
QUESTION

SPONSORED
EMSDN