]> source.dussan.org Git - rspamd.git/commitdiff
[Feature] Add generic fucnction to parse IP maps
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 25 Jun 2016 12:14:09 +0000 (13:14 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 25 Jun 2016 12:14:09 +0000 (13:14 +0100)
Issue: #679

src/libserver/cfg_file.h
src/libserver/cfg_rcl.c
src/libserver/cfg_rcl.h
src/libserver/cfg_utils.c

index eaaafc318748510507a4b6e22320567eeafa3a93..4a0c170627c2bb1b6d015f94fbe81027ddd4651e 100644 (file)
@@ -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, \
index 4f8d3cb36399dab476915cc46bdcbf99ea262e74..976198b9bc5e5d26b67c2c939e00a261894aec7a 100644 (file)
@@ -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,
index 22da0a4458cfc61397e913918b87bb6656482bd8..2fb987b517c98cef95abe6a2eb7e2109d86c737b 100644 (file)
@@ -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
  */
index bbbb062bb29c7435d732d30534300b077a4fa60a..299a852aa6c9cfdef74b3830641735b93529bc2f 100644 (file)
@@ -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;
+}