Skip to content

Commit

Permalink
[Minor] Core: Allow inet addresses to be parsed using memory pool
Browse files Browse the repository at this point in the history
  • Loading branch information
vstakhov committed Feb 5, 2019
1 parent 9f0e1cd commit ed7ecf0
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 31 deletions.
97 changes: 66 additions & 31 deletions src/libutil/addr.c
Expand Up @@ -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 {
Expand Down Expand Up @@ -168,6 +172,7 @@ rspamd_ip_check_ipv6 (void)
else {
ipv6_status = RSPAMD_IPV6_SUPPORTED;
}

close (s);
}
}
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -339,7 +344,8 @@ rspamd_accept_from_socket (gint sock, rspamd_inet_addr_t **target,
}

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;
Expand All @@ -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));
Expand Down Expand Up @@ -437,7 +443,11 @@ rspamd_parse_unix_path (rspamd_inet_addr_t **target, const char *src)

g_strfreev (tokens);
g_free (pwbuf);
rspamd_inet_address_free (addr);

if (!pool) {
rspamd_inet_address_free (addr);
}

return FALSE;
}

Expand Down Expand Up @@ -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 */
Expand All @@ -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));
}
Expand Down Expand Up @@ -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;
Expand All @@ -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] == '[') {
Expand All @@ -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;
}

Expand All @@ -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 {
Expand All @@ -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);
Expand All @@ -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;
}
}
Expand All @@ -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)
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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));
}
Expand Down Expand Up @@ -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));
Expand Down
11 changes: 11 additions & 0 deletions src/libutil/addr.h
Expand Up @@ -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
Expand Down

0 comments on commit ed7ecf0

Please sign in to comment.