From a647cdcb1440392b16b1e65d6868cb349e68da73 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Mon, 3 Jul 2017 09:14:50 +0200 Subject: dns: turn main.dns= into a list This effectively allows us to keep systemd-resolved up to date even if the resolver is not using it as a local DNS forwarder. The default dns mode is now "default,systemd-resolved", meaning that systemd-resolved is kept up to date, but we're not changing resolv.conf to use it. --- man/NetworkManager.conf.xml | 28 ++-- src/dns/nm-dns-dnsmasq.c | 4 +- src/dns/nm-dns-manager.c | 339 ++++++++++++++++---------------------- src/dns/nm-dns-plugin.c | 12 +- src/dns/nm-dns-plugin.h | 16 +- src/dns/nm-dns-systemd-resolved.c | 4 +- src/dns/nm-dns-unbound.c | 4 +- src/nm-config-data.c | 33 ++-- src/nm-config-data.h | 2 +- src/nm-config.c | 1 + src/nm-config.h | 1 + 11 files changed, 195 insertions(+), 249 deletions(-) diff --git a/man/NetworkManager.conf.xml b/man/NetworkManager.conf.xml index d8fa1b3b95..1da3395758 100644 --- a/man/NetworkManager.conf.xml +++ b/man/NetworkManager.conf.xml @@ -309,24 +309,15 @@ no-auto-default=* dns - Set the DNS (resolv.conf) processing mode. - If the key is unspecified, default is used, - unless /etc/resolv.conf is a symlink to - /run/systemd/resolve/resolv.conf, - /lib/systemd/resolv.conf or - /usr/lib/systemd/resolv.conf. - In that case, systemd-resolved is chosen automatically. - - default: NetworkManager will update - /etc/resolv.conf to reflect the nameservers - provided by currently active connections. + Set the list of DNS (resolv.conf) handlers. + The available options are: + default: NetworkManager will update the resolver + to use the nameservers provided by currently active connections. dnsmasq: NetworkManager will run dnsmasq as a local caching nameserver, using a "split DNS" - configuration if you are connected to a VPN, and then update - resolv.conf to point to the local - nameserver. It is possible to pass custom options to the - dnsmasq instance by adding them to files in the - "&sysconfdir;/NetworkManager/dnsmasq.d/" + configuration if you are connected to a VPN. It is possible to pass custom + options to the dnsmasq instance by adding them to files in the + &sysconfdir;/NetworkManager/dnsmasq.d/ directory. Note that when multiple upstream servers are available, dnsmasq will initially contact them in parallel and then use the fastest to respond, probing again other servers @@ -342,6 +333,11 @@ no-auto-default=* none: NetworkManager will not modify resolv.conf. This implies rc-manager unmanaged + If the first or only entry in the list is a local caching DNS forwarder, + the resolver will be configured to use it. If the key is unspecified, + default,systemd-resolved is used, which means that the resolver + will be configured to use the discovered DNS servers directly, while + systemd-resolved will be updated as well if it is available. diff --git a/src/dns/nm-dns-dnsmasq.c b/src/dns/nm-dns-dnsmasq.c index 91a42a6e61..937950246b 100644 --- a/src/dns/nm-dns-dnsmasq.c +++ b/src/dns/nm-dns-dnsmasq.c @@ -552,7 +552,7 @@ start_dnsmasq (NMDnsDnsmasq *self) self); } -static gboolean +static void update (NMDnsPlugin *plugin, const GPtrArray *configs, const NMGlobalDnsConfig *global_config, @@ -585,8 +585,6 @@ update (NMDnsPlugin *plugin, priv->set_server_ex_args = g_variant_ref_sink (g_variant_new ("(aas)", &servers)); send_dnsmasq_update (self); - - return TRUE; } /*****************************************************************************/ diff --git a/src/dns/nm-dns-manager.c b/src/dns/nm-dns-manager.c index e048f9bc78..a4fdf5eb09 100644 --- a/src/dns/nm-dns-manager.c +++ b/src/dns/nm-dns-manager.c @@ -120,6 +120,7 @@ typedef struct { bool need_sort:1; bool dns_touched:1; bool is_stopped:1; + bool use_local_plugin:1; char *hostname; guint updates_queue; @@ -129,7 +130,7 @@ typedef struct { NMDnsManagerResolvConfManager rc_manager; char *mode; - NMDnsPlugin *plugin; + GSList *plugins; NMConfig *config; } NMDnsManagerPrivate; @@ -1074,7 +1075,7 @@ _collect_resolv_conf_data (NMDnsManager *self, /* only for logging context, no o static gboolean update_dns (NMDnsManager *self, - gboolean no_caching, + NMDnsPlugin *plugin, GError **error) { NMDnsManagerPrivate *priv; @@ -1088,6 +1089,7 @@ update_dns (NMDnsManager *self, SpawnResult result = SR_ERROR; NMConfigData *data; NMGlobalDnsConfig *global_config; + GSList *iter; g_return_val_if_fail (!error || !*error, FALSE); @@ -1121,35 +1123,39 @@ update_dns (NMDnsManager *self, _collect_resolv_conf_data (self, global_config, priv->configs, priv->hostname, &searches, &options, &nameservers, &nis_servers, &nis_domain); - /* Let any plugins do their thing first */ - if (priv->plugin) { - NMDnsPlugin *plugin = priv->plugin; - const char *plugin_name = nm_dns_plugin_get_name (plugin); - - if (no_caching) { - _LOGD ("update-dns: plugin %s ignored (caching disabled)", - plugin_name); - goto skip; + if (plugin) { + if (nm_dns_plugin_get_state (plugin) == NM_DNS_PLUGIN_STATE_STOPPED) { + /* We're reviving a stopped plugin. The failed plugins have to wait until + * the next update. */ + _LOGD ("update-dns: restarting plugin %s", nm_dns_plugin_get_name (plugin)); + g_signal_handlers_block_by_func (plugin, plugin_state_changed, self); + nm_dns_plugin_update (plugin, + priv->configs, + global_config, + priv->hostname); + g_signal_handlers_unblock_by_func (plugin, plugin_state_changed, self); } - caching = TRUE; - - _LOGD ("update-dns: updating plugin %s", plugin_name); - g_signal_handlers_block_by_func (plugin, plugin_state_changed, self); - if (!nm_dns_plugin_update (plugin, - priv->configs, - global_config, - priv->hostname)) { - _LOGW ("update-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; + } + + for (iter = priv->plugins; iter; iter = iter->next) { + NMDnsPlugin *this_plugin = NM_DNS_PLUGIN (iter->data); + + g_signal_handlers_block_by_func (this_plugin, plugin_state_changed, self); + if (!plugin) { + /* No specific plugin was passed. Update all. */ + _LOGD ("update-dns: updating plugin %s", nm_dns_plugin_get_name (this_plugin)); + g_signal_handlers_block_by_func (this_plugin, plugin_state_changed, self); + nm_dns_plugin_update (this_plugin, + priv->configs, + global_config, + priv->hostname); + g_signal_handlers_unblock_by_func (this_plugin, plugin_state_changed, self); } - g_signal_handlers_unblock_by_func (plugin, plugin_state_changed, self); + g_signal_handlers_unblock_by_func (this_plugin, plugin_state_changed, self); - skip: - ; + if ( priv->use_local_plugin + && nm_dns_plugin_get_state (this_plugin) != NM_DNS_PLUGIN_STATE_FAILED) + caching = TRUE; } /* If caching was successful, we only send 127.0.0.1 to /etc/resolv.conf @@ -1217,21 +1223,21 @@ plugin_state_changed (NMDnsPlugin *plugin, GParamSpec *pspec, gpointer user_data switch (nm_dns_plugin_get_state (plugin)) { case NM_DNS_PLUGIN_STATE_STOPPED: _LOGI ("dns: plugin %s stopped, restarting it", plugin_name); - if (!update_dns (self, FALSE, &error)) { - _LOGW ("could not commit DNS changes: %s", error->message); - g_clear_error (&error); - } break; case NM_DNS_PLUGIN_STATE_FAILED: _LOGW ("dns: plugin %s failed", plugin_name); - if (!update_dns (self, TRUE, &error)) { - _LOGW ("could not commit DNS changes: %s", error->message); - g_clear_error (&error); - } break; default: return; } + + /* Retry the DNS update, so that a stopped plugin could be restarted or + * nameserver configuration reverted to a non-caching mode if no plugins + * are non-failed. */ + if (!update_dns (self, plugin, &error)) { + _LOGW ("could not commit DNS changes: %s", error->message); + g_clear_error (&error); + } } static void @@ -1309,7 +1315,7 @@ nm_dns_manager_add_ip_config (NMDnsManager *self, } } - if (!priv->updates_queue && !update_dns (self, FALSE, &error)) { + if (!priv->updates_queue && !update_dns (self, NULL, &error)) { _LOGW ("could not commit DNS changes: %s", error->message); g_clear_error (&error); } @@ -1355,7 +1361,7 @@ nm_dns_manager_remove_ip_config (NMDnsManager *self, gpointer config) forget_data (self, data); g_ptr_array_remove_index (priv->configs, i); - if (!priv->updates_queue && !update_dns (self, FALSE, &error)) { + if (!priv->updates_queue && !update_dns (self, NULL, &error)) { _LOGW ("could not commit DNS changes: %s", error->message); g_clear_error (&error); } @@ -1414,7 +1420,7 @@ nm_dns_manager_set_hostname (NMDnsManager *self, if (skip_update) return; - if (!priv->updates_queue && !update_dns (self, FALSE, &error)) { + if (!priv->updates_queue && !update_dns (self, NULL, &error)) { _LOGW ("could not commit DNS changes: %s", error->message); g_clear_error (&error); } @@ -1431,7 +1437,7 @@ nm_dns_manager_get_resolv_conf_explicit (NMDnsManager *self) if ( NM_IN_SET (priv->rc_manager, NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED, NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE) - || priv->plugin) + || priv->plugins) return FALSE; return TRUE; @@ -1484,7 +1490,7 @@ nm_dns_manager_end_updates (NMDnsManager *self, const char *func) /* Commit all the outstanding changes */ _LOGD ("(%s): committing DNS changes (%d)", func, priv->updates_queue); - if (!update_dns (self, FALSE, &error)) { + if (!update_dns (self, NULL, &error)) { _LOGW ("could not commit DNS changes: %s", error->message); g_clear_error (&error); } @@ -1492,49 +1498,23 @@ nm_dns_manager_end_updates (NMDnsManager *self, const char *func) memset (priv->prev_hash, 0, sizeof (priv->prev_hash)); } -void -nm_dns_manager_stop (NMDnsManager *self) -{ - NMDnsManagerPrivate *priv; - GError *error = NULL; - - priv = NM_DNS_MANAGER_GET_PRIVATE (self); - - if (priv->is_stopped) - g_return_if_reached (); - - _LOGT ("stopping..."); - - /* If we're quitting, leave a valid resolv.conf in place, not one - * pointing to 127.0.0.1 if any plugins were active. Thus update - * DNS after disposing of all plugins. But if we haven't done any - * DNS updates yet, there's no reason to touch resolv.conf on shutdown. - */ - if (priv->dns_touched) { - if (!update_dns (self, TRUE, &error)) { - _LOGW ("could not commit DNS changes on shutdown: %s", error->message); - g_clear_error (&error); - } - priv->dns_touched = FALSE; - } - - priv->is_stopped = TRUE; -} - /*****************************************************************************/ -static gboolean -_clear_plugin (NMDnsManager *self) +static void +_clear_plugins (NMDnsManager *self) { NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self); + GSList *iter; - if (priv->plugin) { - g_signal_handlers_disconnect_by_func (priv->plugin, plugin_state_changed, self); - nm_dns_plugin_stop (priv->plugin); - g_clear_object (&priv->plugin); - return TRUE; + for (iter = priv->plugins; iter; iter = iter->next) { + NMDnsPlugin *plugin = NM_DNS_PLUGIN (iter->data); + + g_signal_handlers_disconnect_by_func (plugin, plugin_state_changed, self); + nm_dns_plugin_stop (plugin); } - return FALSE; + g_slist_free (priv->plugins); + priv->plugins = NULL; + priv->use_local_plugin = FALSE; } static NMDnsManagerResolvConfManager @@ -1586,86 +1566,53 @@ _check_resconf_immutable (NMDnsManagerResolvConfManager rc_manager) } } -static gboolean -_resolvconf_resolved_managed (void) +static void +init_resolv_conf_mode (NMDnsManager *self, gboolean reload_dns_mode) { - static const char *const RESOLVED_PATHS[] = { - "/run/systemd/resolve/resolv.conf", - "/lib/systemd/resolv.conf", - "/usr/lib/systemd/resolv.conf", - }; - struct stat st, st_test; - guint i; + NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self); + NMDnsManagerResolvConfManager rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_UNKNOWN; + gs_strfreev char **mode = NULL; + gboolean rc_manager_changed = FALSE; + int i; - if (lstat (_PATH_RESCONF, &st) != 0) - return FALSE; + if (reload_dns_mode) { + mode = nm_config_data_get_dns_mode (nm_config_get_data (priv->config)); + + _clear_plugins (self); + for (i = 0; mode[i]; i++) { + NMDnsPlugin *plugin = NULL; + + if (nm_streq0 (mode[i], "systemd-resolved")) { + plugin = nm_dns_systemd_resolved_new (); + } else if (nm_streq0 (mode[i], "dnsmasq")) { + plugin = nm_dns_dnsmasq_new (); + } else if (nm_streq0 (mode[i], "unbound")) { + plugin = nm_dns_unbound_new (); + } else if (nm_streq0 (mode[i], "none")) { + rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED; + } else if (!nm_streq0 (mode[i], "default")) { + _LOGW ("init: unknown dns mode '%s'", mode[i]); + } - if (S_ISLNK (st.st_mode)) { - gs_free char *full_path = NULL; - nm_auto_free char *real_path = NULL; - - /* see if resolv.conf is a symlink with a target that is - * exactly like one of the candidates. - * - * This check will work for symlinks, even if the target - * does not exist and realpath() cannot resolve anything. - * - * We want to handle that, because systemd-resolved might not - * have started yet. */ - full_path = g_file_read_link (_PATH_RESCONF, NULL); - if (nm_utils_strv_find_first ((char **) RESOLVED_PATHS, - G_N_ELEMENTS (RESOLVED_PATHS), - full_path) >= 0) - return TRUE; + if (plugin) { + _LOGI ("init: dns=%s%s%s%s", + mode[i], NM_PRINT_FMT_QUOTED (plugin, ", plugin=", + nm_dns_plugin_get_name (plugin), "", "")); - /* see if resolv.conf is a symlink that resolves exactly one - * of the candidate paths. - * - * This check will work for symlinks that can be resolved - * to a realpath, but the actual file might not exist. - * - * We want to handle that, because systemd-resolved might not - * have started yet. */ - real_path = realpath (_PATH_RESCONF, NULL); - if (nm_utils_strv_find_first ((char **) RESOLVED_PATHS, - G_N_ELEMENTS (RESOLVED_PATHS), - real_path) >= 0) - return TRUE; + g_signal_connect (plugin, + "notify::" NM_DNS_PLUGIN_STATE, + G_CALLBACK (plugin_state_changed), + self); + priv->plugins = g_slist_append (priv->plugins, plugin); + } - /* fall-through and resolve the symlink, to check the file - * it points to (below). - * - * This check is the most reliable, but it only works if - * systemd-resolved already started and created the file. */ - if (stat (_PATH_RESCONF, &st) != 0) - return FALSE; - } - - /* see if resolv.conf resolves to one of the candidate - * paths (or whether it is hard-linked). */ - for (i = 0; i < G_N_ELEMENTS (RESOLVED_PATHS); i++) { - if ( stat (RESOLVED_PATHS[i], &st_test) == 0 - && st.st_dev == st_test.st_dev - && st.st_ino == st_test.st_ino) - return TRUE; + /* Prefer the local plugin only if it's first in the list. */ + if (i == 0) + priv->use_local_plugin = (plugin != NULL); + } } - return FALSE; -} - -static void -init_resolv_conf_mode (NMDnsManager *self, gboolean force_reload_plugin) -{ - NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self); - NMDnsManagerResolvConfManager rc_manager; - const char *mode; - gboolean param_changed = FALSE, plugin_changed = FALSE; - - mode = nm_config_data_get_dns_mode (nm_config_get_data (priv->config)); - - if (nm_streq0 (mode, "none")) - rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED; - else { + if (rc_manager == NM_DNS_MANAGER_RESOLV_CONF_MAN_UNKNOWN) { const char *man; rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_UNKNOWN; @@ -1698,61 +1645,23 @@ again: rc_manager = _check_resconf_immutable (rc_manager); - if ( (!mode && _resolvconf_resolved_managed ()) - || nm_streq0 (mode, "systemd-resolved")) { - if ( force_reload_plugin - || !NM_IS_DNS_SYSTEMD_RESOLVED (priv->plugin)) { - _clear_plugin (self); - priv->plugin = nm_dns_systemd_resolved_new (); - plugin_changed = TRUE; - } - mode = "systemd-resolved"; - } else if (nm_streq0 (mode, "dnsmasq")) { - if (force_reload_plugin || !NM_IS_DNS_DNSMASQ (priv->plugin)) { - _clear_plugin (self); - priv->plugin = nm_dns_dnsmasq_new (); - plugin_changed = TRUE; - } - } else if (nm_streq0 (mode, "unbound")) { - if (force_reload_plugin || !NM_IS_DNS_UNBOUND (priv->plugin)) { - _clear_plugin (self); - priv->plugin = nm_dns_unbound_new (); - plugin_changed = TRUE; - } - } else { - if (!NM_IN_STRSET (mode, "none", "default")) { - if (mode) - _LOGW ("init: unknown dns mode '%s'", mode); - mode = "default"; - } - if (_clear_plugin (self)) - plugin_changed = TRUE; - } - - if (plugin_changed && priv->plugin) - g_signal_connect (priv->plugin, "notify::" NM_DNS_PLUGIN_STATE, G_CALLBACK (plugin_state_changed), self); - g_object_freeze_notify (G_OBJECT (self)); - if (!nm_streq0 (priv->mode, mode)) { + if (!nm_streq0 (priv->mode, mode[0])) { g_free (priv->mode); - priv->mode = g_strdup (mode); - param_changed = TRUE; + priv->mode = g_strdup (mode[0]); + rc_manager_changed = TRUE; _notify (self, PROP_MODE); } if (priv->rc_manager != rc_manager) { priv->rc_manager = rc_manager; - param_changed = TRUE; + rc_manager_changed = TRUE; _notify (self, PROP_RC_MANAGER); } - if (param_changed || plugin_changed) { - _LOGI ("init: dns=%s, rc-manager=%s%s%s%s", - mode, _rc_manager_to_string (rc_manager), - NM_PRINT_FMT_QUOTED (priv->plugin, ", plugin=", - nm_dns_plugin_get_name (priv->plugin), "", "")); - } + if (rc_manager_changed) + _LOGI ("init: rc-manager=%s", _rc_manager_to_string (rc_manager)); g_object_thaw_notify (G_OBJECT (self)); } @@ -1775,7 +1684,8 @@ config_changed_cb (NMConfig *config, * is immutable, thus, without the configuration changing, we always want to * re-configure the mode. */ init_resolv_conf_mode (self, - NM_FLAGS_ANY (changes, NM_CONFIG_CHANGE_CAUSE_SIGHUP + NM_FLAGS_ANY (changes, NM_CONFIG_CHANGE_DNS_MODE + | NM_CONFIG_CHANGE_CAUSE_SIGHUP | NM_CONFIG_CHANGE_CAUSE_DNS_FULL)); } @@ -1786,7 +1696,7 @@ config_changed_cb (NMConfig *config, NM_CONFIG_CHANGE_DNS_MODE | NM_CONFIG_CHANGE_RC_MANAGER | NM_CONFIG_CHANGE_GLOBAL_DNS_CONFIG)) { - if (!update_dns (self, FALSE, &error)) { + if (!update_dns (self, NULL, &error)) { _LOGW ("could not commit DNS changes: %s", error->message); g_clear_error (&error); } @@ -2028,6 +1938,39 @@ nm_dns_manager_init (NMDnsManager *self) init_resolv_conf_mode (self, TRUE); } +void +nm_dns_manager_stop (NMDnsManager *self) +{ + NMDnsManagerPrivate *priv; + GError *error = NULL; + + priv = NM_DNS_MANAGER_GET_PRIVATE (self); + + if (priv->is_stopped) + g_return_if_reached (); + + _LOGT ("stopping..."); + + /* Clear plugins first so that subsequent update_dns reverts to a + * non-caching configuration. */ + _clear_plugins (self); + + /* If we're quitting, leave a valid resolv.conf in place, not one + * pointing to 127.0.0.1 if any plugins were active. Thus update + * DNS after disposing of all plugins. But if we haven't done any + * DNS updates yet, there's no reason to touch resolv.conf on shutdown. + */ + if (priv->dns_touched) { + if (!update_dns (self, NULL, &error)) { + _LOGW ("could not commit DNS changes on shutdown: %s", error->message); + g_clear_error (&error); + } + priv->dns_touched = FALSE; + } + + priv->is_stopped = TRUE; +} + static void dispose (GObject *object) { @@ -2041,8 +1984,6 @@ dispose (GObject *object) if (!priv->is_stopped) nm_dns_manager_stop (self); - _clear_plugin (self); - if (priv->config) { g_signal_handlers_disconnect_by_func (priv->config, config_changed_cb, self); g_clear_object (&priv->config); diff --git a/src/dns/nm-dns-plugin.c b/src/dns/nm-dns-plugin.c index a998da5807..81b3e00d23 100644 --- a/src/dns/nm-dns-plugin.c +++ b/src/dns/nm-dns-plugin.c @@ -82,7 +82,7 @@ G_DEFINE_TYPE_EXTENDED (NMDnsPlugin, nm_dns_plugin, G_TYPE_OBJECT, G_TYPE_FLAG_A /*****************************************************************************/ -gboolean +void nm_dns_plugin_update (NMDnsPlugin *self, const GPtrArray *configs, const NMGlobalDnsConfig *global_config, @@ -90,14 +90,14 @@ nm_dns_plugin_update (NMDnsPlugin *self, { NMDnsPluginPrivate *priv = NM_DNS_PLUGIN_GET_PRIVATE (self); - g_return_val_if_fail (NM_DNS_PLUGIN_GET_CLASS (self)->update != NULL, FALSE); + g_return_if_fail (NM_DNS_PLUGIN_GET_CLASS (self)->update != NULL); nm_clear_g_source (&priv->plugin_ratelimit.timer); - return NM_DNS_PLUGIN_GET_CLASS (self)->update (self, - configs, - global_config, - hostname); + NM_DNS_PLUGIN_GET_CLASS (self)->update (self, + configs, + global_config, + hostname); } const char * diff --git a/src/dns/nm-dns-plugin.h b/src/dns/nm-dns-plugin.h index e4a6cd40fa..be624730d2 100644 --- a/src/dns/nm-dns-plugin.h +++ b/src/dns/nm-dns-plugin.h @@ -48,10 +48,10 @@ typedef struct { * 'global_config' is the optional global DNS * configuration. */ - gboolean (*update) (NMDnsPlugin *self, - const GPtrArray *configs, - const NMGlobalDnsConfig *global_config, - const char *hostname); + void (*update) (NMDnsPlugin *self, + const GPtrArray *configs, + const NMGlobalDnsConfig *global_config, + const char *hostname); /* Subclasses should override this and return their plugin name */ const char *(*get_name) (NMDnsPlugin *self); @@ -76,10 +76,10 @@ const char *nm_dns_plugin_get_name (NMDnsPlugin *self); NMDnsPluginState nm_dns_plugin_get_state (NMDnsPlugin *self); void nm_dns_plugin_set_state (NMDnsPlugin *self, NMDnsPluginState state); -gboolean nm_dns_plugin_update (NMDnsPlugin *self, - const GPtrArray *configs, - const NMGlobalDnsConfig *global_config, - const char *hostname); +void nm_dns_plugin_update (NMDnsPlugin *self, + const GPtrArray *configs, + const NMGlobalDnsConfig *global_config, + const char *hostname); void nm_dns_plugin_stop (NMDnsPlugin *self); diff --git a/src/dns/nm-dns-systemd-resolved.c b/src/dns/nm-dns-systemd-resolved.c index a48f78d259..e92d00a77c 100644 --- a/src/dns/nm-dns-systemd-resolved.c +++ b/src/dns/nm-dns-systemd-resolved.c @@ -288,7 +288,7 @@ send_updates (NMDnsSystemdResolved *self) } } -static gboolean +static void update (NMDnsPlugin *plugin, const GPtrArray *configs, const NMGlobalDnsConfig *global_config, @@ -322,8 +322,6 @@ update (NMDnsPlugin *plugin, g_array_free (interfaces, TRUE); send_updates (self); - - return TRUE; } /*****************************************************************************/ diff --git a/src/dns/nm-dns-unbound.c b/src/dns/nm-dns-unbound.c index e86e51e08a..f7390083e8 100644 --- a/src/dns/nm-dns-unbound.c +++ b/src/dns/nm-dns-unbound.c @@ -37,7 +37,7 @@ G_DEFINE_TYPE (NMDnsUnbound, nm_dns_unbound, NM_TYPE_DNS_PLUGIN) /*****************************************************************************/ -static gboolean +static void update (NMDnsPlugin *plugin, const GPtrArray *configs, const NMGlobalDnsConfig *global_config, @@ -63,8 +63,6 @@ update (NMDnsPlugin *plugin, nm_dns_plugin_set_state (plugin, success ? NM_DNS_PLUGIN_STATE_RUNNING : NM_DNS_PLUGIN_STATE_FAILED); - - return success; } static const char * diff --git a/src/nm-config-data.c b/src/nm-config-data.c index 21ad1a7346..119f5534a5 100644 --- a/src/nm-config-data.c +++ b/src/nm-config-data.c @@ -217,8 +217,10 @@ nm_config_data_get_value_boolean (const NMConfigData *self, const char *group, c return value; } -char ** -nm_config_data_get_plugins (const NMConfigData *self, gboolean allow_default) +static char ** +get_string_list (const NMConfigData *self, + const char *group, const char *key, const char *dfl, + gboolean allow_default) { const NMConfigDataPrivate *priv; char **list; @@ -227,17 +229,24 @@ nm_config_data_get_plugins (const NMConfigData *self, gboolean allow_default) priv = NM_CONFIG_DATA_GET_PRIVATE (self); - list = g_key_file_get_string_list (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "plugins", NULL, NULL); + list = g_key_file_get_string_list (priv->keyfile, group, key, NULL, NULL); if (!list && allow_default) { gs_unref_keyfile GKeyFile *kf = nm_config_create_keyfile (); /* let keyfile split the default string according to it's own escaping rules. */ - g_key_file_set_value (kf, NM_CONFIG_KEYFILE_GROUP_MAIN, "plugins", NM_CONFIG_DEFAULT_MAIN_PLUGINS); - list = g_key_file_get_string_list (kf, NM_CONFIG_KEYFILE_GROUP_MAIN, "plugins", NULL, NULL); + g_key_file_set_value (kf, group, key, dfl); + list = g_key_file_get_string_list (kf, group, key, NULL, NULL); } return _nm_utils_strv_cleanup (list, TRUE, TRUE, TRUE); } +char ** +nm_config_data_get_plugins (const NMConfigData *self, gboolean allow_default) +{ + return get_string_list (self, NM_CONFIG_KEYFILE_GROUP_MAIN, "plugins", + NM_CONFIG_DEFAULT_MAIN_PLUGINS, allow_default); +} + const char * nm_config_data_get_connectivity_uri (const NMConfigData *self) { @@ -283,12 +292,11 @@ nm_config_data_get_no_auto_default_for_device (const NMConfigData *self, NMDevic || nm_device_spec_match_list (device, priv->no_auto_default.specs_config); } -const char * +char ** nm_config_data_get_dns_mode (const NMConfigData *self) { - g_return_val_if_fail (self, NULL); - - return NM_CONFIG_DATA_GET_PRIVATE (self)->dns_mode; + return get_string_list (self, NM_CONFIG_KEYFILE_GROUP_MAIN, "dns", + NM_CONFIG_DEFAULT_MAIN_DNS, TRUE); } const char * @@ -574,6 +582,7 @@ static const struct { const char *value; } default_values[] = { { NM_CONFIG_KEYFILE_GROUP_MAIN, "plugins", NM_CONFIG_DEFAULT_MAIN_PLUGINS }, + { NM_CONFIG_KEYFILE_GROUP_MAIN, "dns", NM_CONFIG_DEFAULT_MAIN_DNS }, { NM_CONFIG_KEYFILE_GROUP_MAIN, "rc-manager", NM_CONFIG_DEFAULT_MAIN_RC_MANAGER }, { NM_CONFIG_KEYFILE_GROUP_MAIN, NM_CONFIG_KEYFILE_KEY_MAIN_AUTH_POLKIT, NM_CONFIG_DEFAULT_MAIN_AUTH_POLKIT }, { NM_CONFIG_KEYFILE_GROUP_MAIN, NM_CONFIG_KEYFILE_KEY_MAIN_DHCP, NM_CONFIG_DEFAULT_MAIN_DHCP }, @@ -1363,6 +1372,8 @@ nm_config_data_diff (NMConfigData *old_data, NMConfigData *new_data) { NMConfigChangeFlags changes = NM_CONFIG_CHANGE_NONE; NMConfigDataPrivate *priv_old, *priv_new; + gs_strfreev char **dns_mode_old = NULL; + gs_strfreev char **dns_mode_new = NULL; g_return_val_if_fail (NM_IS_CONFIG_DATA (old_data), NM_CONFIG_CHANGE_NONE); g_return_val_if_fail (NM_IS_CONFIG_DATA (new_data), NM_CONFIG_CHANGE_NONE); @@ -1389,7 +1400,9 @@ nm_config_data_diff (NMConfigData *old_data, NMConfigData *new_data) || !_slist_str_equals (priv_old->no_auto_default.specs_config, priv_new->no_auto_default.specs_config)) changes |= NM_CONFIG_CHANGE_NO_AUTO_DEFAULT; - if (g_strcmp0 (nm_config_data_get_dns_mode (old_data), nm_config_data_get_dns_mode (new_data))) + dns_mode_old = nm_config_data_get_dns_mode (old_data); + dns_mode_new = nm_config_data_get_dns_mode (new_data); + if (!_nm_utils_strv_equal (dns_mode_old, dns_mode_new)) changes |= NM_CONFIG_CHANGE_DNS_MODE; if (g_strcmp0 (nm_config_data_get_rc_manager (old_data), nm_config_data_get_rc_manager (new_data))) diff --git a/src/nm-config-data.h b/src/nm-config-data.h index 98c667516c..2b001e21bc 100644 --- a/src/nm-config-data.h +++ b/src/nm-config-data.h @@ -166,7 +166,7 @@ const char *nm_config_data_get_connectivity_response (const NMConfigData *config const char *const*nm_config_data_get_no_auto_default (const NMConfigData *config_data); gboolean nm_config_data_get_no_auto_default_for_device (const NMConfigData *self, NMDevice *device); -const char *nm_config_data_get_dns_mode (const NMConfigData *self); +char **nm_config_data_get_dns_mode (const NMConfigData *self); const char *nm_config_data_get_rc_manager (const NMConfigData *self); gboolean nm_config_data_get_ignore_carrier (const NMConfigData *self, NMDevice *device); diff --git a/src/nm-config.c b/src/nm-config.c index 608ef23e1f..f272f281bc 100644 --- a/src/nm-config.c +++ b/src/nm-config.c @@ -636,6 +636,7 @@ _setting_is_string_list (const char *group, const char *key) { return _IS (NM_CONFIG_KEYFILE_GROUP_MAIN, "plugins") || _IS (NM_CONFIG_KEYFILE_GROUP_MAIN, NM_CONFIG_KEYFILE_KEY_MAIN_DEBUG) + || _IS (NM_CONFIG_KEYFILE_GROUP_MAIN, "dns") || _IS (NM_CONFIG_KEYFILE_GROUP_LOGGING, "domains") || g_str_has_prefix (group, NM_CONFIG_KEYFILE_GROUPPREFIX_TEST_APPEND_STRINGLIST); #undef _IS diff --git a/src/nm-config.h b/src/nm-config.h index c5ff7c67d6..b65668e87d 100644 --- a/src/nm-config.h +++ b/src/nm-config.h @@ -38,6 +38,7 @@ /* Signals */ #define NM_CONFIG_SIGNAL_CONFIG_CHANGED "config-changed" +#define NM_CONFIG_DEFAULT_MAIN_DNS "default,systemd-resolved" #define NM_CONFIG_DEFAULT_CONNECTIVITY_INTERVAL 300 #define NM_CONFIG_DEFAULT_CONNECTIVITY_RESPONSE "NetworkManager is online" /* NOT LOCALIZED */ -- cgit v1.2.1