[PATCH] Use '@interface' for link-local DNS servers in the dnsmasq config



Hi,

the attached patch makes the dnsmasq DNS plugin work with IPv6 DNS
servers with link-local IP addresses. This is similar to commit
c3893b5325ca61261be1749490352f26b41bd479, where '%interface' is
appended to the entries in /etc/resolv.conf for link-local DNS servers.

dnsmasq supports link-local IP addresses when using the syntax
'@interface'. I have talked to the dnsmasq author and he will provide
'%interface' in future versions.

Please tell me if you need any further information or if I should
change something. Otherwise, please merge this patch :).

Thanks,
Best regards,
Michael
>From 99cd08234bffdaebbafb5e4deff302809fa819ae Mon Sep 17 00:00:00 2001
From: Michael Stapelberg <michael stapelberg de>
Date: Fri, 12 Aug 2011 13:43:07 +0200
Subject: [PATCH] Use '@interface' for link-local DNS servers in the dnsmasq
 config

---
 src/dns-manager/nm-dns-bind.c    |    3 ++-
 src/dns-manager/nm-dns-dnsmasq.c |   37 +++++++++++++++++++++++++++----------
 src/dns-manager/nm-dns-manager.c |    3 ++-
 src/dns-manager/nm-dns-plugin.c  |    6 ++++--
 src/dns-manager/nm-dns-plugin.h  |    6 ++++--
 5 files changed, 39 insertions(+), 16 deletions(-)

diff --git a/src/dns-manager/nm-dns-bind.c b/src/dns-manager/nm-dns-bind.c
index fc7af77..55fce03 100644
--- a/src/dns-manager/nm-dns-bind.c
+++ b/src/dns-manager/nm-dns-bind.c
@@ -297,7 +297,8 @@ update (NMDnsPlugin *plugin,
         const GSList *vpn_configs,
         const GSList *dev_configs,
         const GSList *other_configs,
-        const char *hostname)
+        const char *hostname,
+        const char *iface)
 {
 	NMDnsBind *self = NM_DNS_BIND (plugin);
 	NMDnsBindPrivate *priv = NM_DNS_BIND_GET_PRIVATE (self);
diff --git a/src/dns-manager/nm-dns-dnsmasq.c b/src/dns-manager/nm-dns-dnsmasq.c
index 9cc0197..410fb18 100644
--- a/src/dns-manager/nm-dns-dnsmasq.c
+++ b/src/dns-manager/nm-dns-dnsmasq.c
@@ -134,19 +134,35 @@ add_ip4_config (GString *str, NMIP4Config *ip4, gboolean split)
 }
 
 static gboolean
-ip6_addr_to_string (const struct in6_addr *addr, char *buf, size_t buflen)
+ip6_addr_to_string (const struct in6_addr *addr, char *buf, size_t buflen, const char *iface)
 {
+	char *tmp;
 	memset (buf, 0, buflen);
 
 	/* inet_ntop is probably supposed to do this for us, but it doesn't */
 	if (IN6_IS_ADDR_V4MAPPED (addr))
 		return !!inet_ntop (AF_INET, &(addr->s6_addr32[3]), buf, buflen);
-
-	return !!inet_ntop (AF_INET6, addr, buf, buflen);
+	else {
+		if (inet_ntop (AF_INET6, addr, buf, buflen) > 0) {
+			if (IN6_IS_ADDR_LINKLOCAL (addr) && strchr (buf, '%') == NULL) {
+				tmp = g_strdup_printf ("%s@%s", buf, iface);
+				memcpy(buf, tmp, buflen);
+				g_free (tmp);
+			} else {
+				/* replace % with @, dnsmasq only supports @ at
+				 * the moment */
+				tmp = strchr(buf, '%');
+				if (tmp != NULL)
+					*tmp = '@';
+			}
+			return TRUE;
+		}
+		return FALSE;
+	}
 }
 
 static gboolean
-add_ip6_config (GString *str, NMIP6Config *ip6, gboolean split)
+add_ip6_config (GString *str, NMIP6Config *ip6, gboolean split, const char *iface)
 {
 	char buf[INET6_ADDRSTRLEN + 1];
 	const struct in6_addr *addr;
@@ -159,7 +175,7 @@ add_ip6_config (GString *str, NMIP6Config *ip6, gboolean split)
 		 * the first nameserver here.
 		 */
 		addr = nm_ip6_config_get_nameserver (ip6, 0);
-		if (!ip6_addr_to_string (addr, &buf[0], sizeof (buf)))
+		if (!ip6_addr_to_string (addr, &buf[0], sizeof (buf), iface))
 			return FALSE;
 
 		/* searches are preferred over domains */
@@ -188,7 +204,7 @@ add_ip6_config (GString *str, NMIP6Config *ip6, gboolean split)
 		n = nm_ip6_config_get_num_nameservers (ip6);
 		for (i = 0; i < n; i++) {
 			addr = nm_ip6_config_get_nameserver (ip6, i);
-			if (ip6_addr_to_string (addr, &buf[0], sizeof (buf)))
+			if (ip6_addr_to_string (addr, &buf[0], sizeof (buf), iface))
 				g_string_append_printf (str, "server=%s\n", buf);
 		}
 	}
@@ -201,7 +217,8 @@ update (NMDnsPlugin *plugin,
         const GSList *vpn_configs,
         const GSList *dev_configs,
         const GSList *other_configs,
-        const char *hostname)
+        const char *hostname,
+        const char *iface)
 {
 	NMDnsDnsmasq *self = NM_DNS_DNSMASQ (plugin);
 	GString *conf;
@@ -226,7 +243,7 @@ update (NMDnsPlugin *plugin,
 		if (NM_IS_IP4_CONFIG (iter->data))
 			add_ip4_config (conf, NM_IP4_CONFIG (iter->data), TRUE);
 		else if (NM_IS_IP6_CONFIG (iter->data))
-			add_ip6_config (conf, NM_IP6_CONFIG (iter->data), TRUE);
+			add_ip6_config (conf, NM_IP6_CONFIG (iter->data), TRUE, iface);
 	}
 
 	/* Now add interface configs without split DNS */
@@ -234,7 +251,7 @@ update (NMDnsPlugin *plugin,
 		if (NM_IS_IP4_CONFIG (iter->data))
 			add_ip4_config (conf, NM_IP4_CONFIG (iter->data), FALSE);
 		else if (NM_IS_IP6_CONFIG (iter->data))
-			add_ip6_config (conf, NM_IP6_CONFIG (iter->data), FALSE);
+			add_ip6_config (conf, NM_IP6_CONFIG (iter->data), FALSE, iface);
 	}
 
 	/* And any other random configs */
@@ -242,7 +259,7 @@ update (NMDnsPlugin *plugin,
 		if (NM_IS_IP4_CONFIG (iter->data))
 			add_ip4_config (conf, NM_IP4_CONFIG (iter->data), FALSE);
 		else if (NM_IS_IP6_CONFIG (iter->data))
-			add_ip6_config (conf, NM_IP6_CONFIG (iter->data), FALSE);
+			add_ip6_config (conf, NM_IP6_CONFIG (iter->data), FALSE, iface);
 	}
 
 	/* Write out the config file */
diff --git a/src/dns-manager/nm-dns-manager.c b/src/dns-manager/nm-dns-manager.c
index 49cd74e..0203f2b 100644
--- a/src/dns-manager/nm-dns-manager.c
+++ b/src/dns-manager/nm-dns-manager.c
@@ -711,7 +711,8 @@ update_dns (NMDnsManager *self,
 		                           vpn_configs,
 		                           dev_configs,
 		                           other_configs,
-		                           priv->hostname)) {
+		                           priv->hostname,
+					   iface)) {
 			nm_log_warn (LOGD_DNS, "DNS: plugin %s update failed", plugin_name);
 
 			/* If the plugin failed to update, we shouldn't write out a local
diff --git a/src/dns-manager/nm-dns-plugin.c b/src/dns-manager/nm-dns-plugin.c
index ae230ad..e997948 100644
--- a/src/dns-manager/nm-dns-plugin.c
+++ b/src/dns-manager/nm-dns-plugin.c
@@ -55,7 +55,8 @@ nm_dns_plugin_update (NMDnsPlugin *self,
                       const GSList *vpn_configs,
                       const GSList *dev_configs,
                       const GSList *other_configs,
-                      const char *hostname)
+                      const char *hostname,
+                      const char *iface)
 {
 	g_return_val_if_fail (NM_DNS_PLUGIN_GET_CLASS (self)->update != NULL, FALSE);
 
@@ -63,7 +64,8 @@ nm_dns_plugin_update (NMDnsPlugin *self,
 	                                               vpn_configs,
 	                                               dev_configs,
 	                                               other_configs,
-	                                               hostname);
+	                                               hostname,
+						       iface);
 }
 
 static gboolean
diff --git a/src/dns-manager/nm-dns-plugin.h b/src/dns-manager/nm-dns-plugin.h
index d4298b8..37dd733 100644
--- a/src/dns-manager/nm-dns-plugin.h
+++ b/src/dns-manager/nm-dns-plugin.h
@@ -53,7 +53,8 @@ typedef struct {
 	                    const GSList *vpn_configs,
 	                    const GSList *dev_configs,
 	                    const GSList *other_configs,
-	                    const char *hostname);
+	                    const char *hostname,
+	                    const char *iface);
 
 	/* Subclasses should override and return TRUE if they start a local
 	 * caching nameserver that listens on localhost and would block any
@@ -91,7 +92,8 @@ gboolean nm_dns_plugin_update (NMDnsPlugin *self,
                                const GSList *vpn_configs,
                                const GSList *dev_configs,
                                const GSList *other_configs,
-                               const char *hostname);
+                               const char *hostname,
+                               const char *iface);
 
 /* For subclasses/plugins */
 
-- 
1.7.5.4



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]