Esempio n. 1
0
static gboolean
update (NMDnsPlugin *plugin,
        const GSList *vpn_configs,
        const GSList *dev_configs,
        const GSList *other_configs,
        const NMGlobalDnsConfig *global_config,
        const char *hostname)
{
	NMDnsDnsmasq *self = NM_DNS_DNSMASQ (plugin);
	const char *dm_binary;
	GString *conf;
	GSList *iter;
	const char *argv[15];
	GError *error = NULL;
	int ignored;
	GPid pid = 0;
	guint idx = 0;

	/* Kill the old dnsmasq; there doesn't appear to be a way to get dnsmasq
	 * to reread the config file using SIGHUP or similar.  This is a small race
	 * here when restarting dnsmasq when DNS requests could go to the upstream
	 * servers instead of to dnsmasq.
	 */
	nm_dns_plugin_child_kill (plugin);

	dm_binary = nm_utils_find_helper ("dnsmasq", DNSMASQ_PATH, NULL);
	if (!dm_binary) {
		nm_log_warn (LOGD_DNS, "Could not find dnsmasq binary");
		return FALSE;
	}

	/* Build up the new dnsmasq config file */
	conf = g_string_sized_new (150);

	if (global_config)
		add_global_config (conf, global_config);
	else {
		/* Use split DNS for VPN configs */
		for (iter = (GSList *) vpn_configs; iter; iter = g_slist_next (iter)) {
			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);
		}

		/* Now add interface configs without split DNS */
		for (iter = (GSList *) dev_configs; iter; iter = g_slist_next (iter)) {
			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);
		}

		/* And any other random configs */
		for (iter = (GSList *) other_configs; iter; iter = g_slist_next (iter)) {
			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);
		}
	}

	/* Write out the config file */
	if (!g_file_set_contents (CONFFILE, conf->str, -1, &error)) {
		nm_log_warn (LOGD_DNS, "Failed to write dnsmasq config file %s: (%d) %s",
		             CONFFILE,
		             error ? error->code : -1,
		             error && error->message ? error->message : "(unknown)");
		g_clear_error (&error);
		goto out;
	}
	ignored = chmod (CONFFILE, 0644);

	nm_log_dbg (LOGD_DNS, "dnsmasq local caching DNS configuration:");
	nm_log_dbg (LOGD_DNS, "%s", conf->str);

	argv[idx++] = dm_binary;
	argv[idx++] = "--no-resolv";  /* Use only commandline */
	argv[idx++] = "--keep-in-foreground";
	argv[idx++] = "--no-hosts"; /* don't use /etc/hosts to resolve */
	argv[idx++] = "--bind-interfaces";
	argv[idx++] = "--pid-file=" PIDFILE;
	argv[idx++] = "--listen-address=127.0.0.1"; /* Should work for both 4 and 6 */
	argv[idx++] = "--conf-file=" CONFFILE;
	argv[idx++] = "--cache-size=400";
	argv[idx++] = "--proxy-dnssec"; /* Allow DNSSEC to pass through */

	/* dnsmasq exits if the conf dir is not present */
	if (g_file_test (CONFDIR, G_FILE_TEST_IS_DIR))
		argv[idx++] = "--conf-dir=" CONFDIR;

	argv[idx++] = NULL;
	g_warn_if_fail (idx <= G_N_ELEMENTS (argv));

	/* And finally spawn dnsmasq */
	pid = nm_dns_plugin_child_spawn (NM_DNS_PLUGIN (self), argv, PIDFILE, "bin/dnsmasq");

out:
	g_string_free (conf, TRUE);
	return pid ? TRUE : FALSE;
}
Esempio n. 2
0
static gboolean
update (NMDnsPlugin *plugin,
        const GSList *vpn_configs,
        const GSList *dev_configs,
        const GSList *other_configs,
        const char *hostname,
        const char *iface)
{
	NMDnsDnsmasq *self = NM_DNS_DNSMASQ (plugin);
	GString *conf;
	GSList *iter;
	const char *argv[11];
	GError *error = NULL;
	int ignored;
	GPid pid = 0;

	/* Kill the old dnsmasq; there doesn't appear to be a way to get dnsmasq
	 * to reread the config file using SIGHUP or similar.  This is a small race
	 * here when restarting dnsmasq when DNS requests could go to the upstream
	 * servers instead of to dnsmasq.
	 */
	nm_dns_plugin_child_kill (plugin);

	/* Build up the new dnsmasq config file */
	conf = g_string_sized_new (150);

	/* Use split DNS for VPN configs */
	for (iter = (GSList *) vpn_configs; iter; iter = g_slist_next (iter)) {
		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, iface);
	}

	/* Now add interface configs without split DNS */
	for (iter = (GSList *) dev_configs; iter; iter = g_slist_next (iter)) {
		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, iface);
	}

	/* And any other random configs */
	for (iter = (GSList *) other_configs; iter; iter = g_slist_next (iter)) {
		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, iface);
	}

	/* Write out the config file */
	if (!g_file_set_contents (CONFFILE, conf->str, -1, &error)) {
		nm_log_warn (LOGD_DNS, "Failed to write dnsmasq config file %s: (%d) %s",
		             CONFFILE,
		             error ? error->code : -1,
		             error && error->message ? error->message : "(unknown)");
		g_clear_error (&error);
		goto out;
	}
	ignored = chmod (CONFFILE, 0600);

	nm_log_dbg (LOGD_DNS, "dnsmasq local caching DNS configuration:");
	nm_log_dbg (LOGD_DNS, "%s", conf->str);

	argv[0] = find_dnsmasq ();
	argv[1] = "--no-resolv";  /* Use only commandline */
	argv[2] = "--keep-in-foreground";
	argv[3] = "--strict-order";
	argv[4] = "--bind-interfaces";
	argv[5] = "--pid-file=" PIDFILE;
	argv[6] = "--listen-address=127.0.0.1"; /* Should work for both 4 and 6 */
	argv[7] = "--conf-file=" CONFFILE;
	argv[8] = "--cache-size=400";
	argv[9] = NULL;

	/* And finally spawn dnsmasq */
	pid = nm_dns_plugin_child_spawn (NM_DNS_PLUGIN (self), argv, PIDFILE, "bin/dnsmasq");

out:
	g_string_free (conf, TRUE);
	return pid ? TRUE : FALSE;
}
Esempio n. 3
0
static void
start_dnsmasq (NMDnsDnsmasq *self)
{
	NMDnsDnsmasqPrivate *priv = NM_DNS_DNSMASQ_GET_PRIVATE (self);
	const char *dm_binary;
	const char *argv[15];
	GPid pid = 0;
	guint idx = 0;
	NMBusManager *dbus_mgr;
	GDBusConnection *connection;

	if (priv->running) {
		/* the dnsmasq process is running. Nothing to do. */
		return;
	}

	if (nm_dns_plugin_child_pid ((NMDnsPlugin *) self) > 0) {
		/* if we already have a child process spawned, don't do
		 * it again. */
		return;
	}

	dm_binary = nm_utils_find_helper ("dnsmasq", DNSMASQ_PATH, NULL);
	if (!dm_binary) {
		_LOGW ("could not find dnsmasq binary");
		return;
	}

	argv[idx++] = dm_binary;
	argv[idx++] = "--no-resolv";  /* Use only commandline */
	argv[idx++] = "--keep-in-foreground";
	argv[idx++] = "--no-hosts"; /* don't use /etc/hosts to resolve */
	argv[idx++] = "--bind-interfaces";
	argv[idx++] = "--pid-file=" PIDFILE;
	argv[idx++] = "--listen-address=127.0.0.1"; /* Should work for both 4 and 6 */
	argv[idx++] = "--cache-size=400";
	argv[idx++] = "--conf-file=/dev/null"; /* avoid loading /etc/dnsmasq.conf */
	argv[idx++] = "--proxy-dnssec"; /* Allow DNSSEC to pass through */
	argv[idx++] = "--enable-dbus=" DNSMASQ_DBUS_SERVICE;

	/* dnsmasq exits if the conf dir is not present */
	if (g_file_test (CONFDIR, G_FILE_TEST_IS_DIR))
		argv[idx++] = "--conf-dir=" CONFDIR;

	argv[idx++] = NULL;
	nm_assert (idx <= G_N_ELEMENTS (argv));

	/* And finally spawn dnsmasq */
	pid = nm_dns_plugin_child_spawn (NM_DNS_PLUGIN (self), argv, PIDFILE, "bin/dnsmasq");
	if (!pid)
		return;

	if (   priv->dnsmasq
	    || priv->dnsmasq_cancellable) {
		/* we already have a proxy or are about to create it.
		 * We are done. */
		return;
	}

	dbus_mgr = nm_bus_manager_get ();
	g_return_if_fail (dbus_mgr);

	connection = nm_bus_manager_get_connection (dbus_mgr);
	g_return_if_fail (connection);

	priv->dnsmasq_cancellable = g_cancellable_new ();
	g_dbus_proxy_new (connection,
	                  G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
	                  NULL,
	                  DNSMASQ_DBUS_SERVICE,
	                  DNSMASQ_DBUS_PATH,
	                  DNSMASQ_DBUS_SERVICE,
	                  priv->dnsmasq_cancellable,
	                  dnsmasq_proxy_cb,
	                  self);
}