]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Minor] Core: Allow inet addresses to be parsed using memory pool
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 5 Feb 2019 14:37:22 +0000 (14:37 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 5 Feb 2019 14:37:22 +0000 (14:37 +0000)
src/libutil/addr.c
src/libutil/addr.h

index 73b72690e2e0eb4d5e599fc79a633617a72e06ee..68dcb4e8e0d390aab5e230823f5f607b5c0407a3 100644 (file)
@@ -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));
index 3aa24bb1cc802da824782a31a587cb72fb6e84db..46b705a4bf41fb58876835338b97f084df7704f3 100644 (file)
@@ -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