diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2019-06-14 13:23:15 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2019-06-14 13:23:15 +0100 |
commit | 4d32fb1b37d2ff46b4c6e1213a5bc163e3f2e96c (patch) | |
tree | b24af7420652ebe418685907e60cecb7d381e293 /src/libserver/cfg_utils.c | |
parent | 0cbb51f4c06a63707f1e42646f032eb479b87b55 (diff) | |
download | rspamd-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.c | 112 |
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); + } +} |