commit 48f02cf: [Feature] Store SPF records digests

Vsevolod Stakhov vsevolod at highsecure.ru
Tue Apr 9 14:42:03 UTC 2019


Author: Vsevolod Stakhov
Date: 2019-04-09 15:35:22 +0100
URL: https://github.com/rspamd/rspamd/commit/48f02cfd4dfc1e64e9a025c82ee15c6f581a1c03 (HEAD -> master)

[Feature] Store SPF records digests

---
 src/libserver/spf.c | 36 +++++++++++++++++++++++++++++++++++-
 src/libserver/spf.h |  1 +
 src/plugins/spf.c   | 14 +++++++++++++-
 3 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/src/libserver/spf.c b/src/libserver/spf.c
index 6de2fa4b9..b8c7e4c32 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 <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);
 	}
 
diff --git a/src/libserver/spf.h b/src/libserver/spf.h
index 2a844e998..83716297f 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 4c5dff124..6a4004e57 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));


More information about the Commits mailing list