Browse Source

Rework addresses parsing.

tags/0.7.2
Vsevolod Stakhov 9 years ago
parent
commit
6ec67947da
7 changed files with 90 additions and 126 deletions
  1. 1
    1
      src/libserver/cfg_file.h
  2. 4
    18
      src/libserver/cfg_utils.c
  3. 1
    59
      src/libutil/map.c
  4. 72
    0
      src/libutil/radix.c
  5. 10
    0
      src/libutil/radix.h
  6. 1
    38
      src/libutil/util.c
  7. 1
    10
      src/libutil/util.h

+ 1
- 1
src/libserver/cfg_file.h View 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);

+ 4
- 18
src/libserver/cfg_utils.c View 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);
}

/*

+ 1
- 59
src/libutil/map.c View 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 */

+ 72
- 0
src/libutil/radix.c View 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
*/

+ 10
- 0
src/libutil/radix.h View 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

+ 1
- 38
src/libutil/util.c View 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;

+ 1
- 10
src/libutil/util.h View 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

Loading…
Cancel
Save