From: Vsevolod Stakhov Date: Tue, 9 Apr 2019 14:35:22 +0000 (+0100) Subject: [Feature] Store SPF records digests X-Git-Tag: 1.9.2~44 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=48f02cfd4dfc1e64e9a025c82ee15c6f581a1c03;p=thirdparty%2Frspamd.git [Feature] Store SPF records digests --- diff --git a/src/libserver/spf.c b/src/libserver/spf.c index 6de2fa4b95..b8c7e4c328 100644 --- a/src/libserver/spf.c +++ b/src/libserver/spf.c @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include + #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); } diff --git a/src/libserver/spf.h b/src/libserver/spf.h index 2a844e9982..83716297fe 100644 --- a/src/libserver/spf.h +++ b/src/libserver/spf.h @@ -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 */ }; diff --git a/src/plugins/spf.c b/src/plugins/spf.c index 4c5dff1249..6a4004e57e 100644 --- a/src/plugins/spf.c +++ b/src/plugins/spf.c @@ -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));