From 0943c1627ca1ebedd76f3d544ec801210365daee Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Sat, 5 Dec 2015 00:44:00 +0000 Subject: [PATCH] Add replacement method for expressions in the confi --- src/libserver/re_cache.c | 60 ++++++++++++++++++++++++++++------------ src/libserver/re_cache.h | 16 +++++++++++ 2 files changed, 58 insertions(+), 18 deletions(-) diff --git a/src/libserver/re_cache.c b/src/libserver/re_cache.c index 40428b6f1..d8fdc6b58 100644 --- a/src/libserver/re_cache.c +++ b/src/libserver/re_cache.c @@ -36,8 +36,7 @@ struct rspamd_re_class { enum rspamd_re_type type; gpointer type_data; gsize type_len; - GHashTable *re_ids; - GPtrArray *all_re; + GHashTable *re; gchar hash[rspamd_cryptobox_HASHBYTES * 2 + 1]; }; @@ -77,7 +76,6 @@ rspamd_re_cache_destroy (struct rspamd_re_cache *cache) GHashTableIter it; gpointer k, v; struct rspamd_re_class *re_class; - rspamd_regexp_t *re; guint i; g_assert (cache != NULL); @@ -86,14 +84,7 @@ rspamd_re_cache_destroy (struct rspamd_re_cache *cache) while (g_hash_table_iter_next (&it, &k, &v)) { re_class = v; g_hash_table_iter_steal (&it); - - for (i = 0; i < re_class->all_re->len; i++) { - re = g_ptr_array_index (re_class->all_re, i); - - rspamd_regexp_set_cache_id (re, RSPAMD_INVALID_ID); - rspamd_regexp_unref (re); - } - + g_hash_table_unref (re_class->re); g_slice_free1 (sizeof (*re_class), re_class); } @@ -120,6 +111,7 @@ rspamd_re_cache_add (struct rspamd_re_cache *cache, rspamd_regexp_t *re, { guint64 class_id; struct rspamd_re_class *re_class; + rspamd_regexp_t *nre; g_assert (cache != NULL); g_assert (re != NULL); @@ -132,29 +124,60 @@ rspamd_re_cache_add (struct rspamd_re_cache *cache, rspamd_regexp_t *re, re_class->id = class_id; re_class->type_len = datalen; re_class->type = type; - re_class->re_ids = g_hash_table_new (rspamd_regexp_hash, - rspamd_regexp_equal); + re_class->re = g_hash_table_new_full (rspamd_regexp_hash, + rspamd_regexp_equal, NULL, (GDestroyNotify)rspamd_regexp_unref); if (datalen > 0) { re_class->type_data = g_slice_alloc (datalen); memcpy (re_class->type_data, type_data, datalen); } - re_class->all_re = g_ptr_array_new (); g_hash_table_insert (cache->re_classes, &re_class->id, re_class); } - g_ptr_array_add (re_class->all_re, rspamd_regexp_ref (re)); /* * We set re id based on the global position in the cache */ rspamd_regexp_set_cache_id (re, cache->nre ++); + nre = rspamd_regexp_ref (re); + g_hash_table_insert (re_class->re, re, re); +} + +void +rspamd_re_cache_replace (struct rspamd_re_cache *cache, + rspamd_regexp_t *what, + enum rspamd_re_type type, + gpointer type_data, + gsize datalen, + rspamd_regexp_t *with) +{ + guint64 class_id, re_id; + struct rspamd_re_class *re_class; + rspamd_regexp_t *src; + + g_assert (cache != NULL); + g_assert (what != NULL); + g_assert (with != NULL); + + class_id = rspamd_re_cache_class_id (type, type_data, datalen); + re_class = g_hash_table_lookup (cache->re_classes, &class_id); + + if (re_class != NULL) { + re_id = rspamd_regexp_get_cache_id (what); + + g_assert (re_id != RSPAMD_INVALID_ID); + src = g_hash_table_lookup (re_class->re, what); + + if (src) { + g_hash_table_replace (re_class->re, what, with); + } + } } void rspamd_re_cache_init (struct rspamd_re_cache *cache) { - GHashTableIter it; + GHashTableIter it, cit; gpointer k, v; struct rspamd_re_class *re_class; rspamd_cryptobox_hash_state_t st; @@ -171,9 +194,10 @@ rspamd_re_cache_init (struct rspamd_re_cache *cache) rspamd_cryptobox_hash_init (&st, NULL, 0); rspamd_cryptobox_hash_update (&st, (gpointer)&re_class->id, sizeof (re_class->id)); + g_hash_table_iter_init (&cit, re_class->re); - for (i = 0; i < re_class->all_re->len; i ++) { - re = g_ptr_array_index (re_class->all_re, i); + while (g_hash_table_iter_next (&cit, &k, &v)) { + re = v; rspamd_cryptobox_hash_update (&st, rspamd_regexp_get_id (re), rspamd_cryptobox_HASHBYTES); } diff --git a/src/libserver/re_cache.h b/src/libserver/re_cache.h index 4fa3fc286..6f2c0f312 100644 --- a/src/libserver/re_cache.h +++ b/src/libserver/re_cache.h @@ -55,6 +55,22 @@ struct rspamd_re_cache *rspamd_re_cache_new (void); void rspamd_re_cache_add (struct rspamd_re_cache *cache, rspamd_regexp_t *re, enum rspamd_re_type type, gpointer type_data, gsize datalen); +/** + * Replace regexp in the cache with another regexp + * @param cache cache object + * @param what re to replace + * @param type type of object + * @param type_data associated data with the type (e.g. header name) + * @param datalen associated data length + * @param with regexp object to replace the origin + */ +void rspamd_re_cache_replace (struct rspamd_re_cache *cache, + rspamd_regexp_t *what, + enum rspamd_re_type type, + gpointer type_data, + gsize datalen, + rspamd_regexp_t *with); + /** * Initialize and optimize re cache structure */ -- 2.39.5