commit ed7ecf0: [Minor] Core: Allow inet addresses to be parsed using memory pool

Vsevolod Stakhov vsevolod at highsecure.ru
Thu Feb 7 15:14:03 UTC 2019


Author: Vsevolod Stakhov
Date: 2019-02-05 14:37:22 +0000
URL: https://github.com/rspamd/rspamd/commit/ed7ecf0d80246dc047676cfeb5f1726c678eb01b

[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


More information about the Commits mailing list