dns: add reverse DNS IPv6 entries to dnsmasq

https://bugzilla.gnome.org/show_bug.cgi?id=767174
This commit is contained in:
Beniamino Galvani
2016-06-03 22:07:42 +02:00
parent 4d1e7dc23c
commit ae763642d8
6 changed files with 159 additions and 3 deletions

View File

@@ -219,6 +219,8 @@ add_ip6_config (NMDnsDnsmasq *self, GVariantBuilder *servers, NMIP6Config *ip6,
nnameservers = nm_ip6_config_get_num_nameservers (ip6);
if (split) {
char **domains, **iter;
if (nnameservers == 0)
return FALSE;
@@ -248,6 +250,16 @@ add_ip6_config (NMDnsDnsmasq *self, GVariantBuilder *servers, NMIP6Config *ip6,
}
}
/* Ensure reverse-DNS works by directing queries for ip6.arpa
* domains to the split domain's nameserver.
*/
domains = nm_dns_utils_get_ip6_rdns_domains (ip6);
if (domains) {
for (iter = domains; iter && *iter; iter++)
add_dnsmasq_nameserver (self, servers, buf, *iter);
g_strfreev (domains);
}
g_free (buf);
}
}

View File

@@ -57,5 +57,36 @@ nm_dns_utils_get_ip4_rdns_domains (NMIP4Config *ip4)
strv = (char **) g_ptr_array_free (domains, (domains->len == 1));
return _nm_utils_strv_cleanup (strv, FALSE, FALSE, TRUE);
}
char **
nm_dns_utils_get_ip6_rdns_domains (NMIP6Config *ip6)
{
char **strv;
GPtrArray *domains = NULL;
int i;
g_return_val_if_fail (ip6 != NULL, NULL);
domains = g_ptr_array_sized_new (5);
for (i = 0; i < nm_ip6_config_get_num_addresses (ip6); i++) {
const NMPlatformIP6Address *address = nm_ip6_config_get_address (ip6, i);
nm_utils_get_reverse_dns_domains_ip6 (&address->address, address->plen, domains);
}
for (i = 0; i < nm_ip6_config_get_num_routes (ip6); i++) {
const NMPlatformIP6Route *route = nm_ip6_config_get_route (ip6, i);
nm_utils_get_reverse_dns_domains_ip6 (&route->network, route->plen, domains);
}
/* Terminating NULL so we can use g_strfreev() to free it */
g_ptr_array_add (domains, NULL);
/* Free the array and return NULL if the only element was the ending NULL */
strv = (char **) g_ptr_array_free (domains, (domains->len == 1));
return _nm_utils_strv_cleanup (strv, FALSE, FALSE, TRUE);
}

View File

@@ -21,8 +21,10 @@
#define __NETWORKMANAGER_DNS_UTILS_H__
#include "nm-ip4-config.h"
#include "nm-ip6-config.h"
char **nm_dns_utils_get_ip4_rdns_domains (NMIP4Config *ip4);
char **nm_dns_utils_get_ip6_rdns_domains (NMIP6Config *ip6);
#endif /* NM_DNS_UTILS_H */

View File

@@ -3318,3 +3318,60 @@ nm_utils_get_reverse_dns_domains_ip4 (guint32 addr, guint8 plen, GPtrArray *doma
ip2 += 1 << ((32 - plen) & ~7);
}
}
/**
* nm_utils_get_reverse_dns_domains_ip6:
* @addr: IPv6 address
* @plen: prefix length
* @domains: array for results
*
* Creates reverse DNS domains for the given address and prefix length, and
* append them to @domains.
*/
void
nm_utils_get_reverse_dns_domains_ip6 (const struct in6_addr *ip, guint8 plen, GPtrArray *domains)
{
struct in6_addr addr;
guint nibbles, bits, entries;
int i, j;
gsize len0, len;
char *str, *s;
g_return_if_fail (domains);
g_return_if_fail (plen <= 128);
if (!plen)
return;
memcpy (&addr, ip, sizeof (struct in6_addr));
nm_utils_ip6_address_clear_host_address (&addr, &addr, plen);
/* Number of nibbles to include in domains */
nibbles = (plen - 1) / 4 + 1;
/* Prefix length in nibble */
bits = plen - ((plen - 1) / 4 * 4);
/* Number of domains */
entries = 1 << (4 - bits);
len0 = NM_STRLEN ("ip6.arpa") + (2 * nibbles) + 1;
#define N_SHIFT(x) ((x) % 2 ? 0 : 4)
for (i = 0; i < entries; i++) {
len = len0;
str = s = g_malloc (len);
for (j = nibbles - 1; j >= 0; j--)
nm_utils_strbuf_append (&s,
&len,
"%x.",
(addr.s6_addr[j / 2] >> N_SHIFT (j)) & 0xf);
nm_utils_strbuf_append_str (&s, &len, "ip6.arpa");
g_ptr_array_add (domains, str);
addr.s6_addr[(nibbles - 1) / 2] += 1 << N_SHIFT (nibbles - 1);
}
#undef N_SHIFT
}

View File

@@ -407,5 +407,6 @@ gboolean nm_utils_ip4_address_is_link_local (in_addr_t addr);
const char *nm_utils_dnsmasq_status_to_string (int status, char *dest, gsize size);
void nm_utils_get_reverse_dns_domains_ip4 (guint32 ip, guint8 plen, GPtrArray *domains);
void nm_utils_get_reverse_dns_domains_ip6 (const struct in6_addr *ip, guint8 plen, GPtrArray *domains);
#endif /* __NM_CORE_UTILS_H__ */

View File

@@ -1361,8 +1361,6 @@ test_duplicate_decl_specifier (void)
v_result[0] = TEST_MAX (v_const[0], nmtst_get_rand_int () % 5) + v2;
}
/*****************************************************************************/
static void
test_reverse_dns_ip4 (void)
{
@@ -1427,6 +1425,60 @@ test_reverse_dns_ip4 (void)
g_ptr_array_unref (domains);
}
static void
test_reverse_dns_ip6 (void)
{
struct in6_addr addr;
GPtrArray *domains = g_ptr_array_new_full (8, g_free);
inet_pton (AF_INET6, "1234::56", &addr);
nm_utils_get_reverse_dns_domains_ip6 (&addr, 16, domains);
g_assert_cmpuint (domains->len, ==, 1);
g_assert_cmpstr (domains->pdata[0], ==, "4.3.2.1.ip6.arpa");
g_ptr_array_set_size (domains, 0);
inet_pton (AF_INET6, "1234::56", &addr);
nm_utils_get_reverse_dns_domains_ip6 (&addr, 17, domains);
g_assert_cmpuint (domains->len, ==, 8);
g_assert_cmpstr (domains->pdata[0], ==, "0.4.3.2.1.ip6.arpa");
g_assert_cmpstr (domains->pdata[1], ==, "1.4.3.2.1.ip6.arpa");
g_assert_cmpstr (domains->pdata[7], ==, "7.4.3.2.1.ip6.arpa");
g_ptr_array_set_size (domains, 0);
inet_pton (AF_INET6, "2001:db8::", &addr);
nm_utils_get_reverse_dns_domains_ip6 (&addr, 29, domains);
g_assert_cmpuint (domains->len, ==, 8);
g_assert_cmpstr (domains->pdata[0], ==, "8.b.d.0.1.0.0.2.ip6.arpa");
g_assert_cmpstr (domains->pdata[1], ==, "9.b.d.0.1.0.0.2.ip6.arpa");
g_assert_cmpstr (domains->pdata[7], ==, "f.b.d.0.1.0.0.2.ip6.arpa");
g_ptr_array_set_size (domains, 0);
inet_pton (AF_INET6, "0123:4567:89ab:cdef::", &addr);
nm_utils_get_reverse_dns_domains_ip6 (&addr, 63, domains);
g_assert_cmpuint (domains->len, ==, 2);
g_assert_cmpstr (domains->pdata[0], ==, "e.e.d.c.b.a.9.8.7.6.5.4.3.2.1.0.ip6.arpa");
g_assert_cmpstr (domains->pdata[1], ==, "f.e.d.c.b.a.9.8.7.6.5.4.3.2.1.0.ip6.arpa");
g_ptr_array_set_size (domains, 0);
inet_pton (AF_INET6, "fec0:1234:5678:9ab0::", &addr);
nm_utils_get_reverse_dns_domains_ip6 (&addr, 61, domains);
g_assert_cmpuint (domains->len, ==, 8);
g_assert_cmpstr (domains->pdata[0], ==, "0.b.a.9.8.7.6.5.4.3.2.1.0.c.e.f.ip6.arpa");
g_assert_cmpstr (domains->pdata[7], ==, "7.b.a.9.8.7.6.5.4.3.2.1.0.c.e.f.ip6.arpa");
g_ptr_array_set_size (domains, 0);
inet_pton (AF_INET6, "0123:4567:89ab:cdee::", &addr);
nm_utils_get_reverse_dns_domains_ip6 (&addr, 0, domains);
g_assert_cmpuint (domains->len, ==, 0);
g_ptr_array_unref (domains);
}
/*****************************************************************************/
NMTST_DEFINE ();
@@ -1464,6 +1516,7 @@ main (int argc, char **argv)
g_test_add_func ("/general/duplicate_decl_specifier", test_duplicate_decl_specifier);
g_test_add_func ("/general/reverse_dns/ip4", test_reverse_dns_ip4);
g_test_add_func ("/general/reverse_dns/ip6", test_reverse_dns_ip6);
return g_test_run ();
}