]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Feature] Store SPF records digests
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 9 Apr 2019 14:35:22 +0000 (15:35 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 9 Apr 2019 14:35:22 +0000 (15:35 +0100)
src/libserver/spf.c
src/libserver/spf.h
src/plugins/spf.c

index 6de2fa4b95937767b02154eccfa2d4cc99ad6156..b8c7e4c32883d5e2095be9a0a01bbb8dcb8a57eb 100644 (file)
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#include <contrib/librdns/rdns.h>
+
 #include "config.h"
 #include "dns.h"
 #include "spf.h"
@@ -21,6 +21,8 @@
 #include "message.h"
 #include "utlist.h"
 #include "libserver/mempool_vars_internal.h"
+#include "contrib/librdns/rdns.h"
+#include "contrib/mumhash/mum.h"
 
 #define SPF_VER1_STR "v=spf1"
 #define SPF_VER2_STR "spf2."
@@ -369,6 +371,34 @@ rspamd_spf_process_reference (struct spf_resolved *target,
                        DL_FOREACH (cur, cur_addr) {
                                memcpy (&taddr, cur_addr, sizeof (taddr));
                                taddr.spf_string = g_strdup (cur_addr->spf_string);
+
+                               if (cur_addr->flags & RSPAMD_SPF_FLAG_IPV6) {
+                                       guint64 t[3];
+
+                                       memcpy (t, cur_addr->addr6, sizeof (guint64) * 2);
+                                       t[2] = ((guint64)(cur_addr->mech)) << 48;
+                                       t[2] |= cur_addr->m.dual.mask_v6;
+
+                                       for (guint j = 0; j < G_N_ELEMENTS (t); j ++) {
+                                               target->digest = mum_hash_step (target->digest, t[j]);
+                                       }
+                               }
+                               else if (cur_addr->flags & RSPAMD_SPF_FLAG_IPV4) {
+                                       guint64 t;
+
+                                       memcpy (&t, cur_addr->addr4, sizeof (guint32));
+                                       t |= ((guint64)(cur_addr->mech)) << 48;
+                                       t |= ((guint64)cur_addr->m.dual.mask_v4) << 32;
+
+                                       target->digest = mum_hash_step (target->digest, t);
+                               }
+                               else {
+                                       guint64 t = 0;
+
+                                       t |= ((guint64)(cur_addr->mech)) << 48;
+                                       target->digest = mum_hash_step (target->digest, t);
+                               }
+
                                g_array_append_val (target->elts, taddr);
                        }
                }
@@ -391,17 +421,21 @@ rspamd_spf_record_flatten (struct spf_record *rec)
                                rec->resolved->len);
                res->domain = g_strdup (rec->sender_domain);
                res->ttl = rec->ttl;
+               res->digest = mum_hash_init (0xa4aa40bbeec59e2bULL);
                REF_INIT_RETAIN (res, rspamd_flatten_record_dtor);
 
                if (rec->resolved->len > 0) {
                        rspamd_spf_process_reference (res, NULL, rec, TRUE);
                }
+
+               res->digest = mum_hash_finish (res->digest);
        }
        else {
                res = g_malloc0 (sizeof (*res));
                res->elts = g_array_new (FALSE, FALSE, sizeof (struct spf_addr));
                res->domain = g_strdup (rec->sender_domain);
                res->ttl = rec->ttl;
+               res->digest = mum_hash_init (0xa4aa40bbeec59e2bULL);
                REF_INIT_RETAIN (res, rspamd_flatten_record_dtor);
        }
 
index 2a844e9982ab60cbb0c08632e464bc5ff4d60855..83716297fe68f3403452d5b2b3fd02e11d0ec9fe 100644 (file)
@@ -64,6 +64,7 @@ struct spf_resolved {
        gboolean temp_failed;
        gboolean na;
        gboolean perm_failed;
+       guint64 digest;
        GArray *elts; /* Flat list of struct spf_addr */
        ref_entry_t ref; /* Refcounting */
 };
index 4c5dff1249cc05d5b79272ce25364ba39c6e5176..6a4004e57e9f68ec05bccd4f067dcaf2a437d60d 100644 (file)
@@ -504,6 +504,17 @@ spf_check_list (struct spf_resolved *rec, struct rspamd_task *task, gboolean cac
 {
        guint i;
        struct spf_addr *addr;
+       struct spf_ctx *spf_module_ctx = spf_get_context (task->cfg);
+
+       if (cached) {
+               msg_info_task ("use cached record for %s (0x%xuL) in LRU cache for %d seconds, "
+                                          "%d/%d elements in the cache",
+                               rec->domain,
+                               rec->digest,
+                               rec->ttl,
+                               rspamd_lru_hash_size (spf_module_ctx->spf_hash),
+                               rspamd_lru_hash_capacity (spf_module_ctx->spf_hash));
+       }
 
        for (i = 0; i < rec->elts->len; i ++) {
                addr = &g_array_index (rec->elts, struct spf_addr, i);
@@ -562,9 +573,10 @@ spf_plugin_callback (struct spf_resolved *record, struct rspamd_task *task,
                                                record->domain, spf_record_ref (l),
                                                task->tv.tv_sec, record->ttl);
 
-                               msg_info_task ("stored record for %s in LRU cache for %d seconds, "
+                               msg_info_task ("stored record for %s (0x%xuL) in LRU cache for %d seconds, "
                                                           "%d/%d elements in the cache",
                                                record->domain,
+                                               record->digest,
                                                record->ttl,
                                                rspamd_lru_hash_size (spf_module_ctx->spf_hash),
                                                rspamd_lru_hash_capacity (spf_module_ctx->spf_hash));