aboutsummaryrefslogtreecommitdiffstats
path: root/src/libserver/cfg_utils.c
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2019-06-14 13:23:15 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2019-06-14 13:23:15 +0100
commit4d32fb1b37d2ff46b4c6e1213a5bc163e3f2e96c (patch)
treeb24af7420652ebe418685907e60cecb7d381e293 /src/libserver/cfg_utils.c
parent0cbb51f4c06a63707f1e42646f032eb479b87b55 (diff)
downloadrspamd-4d32fb1b37d2ff46b4c6e1213a5bc163e3f2e96c.tar.gz
rspamd-4d32fb1b37d2ff46b4c6e1213a5bc163e3f2e96c.zip
[Project] Add preprocessed settings to the config structure
Diffstat (limited to 'src/libserver/cfg_utils.c')
-rw-r--r--src/libserver/cfg_utils.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/src/libserver/cfg_utils.c b/src/libserver/cfg_utils.c
index 1c8b2ce5f..e32ca7020 100644
--- a/src/libserver/cfg_utils.c
+++ b/src/libserver/cfg_utils.c
@@ -2334,3 +2334,115 @@ rspamd_actions_sort (struct rspamd_config *cfg)
{
HASH_SORT (cfg->actions, rspamd_actions_cmp);
}
+
+static void
+rspamd_config_settings_elt_dtor (struct rspamd_config_settings_elt *e)
+{
+ if (e->symbols_enabled) {
+ ucl_object_unref (e->symbols_enabled);
+ }
+ if (e->symbols_disabled) {
+ ucl_object_unref (e->symbols_disabled);
+ }
+}
+
+static inline guint32
+rspamd_config_name_to_id (const gchar *name, gsize namelen)
+{
+ guint64 h;
+
+ h = rspamd_cryptobox_fast_hash_specific (RSPAMD_CRYPTOBOX_XXHASH64,
+ name, strlen (name), 0x0);
+ /* Take the lower part of hash as LE number */
+ return ((guint32)GUINT64_TO_LE (h));
+}
+
+struct rspamd_config_settings_elt *
+rspamd_config_find_settings_id_ref (struct rspamd_config *cfg,
+ guint32 id)
+{
+ struct rspamd_config_settings_elt *cur;
+
+ DL_FOREACH (cfg->setting_ids, cur) {
+ if (cur->id == id) {
+ REF_RETAIN (cur);
+ return cur;
+ }
+ }
+
+ return NULL;
+}
+
+struct rspamd_config_settings_elt *rspamd_config_find_settings_name_ref (
+ struct rspamd_config *cfg,
+ const gchar *name, gsize namelen)
+{
+ guint32 id;
+
+ id = rspamd_config_name_to_id (name, namelen);
+
+ return rspamd_config_find_settings_id_ref (cfg, id);
+}
+
+void
+rspamd_config_register_settings_id (struct rspamd_config *cfg,
+ const gchar *name,
+ ucl_object_t *symbols_enabled,
+ ucl_object_t *symbols_disabled)
+{
+ struct rspamd_config_settings_elt *elt;
+ guint32 id;
+
+ id = rspamd_config_name_to_id (name, strlen (name));
+ elt = rspamd_config_find_settings_id_ref (cfg, id);
+
+ if (elt) {
+ /* Need to replace */
+ struct rspamd_config_settings_elt *nelt;
+
+ DL_DELETE (cfg->setting_ids, elt);
+
+ nelt = rspamd_mempool_alloc0 (cfg->cfg_pool, sizeof (*nelt));
+
+ nelt->id = id;
+ nelt->name = rspamd_mempool_strdup (cfg->cfg_pool, name);
+
+ if (symbols_enabled) {
+ nelt->symbols_enabled = ucl_object_ref (symbols_enabled);
+ }
+
+ if (symbols_disabled) {
+ nelt->symbols_disabled = ucl_object_ref (symbols_disabled);
+ }
+
+ REF_INIT_RETAIN (nelt, rspamd_config_settings_elt_dtor);
+ msg_info_config ("replace settings id %d (%s)", id, name);
+ DL_APPEND (cfg->setting_ids, nelt);
+
+ /*
+ * Need to unref old element twice as there are two reference holders:
+ * 1. Config structure as we call REF_INIT_RETAIN
+ * 2. rspamd_config_find_settings_id_ref also increases refcount
+ */
+ REF_RELEASE (elt);
+ REF_RELEASE (elt);
+ }
+ else {
+ elt = rspamd_mempool_alloc0 (cfg->cfg_pool, sizeof (*elt));
+
+ elt->id = id;
+ elt->name = rspamd_mempool_strdup (cfg->cfg_pool, name);
+
+ if (symbols_enabled) {
+ elt->symbols_enabled = ucl_object_ref (symbols_enabled);
+ }
+
+ if (symbols_disabled) {
+ elt->symbols_disabled = ucl_object_ref (symbols_disabled);
+ }
+
+ msg_info_config ("register new settings id %d (%s)", id, name);
+ REF_INIT_RETAIN (elt, rspamd_config_settings_elt_dtor);
+ DL_APPEND (cfg->setting_ids, elt);
+ }
+}