mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-08 21:10:25 +01:00
dns: merge IPv4 and IPv6 versions of add_ip_config() (part 2)
(cherry picked from commit 7d4def2764)
This commit is contained in:
parent
0e41dd6b4f
commit
8aea6745c4
1 changed files with 105 additions and 169 deletions
|
|
@ -76,54 +76,41 @@ G_DEFINE_TYPE (NMDnsDnsmasq, nm_dns_dnsmasq, NM_TYPE_DNS_PLUGIN)
|
|||
/*****************************************************************************/
|
||||
|
||||
static char **
|
||||
get_ip4_rdns_domains (NMIP4Config *ip4)
|
||||
get_ip_rdns_domains (NMIPConfig *ip_config)
|
||||
{
|
||||
int addr_family = nm_ip_config_get_addr_family (ip_config);
|
||||
char **strv;
|
||||
GPtrArray *domains = NULL;
|
||||
NMDedupMultiIter ipconf_iter;
|
||||
const NMPlatformIP4Address *address;
|
||||
const NMPlatformIP4Route *route;
|
||||
|
||||
g_return_val_if_fail (ip4 != NULL, NULL);
|
||||
nm_assert_addr_family (addr_family);
|
||||
|
||||
domains = g_ptr_array_sized_new (5);
|
||||
|
||||
nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, ip4, &address)
|
||||
nm_utils_get_reverse_dns_domains_ip4 (address->address, address->plen, domains);
|
||||
if (addr_family == AF_INET) {
|
||||
NMIP4Config *ip4 = (gpointer) ip_config;
|
||||
const NMPlatformIP4Address *address;
|
||||
const NMPlatformIP4Route *route;
|
||||
|
||||
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, ip4, &route) {
|
||||
if (!NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route))
|
||||
nm_utils_get_reverse_dns_domains_ip4 (route->network, route->plen, domains);
|
||||
}
|
||||
nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, ip4, &address)
|
||||
nm_utils_get_reverse_dns_domains_ip4 (address->address, address->plen, domains);
|
||||
|
||||
/* Terminating NULL so we can use g_strfreev() to free it */
|
||||
g_ptr_array_add (domains, NULL);
|
||||
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, ip4, &route) {
|
||||
if (!NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route))
|
||||
nm_utils_get_reverse_dns_domains_ip4 (route->network, route->plen, domains);
|
||||
}
|
||||
} else {
|
||||
NMIP6Config *ip6 = (gpointer) ip_config;
|
||||
const NMPlatformIP6Address *address;
|
||||
const NMPlatformIP6Route *route;
|
||||
|
||||
/* Free the array and return NULL if the only element was the ending NULL */
|
||||
strv = (char **) g_ptr_array_free (domains, (domains->len == 1));
|
||||
nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, ip6, &address)
|
||||
nm_utils_get_reverse_dns_domains_ip6 (&address->address, address->plen, domains);
|
||||
|
||||
return _nm_utils_strv_cleanup (strv, FALSE, FALSE, TRUE);
|
||||
}
|
||||
|
||||
static char **
|
||||
get_ip6_rdns_domains (NMIP6Config *ip6)
|
||||
{
|
||||
char **strv;
|
||||
GPtrArray *domains = NULL;
|
||||
NMDedupMultiIter ipconf_iter;
|
||||
const NMPlatformIP6Address *address;
|
||||
const NMPlatformIP6Route *route;
|
||||
|
||||
g_return_val_if_fail (ip6 != NULL, NULL);
|
||||
|
||||
domains = g_ptr_array_sized_new (5);
|
||||
|
||||
nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, ip6, &address)
|
||||
nm_utils_get_reverse_dns_domains_ip6 (&address->address, address->plen, domains);
|
||||
|
||||
nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, ip6, &route) {
|
||||
if (!NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route))
|
||||
nm_utils_get_reverse_dns_domains_ip6 (&route->network, route->plen, domains);
|
||||
nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, ip6, &route) {
|
||||
if (!NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route))
|
||||
nm_utils_get_reverse_dns_domains_ip6 (&route->network, route->plen, domains);
|
||||
}
|
||||
}
|
||||
|
||||
/* Terminating NULL so we can use g_strfreev() to free it */
|
||||
|
|
@ -155,25 +142,44 @@ add_dnsmasq_nameserver (NMDnsDnsmasq *self,
|
|||
g_variant_builder_close (servers);
|
||||
}
|
||||
|
||||
static char *
|
||||
ip6_addr_to_string (const struct in6_addr *addr, const char *iface)
|
||||
#define IP_ADDR_TO_STRING_BUFLEN (NM_UTILS_INET_ADDRSTRLEN + 1 + IFNAMSIZ)
|
||||
|
||||
static const char *
|
||||
ip_addr_to_string (int addr_family, gconstpointer addr, const char *iface, char *out_buf)
|
||||
{
|
||||
char buf[NM_UTILS_INET_ADDRSTRLEN];
|
||||
int n_written;
|
||||
char buf2[NM_UTILS_INET_ADDRSTRLEN];
|
||||
char separator;
|
||||
|
||||
if (IN6_IS_ADDR_V4MAPPED (addr))
|
||||
nm_utils_inet4_ntop (addr->s6_addr32[3], buf);
|
||||
else
|
||||
nm_utils_inet6_ntop (addr, buf);
|
||||
nm_assert_addr_family (addr_family);
|
||||
nm_assert (addr);
|
||||
nm_assert (iface);
|
||||
nm_assert (out_buf);
|
||||
|
||||
/* Need to scope link-local addresses with %<zone-id>. Before dnsmasq 2.58,
|
||||
* only '@' was supported as delimiter. Since 2.58, '@' and '%' are
|
||||
* supported. Due to a bug, since 2.73 only '%' works properly as "server"
|
||||
* address.
|
||||
*/
|
||||
return g_strdup_printf ("%s%c%s",
|
||||
buf,
|
||||
IN6_IS_ADDR_LINKLOCAL (addr) ? '%' : '@',
|
||||
if (addr_family == AF_INET) {
|
||||
nm_utils_inet_ntop (addr_family, addr, buf2);
|
||||
separator = '@';
|
||||
} else {
|
||||
if (IN6_IS_ADDR_V4MAPPED (addr))
|
||||
nm_utils_inet4_ntop (((const struct in6_addr *) addr)->s6_addr32[3], buf2);
|
||||
else
|
||||
nm_utils_inet6_ntop (addr, buf2);
|
||||
/* Need to scope link-local addresses with %<zone-id>. Before dnsmasq 2.58,
|
||||
* only '@' was supported as delimiter. Since 2.58, '@' and '%' are
|
||||
* supported. Due to a bug, since 2.73 only '%' works properly as "server"
|
||||
* address.
|
||||
*/
|
||||
separator = IN6_IS_ADDR_LINKLOCAL (addr) ? '%' : '@';
|
||||
}
|
||||
|
||||
n_written = g_snprintf (out_buf,
|
||||
IP_ADDR_TO_STRING_BUFLEN,
|
||||
"%s%c%s",
|
||||
buf2,
|
||||
separator,
|
||||
iface);
|
||||
nm_assert (n_written < IP_ADDR_TO_STRING_BUFLEN);
|
||||
return out_buf;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -207,139 +213,69 @@ add_ip_config (NMDnsDnsmasq *self,
|
|||
const char *iface,
|
||||
gboolean split)
|
||||
{
|
||||
int addr_family = nm_ip_config_get_addr_family (ip_config);
|
||||
int addr_family;
|
||||
gconstpointer addr;
|
||||
gboolean added = FALSE;
|
||||
guint nnameservers, i_nameserver, n, i;
|
||||
char ip_addr_to_string_buf[IP_ADDR_TO_STRING_BUFLEN];
|
||||
char **domains, **iter;
|
||||
|
||||
if (addr_family == AF_INET) {
|
||||
NMIP4Config *ip4 = (NMIP4Config *) ip_config;
|
||||
char buf[INET_ADDRSTRLEN + 1 + IFNAMSIZ];
|
||||
char buf2[INET_ADDRSTRLEN];
|
||||
in_addr_t addr;
|
||||
int nnameservers, i_nameserver, n, i;
|
||||
gboolean added = FALSE;
|
||||
g_return_val_if_fail (iface, FALSE);
|
||||
|
||||
g_return_val_if_fail (iface, FALSE);
|
||||
nnameservers = nm_ip4_config_get_num_nameservers (ip4);
|
||||
addr_family = nm_ip_config_get_addr_family (ip_config);
|
||||
g_return_val_if_fail (NM_IN_SET (addr_family, AF_INET, AF_INET6), FALSE);
|
||||
|
||||
if (split) {
|
||||
char **domains, **iter;
|
||||
nnameservers = nm_ip_config_get_num_nameservers (ip_config);
|
||||
|
||||
if (nnameservers == 0)
|
||||
return FALSE;
|
||||
if (split) {
|
||||
if (nnameservers == 0)
|
||||
return FALSE;
|
||||
|
||||
for (i_nameserver = 0; i_nameserver < nnameservers; i_nameserver++) {
|
||||
addr = nm_ip4_config_get_nameserver (ip4, i_nameserver);
|
||||
g_snprintf (buf, sizeof (buf), "%s@%s",
|
||||
nm_utils_inet4_ntop (addr, buf2), iface);
|
||||
for (i_nameserver = 0; i_nameserver < nnameservers; i_nameserver++) {
|
||||
addr = nm_ip_config_get_nameserver (ip_config, i_nameserver);
|
||||
|
||||
/* searches are preferred over domains */
|
||||
n = nm_ip4_config_get_num_searches (ip4);
|
||||
ip_addr_to_string (addr_family, addr, iface, ip_addr_to_string_buf);
|
||||
|
||||
/* searches are preferred over domains */
|
||||
n = nm_ip_config_get_num_searches (ip_config);
|
||||
for (i = 0; i < n; i++) {
|
||||
add_dnsmasq_nameserver (self,
|
||||
servers,
|
||||
ip_addr_to_string_buf,
|
||||
nm_ip_config_get_search (ip_config, i));
|
||||
added = TRUE;
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
/* If not searches, use any domains */
|
||||
n = nm_ip_config_get_num_domains (ip_config);
|
||||
for (i = 0; i < n; i++) {
|
||||
add_dnsmasq_nameserver (self,
|
||||
servers,
|
||||
buf,
|
||||
nm_ip4_config_get_search (ip4, i));
|
||||
ip_addr_to_string_buf,
|
||||
nm_ip_config_get_domain (ip_config, i));
|
||||
added = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
/* If not searches, use any domains */
|
||||
n = nm_ip4_config_get_num_domains (ip4);
|
||||
for (i = 0; i < n; i++) {
|
||||
add_dnsmasq_nameserver (self,
|
||||
servers,
|
||||
buf,
|
||||
nm_ip4_config_get_domain (ip4, i));
|
||||
added = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure reverse-DNS works by directing queries for in-addr.arpa
|
||||
* domains to the split domain's nameserver.
|
||||
*/
|
||||
domains = get_ip4_rdns_domains (ip4);
|
||||
if (domains) {
|
||||
for (iter = domains; iter && *iter; iter++)
|
||||
add_dnsmasq_nameserver (self, servers, buf, *iter);
|
||||
g_strfreev (domains);
|
||||
}
|
||||
/* Ensure reverse-DNS works by directing queries for in-addr4.arpa/ip6.arpa
|
||||
* domains to the split domain's nameserver.
|
||||
*/
|
||||
domains = get_ip_rdns_domains (ip_config);
|
||||
if (domains) {
|
||||
for (iter = domains; *iter; iter++)
|
||||
add_dnsmasq_nameserver (self, servers, ip_addr_to_string_buf, *iter);
|
||||
g_strfreev (domains);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If no searches or domains, just add the nameservers */
|
||||
if (!added) {
|
||||
for (i = 0; i < nnameservers; i++) {
|
||||
addr = nm_ip4_config_get_nameserver (ip4, i);
|
||||
g_snprintf (buf, sizeof (buf), "%s@%s",
|
||||
nm_utils_inet4_ntop (addr, buf2), iface);
|
||||
add_dnsmasq_nameserver (self, servers, buf, NULL);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
NMIP6Config *ip6 = (NMIP6Config *) ip_config;
|
||||
const struct in6_addr *addr;
|
||||
char *buf = NULL;
|
||||
int nnameservers, i_nameserver, n, i;
|
||||
gboolean added = FALSE;
|
||||
|
||||
g_return_val_if_fail (iface, FALSE);
|
||||
nnameservers = nm_ip6_config_get_num_nameservers (ip6);
|
||||
|
||||
if (split) {
|
||||
char **domains, **iter;
|
||||
|
||||
if (nnameservers == 0)
|
||||
return FALSE;
|
||||
|
||||
for (i_nameserver = 0; i_nameserver < nnameservers; i_nameserver++) {
|
||||
addr = nm_ip6_config_get_nameserver (ip6, i_nameserver);
|
||||
buf = ip6_addr_to_string (addr, iface);
|
||||
|
||||
/* searches are preferred over domains */
|
||||
n = nm_ip6_config_get_num_searches (ip6);
|
||||
for (i = 0; i < n; i++) {
|
||||
add_dnsmasq_nameserver (self,
|
||||
servers,
|
||||
buf,
|
||||
nm_ip6_config_get_search (ip6, i));
|
||||
added = TRUE;
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
/* If not searches, use any domains */
|
||||
n = nm_ip6_config_get_num_domains (ip6);
|
||||
for (i = 0; i < n; i++) {
|
||||
add_dnsmasq_nameserver (self,
|
||||
servers,
|
||||
buf,
|
||||
nm_ip6_config_get_domain (ip6, i));
|
||||
added = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure reverse-DNS works by directing queries for ip6.arpa
|
||||
* domains to the split domain's nameserver.
|
||||
*/
|
||||
domains = 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);
|
||||
}
|
||||
}
|
||||
|
||||
/* If no searches or domains, just add the nameservers */
|
||||
if (!added) {
|
||||
for (i = 0; i < nnameservers; i++) {
|
||||
addr = nm_ip6_config_get_nameserver (ip6, i);
|
||||
buf = ip6_addr_to_string (addr, iface);
|
||||
if (buf) {
|
||||
add_dnsmasq_nameserver (self, servers, buf, NULL);
|
||||
g_free (buf);
|
||||
}
|
||||
}
|
||||
/* If no searches or domains, just add the nameservers */
|
||||
if (!added) {
|
||||
for (i = 0; i < nnameservers; i++) {
|
||||
addr = nm_ip_config_get_nameserver (ip_config, i);
|
||||
ip_addr_to_string (addr_family, addr, iface, ip_addr_to_string_buf);
|
||||
add_dnsmasq_nameserver (self, servers, ip_addr_to_string_buf, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue