Re: dnsmasq



Howard Chu wrote:
I've installed dnsmasq on Ubuntu 8.10alpha4, and configured it with
enable-dbus. My belief was that this would allow dnsmasq to pick up nameserver
changes directly from NetworkManager, but instead NM is just overwriting
/etc/resolv.conf. I don't see any commandline options or config files to
control NM's behavior. How do I tell NM not to touch /etc/resolv.conf, and how
do I tell it to update dnsmasq thru dbus?

Answering my own question, the attached patch does what I want.

If dnsmasq is listening when a resolv.conf is going to be updated, the nameserver updates are sent via DBus instead of writing the resolv.conf file. The resolv.conf file should just contain "nameserver 127.0.0.1" and nothing else.
--
  -- Howard Chu
  CTO, Symas Corp.           http://www.symas.com
  Director, Highland Sun     http://highlandsun.com/hyc/
  Chief Architect, OpenLDAP  http://www.openldap.org/project/
Index: named-manager/nm-named-manager.c
===================================================================
--- named-manager/nm-named-manager.c	(revision 4043)
+++ named-manager/nm-named-manager.c	(working copy)
@@ -36,6 +36,7 @@
 #include <glib/gi18n.h>
 
 #include "nm-named-manager.h"
+#include "nm-dbus-manager.h"
 #include "nm-ip4-config.h"
 #include "nm-utils.h"
 #include "NetworkManagerSystem.h"
@@ -62,6 +63,7 @@
 	NMIP4Config *   vpn_config;
 	NMIP4Config *   device_config;
 	GSList *        configs;
+	DBusGProxy *dnsmasq_proxy;
 
 	gboolean disposed;
 };
@@ -356,7 +358,64 @@
 	return *error ? FALSE : TRUE;
 }
 
+static gboolean
+dnsmasq_update(NMNamedManager *mgr)
+{
+	NMNamedManagerPrivate *priv;
+	GSList *iter;
+	DBusMessage *msg;
+	const char *domain;
 
+	priv = NM_NAMED_MANAGER_GET_PRIVATE (mgr);
+
+	msg = dbus_message_new_method_call(
+		"uk.org.thekelleys.dnsmasq",
+		"/uk/org/thekelleys/dnsmasq",
+		"uk.org.thekelleys.dnsmasq",
+		"SetServers");
+	for (iter = priv->configs; iter; iter = g_slist_next (iter)) {
+		NMIP4Config *config = NM_IP4_CONFIG (iter->data);
+		int i, num_nameservers, num_domains;
+
+		/* assume VPN nameserver should only be used for
+		 * the VPN's domain
+		 */
+		if (priv->vpn_config == config)
+		{
+			num_domains = nm_ip4_config_get_num_domains (config);
+		} else
+		{
+			num_domains = 0;
+		}
+		num_nameservers = nm_ip4_config_get_num_nameservers (config);
+		for (i = 0; i < num_nameservers; i++) {
+			guint32 addr;
+			int j;
+
+			addr = htonl(nm_ip4_config_get_nameserver (config, i));
+			dbus_message_append_args(msg,
+				DBUS_TYPE_UINT32, &addr,
+				DBUS_TYPE_INVALID);
+			for (j=0; j<num_domains; j++) {
+				domain = nm_ip4_config_get_domain (config, j);
+				dbus_message_append_args(msg,
+					DBUS_TYPE_STRING, &domain,
+					DBUS_TYPE_INVALID);
+			}
+		}
+	}
+	dbus_g_proxy_send(priv->dnsmasq_proxy, msg, NULL);
+	dbus_message_unref(msg);
+	return TRUE;
+}
+
+static void
+dnsmasq_resend(DBusGProxy *proxy, gpointer data)
+{
+	NMNamedManager *mgr = NM_NAMED_MANAGER(data);
+	dnsmasq_update(mgr);
+}
+
 static gboolean
 rewrite_resolv_conf (NMNamedManager *mgr, const char *iface, GError **error)
 {
@@ -378,6 +437,19 @@
 
 	priv = NM_NAMED_MANAGER_GET_PRIVATE (mgr);
 
+	if (priv->dnsmasq_proxy)
+	{
+		GString *ver;
+		/* see if dnsmasq is listening */
+		if (dbus_g_proxy_call(priv->dnsmasq_proxy, "GetVersion", error,
+			G_TYPE_INVALID, G_TYPE_STRING, &ver, G_TYPE_INVALID ))
+		{
+			success = dnsmasq_update(mgr);
+			if (success)
+				return success;
+		}
+	}
+
 	/* Construct the composite config from all the currently active IP4Configs */
 	composite = nm_ip4_config_new ();
 
@@ -548,6 +620,21 @@
 static void
 nm_named_manager_init (NMNamedManager *mgr)
 {
+	NMNamedManagerPrivate *priv = NM_NAMED_MANAGER_GET_PRIVATE (mgr);
+	NMDBusManager	*dbus_mgr;
+
+	dbus_mgr = nm_dbus_manager_get ();
+	priv->dnsmasq_proxy = dbus_g_proxy_new_for_name(nm_dbus_manager_get_connection(dbus_mgr),
+			"uk.org.thekelleys.dnsmasq",
+			"/uk/org/thekelleys/dnsmasq",
+			"uk.org.thekelleys.dnsmasq");
+	if (priv->dnsmasq_proxy)
+	{
+		dbus_g_proxy_add_signal(priv->dnsmasq_proxy, "Up",
+			G_TYPE_INVALID);
+		dbus_g_proxy_connect_signal(priv->dnsmasq_proxy, "Up",
+			G_CALLBACK(dnsmasq_resend), mgr, NULL);
+	}
 }
 
 static void
Index: named-manager/nm-named-manager.h
===================================================================
--- named-manager/nm-named-manager.h	(revision 4043)
+++ named-manager/nm-named-manager.h	(working copy)
@@ -26,6 +26,7 @@
 #include "config.h"
 #include <glib-object.h>
 #include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
 #include "nm-ip4-config.h"
 
 typedef enum {


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