From: Vsevolod Stakhov Date: Thu, 14 Jun 2018 10:47:36 +0000 (+0100) Subject: [Fix] Cleanup maps data on shutdown X-Git-Tag: 1.7.6~15 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=7406e60b74327df055f3bacfc478bd5cb68fd6c9;p=rspamd.git [Fix] Cleanup maps data on shutdown --- diff --git a/src/fuzzy_storage.c b/src/fuzzy_storage.c index 44b7c555e..234822018 100644 --- a/src/fuzzy_storage.c +++ b/src/fuzzy_storage.c @@ -2880,7 +2880,10 @@ start_fuzzy (struct rspamd_worker *worker) struct rspamd_map *m; if ((m = rspamd_map_add_from_ucl (cfg, ctx->skip_map, - "Skip hashes", rspamd_kv_list_read, rspamd_kv_list_fin, + "Skip hashes", + rspamd_kv_list_read, + rspamd_kv_list_fin, + rspamd_kv_list_dtor, (void **)&ctx->skip_hashes)) == NULL) { msg_warn_config ("cannot load hashes list from %s", ucl_object_tostring (ctx->skip_map)); diff --git a/src/libserver/cfg_utils.c b/src/libserver/cfg_utils.c index e58232a00..ef5d89ff6 100644 --- a/src/libserver/cfg_utils.c +++ b/src/libserver/cfg_utils.c @@ -56,6 +56,7 @@ static gchar * rspamd_ucl_read_cb (gchar * chunk, struct map_cb_data *data, gboolean final); static void rspamd_ucl_fin_cb (struct map_cb_data *data); +static void rspamd_ucl_dtor_cb (struct map_cb_data *data); guint rspamd_config_log_id = (guint)-1; RSPAMD_CONSTRUCTOR(rspamd_config_log_init) @@ -1083,7 +1084,8 @@ rspamd_include_map_handler (const guchar *data, gsize len, "ucl include", rspamd_ucl_read_cb, rspamd_ucl_fin_cb, - (void **)pcbdata); + rspamd_ucl_dtor_cb, + (void **)pcbdata) != NULL; } /* @@ -1364,6 +1366,19 @@ rspamd_ucl_fin_cb (struct map_cb_data *data) } } +static void +rspamd_ucl_dtor_cb (struct map_cb_data *data) +{ + struct rspamd_ucl_map_cbdata *cbdata = data->cur_data; + + if (cbdata != NULL) { + if (cbdata->buf != NULL) { + g_string_free (cbdata->buf, TRUE); + } + g_free (cbdata); + } +} + gboolean rspamd_check_module (struct rspamd_config *cfg, module_t *mod) { @@ -1888,7 +1903,10 @@ rspamd_config_radix_from_ucl (struct rspamd_config *cfg, if (rspamd_map_is_map (str)) { if (rspamd_map_add_from_ucl (cfg, cur_elt, - description, rspamd_radix_read, rspamd_radix_fin, + description, + rspamd_radix_read, + rspamd_radix_fin, + rspamd_radix_dtor, (void **)target) == NULL) { g_set_error (err, g_quark_from_static_string ("rspamd-config"), EINVAL, "bad map definition %s for %s", str, @@ -1908,7 +1926,10 @@ rspamd_config_radix_from_ucl (struct rspamd_config *cfg, case UCL_OBJECT: /* Should be a map description */ if (rspamd_map_add_from_ucl (cfg, cur_elt, - description, rspamd_radix_read, rspamd_radix_fin, + description, + rspamd_radix_read, + rspamd_radix_fin, + rspamd_radix_dtor, (void **)target) == NULL) { g_set_error (err, g_quark_from_static_string ("rspamd-config"), EINVAL, "bad map object for %s", ucl_object_key (obj)); diff --git a/src/libserver/dynamic_cfg.c b/src/libserver/dynamic_cfg.c index 584590ed9..17818888e 100644 --- a/src/libserver/dynamic_cfg.c +++ b/src/libserver/dynamic_cfg.c @@ -222,6 +222,22 @@ json_config_fin_cb (struct map_cb_data *data) jb->cfg->current_dynamic_conf = top; } +static void +json_config_dtor_cb (struct map_cb_data *data) +{ + struct config_json_buf *jb; + + if (data->cur_data) { + jb = data->cur_data; + /* Clean prev data */ + if (jb->buf) { + g_string_free (jb->buf, TRUE); + } + + g_free (jb); + } +} + /** * Init dynamic configuration using map logic and specific configuration * @param cfg config file @@ -244,8 +260,13 @@ init_dynamic_config (struct rspamd_config *cfg) *pjb = jb; cfg->current_dynamic_conf = ucl_object_typed_new (UCL_ARRAY); - if (!rspamd_map_add (cfg, cfg->dynamic_conf, "Dynamic configuration map", - json_config_read_cb, json_config_fin_cb, (void **)pjb)) { + if (!rspamd_map_add (cfg, + cfg->dynamic_conf, + "Dynamic configuration map", + json_config_read_cb, + json_config_fin_cb, + json_config_dtor_cb, + (void **)pjb)) { msg_err ("cannot add map for configuration %s", cfg->dynamic_conf); } } diff --git a/src/libserver/worker_util.c b/src/libserver/worker_util.c index 8c4e934bc..c60273dea 100644 --- a/src/libserver/worker_util.c +++ b/src/libserver/worker_util.c @@ -342,7 +342,6 @@ rspamd_worker_stop_accept (struct rspamd_worker *worker) { GList *cur; struct event *events; - struct rspamd_map *map; /* Remove all events */ cur = worker->accept_events; @@ -383,15 +382,7 @@ rspamd_worker_stop_accept (struct rspamd_worker *worker) #endif /* Cleanup maps */ - for (cur = worker->srv->cfg->maps; cur != NULL; cur = g_list_next (cur)) { - map = cur->data; - - if (map->dtor) { - map->dtor (map->dtor_data); - } - - map->dtor = NULL; - } + rspamd_map_remove_all (worker->srv->cfg); } static rspamd_fstring_t * diff --git a/src/libutil/map.c b/src/libutil/map.c index f666ad98d..efbf85c45 100644 --- a/src/libutil/map.c +++ b/src/libutil/map.c @@ -47,15 +47,6 @@ static void rspamd_map_periodic_callback (gint fd, short what, void *ud); static void rspamd_map_schedule_periodic (struct rspamd_map *map, gboolean locked, gboolean initial, gboolean errored); -struct rspamd_http_map_cached_cbdata { - struct event timeout; - struct rspamd_storage_shmem *shm; - struct rspamd_map *map; - struct http_map_data *data; - guint64 gen; - time_t last_checked; -}; - guint rspamd_map_log_id = (guint)-1; RSPAMD_CONSTRUCTOR(rspamd_map_log_init) { @@ -285,8 +276,8 @@ free_http_cbdata_common (struct http_callback_data *cbd, gboolean plan_new) static void free_http_cbdata (struct http_callback_data *cbd) { - cbd->map->dtor = NULL; - cbd->map->dtor_data = NULL; + cbd->map->tmp_dtor = NULL; + cbd->map->tmp_dtor_data = NULL; free_http_cbdata_common (cbd, TRUE); } @@ -365,6 +356,7 @@ rspamd_map_cache_cb (gint fd, short what, gpointer ud) event_add (&cache_cbd->timeout, &tv); } else { + map->cur_cache_cbd = NULL; g_atomic_int_set (&map->cache->available, 0); MAP_RELEASE (cache_cbd->shm, "rspamd_http_map_cached_cbdata"); msg_info_map ("cached data is now expired for %s", map->name); @@ -453,6 +445,7 @@ http_map_finish (struct rspamd_http_connection *conn, cbd->periodic->cur_backend = 0; /* Reset cache, old cached data will be cleaned on timeout */ g_atomic_int_set (&map->cache->available, 0); + map->cur_cache_cbd = NULL; rspamd_map_periodic_callback (-1, EV_TIMEOUT, cbd->periodic); MAP_RELEASE (cbd, "http_callback_data"); @@ -677,6 +670,7 @@ read_data: cache_cbd); event_base_set (cbd->ev_base, &cache_cbd->timeout); event_add (&cache_cbd->timeout, &tv); + map->cur_cache_cbd = cache_cbd; if (map->next_check) { rspamd_http_date_format (next_check_date, sizeof (next_check_date), @@ -1396,8 +1390,8 @@ check: MAP_RETAIN (cbd, "http_callback_data"); } - map->dtor = free_http_cbdata_dtor; - map->dtor_data = cbd; + map->tmp_dtor = free_http_cbdata_dtor; + map->tmp_dtor_data = cbd; } else { msg_warn_map ("cannot load map: DNS resolver is not initialized"); @@ -1663,6 +1657,7 @@ rspamd_map_remove_all (struct rspamd_config *cfg) struct rspamd_map *map; GList *cur; struct rspamd_map_backend *bk; + struct map_cb_data cbdata; guint i; for (cur = cfg->maps; cur != NULL; cur = g_list_next (cur)) { @@ -1674,11 +1669,27 @@ rspamd_map_remove_all (struct rspamd_config *cfg) } if (g_atomic_int_compare_and_exchange (&map->cache->available, 1, 0)) { + if (map->cur_cache_cbd) { + MAP_RELEASE (map->cur_cache_cbd->shm, "rspamd_http_map_cached_cbdata"); + event_del (&map->cur_cache_cbd->timeout); + g_free (map->cur_cache_cbd); + map->cur_cache_cbd = NULL; + } + unlink (map->cache->shmem_name); } + if (map->tmp_dtor) { + map->tmp_dtor (map->tmp_dtor_data); + } + if (map->dtor) { - map->dtor (map->dtor_data); + cbdata.prev_data = NULL; + cbdata.map = map; + cbdata.cur_data = *map->user_data; + + map->dtor (&cbdata); + *map->user_data = NULL; } } @@ -2015,11 +2026,12 @@ rspamd_map_add_static_string (struct rspamd_config *cfg, struct rspamd_map * rspamd_map_add (struct rspamd_config *cfg, - const gchar *map_line, - const gchar *description, - map_cb_t read_callback, - map_fin_cb_t fin_callback, - void **user_data) + const gchar *map_line, + const gchar *description, + map_cb_t read_callback, + map_fin_cb_t fin_callback, + map_dtor_t dtor, + void **user_data) { struct rspamd_map *map; struct rspamd_map_backend *bk; @@ -2032,6 +2044,7 @@ rspamd_map_add (struct rspamd_config *cfg, map = rspamd_mempool_alloc0 (cfg->cfg_pool, sizeof (struct rspamd_map)); map->read_callback = read_callback; map->fin_callback = fin_callback; + map->dtor = dtor; map->user_data = user_data; map->cfg = cfg; map->id = rspamd_random_uint64_fast (); @@ -2065,11 +2078,12 @@ rspamd_map_add (struct rspamd_config *cfg, struct rspamd_map* rspamd_map_add_from_ucl (struct rspamd_config *cfg, - const ucl_object_t *obj, - const gchar *description, - map_cb_t read_callback, - map_fin_cb_t fin_callback, - void **user_data) + const ucl_object_t *obj, + const gchar *description, + map_cb_t read_callback, + map_fin_cb_t fin_callback, + map_dtor_t dtor, + void **user_data) { ucl_object_iter_t it = NULL; const ucl_object_t *cur, *elt; @@ -2082,12 +2096,13 @@ rspamd_map_add_from_ucl (struct rspamd_config *cfg, if (ucl_object_type (obj) == UCL_STRING) { /* Just a plain string */ return rspamd_map_add (cfg, ucl_object_tostring (obj), description, - read_callback, fin_callback, user_data); + read_callback, fin_callback, dtor, user_data); } map = rspamd_mempool_alloc0 (cfg->cfg_pool, sizeof (struct rspamd_map)); map->read_callback = read_callback; map->fin_callback = fin_callback; + map->dtor = dtor; map->user_data = user_data; map->cfg = cfg; map->id = rspamd_random_uint64_fast (); diff --git a/src/libutil/map.h b/src/libutil/map.h index d10ee331a..e12df4369 100644 --- a/src/libutil/map.h +++ b/src/libutil/map.h @@ -22,6 +22,7 @@ struct map_cb_data; typedef gchar * (*map_cb_t)(gchar *chunk, gint len, struct map_cb_data *data, gboolean final); typedef void (*map_fin_cb_t)(struct map_cb_data *data); +typedef void (*map_dtor_t)(struct map_cb_data *data); typedef gboolean (*rspamd_map_traverse_cb)(gconstpointer key, gconstpointer value, gsize hits, gpointer ud); @@ -56,21 +57,23 @@ gboolean rspamd_map_is_map (const gchar *map_line); * Add map from line */ struct rspamd_map* rspamd_map_add (struct rspamd_config *cfg, - const gchar *map_line, - const gchar *description, - map_cb_t read_callback, - map_fin_cb_t fin_callback, - void **user_data); + const gchar *map_line, + const gchar *description, + map_cb_t read_callback, + map_fin_cb_t fin_callback, + map_dtor_t dtor, + void **user_data); /** * Add map from ucl */ struct rspamd_map* rspamd_map_add_from_ucl (struct rspamd_config *cfg, - const ucl_object_t *obj, - const gchar *description, - map_cb_t read_callback, - map_fin_cb_t fin_callback, - void **user_data); + const ucl_object_t *obj, + const gchar *description, + map_cb_t read_callback, + map_fin_cb_t fin_callback, + map_dtor_t dtor, + void **user_data); /** * Start watching of maps by adding events to libevent event loop diff --git a/src/libutil/map_helpers.c b/src/libutil/map_helpers.c index d0e3e2e95..6c8117cff 100644 --- a/src/libutil/map_helpers.c +++ b/src/libutil/map_helpers.c @@ -813,6 +813,17 @@ rspamd_kv_list_fin (struct map_cb_data *data) } } +void +rspamd_kv_list_dtor (struct map_cb_data *data) +{ + struct rspamd_hash_map_helper *htb; + + if (data->cur_data) { + htb = (struct rspamd_hash_map_helper *)data->cur_data; + rspamd_map_helper_destroy_hash (htb); + } +} + gchar * rspamd_radix_read ( gchar * chunk, @@ -858,6 +869,17 @@ rspamd_radix_fin (struct map_cb_data *data) } } +void +rspamd_radix_dtor (struct map_cb_data *data) +{ + struct rspamd_radix_map_helper *r; + + if (data->cur_data) { + r = (struct rspamd_radix_map_helper *)data->cur_data; + rspamd_map_helper_destroy_radix (r); + } +} + static void rspamd_re_map_finalize (struct rspamd_regexp_map_helper *re_map) { @@ -1037,6 +1059,13 @@ rspamd_regexp_list_fin (struct map_cb_data *data) data->map->digest = rspamd_cryptobox_fast_hash_final (&re_map->hst); } } +void +rspamd_regexp_list_dtor (struct map_cb_data *data) +{ + if (data->cur_data) { + rspamd_map_helper_destroy_regexp (data->cur_data); + } +} #ifdef WITH_HYPERSCAN static int diff --git a/src/libutil/map_helpers.h b/src/libutil/map_helpers.h index bd933fbf2..28a5e336b 100644 --- a/src/libutil/map_helpers.h +++ b/src/libutil/map_helpers.h @@ -53,7 +53,7 @@ gchar * rspamd_radix_read ( struct map_cb_data *data, gboolean final); void rspamd_radix_fin (struct map_cb_data *data); - +void rspamd_radix_dtor (struct map_cb_data *data); /** * Kv list is an ordinal list of keys and values separated by whitespace @@ -64,6 +64,7 @@ gchar * rspamd_kv_list_read ( struct map_cb_data *data, gboolean final); void rspamd_kv_list_fin (struct map_cb_data *data); +void rspamd_kv_list_dtor (struct map_cb_data *data); /** * Regexp list is a list of regular expressions @@ -85,6 +86,7 @@ gchar * rspamd_glob_list_read_single ( struct map_cb_data *data, gboolean final); void rspamd_regexp_list_fin (struct map_cb_data *data); +void rspamd_regexp_list_dtor (struct map_cb_data *data); /** * FSM for lists parsing (support comments, blank lines and partial replies) diff --git a/src/libutil/map_private.h b/src/libutil/map_private.h index 1ea8d8040..b8543356b 100644 --- a/src/libutil/map_private.h +++ b/src/libutil/map_private.h @@ -23,7 +23,7 @@ #include "map.h" #include "ref.h" -typedef void (*rspamd_map_dtor) (gpointer p); +typedef void (*rspamd_map_tmp_dtor) (gpointer p); extern guint rspamd_map_log_id; #define msg_err_map(...) rspamd_default_log_function (G_LOG_LEVEL_CRITICAL, \ "map", map->tag, \ @@ -95,6 +95,15 @@ struct rspamd_map_backend { ref_entry_t ref; }; +struct rspamd_http_map_cached_cbdata { + struct event timeout; + struct rspamd_storage_shmem *shm; + struct rspamd_map *map; + struct http_map_data *data; + guint64 gen; + time_t last_checked; +}; + struct rspamd_map_cachepoint { gint available; gsize len; @@ -108,14 +117,15 @@ struct rspamd_map { GPtrArray *backends; map_cb_t read_callback; map_fin_cb_t fin_callback; + map_dtor_t dtor; void **user_data; struct event_base *ev_base; gchar *description; gchar *name; guint32 id; gboolean scheduled_check; - rspamd_map_dtor dtor; - gpointer dtor_data; + rspamd_map_tmp_dtor tmp_dtor; + gpointer tmp_dtor_data; rspamd_map_traverse_function traverse_function; gpointer lua_map; gsize nelts; @@ -129,6 +139,8 @@ struct rspamd_map { gint *locked; /* Shared cache data */ struct rspamd_map_cachepoint *cache; + /* Non-shared for cache owner, used to cleanup cache */ + struct rspamd_http_map_cached_cbdata *cur_cache_cbd; gchar tag[MEMPOOL_UID_LEN]; }; diff --git a/src/lua/lua_map.c b/src/lua/lua_map.c index 2d2a098d2..d5914706c 100644 --- a/src/lua/lua_map.c +++ b/src/lua/lua_map.c @@ -156,6 +156,7 @@ lua_config_add_radix_map (lua_State *L) if ((m = rspamd_map_add (cfg, map_line, description, rspamd_radix_read, rspamd_radix_fin, + rspamd_radix_dtor, (void **)&map->data.radix)) == NULL) { msg_warn_config ("invalid radix map %s", map_line); lua_pushnil (L); @@ -211,6 +212,7 @@ lua_config_radix_from_config (lua_State *L) if ((m = rspamd_map_add_from_ucl (cfg, fake_obj, "static radix map", rspamd_radix_read, rspamd_radix_fin, + rspamd_radix_dtor, (void **)&map->data.radix)) == NULL) { msg_err_config ("invalid radix map static"); lua_pushnil (L); @@ -270,6 +272,7 @@ lua_config_radix_from_ucl (lua_State *L) if ((m = rspamd_map_add_from_ucl (cfg, fake_obj, "static radix map", rspamd_radix_read, rspamd_radix_fin, + rspamd_radix_dtor, (void **)&map->data.radix)) == NULL) { msg_err_config ("invalid radix map static"); lua_pushnil (L); @@ -311,6 +314,7 @@ lua_config_add_hash_map (lua_State *L) if ((m = rspamd_map_add (cfg, map_line, description, rspamd_kv_list_read, rspamd_kv_list_fin, + rspamd_kv_list_dtor, (void **)&map->data.hash)) == NULL) { msg_warn_config ("invalid set map %s", map_line); lua_pushnil (L); @@ -349,6 +353,7 @@ lua_config_add_kv_map (lua_State *L) if ((m = rspamd_map_add (cfg, map_line, description, rspamd_kv_list_read, rspamd_kv_list_fin, + rspamd_kv_list_dtor, (void **)&map->data.hash)) == NULL) { msg_warn_config ("invalid hash map %s", map_line); lua_pushnil (L); @@ -441,6 +446,23 @@ lua_map_fin (struct map_cb_data *data) cbdata->data = rspamd_fstring_assign (cbdata->data, "", 0); } +static void +lua_map_dtor (struct map_cb_data *data) +{ + struct lua_map_callback_data *cbdata; + + if (data->cur_data) { + cbdata = (struct lua_map_callback_data *)data->cur_data; + if (cbdata->ref != -1) { + luaL_unref (cbdata->L, LUA_REGISTRYINDEX, cbdata->ref); + } + + if (cbdata->data) { + rspamd_fstring_free (cbdata->data); + } + } +} + gint lua_config_add_map (lua_State *L) { @@ -488,7 +510,9 @@ lua_config_add_map (lua_State *L) cbdata->ref = cbidx; if ((m = rspamd_map_add_from_ucl (cfg, map_obj, description, - lua_map_read, lua_map_fin, + lua_map_read, + lua_map_fin, + lua_map_dtor, (void **)&map->data.cbdata)) == NULL) { if (cbidx != -1) { @@ -513,6 +537,7 @@ lua_config_add_map (lua_State *L) if ((m = rspamd_map_add_from_ucl (cfg, map_obj, description, rspamd_kv_list_read, rspamd_kv_list_fin, + rspamd_kv_list_dtor, (void **)&map->data.hash)) == NULL) { lua_pushnil (L); ucl_object_unref (map_obj); @@ -529,6 +554,7 @@ lua_config_add_map (lua_State *L) if ((m = rspamd_map_add_from_ucl (cfg, map_obj, description, rspamd_kv_list_read, rspamd_kv_list_fin, + rspamd_kv_list_dtor, (void **)&map->data.hash)) == NULL) { lua_pushnil (L); ucl_object_unref (map_obj); @@ -545,6 +571,7 @@ lua_config_add_map (lua_State *L) if ((m = rspamd_map_add_from_ucl (cfg, map_obj, description, rspamd_radix_read, rspamd_radix_fin, + rspamd_radix_dtor, (void **)&map->data.radix)) == NULL) { lua_pushnil (L); ucl_object_unref (map_obj); @@ -561,6 +588,7 @@ lua_config_add_map (lua_State *L) if ((m = rspamd_map_add_from_ucl (cfg, map_obj, description, rspamd_regexp_list_read_single, rspamd_regexp_list_fin, + rspamd_regexp_list_dtor, (void **) &map->data.re_map)) == NULL) { lua_pushnil (L); ucl_object_unref (map_obj); @@ -577,6 +605,7 @@ lua_config_add_map (lua_State *L) if ((m = rspamd_map_add_from_ucl (cfg, map_obj, description, rspamd_regexp_list_read_multiple, rspamd_regexp_list_fin, + rspamd_regexp_list_dtor, (void **) &map->data.re_map)) == NULL) { lua_pushnil (L); ucl_object_unref (map_obj); @@ -593,6 +622,7 @@ lua_config_add_map (lua_State *L) if ((m = rspamd_map_add_from_ucl (cfg, map_obj, description, rspamd_glob_list_read_single, rspamd_regexp_list_fin, + rspamd_regexp_list_dtor, (void **) &map->data.re_map)) == NULL) { lua_pushnil (L); ucl_object_unref (map_obj); diff --git a/src/plugins/dkim_check.c b/src/plugins/dkim_check.c index 74bc4ea54..ba2d9e2e3 100644 --- a/src/plugins/dkim_check.c +++ b/src/plugins/dkim_check.c @@ -409,8 +409,11 @@ dkim_module_config (struct rspamd_config *cfg) if ((value = rspamd_config_get_module_opt (cfg, "dkim", "domains")) != NULL) { if (!rspamd_map_add_from_ucl (cfg, value, - "DKIM domains", rspamd_kv_list_read, rspamd_kv_list_fin, - (void **)&dkim_module_ctx->dkim_domains)) { + "DKIM domains", + rspamd_kv_list_read, + rspamd_kv_list_fin, + rspamd_kv_list_dtor, + (void **)&dkim_module_ctx->dkim_domains)) { msg_warn_config ("cannot load dkim domains list from %s", ucl_object_tostring (value)); } @@ -425,7 +428,10 @@ dkim_module_config (struct rspamd_config *cfg) if (!got_trusted && (value = rspamd_config_get_module_opt (cfg, "dkim", "trusted_domains")) != NULL) { if (!rspamd_map_add_from_ucl (cfg, value, - "DKIM domains", rspamd_kv_list_read, rspamd_kv_list_fin, + "DKIM domains", + rspamd_kv_list_read, + rspamd_kv_list_fin, + rspamd_kv_list_dtor, (void **)&dkim_module_ctx->dkim_domains)) { msg_warn_config ("cannot load dkim domains list from %s", ucl_object_tostring (value)); diff --git a/src/plugins/fuzzy_check.c b/src/plugins/fuzzy_check.c index c4318777f..0266d3edd 100644 --- a/src/plugins/fuzzy_check.c +++ b/src/plugins/fuzzy_check.c @@ -425,8 +425,11 @@ fuzzy_parse_rule (struct rspamd_config *cfg, const ucl_object_t *obj, if ((value = ucl_object_lookup (obj, "skip_hashes")) != NULL) { rspamd_map_add_from_ucl (cfg, value, - "Fuzzy hashes whitelist", rspamd_kv_list_read, rspamd_kv_list_fin, - (void **)&rule->skip_map); + "Fuzzy hashes whitelist", + rspamd_kv_list_read, + rspamd_kv_list_fin, + rspamd_kv_list_dtor, + (void **)&rule->skip_map); rspamd_mempool_add_destructor (fuzzy_module_ctx->fuzzy_pool, (rspamd_mempool_destruct_t)rspamd_map_helper_destroy_radix, rule->skip_map); diff --git a/src/plugins/surbl.c b/src/plugins/surbl.c index d0bdd3b8c..238f14fb2 100644 --- a/src/plugins/surbl.c +++ b/src/plugins/surbl.c @@ -269,6 +269,23 @@ fin_exceptions_list (struct map_cb_data *data) } } +static void +dtor_exceptions_list (struct map_cb_data *data) +{ + GHashTable **t; + gint i; + + if (data->cur_data) { + t = data->cur_data; + for (i = 0; i < MAX_LEVELS; i++) { + if (t[i] != NULL) { + g_hash_table_destroy (t[i]); + } + t[i] = NULL; + } + } +} + static void redirector_insert (gpointer st, gconstpointer key, gconstpointer value) { @@ -361,6 +378,18 @@ fin_redirectors_list (struct map_cb_data *data) surbl_module_ctx->redirector_tlds = tld_hash; } +void +dtor_redirectors_list (struct map_cb_data *data) +{ + GHashTable *tld_hash; + + if (data->cur_data) { + tld_hash = data->cur_data; + + g_hash_table_unref (tld_hash); + } +} + gint surbl_module_init (struct rspamd_config *cfg, struct module_ctx **ctx) { @@ -946,8 +975,11 @@ surbl_module_config (struct rspamd_config *cfg) rspamd_config_get_module_opt (cfg, "surbl", "redirector_hosts_map")) != NULL) { if (!rspamd_map_add_from_ucl (cfg, value, - "SURBL redirectors list", read_redirectors_list, fin_redirectors_list, - (void **)&surbl_module_ctx->redirector_map_data)) { + "SURBL redirectors list", + read_redirectors_list, + fin_redirectors_list, + dtor_redirectors_list, + (void **)&surbl_module_ctx->redirector_map_data)) { msg_warn_config ("bad redirectors map definition: %s", ucl_obj_tostring (value)); @@ -958,13 +990,18 @@ surbl_module_config (struct rspamd_config *cfg) rspamd_config_get_module_opt (cfg, "surbl", "exceptions")) != NULL) { rspamd_map_add_from_ucl (cfg, value, "SURBL exceptions list", - read_exceptions_list, fin_exceptions_list, + read_exceptions_list, + fin_exceptions_list, + dtor_exceptions_list, (void **)&surbl_module_ctx->exceptions); } if ((value = rspamd_config_get_module_opt (cfg, "surbl", "whitelist")) != NULL) { rspamd_map_add_from_ucl (cfg, value, - "SURBL whitelist", rspamd_kv_list_read, rspamd_kv_list_fin, + "SURBL whitelist", + rspamd_kv_list_read, + rspamd_kv_list_fin, + rspamd_kv_list_dtor, (void **)&surbl_module_ctx->whitelist); }