From ed7ecf0d80246dc047676cfeb5f1726c678eb01b Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Tue, 5 Feb 2019 14:37:22 +0000 Subject: [PATCH] [Minor] Core: Allow inet addresses to be parsed using memory pool --- src/libutil/addr.c | 97 +++++++++++++++++++++++++++++++--------------- src/libutil/addr.h | 11 ++++++ 2 files changed, 77 insertions(+), 31 deletions(-) diff --git a/src/libutil/addr.c b/src/libutil/addr.c index 73b72690e..68dcb4e8e 100644 --- a/src/libutil/addr.c +++ b/src/libutil/addr.c @@ -104,18 +104,22 @@ rspamd_ip_validate_af (rspamd_inet_addr_t *addr) } } +#define RSPAMD_MAYBE_ALLOC_POOL(pool, sz) \ + (pool != NULL) ? rspamd_mempool_alloc((pool), (sz)) : g_malloc(sz) +#define RSPAMD_MAYBE_ALLOC0_POOL(pool, sz) \ + (pool != NULL) ? rspamd_mempool_alloc0((pool), (sz)) : g_malloc0(sz) static rspamd_inet_addr_t * -rspamd_inet_addr_create (gint af) +rspamd_inet_addr_create (gint af, rspamd_mempool_t *pool) { rspamd_inet_addr_t *addr; - addr = g_malloc0 (sizeof (rspamd_inet_addr_t)); + addr = RSPAMD_MAYBE_ALLOC0_POOL (pool, sizeof(*addr)); addr->af = af; if (af == AF_UNIX) { - addr->u.un = g_malloc0 (sizeof (*addr->u.un)); + addr->u.un = RSPAMD_MAYBE_ALLOC0_POOL(pool, sizeof (*addr->u.un)); addr->slen = sizeof (addr->u.un->addr); } else { @@ -168,6 +172,7 @@ rspamd_ip_check_ipv6 (void) else { ipv6_status = RSPAMD_IPV6_SUPPORTED; } + close (s); } } @@ -269,26 +274,26 @@ rspamd_accept_from_socket (gint sock, rspamd_inet_addr_t **target, p = (const guint8 *)&su.s6.sin6_addr; if ((p[10] == 0xff && p[11] == 0xff)) { - addr = rspamd_inet_addr_create (AF_INET); + addr = rspamd_inet_addr_create (AF_INET, NULL); memcpy (&addr->u.in.addr.s4.sin_addr, &p[12], sizeof (struct in_addr)); } else { /* Something strange but not mapped v4 address */ - addr = rspamd_inet_addr_create (AF_INET6); + addr = rspamd_inet_addr_create (AF_INET6, NULL); memcpy (&addr->u.in.addr.s6.sin6_addr, &su.s6.sin6_addr, sizeof (struct in6_addr)); } } else { - addr = rspamd_inet_addr_create (AF_INET6); + addr = rspamd_inet_addr_create (AF_INET6, NULL); memcpy (&addr->u.in.addr.s6.sin6_addr, &su.s6.sin6_addr, sizeof (struct in6_addr)); } } else { - addr = rspamd_inet_addr_create (su.sa.sa_family); + addr = rspamd_inet_addr_create (su.sa.sa_family, NULL); addr->slen = len; if (addr->af == AF_UNIX) { @@ -339,7 +344,8 @@ out: } static gboolean -rspamd_parse_unix_path (rspamd_inet_addr_t **target, const char *src) +rspamd_parse_unix_path (rspamd_inet_addr_t **target, const char *src, + rspamd_mempool_t *pool) { gchar **tokens, **cur_tok, *p, *pwbuf; glong pwlen; @@ -349,7 +355,7 @@ rspamd_parse_unix_path (rspamd_inet_addr_t **target, const char *src) bool has_group = false; tokens = g_strsplit_set (src, " ,", -1); - addr = rspamd_inet_addr_create (AF_UNIX); + addr = rspamd_inet_addr_create (AF_UNIX, pool); rspamd_strlcpy (addr->u.un->addr.sun_path, tokens[0], sizeof (addr->u.un->addr.sun_path)); @@ -437,7 +443,11 @@ err: g_strfreev (tokens); g_free (pwbuf); - rspamd_inet_address_free (addr); + + if (!pool) { + rspamd_inet_address_free (addr); + } + return FALSE; } @@ -614,7 +624,8 @@ rspamd_parse_inet_address_ip6 (const guchar *text, gsize len, gpointer target) /* Checks for ipv6 mapped address */ static rspamd_inet_addr_t * -rspamd_inet_address_v6_maybe_map (const struct sockaddr_in6 *sin6) +rspamd_inet_address_v6_maybe_map (const struct sockaddr_in6 *sin6, + rspamd_mempool_t *pool) { rspamd_inet_addr_t *addr = NULL; /* 10 zero bytes or 80 bits */ @@ -627,19 +638,19 @@ rspamd_inet_address_v6_maybe_map (const struct sockaddr_in6 *sin6) p = (const guint8 *)&sin6->sin6_addr; if ((p[10] == 0xff && p[11] == 0xff)) { - addr = rspamd_inet_addr_create (AF_INET); + addr = rspamd_inet_addr_create (AF_INET, pool); memcpy (&addr->u.in.addr.s4.sin_addr, &p[12], sizeof (struct in_addr)); } else { /* Something strange but not mapped v4 address */ - addr = rspamd_inet_addr_create (AF_INET6); + addr = rspamd_inet_addr_create (AF_INET6, pool); memcpy (&addr->u.in.addr.s6.sin6_addr, &sin6->sin6_addr, sizeof (struct in6_addr)); } } else { - addr = rspamd_inet_addr_create (AF_INET6); + addr = rspamd_inet_addr_create (AF_INET6, pool); memcpy (&addr->u.in.addr.s6.sin6_addr, &sin6->sin6_addr, sizeof (struct in6_addr)); } @@ -682,10 +693,11 @@ rspamd_inet_address_v6_maybe_map_static (const struct sockaddr_in6 *sin6, } } -gboolean -rspamd_parse_inet_address (rspamd_inet_addr_t **target, - const char *src, - gsize srclen) +static gboolean +rspamd_parse_inet_address_common (rspamd_inet_addr_t **target, + const char *src, + gsize srclen, + rspamd_mempool_t *pool) { gboolean ret = FALSE; rspamd_inet_addr_t *addr = NULL; @@ -705,7 +717,7 @@ rspamd_parse_inet_address (rspamd_inet_addr_t **target, rspamd_ip_check_ipv6 (); if (src[0] == '/' || src[0] == '.') { - return rspamd_parse_unix_path (target, src); + return rspamd_parse_unix_path (target, src, pool); } if (src[0] == '[') { @@ -726,7 +738,7 @@ rspamd_parse_inet_address (rspamd_inet_addr_t **target, if (rspamd_parse_inet_address_ip6 (ipbuf, iplen, &su.s6.sin6_addr)) { - addr = rspamd_inet_address_v6_maybe_map (&su.s6); + addr = rspamd_inet_address_v6_maybe_map (&su.s6, pool); ret = TRUE; } @@ -742,8 +754,9 @@ rspamd_parse_inet_address (rspamd_inet_addr_t **target, /* This is either port number and ipv4 addr or ipv6 addr */ /* Search for another semicolon */ if (memchr (end + 1, ':', srclen - (end - src + 1)) && - rspamd_parse_inet_address_ip6 (src, srclen, &su.s6.sin6_addr)) { - addr = rspamd_inet_address_v6_maybe_map (&su.s6); + rspamd_parse_inet_address_ip6 (src, srclen, + &su.s6.sin6_addr)) { + addr = rspamd_inet_address_v6_maybe_map (&su.s6, pool); ret = TRUE; } else { @@ -759,7 +772,7 @@ rspamd_parse_inet_address (rspamd_inet_addr_t **target, if (rspamd_parse_inet_address_ip4 (ipbuf, iplen, &su.s4.sin_addr)) { - addr = rspamd_inet_addr_create (AF_INET); + addr = rspamd_inet_addr_create (AF_INET, pool); memcpy (&addr->u.in.addr.s4.sin_addr, &su.s4.sin_addr, sizeof (struct in_addr)); rspamd_strtoul (end + 1, srclen - iplen - 1, &portnum); @@ -770,13 +783,13 @@ rspamd_parse_inet_address (rspamd_inet_addr_t **target, } else { if (rspamd_parse_inet_address_ip4 (src, srclen, &su.s4.sin_addr)) { - addr = rspamd_inet_addr_create (AF_INET); + addr = rspamd_inet_addr_create (AF_INET, pool); memcpy (&addr->u.in.addr.s4.sin_addr, &su.s4.sin_addr, sizeof (struct in_addr)); ret = TRUE; } else if (rspamd_parse_inet_address_ip6 (src, srclen, &su.s6.sin6_addr)) { - addr = rspamd_inet_address_v6_maybe_map (&su.s6); + addr = rspamd_inet_address_v6_maybe_map (&su.s6, pool); ret = TRUE; } } @@ -789,6 +802,28 @@ rspamd_parse_inet_address (rspamd_inet_addr_t **target, return ret; } +gboolean +rspamd_parse_inet_address (rspamd_inet_addr_t **target, + const char *src, + gsize srclen) +{ + return rspamd_parse_inet_address_common (target, src, srclen, NULL); +} + +rspamd_inet_addr_t * +rspamd_parse_inet_address_pool (const char *src, + gsize srclen, + rspamd_mempool_t *pool) +{ + rspamd_inet_addr_t *ret = NULL; + + if (!rspamd_parse_inet_address_common (&ret, src, srclen, pool)) { + return NULL; + } + + return ret; +} + gboolean rspamd_parse_inet_address_ip (const char *src, gsize srclen, rspamd_inet_addr_t *target) @@ -1106,7 +1141,7 @@ rspamd_inet_address_recvfrom (gint fd, void *buf, gsize len, gint fl, } if (target) { - addr = rspamd_inet_addr_create (su.sa.sa_family); + addr = rspamd_inet_addr_create (su.sa.sa_family, NULL); addr->slen = slen; if (addr->af == AF_UNIX) { @@ -1457,7 +1492,7 @@ rspamd_inet_address_new (int af, const void *init) { rspamd_inet_addr_t *addr; - addr = rspamd_inet_addr_create (af); + addr = rspamd_inet_addr_create (af, NULL); if (init != NULL) { if (af == AF_UNIX) { @@ -1487,7 +1522,7 @@ rspamd_inet_address_from_sa (const struct sockaddr *sa, socklen_t slen) g_assert (sa != NULL); g_assert (slen >= sizeof (struct sockaddr)); - addr = rspamd_inet_addr_create (sa->sa_family); + addr = rspamd_inet_addr_create (sa->sa_family, NULL); if (sa->sa_family == AF_UNIX) { /* Init is a path */ @@ -1525,12 +1560,12 @@ rspamd_inet_address_from_rnds (const struct rdns_reply_entry *rep) g_assert (rep != NULL); if (rep->type == RDNS_REQUEST_A) { - addr = rspamd_inet_addr_create (AF_INET); + addr = rspamd_inet_addr_create (AF_INET, NULL); memcpy (&addr->u.in.addr.s4.sin_addr, &rep->content.a.addr, sizeof (struct in_addr)); } else if (rep->type == RDNS_REQUEST_AAAA) { - addr = rspamd_inet_addr_create (AF_INET6); + addr = rspamd_inet_addr_create (AF_INET6, NULL); memcpy (&addr->u.in.addr.s6.sin6_addr, &rep->content.aaa.addr, sizeof (struct in6_addr)); } @@ -1639,7 +1674,7 @@ rspamd_inet_address_copy (const rspamd_inet_addr_t *addr) return NULL; } - n = rspamd_inet_addr_create (addr->af); + n = rspamd_inet_addr_create (addr->af, NULL); if (n->af == AF_UNIX) { memcpy (n->u.un, addr->u.un, sizeof (*addr->u.un)); diff --git a/src/libutil/addr.h b/src/libutil/addr.h index 3aa24bb1c..46b705a4b 100644 --- a/src/libutil/addr.h +++ b/src/libutil/addr.h @@ -112,6 +112,17 @@ gboolean rspamd_parse_inet_address (rspamd_inet_addr_t **target, const char *src, gsize srclen); +/** + * Use memory pool allocated inet address + * @param src + * @param srclen + * @param pool + * @return + */ +rspamd_inet_addr_t* rspamd_parse_inet_address_pool (const char *src, + gsize srclen, + rspamd_mempool_t *pool); + /** * Returns string representation of inet address * @param addr -- 2.39.5