aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2014-10-01 15:58:23 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2014-10-01 15:58:23 +0100
commit6ec67947dadeba207104ac0e2c65c9e10a3a580d (patch)
tree85e7fdbbf5081c779bdec6bba723fb35815f2ff9
parenta8c9abd046add08c8ac8f91c3c12d5c823fb44e3 (diff)
downloadrspamd-6ec67947dadeba207104ac0e2c65c9e10a3a580d.tar.gz
rspamd-6ec67947dadeba207104ac0e2c65c9e10a3a580d.zip
Rework addresses parsing.
-rw-r--r--src/libserver/cfg_file.h2
-rw-r--r--src/libserver/cfg_utils.c22
-rw-r--r--src/libutil/map.c60
-rw-r--r--src/libutil/radix.c72
-rw-r--r--src/libutil/radix.h10
-rw-r--r--src/libutil/util.c39
-rw-r--r--src/libutil/util.h11
7 files changed, 90 insertions, 126 deletions
diff --git a/src/libserver/cfg_file.h b/src/libserver/cfg_file.h
index a16541ebe..7e3d60db8 100644
--- a/src/libserver/cfg_file.h
+++ b/src/libserver/cfg_file.h
@@ -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);
diff --git a/src/libserver/cfg_utils.c b/src/libserver/cfg_utils.c
index 4d2b86880..aecef53d4 100644
--- a/src/libserver/cfg_utils.c
+++ b/src/libserver/cfg_utils.c
@@ -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);
}
/*
diff --git a/src/libutil/map.c b/src/libutil/map.c
index 7d0313d95..89ab75b64 100644
--- a/src/libutil/map.c
+++ b/src/libutil/map.c
@@ -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 */
diff --git a/src/libutil/radix.c b/src/libutil/radix.c
index acf276285..240a7d67d 100644
--- a/src/libutil/radix.c
+++ b/src/libutil/radix.c
@@ -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
*/
diff --git a/src/libutil/radix.h b/src/libutil/radix.h
index 38af00b51..5bf6a1dd8 100644
--- a/src/libutil/radix.h
+++ b/src/libutil/radix.h
@@ -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
diff --git a/src/libutil/util.c b/src/libutil/util.c
index a4117d3c3..73ab64453 100644
--- a/src/libutil/util.c
+++ b/src/libutil/util.c
@@ -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;
diff --git a/src/libutil/util.h b/src/libutil/util.h
index 1b95ab8a0..40d8004e3 100644
--- a/src/libutil/util.h
+++ b/src/libutil/util.h
@@ -408,15 +408,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
* @param size size of the buffer
@@ -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