about summary refs log tree commit diff
path: root/src/dns/nm-dns-dnsmasq.c
diff options
context:
space:
mode:
authorIain Lane <iain@orangesquash.org.uk>2018-09-24 09:29:55 +0100
committerIain Lane <iain@orangesquash.org.uk>2018-09-24 09:29:55 +0100
commite152ec7bf4ba252ff9d3eb13eabd417b931dac9a (patch)
treec323cf856ee0bb8e44590670dd54c19653a55748 /src/dns/nm-dns-dnsmasq.c
parentee9c73a923909e23a649407be77e25235d769e25 (diff)
Import Upstream version 1.12.2
Diffstat (limited to 'src/dns/nm-dns-dnsmasq.c')
-rw-r--r--src/dns/nm-dns-dnsmasq.c317
1 files changed, 67 insertions, 250 deletions
diff --git a/src/dns/nm-dns-dnsmasq.c b/src/dns/nm-dns-dnsmasq.c
index e6436c79..b5b93280 100644
--- a/src/dns/nm-dns-dnsmasq.c
+++ b/src/dns/nm-dns-dnsmasq.c
@@ -35,7 +35,7 @@
 #include "nm-utils.h"
 #include "nm-ip4-config.h"
 #include "nm-ip6-config.h"
-#include "nm-bus-manager.h"
+#include "nm-dbus-manager.h"
 #include "NetworkManagerUtils.h"
 
 #define PIDFILE NMRUNDIR "/dnsmasq.pid"
@@ -75,66 +75,6 @@ G_DEFINE_TYPE (NMDnsDnsmasq, nm_dns_dnsmasq, NM_TYPE_DNS_PLUGIN)
 
 /*****************************************************************************/
 
-static char **
-get_ip4_rdns_domains (NMIP4Config *ip4)
-{
-	char **strv;
-	GPtrArray *domains = NULL;
-	NMDedupMultiIter ipconf_iter;
-	const NMPlatformIP4Address *address;
-	const NMPlatformIP4Route *route;
-
-	g_return_val_if_fail (ip4 != NULL, NULL);
-
-	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);
-
-	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);
-	}
-
-	/* 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);
-}
-
-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);
-	}
-
-	/* 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);
-}
-
 static void
 add_dnsmasq_nameserver (NMDnsDnsmasq *self,
                         GVariantBuilder *servers,
@@ -155,96 +95,43 @@ add_dnsmasq_nameserver (NMDnsDnsmasq *self,
 	g_variant_builder_close (servers);
 }
 
-static gboolean
-add_ip4_config (NMDnsDnsmasq *self, GVariantBuilder *servers, NMIP4Config *ip4,
-                const char *iface, gboolean split)
-{
-	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);
-	nnameservers = nm_ip4_config_get_num_nameservers (ip4);
-
-	if (split) {
-		char **domains, **iter;
-
-		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);
-
-			/* searches are preferred over domains */
-			n = nm_ip4_config_get_num_searches (ip4);
-			for (i = 0; i < n; i++) {
-				add_dnsmasq_nameserver (self,
-				                        servers,
-				                        buf,
-				                        nm_ip4_config_get_search (ip4, 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);
-			}
-		}
-	}
+#define IP_ADDR_TO_STRING_BUFLEN (NM_UTILS_INET_ADDRSTRLEN + 1 + IFNAMSIZ)
 
-	/* 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);
-		}
-	}
+static const char *
+ip_addr_to_string (int addr_family, gconstpointer addr, const char *iface, char *out_buf)
+{
+	int n_written;
+	char buf2[NM_UTILS_INET_ADDRSTRLEN];
+	const char *separator;
 
-	return TRUE;
-}
+	nm_assert_addr_family (addr_family);
+	nm_assert (addr);
+	nm_assert (out_buf);
 
-static char *
-ip6_addr_to_string (const struct in6_addr *addr, const char *iface)
-{
-	char buf[NM_UTILS_INET_ADDRSTRLEN];
+	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) ? "%" : "@";
+	}
 
-	if (IN6_IS_ADDR_V4MAPPED (addr))
-		nm_utils_inet4_ntop (addr->s6_addr32[3], buf);
-	else
-		nm_utils_inet6_ntop (addr, 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) ? '%' : '@',
-	                        iface);
+	n_written = g_snprintf (out_buf,
+	                        IP_ADDR_TO_STRING_BUFLEN,
+	                        "%s%s%s",
+	                        buf2,
+	                        iface ? separator : "",
+	                        iface ?: "");
+	nm_assert (n_written < IP_ADDR_TO_STRING_BUFLEN);
+	return out_buf;
 }
 
 static void
@@ -271,103 +158,43 @@ add_global_config (NMDnsDnsmasq *self, GVariantBuilder *dnsmasq_servers, const N
 	}
 }
 
-static gboolean
-add_ip6_config (NMDnsDnsmasq *self, GVariantBuilder *servers, NMIP6Config *ip6,
-                const char *iface, gboolean split)
+static void
+add_ip_config (NMDnsDnsmasq *self, GVariantBuilder *servers, const NMDnsIPConfigData *ip_data)
 {
-	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);
+	NMIPConfig *ip_config = ip_data->ip_config;
+	gconstpointer addr;
+	const char *iface, *domain;
+	char ip_addr_to_string_buf[IP_ADDR_TO_STRING_BUFLEN];
+	int addr_family;
+	guint i, j, num;
+
+	iface = nm_platform_link_get_name (NM_PLATFORM_GET, ip_data->data->ifindex);
+	addr_family = nm_ip_config_get_addr_family (ip_config);
+
+	num = nm_ip_config_get_num_nameservers (ip_config);
+	for (i = 0; i < num; i++) {
+		addr = nm_ip_config_get_nameserver (ip_config, i);
+		ip_addr_to_string (addr_family, addr, iface, ip_addr_to_string_buf);
+		for (j = 0; ip_data->domains.search[j]; j++) {
+			domain = nm_utils_parse_dns_domain (ip_data->domains.search[j], NULL);
+			add_dnsmasq_nameserver (self,
+			                        servers,
+			                        ip_addr_to_string_buf,
+			                        domain[0] ? domain : NULL);
 		}
-	}
 
-	/* 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);
-			}
+		for (j = 0; ip_data->domains.reverse[j]; j++) {
+			add_dnsmasq_nameserver (self, servers,
+			                        ip_addr_to_string_buf,
+			                        ip_data->domains.reverse[j]);
 		}
 	}
-
-	return TRUE;
-}
-
-static gboolean
-add_ip_config_data (NMDnsDnsmasq *self, GVariantBuilder *servers, const NMDnsIPConfigData *data)
-{
-	if (NM_IS_IP4_CONFIG (data->config)) {
-		return add_ip4_config (self,
-		                       servers,
-		                       (NMIP4Config *) data->config,
-		                       data->iface,
-		                       data->type == NM_DNS_IP_CONFIG_TYPE_VPN);
-	} else if (NM_IS_IP6_CONFIG (data->config)) {
-		return add_ip6_config (self,
-		                       servers,
-		                       (NMIP6Config *) data->config,
-		                       data->iface,
-		                       data->type == NM_DNS_IP_CONFIG_TYPE_VPN);
-	} else
-		g_return_val_if_reached (FALSE);
 }
 
 static void
 dnsmasq_update_done (GDBusProxy *proxy, GAsyncResult *res, gpointer user_data)
 {
 	NMDnsDnsmasq *self;
-	NMDnsDnsmasqPrivate *priv;
 	gs_free_error GError *error = NULL;
 	gs_unref_variant GVariant *response = NULL;
 
@@ -376,7 +203,6 @@ dnsmasq_update_done (GDBusProxy *proxy, GAsyncResult *res, gpointer user_data)
 		return;
 
 	self = NM_DNS_DNSMASQ (user_data);
-	priv = NM_DNS_DNSMASQ_GET_PRIVATE (self);
 
 	if (!response)
 		_LOGW ("dnsmasq update failed: %s", error->message);
@@ -478,7 +304,7 @@ start_dnsmasq (NMDnsDnsmasq *self)
 	const char *argv[15];
 	GPid pid = 0;
 	guint idx = 0;
-	NMBusManager *dbus_mgr;
+	NMDBusManager *dbus_mgr;
 	GDBusConnection *connection;
 
 	if (priv->running) {
@@ -530,10 +356,10 @@ start_dnsmasq (NMDnsDnsmasq *self)
 		return;
 	}
 
-	dbus_mgr = nm_bus_manager_get ();
+	dbus_mgr = nm_dbus_manager_get ();
 	g_return_if_fail (dbus_mgr);
 
-	connection = nm_bus_manager_get_connection (dbus_mgr);
+	connection = nm_dbus_manager_get_connection (dbus_mgr);
 	g_return_if_fail (connection);
 
 	priv->dnsmasq_cancellable = g_cancellable_new ();
@@ -550,15 +376,14 @@ start_dnsmasq (NMDnsDnsmasq *self)
 
 static gboolean
 update (NMDnsPlugin *plugin,
-        const GPtrArray *configs,
         const NMGlobalDnsConfig *global_config,
+        const CList *ip_config_lst_head,
         const char *hostname)
 {
 	NMDnsDnsmasq *self = NM_DNS_DNSMASQ (plugin);
 	NMDnsDnsmasqPrivate *priv = NM_DNS_DNSMASQ_GET_PRIVATE (self);
 	GVariantBuilder servers;
-	guint i;
-	int prio, first_prio;
+	const NMDnsIPConfigData *ip_data;
 
 	start_dnsmasq (self);
 
@@ -567,16 +392,8 @@ update (NMDnsPlugin *plugin,
 	if (global_config)
 		add_global_config (self, &servers, global_config);
 	else {
-		for (i = 0; i < configs->len; i++) {
-			const NMDnsIPConfigData *data = configs->pdata[i];
-
-			prio = nm_ip_config_get_dns_priority (data->config);
-			if (i == 0)
-				first_prio = prio;
-			else if (first_prio < 0 && first_prio != prio)
-				break;
-			add_ip_config_data (self, &servers, data);
-		}
+		c_list_for_each_entry (ip_data, ip_config_lst_head, ip_config_lst)
+			add_ip_config (self, &servers, ip_data);
 	}
 
 	g_clear_pointer (&priv->set_server_ex_args, g_variant_unref);