diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2016-06-27 18:42:04 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2016-06-27 18:42:04 +0100 |
commit | 3bb4e1cd86c65a854bcfe4e7d0bb0a1c64347fc7 (patch) | |
tree | c21bfdd8b22b341608b160643b5d1a06ca6c87d1 | |
parent | 79052d53a490c8f1122f15e5e75465c6653d9b1a (diff) | |
download | rspamd-3bb4e1cd86c65a854bcfe4e7d0bb0a1c64347fc7.tar.gz rspamd-3bb4e1cd86c65a854bcfe4e7d0bb0a1c64347fc7.zip |
[Feature] Allow hostnames in IP maps
-rw-r--r-- | src/libserver/cfg_utils.c | 4 | ||||
-rw-r--r-- | src/libutil/map.c | 2 | ||||
-rw-r--r-- | src/libutil/radix.c | 69 | ||||
-rw-r--r-- | src/libutil/radix.h | 4 | ||||
-rw-r--r-- | src/lua/lua_map.c | 3 |
5 files changed, 69 insertions, 13 deletions
diff --git a/src/libserver/cfg_utils.c b/src/libserver/cfg_utils.c index 34029664b..7967b297f 100644 --- a/src/libserver/cfg_utils.c +++ b/src/libserver/cfg_utils.c @@ -1676,7 +1676,7 @@ rspamd_config_radix_from_ucl (struct rspamd_config *cfg, } else { /* Just a list */ - if (!radix_add_generic_iplist (str, target)) { + if (!radix_add_generic_iplist (str, target, TRUE)) { g_set_error (err, g_quark_from_static_string ("rspamd-config"), EINVAL, "bad map definition %s for %s", str, ucl_object_key (obj)); @@ -1699,7 +1699,7 @@ rspamd_config_radix_from_ucl (struct rspamd_config *cfg, while ((cur = ucl_iterate_object (cur_elt, &it, true)) != NULL) { str = ucl_object_tostring (cur); - if (str == NULL || !radix_add_generic_iplist (str, target)) { + if (str == NULL || !radix_add_generic_iplist (str, target, TRUE)) { g_set_error (err, g_quark_from_static_string ("rspamd-config"), EINVAL, "bad map element %s for %s", str, ucl_object_key (obj)); diff --git a/src/libutil/map.c b/src/libutil/map.c index 17ab1058e..171719b5e 100644 --- a/src/libutil/map.c +++ b/src/libutil/map.c @@ -1780,7 +1780,7 @@ radix_tree_insert_helper (gpointer st, gconstpointer key, gconstpointer value) { radix_compressed_t *tree = (radix_compressed_t *)st; - rspamd_radix_add_iplist ((gchar *)key, " ,;", tree, value); + rspamd_radix_add_iplist ((gchar *)key, " ,;", tree, value, FALSE); } static void diff --git a/src/libutil/radix.c b/src/libutil/radix.c index a91a82d19..14ef21fbd 100644 --- a/src/libutil/radix.c +++ b/src/libutil/radix.c @@ -140,14 +140,15 @@ radix_find_compressed_addr (radix_compressed_t *tree, gint rspamd_radix_add_iplist (const gchar *list, const gchar *separators, - radix_compressed_t *tree, gconstpointer value) + radix_compressed_t *tree, gconstpointer value, gboolean resolve) { gchar *token, *ipnet, *err_str, **strv, **cur, *brace; struct in_addr ina; struct in6_addr ina6; guint k = G_MAXINT; gint af; - gint res = 0; + gint res = 0, r; + struct addrinfo hints, *ai_res, *cur_ai; /* Split string if there are multiple items inside a single string */ strv = g_strsplit_set (list, separators, 0); @@ -209,10 +210,63 @@ rspamd_radix_add_iplist (const gchar *list, const gchar *separators, af = AF_INET6; } else { - msg_warn_radix ("invalid IP address: %s", token); - cur ++; - continue; + if (resolve) { + memset (&hints, 0, sizeof (hints)); + hints.ai_socktype = SOCK_STREAM; /* Type of the socket */ + hints.ai_flags = AI_NUMERICSERV; + hints.ai_family = AF_UNSPEC; + + if ((r = getaddrinfo (token, NULL, &hints, &ai_res)) == 0) { + for (cur_ai = ai_res; cur_ai != NULL; + cur_ai = cur_ai->ai_next) { + + if (cur_ai->ai_family == AF_INET) { + struct sockaddr_in *sin; + + sin = (struct sockaddr_in *)cur_ai->ai_addr; + if (k > 32) { + k = 32; + } + + radix_insert_compressed (tree, + (guint8 *)&sin->sin_addr, + sizeof (sin->sin_addr), + 32 - k, (uintptr_t)value); + res ++; + } + else if (cur_ai->ai_family == AF_INET6) { + struct sockaddr_in6 *sin6; + + sin6 = (struct sockaddr_in6 *)cur_ai->ai_addr; + if (k > 128) { + k = 128; + } + + radix_insert_compressed (tree, + (guint8 *)&sin6->sin6_addr, + sizeof (sin6->sin6_addr), + 128 - k, (uintptr_t)value); + res ++; + } + } + + freeaddrinfo (ai_res); + } + else { + msg_warn_radix ("getaddrinfo failed for %s: %s", token, + gai_strerror (r)); + } + + cur ++; + continue; + } + else { + msg_warn_radix ("invalid IP address: %s", token); + + cur ++; + continue; + } } } @@ -241,14 +295,15 @@ rspamd_radix_add_iplist (const gchar *list, const gchar *separators, } gboolean -radix_add_generic_iplist (const gchar *ip_list, radix_compressed_t **tree) +radix_add_generic_iplist (const gchar *ip_list, radix_compressed_t **tree, + gboolean resolve) { if (*tree == NULL) { *tree = radix_create_compressed (); } return (rspamd_radix_add_iplist (ip_list, ",; ", *tree, - GINT_TO_POINTER (1)) > 0); + GINT_TO_POINTER (1), resolve) > 0); } diff --git a/src/libutil/radix.h b/src/libutil/radix.h index 65d86499b..fc6e0db1e 100644 --- a/src/libutil/radix.h +++ b/src/libutil/radix.h @@ -79,14 +79,14 @@ radix_compressed_t *radix_create_compressed (void); * @return number of elements inserted */ gint rspamd_radix_add_iplist (const gchar *list, const gchar *separators, - radix_compressed_t *tree, gconstpointer value); + radix_compressed_t *tree, gconstpointer value, gboolean resolve); /** * Generic version of @see rspamd_radix_add_iplist. This function creates tree * if `tree` is NULL. */ gboolean radix_add_generic_iplist (const gchar *ip_list, - radix_compressed_t **tree); + radix_compressed_t **tree, gboolean resolve); /** * Returns number of elements in the tree diff --git a/src/lua/lua_map.c b/src/lua/lua_map.c index 223664a15..f6fde2124 100644 --- a/src/lua/lua_map.c +++ b/src/lua/lua_map.c @@ -174,7 +174,8 @@ lua_config_radix_from_config (lua_State *L) map->type = RSPAMD_LUA_MAP_RADIX; map->data.radix = radix_create_compressed (); map->flags |= RSPAMD_LUA_MAP_FLAG_EMBEDDED; - radix_add_generic_iplist (ucl_obj_tostring (obj), &map->data.radix); + radix_add_generic_iplist (ucl_obj_tostring (obj), &map->data.radix, + TRUE); pmap = lua_newuserdata (L, sizeof (void *)); *pmap = map; rspamd_lua_setclass (L, "rspamd{map}", -1); |