]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
Rework addresses parsing.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 1 Oct 2014 14:58:23 +0000 (15:58 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 1 Oct 2014 14:58:23 +0000 (15:58 +0100)
src/libserver/cfg_file.h
src/libserver/cfg_utils.c
src/libutil/map.c
src/libutil/radix.c
src/libutil/radix.h
src/libutil/util.c
src/libutil/util.h

index a16541ebe57ee9ab4afa3c963990ec98bd7721ab..7e3d60db8eb277b8e5017596276284115838b420 100644 (file)
@@ -480,7 +480,7 @@ struct rspamd_classifier_config * rspamd_config_find_classifier (
  * Parse input `ip_list` to radix tree `tree`. Now supports only IPv4 addresses.
  */
 gboolean rspamd_config_parse_ip_list (const gchar *ip_list,
-       radix_tree_t **tree);
+               radix_compressed_t **tree);
 
 void rspamd_ucl_add_conf_macros (struct ucl_parser *parser,
        struct rspamd_config *cfg);
index 4d2b868803159884a526171135f8028753f73d2a..aecef53d4c8708a13b6558b16d7540def253ae89 100644 (file)
@@ -1005,27 +1005,13 @@ rspamd_ucl_fin_cb (rspamd_mempool_t * pool, struct map_cb_data *data)
 }
 
 gboolean
-rspamd_config_parse_ip_list (const gchar *ip_list, radix_tree_t **tree)
+rspamd_config_parse_ip_list (const gchar *ip_list, radix_compressed_t **tree)
 {
-       gchar **strvec, **cur;
-       struct in_addr ina;
-       guint32 mask;
-
-       strvec = g_strsplit_set (ip_list, ",", 0);
-       cur = strvec;
-
-       while (*cur != NULL) {
-               /* XXX: handle only ipv4 addresses */
-               if (parse_ipmask_v4 (*cur, &ina, &mask)) {
-                       if (*tree == NULL) {
-                               *tree = radix_tree_create ();
-                       }
-                       radix32tree_add (*tree, htonl (ina.s_addr), mask, 1);
-               }
-               cur++;
+       if (*tree == NULL) {
+               *tree = radix_create_compressed ();
        }
 
-       return (*tree != NULL);
+       return (rspamd_radix_add_iplist (ip_list, ",; ", *tree) > 0);
 }
 
 /*
index 7d0313d951dd8812d06244f17616b0e94fd82427..89ab75b64e823753b61152402d24280e9ddc1ec0 100644 (file)
@@ -798,65 +798,7 @@ radix_tree_insert_helper (gpointer st, gconstpointer key, gpointer value)
 {
        radix_compressed_t *tree = (radix_compressed_t *)st;
 
-       gchar *token, *ipnet, *err_str, **strv, **cur;
-       struct in_addr ina;
-       struct in6_addr ina6;
-       guint k = 0;
-       gint af;
-
-       /* Split string if there are multiple items inside a single string */
-       strv = g_strsplit_set ((gchar *)key, " ,;", 0);
-       cur = strv;
-       while (*cur) {
-               af = AF_UNSPEC;
-               if (**cur == '\0') {
-                       cur++;
-                       continue;
-               }
-               /* Extract ipnet */
-               ipnet = *cur;
-               token = strsep (&ipnet, "/");
-
-               if (ipnet != NULL) {
-                       errno = 0;
-                       /* Get mask */
-                       k = strtoul (ipnet, &err_str, 10);
-                       if (errno != 0) {
-                               msg_warn (
-                                       "invalid netmask, error detected on symbol: %s, erorr: %s",
-                                       err_str,
-                                       strerror (errno));
-                               k = 32;
-                       }
-               }
-
-               /* Check IP */
-               if (inet_pton (AF_INET, token, &ina) == 1) {
-                       af = AF_INET;
-               }
-               else if (inet_pton (AF_INET6, token, &ina6) == 1) {
-                       af = AF_INET6;
-               }
-               else {
-                       msg_warn ("invalid IP address: %s", token);
-               }
-
-               if (af == AF_INET) {
-                       if (k > 32) {
-                               k = 32;
-                       }
-                       radix_insert_compressed (tree, (guint8 *)&ina, sizeof (ina), 32 - k, 1);
-               }
-               else if (af == AF_INET6){
-                       if (k > 128) {
-                               k = 128;
-                       }
-                       radix_insert_compressed (tree, (guint8 *)&ina6, sizeof (ina6), 128 - k, 1);
-               }
-               cur++;
-       }
-
-       g_strfreev (strv);
+       rspamd_radix_add_iplist ((gchar *)key, " ,;", tree);
 }
 
 /* Helpers */
index acf276285a2b537c0666be5814b66e46c46303f1..240a7d67de14111a330e393d5d6ae3bc964a90dc 100644 (file)
@@ -887,6 +887,78 @@ radix_find_compressed_addr (radix_compressed_t *tree, rspamd_inet_addr_t *addr)
        return RADIX_NO_VALUE;
 }
 
+gint
+rspamd_radix_add_iplist (const gchar *list, const gchar *separators,
+               radix_compressed_t *tree)
+{
+       gchar *token, *ipnet, *err_str, **strv, **cur;
+       struct in_addr ina;
+       struct in6_addr ina6;
+       guint k = 0;
+       gint af;
+       gint res = 0;
+
+       /* Split string if there are multiple items inside a single string */
+       strv = g_strsplit_set (list, separators, 0);
+       cur = strv;
+       while (*cur) {
+               af = AF_UNSPEC;
+               if (**cur == '\0') {
+                       cur++;
+                       continue;
+               }
+               /* Extract ipnet */
+               ipnet = *cur;
+               token = strsep (&ipnet, "/");
+
+               if (ipnet != NULL) {
+                       errno = 0;
+                       /* Get mask */
+                       k = strtoul (ipnet, &err_str, 10);
+                       if (errno != 0) {
+                               msg_warn (
+                                               "invalid netmask, error detected on symbol: %s, erorr: %s",
+                                               err_str,
+                                               strerror (errno));
+                               k = 32;
+                       }
+               }
+
+               /* Check IP */
+               if (inet_pton (AF_INET, token, &ina) == 1) {
+                       af = AF_INET;
+               }
+               else if (inet_pton (AF_INET6, token, &ina6) == 1) {
+                       af = AF_INET6;
+               }
+               else {
+                       msg_warn ("invalid IP address: %s", token);
+               }
+
+               if (af == AF_INET) {
+                       if (k > 32) {
+                               k = 32;
+                       }
+                       radix_insert_compressed (tree, (guint8 *)&ina, sizeof (ina),
+                                       32 - k, 1);
+                       res ++;
+               }
+               else if (af == AF_INET6){
+                       if (k > 128) {
+                               k = 128;
+                       }
+                       radix_insert_compressed (tree, (guint8 *)&ina6, sizeof (ina6),
+                                       128 - k, 1);
+                       res ++;
+               }
+               cur++;
+       }
+
+       g_strfreev (strv);
+
+       return res;
+}
+
 /*
  * vi:ts=4
  */
index 38af00b51f529902724294742027b2b91df9f6c9..5bf6a1dd801d76dd6f1b6d511e22cbcdd00e49cc 100644 (file)
@@ -117,4 +117,14 @@ void radix_destroy_compressed (radix_compressed_t *tree);
 
 radix_compressed_t *radix_create_compressed (void);
 
+/**
+ * Insert list of ip addresses and masks to the radix tree
+ * @param list string line of addresses
+ * @param separators string of characters used as separators
+ * @param tree target tree
+ * @return number of elements inserted
+ */
+gint rspamd_radix_add_iplist (const gchar *list, const gchar *separators,
+               radix_compressed_t *tree);
+
 #endif
index a4117d3c36aff686a8545e65c4026bd0d03c89ed..73ab644531a95988bb81f0b81861cd701fceeff1 100644 (file)
@@ -1855,43 +1855,6 @@ rspamd_str_pool_copy (gconstpointer data, gpointer ud)
        return data ? rspamd_mempool_strdup (pool, data) : NULL;
 }
 
-gboolean
-parse_ipmask_v4 (const char *line, struct in_addr *ina, int *mask)
-{
-       const char *pos;
-       char ip_buf[INET_ADDRSTRLEN + 1], mask_buf[3] = { '\0', '\0', '\0' };
-
-       bzero (ip_buf, sizeof (ip_buf));
-
-       if ((pos = strchr (line, '/')) != NULL) {
-               rspamd_strlcpy (ip_buf, line,
-                       MIN ((gsize)(pos - line), sizeof (ip_buf)));
-               rspamd_strlcpy (mask_buf, pos + 1, sizeof (mask_buf));
-       }
-       else {
-               rspamd_strlcpy (ip_buf, line, sizeof (ip_buf));
-       }
-
-       if (!inet_aton (ip_buf, ina)) {
-               return FALSE;
-       }
-
-       if (mask_buf[0] != '\0') {
-               /* Also parse mask */
-               *mask = (mask_buf[0] - '0') * 10 + mask_buf[1] - '0';
-               if (*mask > 32) {
-                       return FALSE;
-               }
-       }
-       else {
-               *mask = 32;
-       }
-
-       *mask = G_MAXUINT32 << (32 - *mask);
-
-       return TRUE;
-}
-
 static volatile sig_atomic_t saved_signo[NSIG];
 
 static
@@ -2253,7 +2216,7 @@ rspamd_inet_address_connect (rspamd_inet_addr_t *addr, gint type,
  */
 
 gchar *
-rspamd_encode_base32(guchar *in, gsize inlen)
+rspamd_encode_base32 (guchar *in, gsize inlen)
 {
        gint remain = -1, r, x;
        gsize i;
index 1b95ab8a0c0c0c4e3e8b8762617ef49e70df522d..40d8004e31f58c21f35134d5123005631232b1de 100644 (file)
@@ -407,15 +407,6 @@ void rspamd_hash_table_copy (GHashTable *src, GHashTable *dst,
  */
 gpointer rspamd_str_pool_copy (gconstpointer data, gpointer ud);
 
-/**
- * Parse ipv4 address with optional mask in CIDR format
- * @param line cidr notation of ipv4 address
- * @param ina destination address
- * @param mask destination mask
- * @return
- */
-gboolean parse_ipmask_v4 (const char *line, struct in_addr *ina, int *mask);
-
 /**
  * Read passphrase from tty
  * @param buf buffer to fill with a password
@@ -495,6 +486,6 @@ int rspamd_inet_address_connect (rspamd_inet_addr_t *addr, gint type,
  * @param inlen input length
  * @return freshly allocated base32 encoding of a specified string
  */
-gchar * rspamd_encode_base32(guchar *in, gsize inlen);
+gchar * rspamd_encode_base32 (guchar *in, gsize inlen);
 
 #endif