From: Vsevolod Stakhov Date: Sat, 25 Jun 2016 12:14:09 +0000 (+0100) Subject: [Feature] Add generic fucnction to parse IP maps X-Git-Tag: 1.3.0~255 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=62e266e47646a68bd9de0d3d49490dcc606799d7;p=rspamd.git [Feature] Add generic fucnction to parse IP maps Issue: #679 --- diff --git a/src/libserver/cfg_file.h b/src/libserver/cfg_file.h index eaaafc318..4a0c17062 100644 --- a/src/libserver/cfg_file.h +++ b/src/libserver/cfg_file.h @@ -15,6 +15,7 @@ #include "regexp.h" #include "libserver/re_cache.h" #include "ref.h" +#include "libutil/radix.h" #define DEFAULT_BIND_PORT 11333 #define DEFAULT_CONTROL_PORT 11334 @@ -606,6 +607,20 @@ gboolean rspamd_config_set_action_score (struct rspamd_config *cfg, gboolean rspamd_config_is_module_enabled (struct rspamd_config *cfg, const gchar *module_name); +/** + * Parse radix tree or radix map from ucl object + * @param cfg configuration object + * @param obj ucl object with parameter + * @param target target radix tree + * @param err error pointer + * @return + */ +gboolean rspamd_config_radix_from_ucl (struct rspamd_config *cfg, + const ucl_object_t *obj, + const gchar *description, + radix_compressed_t **target, + GError **err); + #define msg_err_config(...) rspamd_default_log_function (G_LOG_LEVEL_CRITICAL, \ cfg->cfg_pool->tag.tagname, cfg->checksum, \ G_STRFUNC, \ diff --git a/src/libserver/cfg_rcl.c b/src/libserver/cfg_rcl.c index 4f8d3cb36..976198b9b 100644 --- a/src/libserver/cfg_rcl.c +++ b/src/libserver/cfg_rcl.c @@ -2896,6 +2896,22 @@ rspamd_rcl_parse_struct_ucl (rspamd_mempool_t *pool, return TRUE; } +gboolean +rspamd_rcl_parse_struct_iplist (rspamd_mempool_t *pool, + const ucl_object_t *obj, + gpointer ud, + struct rspamd_rcl_section *section, + GError **err) +{ + struct rspamd_rcl_struct_parser *pd = ud; + radix_compressed_t **target; + + target = (radix_compressed_t **)(((gchar *)pd->user_struct) + pd->offset); + + return rspamd_config_radix_from_ucl (pd->cfg, obj, + ucl_object_key (obj), target, err); +} + gboolean rspamd_rcl_parse_struct_boolean (rspamd_mempool_t *pool, diff --git a/src/libserver/cfg_rcl.h b/src/libserver/cfg_rcl.h index 22da0a445..2fb987b51 100644 --- a/src/libserver/cfg_rcl.h +++ b/src/libserver/cfg_rcl.h @@ -343,6 +343,21 @@ gboolean rspamd_rcl_parse_struct_ucl (rspamd_mempool_t *pool, struct rspamd_rcl_section *section, GError **err); +/** + * Parse IP list or map, accepts radix_tree_t ** as an argument + * @param cfg config pointer + * @param obj object to parse + * @param ud struct_parser structure (flags mean the exact structure used) + * @param section the current section + * @param err error pointer + * @return TRUE if a value has been successfully parsed + */ +gboolean rspamd_rcl_parse_struct_iplist (rspamd_mempool_t *pool, + const ucl_object_t *obj, + gpointer ud, + struct rspamd_rcl_section *section, + GError **err); + /** * Utility functions */ diff --git a/src/libserver/cfg_utils.c b/src/libserver/cfg_utils.c index bbbb062bb..299a852aa 100644 --- a/src/libserver/cfg_utils.c +++ b/src/libserver/cfg_utils.c @@ -1642,3 +1642,81 @@ rspamd_config_set_action_score (struct rspamd_config *cfg, return TRUE; } + + +gboolean +rspamd_config_radix_from_ucl (struct rspamd_config *cfg, + const ucl_object_t *obj, + const gchar *description, + radix_compressed_t **target, + GError **err) +{ + ucl_type_t type; + ucl_object_iter_t it = NULL; + const ucl_object_t *cur; + const gchar *str; + + type = ucl_object_type (obj); + + switch (type) { + case UCL_STRING: + /* Either map or a list of IPs */ + str = ucl_object_tostring (obj); + + if (rspamd_map_is_map (str)) { + if (rspamd_map_add_from_ucl (cfg, cfg->local_addrs, + description, rspamd_radix_read, rspamd_radix_fin, + (void **)target) == NULL) { + g_set_error (err, g_quark_from_static_string ("rspamd-config"), + EINVAL, "bad map definition %s for %s", str, + ucl_object_key (obj)); + return FALSE; + } + } + else { + /* Just a list */ + if (!radix_add_generic_iplist (str, target)) { + g_set_error (err, g_quark_from_static_string ("rspamd-config"), + EINVAL, "bad map definition %s for %s", str, + ucl_object_key (obj)); + return FALSE; + } + } + break; + case UCL_OBJECT: + /* Should be a map description */ + if (rspamd_map_add_from_ucl (cfg, cfg->local_addrs, + description, rspamd_radix_read, rspamd_radix_fin, + (void **)target) == NULL) { + g_set_error (err, g_quark_from_static_string ("rspamd-config"), + EINVAL, "bad map object for %s", ucl_object_key (obj)); + return FALSE; + } + break; + case UCL_ARRAY: + /* List of IP addresses */ + while ((cur = ucl_iterate_object (obj, &it, true)) != NULL) { + str = ucl_object_tostring (cur); + + if (str == NULL || !radix_add_generic_iplist (str, target)) { + g_set_error (err, g_quark_from_static_string ("rspamd-config"), + EINVAL, "bad map element %s for %s", str, + ucl_object_key (obj)); + + if (*target) { + radix_destroy_compressed (*target); + } + + return FALSE; + } + } + break; + default: + g_set_error (err, g_quark_from_static_string ("rspamd-config"), + EINVAL, "bad map type %s for %s", ucl_object_type_to_string (type), + ucl_object_key (obj)); + return FALSE; + } + + return TRUE; +}