From 3b9b23600f97365585c32827c0b6df4b620c8653 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Mon, 28 Nov 2016 10:16:06 +0000 Subject: [PATCH] [Fix] Do not resolve numeric IP addresses due to ipv6 insanity --- src/libserver/dns.c | 5 +- src/libutil/addr.c | 109 +++++++++++++++++++++++++------------------- 2 files changed, 67 insertions(+), 47 deletions(-) diff --git a/src/libserver/dns.c b/src/libserver/dns.c index 34b685260..b6a38dab0 100644 --- a/src/libserver/dns.c +++ b/src/libserver/dns.c @@ -216,6 +216,8 @@ rspamd_dns_server_init (struct upstream *up, gpointer ud) rspamd_inet_address_get_port (addr), 0, 8); } + g_assert (serv != NULL); + elt = g_slice_alloc0 (sizeof (*elt)); elt->server = serv; elt->lib_data = up; @@ -265,6 +267,8 @@ dns_resolver_init (rspamd_logger_t *logger, } else { dns_resolver->ups = rspamd_upstreams_create (cfg->ups_ctx); + rspamd_upstreams_set_flags (dns_resolver->ups, + RSPAMD_UPSTREAM_FLAG_NORESOLVE); if (!rspamd_upstreams_from_ucl (dns_resolver->ups, cfg->nameservers, 53, dns_resolver)) { @@ -277,7 +281,6 @@ dns_resolver_init (rspamd_logger_t *logger, rspamd_upstreams_foreach (dns_resolver->ups, rspamd_dns_server_init, dns_resolver); - rspamd_upstreams_set_flags (dns_resolver->ups, RSPAMD_UPSTREAM_FLAG_NORESOLVE); rdns_resolver_set_upstream_lib (dns_resolver->r, &rspamd_ups_ctx, dns_resolver->ups); } diff --git a/src/libutil/addr.c b/src/libutil/addr.c index 471d5d574..dbb279579 100644 --- a/src/libutil/addr.c +++ b/src/libutil/addr.c @@ -999,34 +999,10 @@ rspamd_resolve_addrs (const char *begin, size_t len, GPtrArray **addrs, gchar *addr_cpy = NULL; rspamd_ip_check_ipv6 (); - memset (&hints, 0, sizeof (hints)); - hints.ai_socktype = SOCK_STREAM; /* Type of the socket */ - hints.ai_flags = AI_NUMERICSERV|flags; - - if (len > 0) { - addr_cpy = g_malloc (len + 1); - rspamd_strlcpy (addr_cpy, begin, len + 1); - } - /* Otherwise it will be NULL */ - - if (ipv6_status == RSPAMD_IPV6_SUPPORTED) { - hints.ai_family = AF_UNSPEC; - } - else { - hints.ai_family = AF_INET; - } - - if ((r = getaddrinfo (addr_cpy, portbuf, &hints, &res)) == 0) { - /* Now copy up to max_addrs of addresses */ - addr_cnt = 0; - cur = res; - while (cur) { - cur = cur->ai_next; - addr_cnt ++; - } + if (rspamd_parse_inet_address (&cur_addr, begin, len)) { if (*addrs == NULL) { - *addrs = g_ptr_array_new_full (addr_cnt, + *addrs = g_ptr_array_new_full (1, (GDestroyNotify)rspamd_inet_address_destroy); if (pool != NULL) { @@ -1035,30 +1011,71 @@ rspamd_resolve_addrs (const char *begin, size_t len, GPtrArray **addrs, } } - cur = res; - while (cur) { - cur_addr = rspamd_inet_address_from_sa (cur->ai_addr, - cur->ai_addrlen); + rspamd_inet_address_set_port (cur_addr, strtoul (portbuf, NULL, 10)); + g_ptr_array_add (*addrs, cur_addr); + } + else { + memset (&hints, 0, sizeof (hints)); + hints.ai_socktype = SOCK_STREAM; /* Type of the socket */ + hints.ai_flags = AI_NUMERICSERV|flags; - if (cur_addr != NULL) { - g_ptr_array_add (*addrs, cur_addr); - } - cur = cur->ai_next; + if (len > 0) { + addr_cpy = g_malloc (len + 1); + rspamd_strlcpy (addr_cpy, begin, len + 1); } + /* Otherwise it will be NULL */ - freeaddrinfo (res); - } - else if (addr_cpy) { - msg_err_pool_check ("address resolution for %s failed: %s", - addr_cpy, - gai_strerror (r)); - g_free (addr_cpy); + if (ipv6_status == RSPAMD_IPV6_SUPPORTED) { + hints.ai_family = AF_UNSPEC; + } + else { + hints.ai_family = AF_INET; + } - return FALSE; - } - else { - /* Should never ever happen */ - g_assert (0); + if ((r = getaddrinfo (addr_cpy, portbuf, &hints, &res)) == 0) { + /* Now copy up to max_addrs of addresses */ + addr_cnt = 0; + cur = res; + while (cur) { + cur = cur->ai_next; + addr_cnt ++; + } + + if (*addrs == NULL) { + *addrs = g_ptr_array_new_full (addr_cnt, + (GDestroyNotify)rspamd_inet_address_destroy); + + if (pool != NULL) { + rspamd_mempool_add_destructor (pool, + rspamd_ptr_array_free_hard, *addrs); + } + } + + cur = res; + while (cur) { + cur_addr = rspamd_inet_address_from_sa (cur->ai_addr, + cur->ai_addrlen); + + if (cur_addr != NULL) { + g_ptr_array_add (*addrs, cur_addr); + } + cur = cur->ai_next; + } + + freeaddrinfo (res); + } + else if (addr_cpy) { + msg_err_pool_check ("address resolution for %s failed: %s", + addr_cpy, + gai_strerror (r)); + g_free (addr_cpy); + + return FALSE; + } + else { + /* Should never ever happen */ + g_assert (0); + } } return TRUE; -- 2.39.5