mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-07 03:10:16 +01:00
dns: hook plugins into DNS updates and make dnsmasq plugin actually work
This commit is contained in:
parent
4da443dc69
commit
a2982b5f7b
4 changed files with 213 additions and 133 deletions
|
|
@ -41,83 +41,11 @@ G_DEFINE_TYPE (NMDnsDnsmasq, nm_dns_dnsmasq, NM_TYPE_DNS_PLUGIN)
|
|||
#define CONFFILE LOCALSTATEDIR "/run/nm-dns-dnsmasq.conf"
|
||||
|
||||
typedef struct {
|
||||
int pid;
|
||||
guint32 foo;
|
||||
} NMDnsDnsmasqPrivate;
|
||||
|
||||
/*******************************************/
|
||||
|
||||
#if 0
|
||||
static NMCmdLine *
|
||||
create_dm_cmd_line (const char *iface,
|
||||
const char *pidfile,
|
||||
GError **error)
|
||||
{
|
||||
const char *dm_binary;
|
||||
GString *conf;
|
||||
NMIP4Address *tmp;
|
||||
struct in_addr addr;
|
||||
char buf[INET_ADDRSTRLEN + 15];
|
||||
char localaddr[INET_ADDRSTRLEN + 1];
|
||||
int i;
|
||||
|
||||
dm_binary = nm_find_dnsmasq ();
|
||||
if (!dm_binary) {
|
||||
nm_log_warn (LOGD_DNS, "could not find dnsmasq binary.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Create dnsmasq command line */
|
||||
cmd = nm_cmd_line_new ();
|
||||
nm_cmd_line_add_string (cmd, dm_binary);
|
||||
|
||||
if (getenv ("NM_DNSMASQ_DEBUG"))
|
||||
nm_cmd_line_add_string (cmd, "--log-queries");
|
||||
|
||||
/* dnsmasq may read from it's default config file location, which if that
|
||||
* location is a valid config file, it will combine with the options here
|
||||
* and cause undesirable side-effects. Like sending bogus IP addresses
|
||||
* as the gateway or whatever. So give dnsmasq a bogus config file
|
||||
* location to avoid screwing up the configuration we're passing to it.
|
||||
*/
|
||||
memset (buf, 0, sizeof (buf));
|
||||
strcpy (buf, "/tmp/");
|
||||
for (i = 5; i < 15; i++)
|
||||
buf[i] = (char) (g_random_int_range ((guint32) 'a', (guint32) 'z') & 0xFF);
|
||||
strcat (buf, ".conf");
|
||||
|
||||
nm_cmd_line_add_string (cmd, "--conf-file");
|
||||
nm_cmd_line_add_string (cmd, buf);
|
||||
|
||||
nm_cmd_line_add_string (cmd, "--no-hosts");
|
||||
nm_cmd_line_add_string (cmd, "--keep-in-foreground");
|
||||
nm_cmd_line_add_string (cmd, "--bind-interfaces");
|
||||
nm_cmd_line_add_string (cmd, "--except-interface=lo");
|
||||
nm_cmd_line_add_string (cmd, "--clear-on-reload");
|
||||
|
||||
/* Use strict order since in the case of VPN connections, the VPN's
|
||||
* nameservers will be first in resolv.conf, and those need to be tried
|
||||
* first by dnsmasq to successfully resolve names from the VPN.
|
||||
*/
|
||||
nm_cmd_line_add_string (cmd, "--strict-order");
|
||||
|
||||
s = g_string_new ("--listen-address=");
|
||||
addr.s_addr = nm_ip4_address_get_address (tmp);
|
||||
if (!inet_ntop (AF_INET, &addr, &localaddr[0], INET_ADDRSTRLEN)) {
|
||||
nm_log_warn (LOGD_SHARING, "error converting IP4 address 0x%X",
|
||||
ntohl (addr.s_addr));
|
||||
goto error;
|
||||
}
|
||||
g_string_append (s, localaddr);
|
||||
nm_cmd_line_add_string (cmd, s->str);
|
||||
g_string_free (s, TRUE);
|
||||
return cmd;
|
||||
|
||||
error:
|
||||
nm_cmd_line_destroy (cmd);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline const char *
|
||||
find_dnsmasq (void)
|
||||
{
|
||||
|
|
@ -234,12 +162,19 @@ update (NMDnsPlugin *plugin,
|
|||
const char *hostname)
|
||||
{
|
||||
NMDnsDnsmasq *self = NM_DNS_DNSMASQ (plugin);
|
||||
NMDnsDnsmasqPrivate *priv = NM_DNS_DNSMASQ_GET_PRIVATE (self);
|
||||
GString *conf;
|
||||
GSList *iter;
|
||||
const char *argv[10];
|
||||
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);
|
||||
|
|
@ -285,17 +220,18 @@ update (NMDnsPlugin *plugin,
|
|||
argv[0] = find_dnsmasq ();
|
||||
argv[1] = "--no-resolv"; /* Use only commandline */
|
||||
argv[2] = "--keep-in-foreground";
|
||||
argv[3] = "--pid-file=" PIDFILE;
|
||||
argv[4] = "--listen-address=127.0.0.1"; /* Should work for both 4 and 6 */
|
||||
argv[5] = "--conf-file=" CONFFILE;
|
||||
argv[6] = NULL;
|
||||
argv[3] = "--bind-interfaces";
|
||||
argv[4] = "--pid-file=" PIDFILE;
|
||||
argv[5] = "--listen-address=127.0.0.1"; /* Should work for both 4 and 6 */
|
||||
argv[6] = "--conf-file=" CONFFILE;
|
||||
argv[7] = NULL;
|
||||
|
||||
/* And finally spawn dnsmasq */
|
||||
priv->pid = nm_dns_plugin_child_spawn (NM_DNS_PLUGIN (self), argv, PIDFILE, "bin/dnsmasq");
|
||||
pid = nm_dns_plugin_child_spawn (NM_DNS_PLUGIN (self), argv, PIDFILE, "bin/dnsmasq");
|
||||
|
||||
out:
|
||||
g_string_free (conf, TRUE);
|
||||
return priv->pid ? TRUE : FALSE;
|
||||
return pid ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
|
|
@ -322,7 +258,6 @@ static void
|
|||
child_quit (NMDnsPlugin *plugin, gint status)
|
||||
{
|
||||
NMDnsDnsmasq *self = NM_DNS_DNSMASQ (plugin);
|
||||
NMDnsDnsmasqPrivate *priv = NM_DNS_DNSMASQ_GET_PRIVATE (self);
|
||||
gboolean failed = TRUE;
|
||||
int err;
|
||||
|
||||
|
|
@ -341,12 +276,10 @@ child_quit (NMDnsPlugin *plugin, gint status)
|
|||
} else {
|
||||
nm_log_warn (LOGD_DNS, "dnsmasq died from an unknown cause");
|
||||
}
|
||||
unlink (CONFFILE);
|
||||
|
||||
if (failed)
|
||||
g_signal_emit_by_name (self, NM_DNS_PLUGIN_FAILED);
|
||||
|
||||
priv->pid = 0;
|
||||
unlink (CONFFILE);
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
|
|
@ -358,11 +291,17 @@ init (NMDnsPlugin *plugin)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
is_exclusive (NMDnsPlugin *plugin)
|
||||
is_caching (NMDnsPlugin *plugin)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_name (NMDnsPlugin *plugin)
|
||||
{
|
||||
return "dnsmasq";
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
|
||||
NMDnsDnsmasq *
|
||||
|
|
@ -376,16 +315,28 @@ nm_dns_dnsmasq_init (NMDnsDnsmasq *self)
|
|||
{
|
||||
}
|
||||
|
||||
static void
|
||||
dispose (GObject *object)
|
||||
{
|
||||
unlink (CONFFILE);
|
||||
|
||||
G_OBJECT_CLASS (nm_dns_dnsmasq_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
nm_dns_dnsmasq_class_init (NMDnsDnsmasqClass *dns_class)
|
||||
{
|
||||
NMDnsPluginClass *plugin_class = NM_DNS_PLUGIN_CLASS (dns_class);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (dns_class);
|
||||
|
||||
g_type_class_add_private (dns_class, sizeof (NMDnsDnsmasqPrivate));
|
||||
|
||||
object_class->dispose = dispose;
|
||||
|
||||
plugin_class->init = init;
|
||||
plugin_class->child_quit = child_quit;
|
||||
plugin_class->is_exclusive = is_exclusive;
|
||||
plugin_class->is_caching = is_caching;
|
||||
plugin_class->update = update;
|
||||
plugin_class->get_name = get_name;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -245,10 +245,11 @@ dispatch_netconfig (const char *domain,
|
|||
char **nameservers,
|
||||
const char *nis_domain,
|
||||
char **nis_servers,
|
||||
gboolean caching,
|
||||
const char *iface,
|
||||
GError **error)
|
||||
{
|
||||
char *str;
|
||||
char *str, *tmp;
|
||||
GPid pid;
|
||||
gint fd;
|
||||
int ret;
|
||||
|
|
@ -284,9 +285,14 @@ dispatch_netconfig (const char *domain,
|
|||
}
|
||||
|
||||
if (nameservers) {
|
||||
str = g_strjoinv (" ", nameservers);
|
||||
tmp = g_strjoinv (" ", nameservers);
|
||||
if (caching)
|
||||
str = g_strdup_printf ("127.0.0.1 %s", tmp);
|
||||
else
|
||||
str = g_strdup (tmp);
|
||||
write_to_netconfig (fd, "DNSSERVERS", str);
|
||||
g_free (str);
|
||||
g_free (tmp);
|
||||
}
|
||||
|
||||
if (nis_domain)
|
||||
|
|
@ -321,6 +327,7 @@ static gboolean
|
|||
write_resolv_conf (FILE *f, const char *domain,
|
||||
char **searches,
|
||||
char **nameservers,
|
||||
gboolean caching,
|
||||
GError **error)
|
||||
{
|
||||
char *domain_str = NULL;
|
||||
|
|
@ -328,6 +335,7 @@ write_resolv_conf (FILE *f, const char *domain,
|
|||
char *nameservers_str = NULL;
|
||||
int i;
|
||||
gboolean retval = FALSE;
|
||||
GString *str;
|
||||
|
||||
if (fprintf (f, "%s","# Generated by NetworkManager\n") < 0) {
|
||||
g_set_error (error,
|
||||
|
|
@ -349,15 +357,16 @@ write_resolv_conf (FILE *f, const char *domain,
|
|||
g_free (tmp_str);
|
||||
}
|
||||
|
||||
if (nameservers) {
|
||||
GString *str;
|
||||
int num;
|
||||
str = g_string_new ("");
|
||||
|
||||
str = g_string_new ("");
|
||||
num = g_strv_length (nameservers);
|
||||
if (caching)
|
||||
g_string_append_printf (str, "nameserver 127.0.0.1\n");
|
||||
|
||||
if (nameservers) {
|
||||
int num = g_strv_length (nameservers);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
if (i == 3) {
|
||||
if (i == 3 && !caching) {
|
||||
g_string_append (str, "# ");
|
||||
g_string_append (str, _("NOTE: the libc resolver may not support more than 3 nameservers."));
|
||||
g_string_append (str, "\n# ");
|
||||
|
|
@ -369,14 +378,14 @@ write_resolv_conf (FILE *f, const char *domain,
|
|||
g_string_append (str, nameservers[i]);
|
||||
g_string_append_c (str, '\n');
|
||||
}
|
||||
|
||||
nameservers_str = g_string_free (str, FALSE);
|
||||
}
|
||||
|
||||
nameservers_str = g_string_free (str, FALSE);
|
||||
|
||||
if (fprintf (f, "%s%s%s",
|
||||
domain_str ? domain_str : "",
|
||||
searches_str ? searches_str : "",
|
||||
nameservers_str ? nameservers_str : "") != -1)
|
||||
strlen (nameservers_str) ? nameservers_str : "") != -1)
|
||||
retval = TRUE;
|
||||
|
||||
g_free (domain_str);
|
||||
|
|
@ -391,6 +400,7 @@ static gboolean
|
|||
dispatch_resolvconf (const char *domain,
|
||||
char **searches,
|
||||
char **nameservers,
|
||||
gboolean caching,
|
||||
const char *iface,
|
||||
GError **error)
|
||||
{
|
||||
|
|
@ -412,7 +422,7 @@ dispatch_resolvconf (const char *domain,
|
|||
RESOLVCONF_PATH,
|
||||
g_strerror (errno));
|
||||
else {
|
||||
retval = write_resolv_conf (f, domain, searches, nameservers, error);
|
||||
retval = write_resolv_conf (f, domain, searches, nameservers, caching, error);
|
||||
retval &= (pclose (f) == 0);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -432,6 +442,7 @@ static gboolean
|
|||
update_resolv_conf (const char *domain,
|
||||
char **searches,
|
||||
char **nameservers,
|
||||
gboolean caching,
|
||||
const char *iface,
|
||||
GError **error)
|
||||
{
|
||||
|
|
@ -479,7 +490,7 @@ update_resolv_conf (const char *domain,
|
|||
strcpy (tmp_resolv_conf_realpath, RESOLV_CONF);
|
||||
}
|
||||
|
||||
write_resolv_conf (f, domain, searches, nameservers, error);
|
||||
write_resolv_conf (f, domain, searches, nameservers, caching, error);
|
||||
|
||||
if (fclose (f) < 0) {
|
||||
if (*error == NULL) {
|
||||
|
|
@ -515,23 +526,26 @@ out:
|
|||
}
|
||||
|
||||
static gboolean
|
||||
rewrite_resolv_conf (NMDnsManager *mgr, const char *iface, GError **error)
|
||||
update_dns (NMDnsManager *self,
|
||||
const char *iface,
|
||||
gboolean no_caching,
|
||||
GError **error)
|
||||
{
|
||||
NMDnsManagerPrivate *priv;
|
||||
NMResolvConfData rc;
|
||||
GSList *iter;
|
||||
GSList *iter, *vpn_configs = NULL, *dev_configs = NULL, *other_configs = NULL;
|
||||
const char *domain = NULL;
|
||||
const char *nis_domain = NULL;
|
||||
char **searches = NULL;
|
||||
char **nameservers = NULL;
|
||||
char **nis_servers = NULL;
|
||||
int num, i, len;
|
||||
gboolean success = FALSE;
|
||||
gboolean success = FALSE, caching = FALSE;
|
||||
|
||||
g_return_val_if_fail (error != NULL, FALSE);
|
||||
g_return_val_if_fail (*error == NULL, FALSE);
|
||||
|
||||
priv = NM_DNS_MANAGER_GET_PRIVATE (mgr);
|
||||
priv = NM_DNS_MANAGER_GET_PRIVATE (self);
|
||||
|
||||
if (iface) {
|
||||
g_free (priv->last_iface);
|
||||
|
|
@ -618,20 +632,74 @@ rewrite_resolv_conf (NMDnsManager *mgr, const char *iface, GError **error)
|
|||
|
||||
nis_domain = rc.nis_domain;
|
||||
|
||||
/* Build up config lists for plugins; we use the raw configs here, not the
|
||||
* merged information that we write to resolv.conf so that the plugins can
|
||||
* still use the domain information in each config to provide split DNS if
|
||||
* they want to.
|
||||
*/
|
||||
if (priv->ip4_vpn_config)
|
||||
vpn_configs = g_slist_append (vpn_configs, priv->ip4_vpn_config);
|
||||
if (priv->ip6_vpn_config)
|
||||
vpn_configs = g_slist_append (vpn_configs, priv->ip6_vpn_config);
|
||||
if (priv->ip4_device_config)
|
||||
dev_configs = g_slist_append (dev_configs, priv->ip4_device_config);
|
||||
if (priv->ip6_device_config)
|
||||
dev_configs = g_slist_append (dev_configs, priv->ip6_device_config);
|
||||
|
||||
for (iter = priv->configs; iter; iter = g_slist_next (iter)) {
|
||||
if ( (iter->data != priv->ip4_vpn_config)
|
||||
&& (iter->data != priv->ip4_device_config)
|
||||
&& (iter->data != priv->ip6_vpn_config)
|
||||
&& (iter->data != priv->ip6_device_config))
|
||||
other_configs = g_slist_append (other_configs, iter->data);
|
||||
}
|
||||
|
||||
/* Let any plugins do their thing first */
|
||||
for (iter = priv->plugins; iter; iter = g_slist_next (iter)) {
|
||||
NMDnsPlugin *plugin = NM_DNS_PLUGIN (iter->data);
|
||||
const char *plugin_name = nm_dns_plugin_get_name (plugin);
|
||||
|
||||
if (nm_dns_plugin_is_caching (plugin)) {
|
||||
if (no_caching) {
|
||||
nm_log_dbg (LOGD_DNS, "DNS: plugin %s ignored (caching disabled)",
|
||||
plugin_name);
|
||||
continue;
|
||||
}
|
||||
caching = TRUE;
|
||||
}
|
||||
|
||||
nm_log_dbg (LOGD_DNS, "DNS: updating plugin %s", plugin_name);
|
||||
if (!nm_dns_plugin_update (plugin,
|
||||
vpn_configs,
|
||||
dev_configs,
|
||||
other_configs,
|
||||
priv->hostname)) {
|
||||
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
|
||||
* caching DNS configuration to resolv.conf.
|
||||
*/
|
||||
caching = FALSE;
|
||||
}
|
||||
}
|
||||
g_slist_free (vpn_configs);
|
||||
g_slist_free (dev_configs);
|
||||
g_slist_free (other_configs);
|
||||
|
||||
#ifdef RESOLVCONF_PATH
|
||||
success = dispatch_resolvconf (domain, searches, nameservers, iface, error);
|
||||
success = dispatch_resolvconf (domain, searches, nameservers, caching, iface, error);
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_SUSE
|
||||
if (success == FALSE) {
|
||||
success = dispatch_netconfig (domain, searches, nameservers,
|
||||
nis_domain, nis_servers,
|
||||
iface, error);
|
||||
caching, iface, error);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (success == FALSE)
|
||||
success = update_resolv_conf (domain, searches, nameservers, iface, error);
|
||||
success = update_resolv_conf (domain, searches, nameservers, caching, iface, error);
|
||||
|
||||
if (success)
|
||||
nm_system_update_dns ();
|
||||
|
|
@ -646,6 +714,26 @@ rewrite_resolv_conf (NMDnsManager *mgr, const char *iface, GError **error)
|
|||
return success;
|
||||
}
|
||||
|
||||
static void
|
||||
plugin_failed (NMDnsPlugin *plugin, gpointer user_data)
|
||||
{
|
||||
NMDnsManager *self = NM_DNS_MANAGER (user_data);
|
||||
NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self);
|
||||
GError *error = NULL;
|
||||
|
||||
/* Errors with non-caching plugins aren't fatal */
|
||||
if (!nm_dns_plugin_is_caching (plugin))
|
||||
return;
|
||||
|
||||
/* Disable caching until the next DNS update */
|
||||
if (!update_dns (self, priv->last_iface, TRUE, &error)) {
|
||||
nm_log_warn (LOGD_DNS, "could not commit DNS changes: (%d) %s",
|
||||
error ? error->code : -1,
|
||||
error && error->message ? error->message : "(unknown)");
|
||||
g_clear_error (&error);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_dns_manager_add_ip4_config (NMDnsManager *mgr,
|
||||
const char *iface,
|
||||
|
|
@ -676,9 +764,11 @@ nm_dns_manager_add_ip4_config (NMDnsManager *mgr,
|
|||
if (!g_slist_find (priv->configs, config))
|
||||
priv->configs = g_slist_append (priv->configs, g_object_ref (config));
|
||||
|
||||
if (!rewrite_resolv_conf (mgr, iface, &error)) {
|
||||
nm_log_warn (LOGD_DNS, "could not commit DNS changes: '%s'", error ? error->message : "(none)");
|
||||
g_error_free (error);
|
||||
if (!update_dns (mgr, iface, FALSE, &error)) {
|
||||
nm_log_warn (LOGD_DNS, "could not commit DNS changes: (%d) %s",
|
||||
error ? error->code : -1,
|
||||
error && error->message ? error->message : "(unknown)");
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
@ -711,10 +801,11 @@ nm_dns_manager_remove_ip4_config (NMDnsManager *mgr,
|
|||
|
||||
g_object_unref (config);
|
||||
|
||||
if (!rewrite_resolv_conf (mgr, iface, &error)) {
|
||||
nm_log_warn (LOGD_DNS, "could not commit DNS changes: '%s'", error ? error->message : "(none)");
|
||||
if (error)
|
||||
g_error_free (error);
|
||||
if (!update_dns (mgr, iface, FALSE, &error)) {
|
||||
nm_log_warn (LOGD_DNS, "could not commit DNS changes: (%d) %s",
|
||||
error ? error->code : -1,
|
||||
error && error->message ? error->message : "(unknown)");
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
@ -752,9 +843,11 @@ nm_dns_manager_add_ip6_config (NMDnsManager *mgr,
|
|||
if (!g_slist_find (priv->configs, config))
|
||||
priv->configs = g_slist_append (priv->configs, g_object_ref (config));
|
||||
|
||||
if (!rewrite_resolv_conf (mgr, iface, &error)) {
|
||||
nm_log_warn (LOGD_DNS, "could not commit DNS changes: '%s'", error ? error->message : "(none)");
|
||||
g_error_free (error);
|
||||
if (!update_dns (mgr, iface, FALSE, &error)) {
|
||||
nm_log_warn (LOGD_DNS, "could not commit DNS changes: (%d) %s",
|
||||
error ? error->code : -1,
|
||||
error && error->message ? error->message : "(unknown)");
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
@ -787,10 +880,11 @@ nm_dns_manager_remove_ip6_config (NMDnsManager *mgr,
|
|||
|
||||
g_object_unref (config);
|
||||
|
||||
if (!rewrite_resolv_conf (mgr, iface, &error)) {
|
||||
nm_log_warn (LOGD_DNS, "could not commit DNS changes: '%s'", error ? error->message : "(none)");
|
||||
if (error)
|
||||
g_error_free (error);
|
||||
if (!update_dns (mgr, iface, FALSE, &error)) {
|
||||
nm_log_warn (LOGD_DNS, "could not commit DNS changes: (%d) %s",
|
||||
error ? error->code : -1,
|
||||
error && error->message ? error->message : "(unknown)");
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
@ -824,8 +918,10 @@ nm_dns_manager_set_hostname (NMDnsManager *mgr,
|
|||
* wants one. But hostname changes are system-wide and *not* tied to a
|
||||
* specific interface, so netconfig can't really handle this. Fake it.
|
||||
*/
|
||||
if (!rewrite_resolv_conf (mgr, priv->last_iface, &error)) {
|
||||
nm_log_warn (LOGD_DNS, "could not commit DNS changes: '%s'", error ? error->message : "(none)");
|
||||
if (!update_dns (mgr, priv->last_iface, FALSE, &error)) {
|
||||
nm_log_warn (LOGD_DNS, "could not commit DNS changes: (%d) %s",
|
||||
error ? error->code : -1,
|
||||
error && error->message ? error->message : "(unknown)");
|
||||
g_clear_error (&error);
|
||||
}
|
||||
}
|
||||
|
|
@ -848,6 +944,7 @@ load_plugins (NMDnsManager *self, const char **plugins)
|
|||
NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self);
|
||||
NMDnsPlugin *plugin;
|
||||
const char **iter;
|
||||
gboolean have_caching = FALSE;
|
||||
|
||||
if (plugins && *plugins) {
|
||||
/* Create each configured plugin */
|
||||
|
|
@ -859,19 +956,39 @@ load_plugins (NMDnsManager *self, const char **plugins)
|
|||
else if (!strcasecmp (*iter, "chromium"))
|
||||
plugin = NM_DNS_PLUGIN (nm_dns_chromium_new ());
|
||||
else {
|
||||
nm_log_warn (LOGD_DNS, "Unknown DNS plugin '%s'", *iter);
|
||||
nm_log_warn (LOGD_DNS, "Unknown DNS plugin '%s'", *iter);\
|
||||
continue;
|
||||
}
|
||||
g_assert (plugin);
|
||||
|
||||
/* Only one caching DNS plugin is allowed */
|
||||
if (nm_dns_plugin_is_caching (plugin)) {
|
||||
if (have_caching) {
|
||||
nm_log_warn (LOGD_DNS,
|
||||
"Ignoring plugin %s; only one caching DNS "
|
||||
"plugin is allowed.",
|
||||
*iter);
|
||||
g_object_unref (plugin);
|
||||
continue;
|
||||
}
|
||||
have_caching = TRUE;
|
||||
}
|
||||
|
||||
if (plugin)
|
||||
priv->plugins = g_slist_append (priv->plugins, plugin);
|
||||
nm_log_info (LOGD_DNS, "DNS: loaded plugin %s", nm_dns_plugin_get_name (plugin));
|
||||
priv->plugins = g_slist_append (priv->plugins, plugin);
|
||||
g_signal_connect (plugin, NM_DNS_PLUGIN_FAILED,
|
||||
G_CALLBACK (plugin_failed),
|
||||
self);
|
||||
}
|
||||
} else {
|
||||
/* Create default plugins */
|
||||
|
||||
/* Chromium support */
|
||||
#if 0
|
||||
plugin = NM_DNS_PLUGIN (nm_dns_chromium_new ());
|
||||
g_assert (plugin);
|
||||
priv->plugins = g_slist_append (priv->plugins, plugin);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -66,15 +66,22 @@ nm_dns_plugin_update (NMDnsPlugin *self,
|
|||
}
|
||||
|
||||
static gboolean
|
||||
is_exclusive (NMDnsPlugin *self)
|
||||
is_caching (NMDnsPlugin *self)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_dns_plugin_is_exclusive (NMDnsPlugin *self)
|
||||
nm_dns_plugin_is_caching (NMDnsPlugin *self)
|
||||
{
|
||||
return NM_DNS_PLUGIN_GET_CLASS (self)->is_exclusive (self);
|
||||
return NM_DNS_PLUGIN_GET_CLASS (self)->is_caching (self);
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_dns_plugin_get_name (NMDnsPlugin *self)
|
||||
{
|
||||
g_assert (NM_DNS_PLUGIN_GET_CLASS (self)->get_name);
|
||||
return NM_DNS_PLUGIN_GET_CLASS (self)->get_name (self);
|
||||
}
|
||||
|
||||
/********************************************/
|
||||
|
|
@ -158,9 +165,9 @@ nm_dns_plugin_child_spawn (NMDnsPlugin *self,
|
|||
priv->pidfile = g_strdup (pidfile);
|
||||
}
|
||||
|
||||
nm_log_info (LOGD_DNS, "Starting %s...", priv->progname);
|
||||
nm_log_info (LOGD_DNS, "DNS: starting %s...", priv->progname);
|
||||
cmdline = g_strjoinv (" ", (char **) argv);
|
||||
nm_log_dbg (LOGD_DNS, "Command line: %s", cmdline);
|
||||
nm_log_dbg (LOGD_DNS, "DNS: command line: %s", cmdline);
|
||||
g_free (cmdline);
|
||||
|
||||
priv->pid = 0;
|
||||
|
|
@ -287,7 +294,7 @@ nm_dns_plugin_class_init (NMDnsPluginClass *plugin_class)
|
|||
/* virtual methods */
|
||||
object_class->dispose = dispose;
|
||||
object_class->finalize = finalize;
|
||||
plugin_class->is_exclusive = is_exclusive;
|
||||
plugin_class->is_caching = is_caching;
|
||||
|
||||
/* signals */
|
||||
signals[FAILED] =
|
||||
|
|
|
|||
|
|
@ -59,7 +59,10 @@ typedef struct {
|
|||
* caching nameserver that listens on localhost and would block any
|
||||
* other local caching nameserver from operating.
|
||||
*/
|
||||
gboolean (*is_exclusive) (NMDnsPlugin *self);
|
||||
gboolean (*is_caching) (NMDnsPlugin *self);
|
||||
|
||||
/* Subclasses should override this and return their plugin name */
|
||||
const char *(*get_name) (NMDnsPlugin *self);
|
||||
|
||||
/* Signals */
|
||||
|
||||
|
|
@ -80,7 +83,9 @@ typedef struct {
|
|||
|
||||
GType nm_dns_plugin_get_type (void);
|
||||
|
||||
gboolean nm_dns_plugin_is_exclusive (NMDnsPlugin *self);
|
||||
gboolean nm_dns_plugin_is_caching (NMDnsPlugin *self);
|
||||
|
||||
const char *nm_dns_plugin_get_name (NMDnsPlugin *self);
|
||||
|
||||
gboolean nm_dns_plugin_update (NMDnsPlugin *self,
|
||||
const GSList *vpn_configs,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue