]> source.dussan.org Git - rspamd.git/commitdiff
Rework DNS callback.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 18 Mar 2015 16:13:21 +0000 (16:13 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 18 Mar 2015 16:13:21 +0000 (16:13 +0000)
src/libserver/spf.c
src/libserver/spf.h

index 619f94fc40bd898c014fbe4925ef8f0fe361ae7d..163ebf5c2cae93a2edb26b7ff8014ad48e4f4687 100644 (file)
@@ -95,6 +95,7 @@ struct spf_record {
 struct spf_dns_cb {
        struct spf_record *rec;
        struct spf_addr *addr;
+       struct spf_resolved_element *resolved;
        gchar *ptr_host;
        spf_action_t cur_action;
        gboolean in_include;
@@ -190,95 +191,7 @@ rspamd_spf_new_addr_list (struct spf_record *rec, const gchar *domain)
 static void
 dump_spf_record (GList *addrs)
 {
-       struct spf_addr *addr;
-       GList *cur;
-       gint r = 0;
-       gchar logbuf[BUFSIZ], c;
-#ifdef HAVE_INET_PTON
-       gchar ipbuf[INET6_ADDRSTRLEN];
-#else
-       struct in_addr ina;
-#endif
-
-       cur = addrs;
-
-       while (cur) {
-               addr = cur->data;
-               if (!addr->is_list) {
-                       switch (addr->mech) {
-                       case SPF_FAIL:
-                               c = '-';
-                               break;
-                       case SPF_SOFT_FAIL:
-                       case SPF_NEUTRAL:
-                               c = '~';
-                               break;
-                       case SPF_PASS:
-                               c = '+';
-                               break;
-                       }
-#ifdef HAVE_INET_PTON
-                       if (addr->data.normal.ipv6) {
-                               inet_ntop (AF_INET6, &addr->data.normal.d.in6, ipbuf,
-                                       sizeof (ipbuf));
 
-                       }
-                       else {
-                               inet_ntop (AF_INET, &addr->data.normal.d.in4, ipbuf,
-                                       sizeof (ipbuf));
-                       }
-                       r += snprintf (logbuf + r,
-                                       sizeof (logbuf) - r,
-                                       "%c%s/%d; ",
-                                       c,
-                                       ipbuf,
-                                       addr->data.normal.mask);
-#else
-                       ina.s_addr = addr->data.normal.d.in4.s_addr;
-                       r += snprintf (logbuf + r,
-                                       sizeof (logbuf) - r,
-                                       "%c%s/%d; ",
-                                       c,
-                                       inet_ntoa (ina),
-                                       addr->data.normal.mask);
-#endif
-               }
-               else {
-                       r += snprintf (logbuf + r,
-                                       sizeof (logbuf) - r,
-                                       "%s; ",
-                                       addr->spf_string);
-                       dump_spf_record (addr->data.list);
-               }
-               cur = g_list_next (cur);
-       }
-       msg_info ("spf record: %s", logbuf);
-}
-
-/* Find position of address inside addrs list */
-static GList *
-spf_addr_find (GList *addrs, gpointer to_find)
-{
-       struct spf_addr *addr;
-       GList *cur, *res = NULL;
-
-       cur = addrs;
-       while (cur) {
-               addr = cur->data;
-               if (addr->is_list) {
-                       if ((res = spf_addr_find (addr->data.list, to_find)) != NULL) {
-                               return cur;
-                       }
-               }
-               else {
-                       if (cur->data == to_find) {
-                               return cur;
-                       }
-               }
-               cur = g_list_next (cur);
-       }
-
-       return res;
 }
 
 /*
@@ -312,11 +225,8 @@ parse_spf_ipmask (const gchar *begin,
        const gchar *pos;
        gchar mask_buf[5] = {'\0'}, *p;
        gint state = 0, dots = 0;
-#ifdef HAVE_INET_PTON
+       guint mask;
        gchar ip_buf[INET6_ADDRSTRLEN];
-#else
-       gchar ip_buf[INET_ADDRSTRLEN];
-#endif
 
        bzero (ip_buf,   sizeof (ip_buf));
        bzero (mask_buf, sizeof (mask_buf));
@@ -338,7 +248,6 @@ parse_spf_ipmask (const gchar *begin,
                        dots = 0;
                        break;
                case 1:
-#ifdef HAVE_INET_PTON
                        if (p - ip_buf >= (gint)sizeof (ip_buf)) {
                                return FALSE;
                        }
@@ -349,19 +258,6 @@ parse_spf_ipmask (const gchar *begin,
                                *p++ = *pos++;
                                dots++;
                        }
-#else
-                       /* Begin parse ip */
-                       if (p - ip_buf >= (gint)sizeof (ip_buf) || dots > 3) {
-                               return FALSE;
-                       }
-                       if (g_ascii_isdigit (*pos)) {
-                               *p++ = *pos++;
-                       }
-                       else if (*pos == '.') {
-                               *p++ = *pos++;
-                               dots++;
-                       }
-#endif
                        else if (*pos == '/') {
                                pos++;
                                p = mask_buf;
@@ -391,10 +287,9 @@ parse_spf_ipmask (const gchar *begin,
                }
        }
 
-#ifdef HAVE_INET_PTON
-       if (inet_pton (AF_INET, ip_buf, &addr->data.normal.d.in4) != 1) {
-               if (inet_pton (AF_INET6, ip_buf, &addr->data.normal.d.in6) == 1) {
-                       addr->data.normal.ipv6 = TRUE;
+       if (inet_pton (AF_INET, ip_buf, &addr->addr) != 1) {
+               if (inet_pton (AF_INET6, ip_buf, &addr->addr) == 1) {
+                       addr->flags |= RSPAMD_SPF_FLAG_IPV6;
                }
                else {
                        msg_info ("<%s>: spf error for domain %s: invalid ip address",
@@ -402,109 +297,34 @@ parse_spf_ipmask (const gchar *begin,
                        return FALSE;
                }
        }
-       else {
-               addr->data.normal.ipv6 = FALSE;
-       }
-#else
-       if (!inet_aton (ip_buf, &addr->data.normal.d.in4)) {
-               return FALSE;
-       }
-#endif
+
        if (state == 2) {
                /* Also parse mask */
-               if (!addr->data.normal.ipv6) {
-                       addr->data.normal.mask = strtoul (mask_buf, NULL, 10);
-                       if (addr->data.normal.mask > 32) {
-                               msg_info (
-                                       "<%s>: spf error for domain %s: bad ipmask value: '%s'",
-                                       rec->task->message_id,
-                                       rec->sender_domain,
-                                       begin);
-                               return FALSE;
-                       }
-               }
-               else {
-                       addr->data.normal.mask = strtoul (mask_buf, NULL, 10);
-                       if (addr->data.normal.mask > 128) {
-                               msg_info (
+               mask = strtoul (mask_buf, NULL, 10);
+               if (mask > (addr->flags & RSPAMD_SPF_FLAG_IPV6) ? 128 : 32) {
+                       msg_info (
                                        "<%s>: spf error for domain %s: bad ipmask value: '%s'",
                                        rec->task->message_id,
                                        rec->sender_domain,
                                        begin);
-                               return FALSE;
-                       }
+                       return FALSE;
                }
-       }
-       else {
-               addr->data.normal.mask = addr->data.normal.ipv6 ? 128 : 32;
-       }
-       addr->data.normal.parsed = TRUE;
-       return TRUE;
-
-}
 
-static void
-spf_record_process_addr (struct rdns_reply_entry *elt,
-       struct spf_dns_cb *cb, struct rspamd_task *task)
-{
-       struct spf_addr *addr = cb->addr, *new_addr;
-       GList *tmp = NULL;
-
-       if (elt->type == RDNS_REQUEST_A) {
-               if (!addr->data.normal.parsed) {
-                       addr->data.normal.d.in4.s_addr = elt->content.a.addr.s_addr;
-                       addr->data.normal.parsed = TRUE;
+               if (addr->flags & RSPAMD_SPF_FLAG_IPV6) {
+                       addr->m.dual.mask_v6 = mask;
                }
                else {
-                       /* Insert one more address */
-                       tmp = spf_addr_find (cb->rec->addrs, addr);
-                       if (tmp) {
-                               new_addr = rspamd_mempool_alloc (task->task_pool,
-                                               sizeof (struct spf_addr));
-                               memcpy (new_addr, addr, sizeof (struct spf_addr));
-                               new_addr->data.normal.d.in4.s_addr = elt->content.a.addr.s_addr;
-                               new_addr->data.normal.parsed = TRUE;
-                               cb->rec->addrs = g_list_insert_before (cb->rec->addrs,
-                                               tmp,
-                                               new_addr);
-                       }
-                       else {
-                               msg_info ("<%s>: spf error for domain %s: addresses mismatch",
-                                       task->message_id, cb->rec->sender_domain);
-                       }
+                       addr->m.dual.mask_v4 = mask;
                }
 
        }
-       else if (elt->type == RDNS_REQUEST_AAAA) {
-               if (!addr->data.normal.parsed) {
-                       memcpy (&addr->data.normal.d.in6,
-                               &elt->content.aaa.addr, sizeof (struct in6_addr));
-                       addr->data.normal.mask = 32;
-                       addr->data.normal.parsed = TRUE;
-                       addr->data.normal.ipv6 = TRUE;
-               }
-               else {
-                       /* Insert one more address */
-                       tmp = spf_addr_find (cb->rec->addrs, addr);
-                       if (tmp) {
-                               new_addr =
-                                       rspamd_mempool_alloc (task->task_pool,
-                                               sizeof (struct spf_addr));
-                               memcpy (new_addr, addr, sizeof (struct spf_addr));
-                               memcpy (&new_addr->data.normal.d.in6,
-                                       &elt->content.aaa.addr, sizeof (struct in6_addr));
-                               new_addr->data.normal.parsed = TRUE;
-                               new_addr->data.normal.ipv6 = TRUE;
-                               cb->rec->addrs = g_list_insert_before (cb->rec->addrs,
-                                               tmp,
-                                               new_addr);
-                       }
-                       else {
-                               msg_info ("<%s>: spf error for domain %s: addresses mismatch",
-                                       task->message_id, cb->rec->sender_domain);
-                       }
-               }
+       else {
+               addr->m.dual.mask_v6 = 128;
+               addr->m.dual.mask_v4 = 32;
        }
+
+       return TRUE;
+
 }
 
 static gboolean
@@ -520,7 +340,7 @@ spf_check_ptr_host (struct spf_dns_cb *cb, const char *name)
 
        }
        else {
-               dstart = cb->rec->cur_domain;
+               dstart = cb->resolved->cur_domain;
        }
 
        msg_debug ("check ptr %s vs %s", name, dstart);
@@ -544,7 +364,7 @@ spf_check_ptr_host (struct spf_dns_cb *cb, const char *name)
        /* Now compare from end to start */
        for (;;) {
                if (g_ascii_tolower (*dend) != g_ascii_tolower (*nend)) {
-                       msg_debug ("ptr records missmatch: %s and %s", dend, nend);
+                       msg_debug ("ptr records mismatch: %s and %s", dend, nend);
                        return FALSE;
                }
                if (dend == dstart) {
@@ -565,6 +385,44 @@ spf_check_ptr_host (struct spf_dns_cb *cb, const char *name)
        return TRUE;
 }
 
+static void
+spf_record_process_addr (struct spf_addr *addr, struct rdns_reply_entry *reply)
+{
+       if (reply->type == RDNS_REQUEST_AAAA) {
+               memcpy (addr->addr6, &reply->content.aaa.addr, sizeof (addr->addr6));
+       }
+       else if (reply->type == RDNS_REQUEST_A) {
+               memcpy (addr->addr4, &reply->content.a.addr, sizeof (addr->addr4));
+       }
+       else {
+               msg_err ("internal error, bad DNS reply is treated as address: %s",
+                       rdns_strtype (reply->type));
+       }
+}
+
+static void
+spf_record_addr_set (struct spf_addr *addr, gboolean allow_any)
+{
+       guchar fill;
+       guint maskv4, maskv6;
+
+       if (allow_any) {
+               fill = 0;
+               maskv4 = 0;
+               maskv6 = 0;
+       }
+       else {
+               fill = 0xff;
+               maskv4 = 32;
+               maskv6 = 128;
+       }
+
+       memset (addr->addr4, fill, sizeof (addr->addr4));
+       memset (addr->addr6, fill, sizeof (addr->addr6));
+       addr->m.dual.mask_v4 = maskv4;
+       addr->m.dual.mask_v6 = maskv6;
+}
+
 static void
 spf_record_dns_callback (struct rdns_reply *reply, gpointer arg)
 {
@@ -573,11 +431,13 @@ spf_record_dns_callback (struct rdns_reply *reply, gpointer arg)
        struct rdns_reply_entry *elt_data;
        GList *tmp = NULL;
        struct rspamd_task *task;
+       struct spf_addr *addr;
        gboolean ret;
 
        task = cb->rec->task;
 
        cb->rec->requests_inflight--;
+       addr = cb->addr;
 
        if (reply->code == RDNS_RC_NOERROR) {
                /* Add all logic for all DNS states here */
@@ -605,12 +465,12 @@ spf_record_dns_callback (struct rdns_reply *reply, gpointer arg)
                                        }
                                }
                                else {
-                                       spf_record_process_addr (elt_data, cb, task);
+                                       spf_record_process_addr (addr, elt_data);
                                }
                                break;
                        case SPF_RESOLVE_A:
                        case SPF_RESOLVE_AAA:
-                               spf_record_process_addr (elt_data, cb, task);
+                               spf_record_process_addr (addr, elt_data);
                                break;
                        case SPF_RESOLVE_PTR:
                                if (elt_data->type == RDNS_REQUEST_PTR) {
@@ -637,46 +497,19 @@ spf_record_dns_callback (struct rdns_reply *reply, gpointer arg)
                                        }
                                }
                                else {
-                                       spf_record_process_addr (elt_data, cb, task);
+                                       spf_record_process_addr (addr, elt_data);
                                }
                                break;
                        case SPF_RESOLVE_REDIRECT:
                                if (elt_data->type == RDNS_REQUEST_TXT) {
                                        begin = elt_data->content.txt.data;
-
-                                       if (!cb->in_include && cb->rec->addrs) {
-                                               g_list_free (cb->rec->addrs);
-                                               cb->rec->addrs = NULL;
-                                       }
-                                       start_spf_parse (cb->rec, begin, elt_data->ttl);
-
+                                       ret = start_spf_parse (cb->rec, begin, 0);
                                }
                                break;
                        case SPF_RESOLVE_INCLUDE:
                                if (elt_data->type == RDNS_REQUEST_TXT) {
                                        begin = elt_data->content.txt.data;
-#ifdef SPF_DEBUG
-                                       msg_info ("before include");
-                                       dump_spf_record (cb->rec->addrs);
-#endif
-                                       tmp = cb->rec->addrs;
-                                       cb->rec->addrs = NULL;
-                                       cb->rec->in_include = TRUE;
                                        ret = start_spf_parse (cb->rec, begin, 0);
-                                       cb->rec->in_include = FALSE;
-
-#ifdef SPF_DEBUG
-                                       msg_info ("after include");
-                                       dump_spf_record (cb->rec->addrs);
-#endif
-
-                                       if (ret) {
-                                               /* Insert new list */
-                                               cb->addr->is_list = TRUE;
-                                               cb->addr->data.list = cb->rec->addrs;
-                                       }
-
-                                       cb->rec->addrs = tmp;
                                }
                                break;
                        case SPF_RESOLVE_EXP:
@@ -685,8 +518,7 @@ spf_record_dns_callback (struct rdns_reply *reply, gpointer arg)
                                if (elt_data->type == RDNS_REQUEST_A || elt_data->type ==
                                        RDNS_REQUEST_AAAA) {
                                        /* If specified address resolves, we can accept connection from every IP */
-                                       cb->addr->data.normal.d.in4.s_addr = INADDR_NONE;
-                                       cb->addr->data.normal.mask = 0;
+                                       spf_record_addr_set (addr, TRUE);
                                }
                                break;
                        }
@@ -700,56 +532,51 @@ spf_record_dns_callback (struct rdns_reply *reply, gpointer arg)
                                        "<%s>: spf error for domain %s: cannot find MX record for %s",
                                        task->message_id,
                                        cb->rec->sender_domain,
-                                       cb->rec->cur_domain);
-                               cb->addr->data.normal.d.in4.s_addr = INADDR_NONE;
-                               cb->addr->data.normal.mask = 32;
+                                       cb->resolved->cur_domain);
+                               spf_record_addr_set (addr, FALSE);
                        }
                        else {
                                msg_info (
                                        "<%s>: spf error for domain %s: cannot resolve MX record for %s",
                                        task->message_id,
                                        cb->rec->sender_domain,
-                                       cb->rec->cur_domain);
-                               cb->addr->data.normal.d.in4.s_addr = INADDR_NONE;
-                               cb->addr->data.normal.mask = 32;
+                                       cb->resolved->cur_domain);
+                               spf_record_addr_set (addr, FALSE);
                        }
                        break;
                case SPF_RESOLVE_A:
                        if (rdns_request_has_type (reply->request, RDNS_REQUEST_A)) {
-                               cb->addr->data.normal.d.in4.s_addr = INADDR_NONE;
-                               cb->addr->data.normal.mask = 32;
+                               spf_record_addr_set (addr, FALSE);
                        }
                        break;
 #ifdef HAVE_INET_PTON
                case SPF_RESOLVE_AAA:
                        if (rdns_request_has_type (reply->request, RDNS_REQUEST_AAAA)) {
-                               memset (&cb->addr->data.normal.d.in6, 0xff,
-                                       sizeof (struct in6_addr));
-                               cb->addr->data.normal.mask = 32;
+                               spf_record_addr_set (addr, FALSE);
                        }
                        break;
 #endif
                case SPF_RESOLVE_PTR:
+                       spf_record_addr_set (addr, FALSE);
                        break;
                case SPF_RESOLVE_REDIRECT:
                        msg_info (
                                "<%s>: spf error for domain %s: cannot resolve TXT record for %s",
                                task->message_id,
                                cb->rec->sender_domain,
-                               cb->rec->cur_domain);
+                               cb->resolved->cur_domain);
                        break;
                case SPF_RESOLVE_INCLUDE:
                        msg_info (
                                "<%s>: spf error for domain %s: cannot resolve TXT record for %s",
                                task->message_id,
                                cb->rec->sender_domain,
-                               cb->rec->cur_domain);
+                               cb->resolved->cur_domain);
                        break;
                case SPF_RESOLVE_EXP:
                        break;
                case SPF_RESOLVE_EXISTS:
-                       cb->addr->data.normal.d.in4.s_addr = INADDR_NONE;
-                       cb->addr->data.normal.mask = 32;
+                       spf_record_addr_set (addr, FALSE);
                        break;
                }
        }
@@ -779,7 +606,8 @@ parse_spf_domain_mask (struct spf_record *rec, struct spf_addr *addr,
                parse_slash,
                parse_ipv4_mask,
                parse_second_slash,
-               parse_ipv6_mask
+               parse_ipv6_mask,
+               skip_garbadge
        } state = 0;
        const gchar *p = addr->spf_string, *host, *c;
        gchar *hostbuf;
@@ -823,7 +651,12 @@ parse_spf_domain_mask (struct spf_record *rec, struct spf_addr *addr,
                        break;
                case parse_slash:
                        c = p;
-                       state = parse_ipv4_mask;
+                       if (allow_mask) {
+                               state = parse_ipv4_mask;
+                       }
+                       else {
+                               state = skip_garbadge;
+                       }
                        cur_mask = 0;
                        break;
                case parse_ipv4_mask:
@@ -854,6 +687,9 @@ parse_spf_domain_mask (struct spf_record *rec, struct spf_addr *addr,
                        }
                        p ++;
                        break;
+               case skip_garbadge:
+                       p++;
+                       break;
                }
        }
 
@@ -884,41 +720,18 @@ parse_spf_domain_mask (struct spf_record *rec, struct spf_addr *addr,
 }
 
 static gboolean
-parse_spf_a (struct rspamd_task *task,
-       const gchar *begin,
-       struct spf_record *rec,
-       struct spf_addr *addr)
+parse_spf_a (struct spf_record *rec, struct spf_addr *addr)
 {
        struct spf_dns_cb *cb;
-       gchar *host = NULL;
+       const gchar *host = NULL;
+       struct rspamd_task *task = rec->task;
+       struct spf_resolved_element *resolved;
 
+       resolved = &g_array_index (rec->resolved, struct spf_resolved_element,
+                       rec->resolved->len - 1);
        CHECK_REC (rec);
 
-       /*
-        * a
-        * a/<prefix-length>
-        * a:<domain>
-        * a:<domain>/<prefix-length>
-        */
-       if (begin == NULL) {
-               return FALSE;
-       }
-       if (*begin == '\0') {
-               /* Use current domain only */
-               host = rec->cur_domain;
-               addr->data.normal.mask = 32;
-       }
-       else if (*begin == ':') {
-               begin++;
-       }
-       else if (*begin != '/') {
-               /* Invalid A record */
-               return FALSE;
-       }
-
-       if (host == NULL) {
-               host = parse_spf_hostmask (task, begin, addr, rec);
-       }
+       host = parse_spf_domain_mask (rec, addr, TRUE);
 
        if (host == NULL) {
                return FALSE;
@@ -929,8 +742,9 @@ parse_spf_a (struct rspamd_task *task,
        cb->rec = rec;
        cb->addr = addr;
        cb->cur_action = SPF_RESOLVE_A;
-       cb->in_include = rec->in_include;
+       cb->resolved = resolved;
        msg_debug ("resolve a %s", host);
+
        if (make_dns_request (task->resolver, task->s, task->task_pool,
                spf_record_dns_callback, (void *)cb, RDNS_REQUEST_A, host)) {
                task->dns_requests++;
@@ -943,43 +757,34 @@ parse_spf_a (struct rspamd_task *task,
 }
 
 static gboolean
-parse_spf_ptr (struct rspamd_task *task,
-       const gchar *begin,
-       struct spf_record *rec,
-       struct spf_addr *addr)
+parse_spf_ptr (struct spf_record *rec, struct spf_addr *addr)
 {
        struct spf_dns_cb *cb;
        gchar *host, *ptr;
+       struct rspamd_task *task = rec->task;
+       struct spf_resolved_element *resolved;
 
+       resolved = &g_array_index (rec->resolved, struct spf_resolved_element,
+                       rec->resolved->len - 1);
        CHECK_REC (rec);
 
-       if (begin == NULL) {
-               return FALSE;
-       }
-       if (*begin == ':') {
-               begin++;
-               host = rspamd_mempool_strdup (task->task_pool, begin);
-       }
-       else if (*begin == '\0') {
-               host = NULL;
-       }
-       else {
-               return FALSE;
-       }
+       host = parse_spf_domain_mask (rec, addr, FALSE);
 
        rec->dns_requests++;
        cb = rspamd_mempool_alloc (task->task_pool, sizeof (struct spf_dns_cb));
        cb->rec = rec;
        cb->addr = addr;
        cb->cur_action = SPF_RESOLVE_PTR;
-       cb->in_include = rec->in_include;
+       cb->resolved = resolved;
        cb->ptr_host = host;
        ptr =
                rdns_generate_ptr_from_str (rspamd_inet_address_to_string (
                                task->from_addr));
+
        if (ptr == NULL) {
                return FALSE;
        }
+
        rspamd_mempool_add_destructor (task->task_pool, free, ptr);
        msg_debug ("resolve ptr %s for %s", ptr, host);
        if (make_dns_request (task->resolver, task->s, task->task_pool,
@@ -991,7 +796,6 @@ parse_spf_ptr (struct rspamd_task *task,
        }
 
        return FALSE;
-       return TRUE;
 }
 
 static gboolean
@@ -999,27 +803,27 @@ parse_spf_mx (struct spf_record *rec, struct spf_addr *addr)
 {
        struct spf_dns_cb *cb;
        gchar *host;
+       struct rspamd_task *task = rec->task;
+       struct spf_resolved_element *resolved;
 
-       CHECK_REC (rec);
+       resolved = &g_array_index (rec->resolved, struct spf_resolved_element,
+                       rec->resolved->len - 1);
 
-       if (begin == NULL) {
-               return FALSE;
-       }
-       if (*begin == ':') {
-               begin++;
-       }
+       CHECK_REC (rec);
 
-       host = parse_spf_hostmask (task, begin, addr, rec);
+       host = parse_spf_domain_mask (rec, addr, TRUE);
 
        if (host == NULL) {
                return FALSE;
        }
+
        rec->dns_requests++;
        cb = rspamd_mempool_alloc (task->task_pool, sizeof (struct spf_dns_cb));
        cb->rec = rec;
        cb->addr = addr;
        cb->cur_action = SPF_RESOLVE_MX;
-       cb->in_include = rec->in_include;
+       cb->resolved = resolved;
+
        msg_debug ("resolve mx for %s", host);
        if (make_dns_request (task->resolver, task->s, task->task_pool,
                spf_record_dns_callback, (void *)cb, RDNS_REQUEST_MX, host)) {
@@ -1036,8 +840,10 @@ static gboolean
 parse_spf_all (struct spf_record *rec, struct spf_addr *addr)
 {
        /* All is 0/0 */
-       memset (&addr->addr, 0, sizeof (addr->addr));
-       addr->m.mask = 0;
+       memset (&addr->addr4, 0, sizeof (addr->addr4));
+       memset (&addr->addr6, 0, sizeof (addr->addr6));
+       /* Here we set all masks to 0 */
+       addr->m.idx = 0;
        addr->flags |= RSPAMD_SPF_FLAG_ANY;
 
        return TRUE;
@@ -1068,8 +874,8 @@ parse_spf_include (struct spf_record *rec, struct spf_addr *addr)
 {
        struct spf_dns_cb *cb;
        gchar *domain;
-       struct spf_resolved_element *resolved;
        struct rspamd_task *task = rec->task;
+       struct spf_resolved_element *resolved;
 
        resolved = &g_array_index (rec->resolved, struct spf_resolved_element,
                        rec->resolved->len - 1);
@@ -1091,7 +897,7 @@ parse_spf_include (struct spf_record *rec, struct spf_addr *addr)
        cb->cur_action = SPF_RESOLVE_INCLUDE;
        /* Set reference */
        addr->flags |= RSPAMD_SPF_FLAG_REFRENCE;
-       addr->m.mask = rec->resolved->len;
+       addr->m.idx = rec->resolved->len;
        rspamd_spf_new_addr_list (rec, domain);
        msg_debug ("resolve include %s", domain);
 
@@ -1154,7 +960,7 @@ parse_spf_redirect (struct spf_record *rec, struct spf_addr *addr)
        cb = rspamd_mempool_alloc (task->task_pool, sizeof (struct spf_dns_cb));
        /* Set reference */
        addr->flags |= RSPAMD_SPF_FLAG_REFRENCE;
-       addr->m.mask = rec->resolved->len;
+       addr->m.idx = rec->resolved->len;
        rspamd_spf_new_addr_list (rec, domain);
 
        cb->rec = rec;
@@ -1236,7 +1042,6 @@ reverse_spf_ip (gchar *ip, gint len)
        }
 
        memcpy (p - 1, c - t, t + 1);
-
        memcpy (ip,        ipbuf, len);
 }
 
index c491cd8b45ef06d120f1e5891b1b2f09d0907643..93098e9419c561c440dc175569e9950be3d52466 100644 (file)
@@ -34,13 +34,14 @@ typedef enum spf_action_e {
 #define RSPAMD_SPF_FLAG_REFRENCE (1 << 4)
 
 struct spf_addr {
-       guchar addr[sizeof (struct in6_addr)];
+       guchar addr6[sizeof (struct in6_addr)];
+       guchar addr4[sizeof (struct in_addr)];
        union {
                struct {
                        guint16 mask_v4;
                        guint16 mask_v6;
                } dual;
-               guint32 mask;
+               guint32 idx;
        } m;
        guint flags;
        spf_mech_t mech;