aboutsummaryrefslogtreecommitdiffstats
path: root/src/libutil/addr.c
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2019-02-05 14:37:22 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2019-02-05 14:37:22 +0000
commited7ecf0d80246dc047676cfeb5f1726c678eb01b (patch)
tree3ed19699708e29bd5524726e73305043877c947d /src/libutil/addr.c
parent9f0e1cd979389a6a4aca66e99f3b18bf9e67b7f5 (diff)
downloadrspamd-ed7ecf0d80246dc047676cfeb5f1726c678eb01b.tar.gz
rspamd-ed7ecf0d80246dc047676cfeb5f1726c678eb01b.zip
[Minor] Core: Allow inet addresses to be parsed using memory pool
Diffstat (limited to 'src/libutil/addr.c')
-rw-r--r--src/libutil/addr.c97
1 files changed, 66 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;
}
}
@@ -790,6 +803,28 @@ rspamd_parse_inet_address (rspamd_inet_addr_t **target,
}
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));