diff options
-rw-r--r-- | src/dns/nm-dns-dnsmasq.c | 131 | ||||
-rw-r--r-- | src/dns/nm-dns-manager.c | 586 | ||||
-rw-r--r-- | src/dns/nm-dns-manager.h | 42 | ||||
-rw-r--r-- | src/dns/nm-dns-plugin.c | 16 | ||||
-rw-r--r-- | src/dns/nm-dns-plugin.h | 13 | ||||
-rw-r--r-- | src/dns/nm-dns-systemd-resolved.c | 59 | ||||
-rw-r--r-- | src/dns/nm-dns-unbound.c | 2 | ||||
-rw-r--r-- | src/nm-ip4-config.h | 6 | ||||
-rw-r--r-- | src/nm-policy.c | 117 |
9 files changed, 391 insertions, 581 deletions
diff --git a/src/dns/nm-dns-dnsmasq.c b/src/dns/nm-dns-dnsmasq.c index 2e1c9fbe78..c18aaba0da 100644 --- a/src/dns/nm-dns-dnsmasq.c +++ b/src/dns/nm-dns-dnsmasq.c @@ -149,16 +149,15 @@ ip_addr_to_string (int addr_family, gconstpointer addr, const char *iface, char { int n_written; char buf2[NM_UTILS_INET_ADDRSTRLEN]; - char separator; + const char *separator; nm_assert_addr_family (addr_family); nm_assert (addr); - nm_assert (iface); nm_assert (out_buf); if (addr_family == AF_INET) { nm_utils_inet_ntop (addr_family, addr, buf2); - separator = '@'; + separator = "@"; } else { if (IN6_IS_ADDR_V4MAPPED (addr)) nm_utils_inet4_ntop (((const struct in6_addr *) addr)->s6_addr32[3], buf2); @@ -169,15 +168,15 @@ ip_addr_to_string (int addr_family, gconstpointer addr, const char *iface, char * supported. Due to a bug, since 2.73 only '%' works properly as "server" * address. */ - separator = IN6_IS_ADDR_LINKLOCAL (addr) ? '%' : '@'; + separator = IN6_IS_ADDR_LINKLOCAL (addr) ? "%" : "@"; } n_written = g_snprintf (out_buf, IP_ADDR_TO_STRING_BUFLEN, - "%s%c%s", + "%s%s%s", buf2, - separator, - iface); + iface ? separator : "", + iface ?: ""); nm_assert (n_written < IP_ADDR_TO_STRING_BUFLEN); return out_buf; } @@ -206,11 +205,11 @@ add_global_config (NMDnsDnsmasq *self, GVariantBuilder *dnsmasq_servers, const N } } -static gboolean +static void add_ip_config (NMDnsDnsmasq *self, GVariantBuilder *servers, + int ifindex, NMIPConfig *ip_config, - const char *iface, gboolean split) { int addr_family; @@ -219,77 +218,79 @@ add_ip_config (NMDnsDnsmasq *self, guint nnameservers, i_nameserver, n, i; char ip_addr_to_string_buf[IP_ADDR_TO_STRING_BUFLEN]; char **domains, **iter; - - g_return_val_if_fail (iface, FALSE); + gboolean iface_resolved = FALSE; + const char *iface = NULL; addr_family = nm_ip_config_get_addr_family (ip_config); - g_return_val_if_fail (NM_IN_SET (addr_family, AF_INET, AF_INET6), FALSE); + g_return_if_fail (NM_IN_SET (addr_family, AF_INET, AF_INET6)); + + nm_assert (ifindex > 0); + nm_assert (ifindex == nm_ip_config_get_ifindex (ip_config)); nnameservers = nm_ip_config_get_num_nameservers (ip_config); if (split) { if (nnameservers == 0) - return FALSE; + return; - for (i_nameserver = 0; i_nameserver < nnameservers; i_nameserver++) { - addr = nm_ip_config_get_nameserver (ip_config, i_nameserver); + if (!iface_resolved) { + iface = nm_platform_link_get_name (NM_PLATFORM_GET, ifindex); + iface_resolved = TRUE; + } - ip_addr_to_string (addr_family, addr, iface, ip_addr_to_string_buf); + if (iface) { + for (i_nameserver = 0; i_nameserver < nnameservers; i_nameserver++) { + addr = nm_ip_config_get_nameserver (ip_config, i_nameserver); - /* searches are preferred over domains */ - n = nm_ip_config_get_num_searches (ip_config); - for (i = 0; i < n; i++) { - add_dnsmasq_nameserver (self, - servers, - ip_addr_to_string_buf, - nm_ip_config_get_search (ip_config, i)); - added = TRUE; - } + ip_addr_to_string (addr_family, addr, iface, ip_addr_to_string_buf); - if (n == 0) { - /* If not searches, use any domains */ - n = nm_ip_config_get_num_domains (ip_config); + /* searches are preferred over domains */ + n = nm_ip_config_get_num_searches (ip_config); for (i = 0; i < n; i++) { add_dnsmasq_nameserver (self, servers, ip_addr_to_string_buf, - nm_ip_config_get_domain (ip_config, i)); + nm_ip_config_get_search (ip_config, i)); added = TRUE; } - } - /* Ensure reverse-DNS works by directing queries for in-addr4.arpa/ip6.arpa - * domains to the split domain's nameserver. - */ - domains = get_ip_rdns_domains (ip_config); - if (domains) { - for (iter = domains; *iter; iter++) - add_dnsmasq_nameserver (self, servers, ip_addr_to_string_buf, *iter); - g_strfreev (domains); + if (n == 0) { + /* If not searches, use any domains */ + n = nm_ip_config_get_num_domains (ip_config); + for (i = 0; i < n; i++) { + add_dnsmasq_nameserver (self, + servers, + ip_addr_to_string_buf, + nm_ip_config_get_domain (ip_config, i)); + added = TRUE; + } + } + + /* Ensure reverse-DNS works by directing queries for in-addr4.arpa/ip6.arpa + * domains to the split domain's nameserver. + */ + domains = get_ip_rdns_domains (ip_config); + if (domains) { + for (iter = domains; *iter; iter++) + add_dnsmasq_nameserver (self, servers, ip_addr_to_string_buf, *iter); + g_strfreev (domains); + } } } } /* If no searches or domains, just add the nameservers */ if (!added) { - for (i = 0; i < nnameservers; i++) { - addr = nm_ip_config_get_nameserver (ip_config, i); - ip_addr_to_string (addr_family, addr, iface, ip_addr_to_string_buf); - add_dnsmasq_nameserver (self, servers, ip_addr_to_string_buf, NULL); + if (!iface_resolved) + iface = nm_platform_link_get_name (NM_PLATFORM_GET, ifindex); + if (iface) { + for (i = 0; i < nnameservers; i++) { + addr = nm_ip_config_get_nameserver (ip_config, i); + ip_addr_to_string (addr_family, addr, iface, ip_addr_to_string_buf); + add_dnsmasq_nameserver (self, servers, ip_addr_to_string_buf, NULL); + } } } - - return TRUE; -} - -static gboolean -add_ip_config_data (NMDnsDnsmasq *self, GVariantBuilder *servers, const NMDnsIPConfigData *data) -{ - return add_ip_config (self, - servers, - data->config, - data->iface, - data->type == NM_DNS_IP_CONFIG_TYPE_VPN); } static void @@ -477,15 +478,16 @@ start_dnsmasq (NMDnsDnsmasq *self) static gboolean update (NMDnsPlugin *plugin, - const GPtrArray *configs, const NMGlobalDnsConfig *global_config, + const CList *ip_config_lst_head, const char *hostname) { NMDnsDnsmasq *self = NM_DNS_DNSMASQ (plugin); NMDnsDnsmasqPrivate *priv = NM_DNS_DNSMASQ_GET_PRIVATE (self); GVariantBuilder servers; - guint i; int prio, first_prio; + const NMDnsIPConfigData *ip_data; + gboolean is_first = TRUE; start_dnsmasq (self); @@ -494,15 +496,18 @@ update (NMDnsPlugin *plugin, if (global_config) add_global_config (self, &servers, global_config); else { - for (i = 0; i < configs->len; i++) { - const NMDnsIPConfigData *data = configs->pdata[i]; - - prio = nm_ip_config_get_dns_priority (data->config); - if (i == 0) + c_list_for_each_entry (ip_data, ip_config_lst_head, ip_config_lst) { + prio = nm_ip_config_get_dns_priority (ip_data->ip_config); + if (is_first) { + is_first = FALSE; first_prio = prio; - else if (first_prio < 0 && first_prio != prio) + } else if (first_prio < 0 && first_prio != prio) break; - add_ip_config_data (self, &servers, data); + add_ip_config (self, + &servers, + ip_data->data->ifindex, + ip_data->ip_config, + ip_data->ip_config_type == NM_DNS_IP_CONFIG_TYPE_VPN); } } diff --git a/src/dns/nm-dns-manager.c b/src/dns/nm-dns-manager.c index 87ae09ab3f..0e9d0903fd 100644 --- a/src/dns/nm-dns-manager.c +++ b/src/dns/nm-dns-manager.c @@ -103,12 +103,15 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMDnsManager, static guint signals[LAST_SIGNAL] = { 0 }; typedef struct { - GPtrArray *ip_configs; - GPtrArray *connection_configs; + GHashTable *configs; + CList ip_config_lst_head; GVariant *config_variant; - NMDnsIPConfigData *best_conf4, *best_conf6; - bool need_sort:1; + NMDnsIPConfigData *best_ip_config_4; + NMDnsIPConfigData *best_ip_config_6; + + bool ip_config_lst_need_sort:1; + bool dns_touched:1; bool is_stopped:1; @@ -170,6 +173,12 @@ NM_DEFINE_SINGLETON_GETTER (NMDnsManager, nm_dns_manager_get, NM_TYPE_DNS_MANAGE /*****************************************************************************/ +static void _ip_config_dns_priority_changed (gpointer config, + GParamSpec *pspec, + NMDnsIPConfigData *ip_data); + +/*****************************************************************************/ + static gboolean domain_is_valid (const gchar *domain, gboolean check_public_suffix) { @@ -197,69 +206,109 @@ NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_rc_manager_to_string, NMDnsManagerResolvConf NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_config_type_to_string, NMDnsIPConfigType, NM_UTILS_LOOKUP_DEFAULT_WARN ("<unknown>"), + NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_IP_CONFIG_TYPE_REMOVED, "removed"), NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_IP_CONFIG_TYPE_DEFAULT, "default"), NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE, "best"), NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_IP_CONFIG_TYPE_VPN, "vpn"), ); -static NMDnsIPConfigData * -ip_config_data_new (gpointer config, NMDnsIPConfigType type, const char *iface) +/*****************************************************************************/ + +static void +_ASSERT_config_data (const NMDnsConfigData *data) +{ + nm_assert (data); + nm_assert (NM_IS_DNS_MANAGER (data->self)); + nm_assert (data->ifindex > 0); +} + +static void +_ASSERT_ip_config_data (const NMDnsIPConfigData *ip_data) { - NMDnsIPConfigData *data; + nm_assert (ip_data); + _ASSERT_config_data (ip_data->data); + nm_assert (NM_IS_IP_CONFIG (ip_data->ip_config)); + nm_assert (c_list_contains (&ip_data->data->data_lst_head, &ip_data->data_lst)); + nm_assert (ip_data->data->ifindex == nm_ip_config_get_ifindex (ip_data->ip_config)); +} - data = g_slice_new0 (NMDnsIPConfigData); - data->config = g_object_ref (config); - data->iface = g_strdup (iface); - data->type = type; +static NMDnsIPConfigData * +_ip_config_data_new (NMDnsConfigData *data, + NMIPConfig *ip_config, + NMDnsIPConfigType ip_config_type) +{ + NMDnsIPConfigData *ip_data; - return data; + _ASSERT_config_data (data); + nm_assert (NM_IS_IP_CONFIG (ip_config)); + nm_assert (ip_config_type != NM_DNS_IP_CONFIG_TYPE_REMOVED); + + ip_data = g_slice_new0 (NMDnsIPConfigData); + ip_data->data = data; + ip_data->ip_config = g_object_ref (ip_config); + ip_data->ip_config_type = ip_config_type; + c_list_link_tail (&data->data_lst_head, &ip_data->data_lst); + c_list_link_tail (&NM_DNS_MANAGER_GET_PRIVATE (data->self)->ip_config_lst_head, &ip_data->ip_config_lst); + + g_signal_connect (ip_config, + NM_IS_IP4_CONFIG (ip_config) + ? "notify::" NM_IP4_CONFIG_DNS_PRIORITY + : "notify::" NM_IP6_CONFIG_DNS_PRIORITY, + (GCallback) _ip_config_dns_priority_changed, ip_data); + + _ASSERT_ip_config_data (ip_data); + return ip_data; } -static NMDnsConnectionConfigData * -connection_config_data_new (NMSettingConnectionMdns mdns, const char *iface, int ifindex) +static void +_ip_config_data_free (NMDnsIPConfigData *ip_data) { - NMDnsConnectionConfigData *data; + _ASSERT_ip_config_data (ip_data); - data = g_slice_new0 (NMDnsConnectionConfigData); - data->mdns = mdns; - data->iface = g_strdup (iface); - data->ifindex = ifindex; + c_list_unlink_stale (&ip_data->data_lst); + c_list_unlink_stale (&ip_data->ip_config_lst); - return data; + g_signal_handlers_disconnect_by_func (ip_data->ip_config, + _ip_config_dns_priority_changed, + ip_data); + + g_object_unref (ip_data->ip_config); + g_slice_free (NMDnsIPConfigData, ip_data); } -static void -ip_config_data_destroy (gpointer ptr) +static NMDnsIPConfigData * +_config_data_find_ip_config (NMDnsConfigData *data, + NMIPConfig *ip_config) { - NMDnsIPConfigData *data = ptr; + NMDnsIPConfigData *ip_data; - if (!data) - return; + _ASSERT_config_data (data); + + c_list_for_each_entry (ip_data, &data->data_lst_head, data_lst) { + _ASSERT_ip_config_data (ip_data); - g_object_unref (data->config); - g_free (data->iface); - g_slice_free (NMDnsIPConfigData, data); + if (ip_data->ip_config == ip_config) + return ip_data; + } + return NULL; } static void -connection_config_data_destroy (gpointer ptr) +_config_data_free (NMDnsConfigData *data) { - NMDnsConnectionConfigData *data = ptr; + _ASSERT_config_data (data); - if (!data) - return; - - g_free (data->iface); - g_slice_free (NMDnsConnectionConfigData, data); + nm_assert (c_list_is_empty (&data->data_lst_head)); + g_slice_free (NMDnsConfigData, data); } static gint -ip_config_data_compare (const NMDnsIPConfigData *a, const NMDnsIPConfigData *b) +_ip_config_data_cmp (const NMDnsIPConfigData *a, const NMDnsIPConfigData *b) { int a_prio, b_prio; - a_prio = nm_ip_config_get_dns_priority (a->config); - b_prio = nm_ip_config_get_dns_priority (b->config); + a_prio = nm_ip_config_get_dns_priority (a->ip_config); + b_prio = nm_ip_config_get_dns_priority (b->ip_config); /* Configurations with lower priority value first */ if (a_prio < b_prio) @@ -268,22 +317,38 @@ ip_config_data_compare (const NMDnsIPConfigData *a, const NMDnsIPConfigData *b) return 1; /* Sort also according to type */ - if (a->type > b->type) + if (a->ip_config_type > b->ip_config_type) return -1; - else if (a->type < b->type) + else if (a->ip_config_type < b->ip_config_type) return 1; return 0; } static gint -ip_config_data_ptr_compare (gconstpointer a, gconstpointer b) +_ip_config_lst_cmp (const CList *a, + const CList *b, + const void *user_data) { - const NMDnsIPConfigData *const *ptr_a = a, *const *ptr_b = b; + return _ip_config_data_cmp (c_list_entry (a, NMDnsIPConfigData, ip_config_lst), + c_list_entry (b, NMDnsIPConfigData, ip_config_lst)); +} - return ip_config_data_compare (*ptr_a, *ptr_b); +static CList * +_ip_config_lst_head (NMDnsManager *self) +{ + NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self); + + if (priv->ip_config_lst_need_sort) { + priv->ip_config_lst_need_sort = FALSE; + c_list_sort (&priv->ip_config_lst_head, _ip_config_lst_cmp, NULL); + } + + return &priv->ip_config_lst_head; } +/*****************************************************************************/ + static void add_string_item (GPtrArray *array, const char *str) { @@ -313,8 +378,8 @@ add_dns_option_item (GPtrArray *array, const char *str) static void merge_one_ip_config (NMResolvConfData *rc, - const NMIPConfig *ip_config, - const char *iface) + int ifindex, + const NMIPConfig *ip_config) { int addr_family; guint num, num_domains, num_searches, i; @@ -324,6 +389,8 @@ merge_one_ip_config (NMResolvConfData *rc, addr_family = nm_ip_config_get_addr_family (ip_config); nm_assert_addr_family (addr_family); + nm_assert (ifindex > 0); + nm_assert (ifindex == nm_ip_config_get_ifindex (ip_config)); num = nm_ip_config_get_num_nameservers (ip_config); for (i = 0; i < num; i++) { @@ -337,8 +404,13 @@ merge_one_ip_config (NMResolvConfData *rc, else { nm_utils_inet6_ntop (&addr->addr6, buf); if (IN6_IS_ADDR_LINKLOCAL (addr)) { - g_strlcat (buf, "%", sizeof (buf)); - g_strlcat (buf, iface, sizeof (buf)); + const char *ifname; + + ifname = nm_platform_link_get_name (NM_PLATFORM_GET, ifindex); + if (ifname) { + g_strlcat (buf, "%", sizeof (buf)); + g_strlcat (buf, ifname, sizeof (buf)); + } } } @@ -848,25 +920,21 @@ update_resolv_conf (NMDnsManager *self, static void compute_hash (NMDnsManager *self, const NMGlobalDnsConfig *global, guint8 buffer[HASH_LEN]) { - NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self); GChecksum *sum; gsize len = HASH_LEN; - guint i; + NMDnsIPConfigData *ip_data; sum = g_checksum_new (G_CHECKSUM_SHA1); - g_assert (len == g_checksum_type_get_length (G_CHECKSUM_SHA1)); + nm_assert (len == g_checksum_type_get_length (G_CHECKSUM_SHA1)); if (global) nm_global_dns_config_update_checksum (global, sum); else { - for (i = 0; i < priv->ip_configs->len; i++) { - NMDnsIPConfigData *data = priv->ip_configs->pdata[i]; + const CList *head; - if (NM_IS_IP4_CONFIG (data->config)) - nm_ip4_config_hash ((NMIP4Config *) data->config, sum, TRUE); - else if (NM_IS_IP6_CONFIG (data->config)) - nm_ip6_config_hash ((NMIP6Config *) data->config, sum, TRUE); - } + head = _ip_config_lst_head (self); + c_list_for_each_entry (ip_data, head, ip_config_lst) + nm_ip_config_hash (ip_data->ip_config, sum, TRUE); } g_checksum_get_digest (sum, buffer, &len); @@ -940,16 +1008,15 @@ _ptrarray_to_strv (GPtrArray *parray) } static void -_collect_resolv_conf_data (NMDnsManager *self, /* only for logging context, no other side-effects */ +_collect_resolv_conf_data (NMDnsManager *self, NMGlobalDnsConfig *global_config, - const GPtrArray *ip_configs, - const char *hostname, char ***out_searches, char ***out_options, char ***out_nameservers, char ***out_nis_servers, const char **out_nis_domain) { + NMDnsManagerPrivate *priv; guint i, num, len; NMResolvConfData rc = { .nameservers = g_ptr_array_new (), @@ -959,37 +1026,44 @@ _collect_resolv_conf_data (NMDnsManager *self, /* only for logging context, no o .nis_servers = g_ptr_array_new (), }; + priv = NM_DNS_MANAGER_GET_PRIVATE (self); + if (global_config) merge_global_dns_config (&rc, global_config); else { nm_auto_free_gstring GString *tmp_gstring = NULL; int prio, first_prio = 0; - NMDnsIPConfigData *current; + const NMDnsIPConfigData *ip_data; + const CList *head; + gboolean is_first = TRUE; - for (i = 0; i < ip_configs->len; i++) { + head = _ip_config_lst_head (self); + c_list_for_each_entry (ip_data, head, ip_config_lst) { gboolean skip = FALSE; - current = ip_configs->pdata[i]; + _ASSERT_ip_config_data (ip_data); - prio = nm_ip_config_get_dns_priority (current->config); + prio = nm_ip_config_get_dns_priority (ip_data->ip_config); - if (i == 0) + if (is_first) { + is_first = FALSE; first_prio = prio; - else if (first_prio < 0 && first_prio != prio) + } else if ( first_prio < 0 + && first_prio != prio) skip = TRUE; - if (nm_ip_config_get_num_nameservers (current->config)) { - _LOGT ("config: %8d %-7s v%c %-16s %s: %s", + if (nm_ip_config_get_num_nameservers (ip_data->ip_config)) { + _LOGT ("config: %8d %-7s v%c %-5d %s: %s", prio, - _config_type_to_string (current->type), - nm_utils_addr_family_to_char (nm_ip_config_get_addr_family (current->config)), - current->iface, + _config_type_to_string (ip_data->ip_config_type), + nm_utils_addr_family_to_char (nm_ip_config_get_addr_family (ip_data->ip_config)), + ip_data->data->ifindex, skip ? "<SKIP>" : "", - get_nameserver_list (current->config, &tmp_gstring)); + get_nameserver_list (ip_data->ip_config, &tmp_gstring)); } if (!skip) - merge_one_ip_config (&rc, current->config, current->iface); + merge_one_ip_config (&rc, ip_data->data->ifindex, ip_data->ip_config); } } @@ -1000,16 +1074,16 @@ _collect_resolv_conf_data (NMDnsManager *self, /* only for logging context, no o * (eg, "example.com"), then use the hostname itself as the search (since the user is * unlikely to want "com" as a search domain). */ - if (hostname) { - const char *hostdomain = strchr (hostname, '.'); + if (priv->hostname) { + const char *hostdomain = strchr (priv->hostname, '.'); if ( hostdomain - && !nm_utils_ipaddr_valid (AF_UNSPEC, hostname)) { + && !nm_utils_ipaddr_valid (AF_UNSPEC, priv->hostname)) { hostdomain++; if (domain_is_valid (hostdomain, TRUE)) add_string_item (rc.searches, hostdomain); - else if (domain_is_valid (hostname, TRUE)) - add_string_item (rc.searches, hostname); + else if (domain_is_valid (priv->hostname, TRUE)) + add_string_item (rc.searches, priv->hostname); } } @@ -1071,16 +1145,12 @@ update_dns (NMDnsManager *self, data = nm_config_get_data (priv->config); global_config = nm_config_data_get_global_dns_config (data); - if (priv->need_sort) { - g_ptr_array_sort (priv->ip_configs, ip_config_data_ptr_compare); - priv->need_sort = FALSE; - } - /* Update hash with config we're applying */ compute_hash (self, global_config, priv->hash); - _collect_resolv_conf_data (self, global_config, priv->ip_configs, priv->hostname, - &searches, &options, &nameservers, &nis_servers, &nis_domain); + _collect_resolv_conf_data (self, global_config, + &searches, &options, &nameservers, + &nis_servers, &nis_domain); /* Let any plugins do their thing first */ if (priv->plugin) { @@ -1098,8 +1168,8 @@ update_dns (NMDnsManager *self, _LOGD ("update-dns: updating plugin %s", plugin_name); if (!nm_dns_plugin_update (plugin, - priv->ip_configs, global_config, + _ip_config_lst_head (self), priv->hostname)) { _LOGW ("update-dns: plugin %s update failed", plugin_name); @@ -1240,116 +1310,96 @@ plugin_child_quit (NMDnsPlugin *plugin, int exit_status, gpointer user_data) } static void -ip_config_dns_priority_changed (gpointer config, - GParamSpec *pspec, - NMDnsManager *self) +_ip_config_dns_priority_changed (gpointer config, + GParamSpec *pspec, + NMDnsIPConfigData *ip_data) { - NM_DNS_MANAGER_GET_PRIVATE (self)->need_sort = TRUE; -} - -static void -forget_ip_data (NMDnsManager *self, NMDnsIPConfigData *data) -{ - NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self); - - if (data == priv->best_conf4) - priv->best_conf4 = NULL; - else if (data == priv->best_conf6) - priv->best_conf6 = NULL; - - g_signal_handlers_disconnect_by_func (data->config, ip_config_dns_priority_changed, self); -} - -void nm_dns_manager_update_ifindex (NMDnsManager *self, - const char *iface, - int new_ifindex) -{ - NMDnsConnectionConfigData *data; - NMDnsManagerPrivate *priv; - NMDnsPlugin *plugin; - guint i; - - g_return_if_fail (NM_IS_DNS_MANAGER (self)); - g_return_if_fail (iface && iface[0]); - g_return_if_fail (new_ifindex > 0); + _ASSERT_ip_config_data (ip_data); - priv = NM_DNS_MANAGER_GET_PRIVATE (self); - plugin = priv->plugin; - - for (i = 0; i < priv->connection_configs->len; i++) { - data = priv->connection_configs->pdata[i]; - if (nm_streq (data->iface, iface)) { - if (data->ifindex == new_ifindex) - return; - - nm_dns_plugin_update_mdns (plugin, - data->ifindex, - NM_SETTING_CONNECTION_MDNS_UNKNOWN); - data->ifindex = new_ifindex; - nm_dns_plugin_update_mdns (plugin, - data->ifindex, - data->mdns); - return; - } - } + NM_DNS_MANAGER_GET_PRIVATE (ip_data->data->self)->ip_config_lst_need_sort = TRUE; } gboolean -nm_dns_manager_add_ip_config (NMDnsManager *self, - const char *iface, - gpointer config, - NMDnsIPConfigType cfg_type) +nm_dns_manager_set_ip_config (NMDnsManager *self, + NMIPConfig *ip_config, + NMDnsIPConfigType ip_config_type) { NMDnsManagerPrivate *priv; GError *error = NULL; - NMDnsIPConfigData *data; - gboolean v4 = NM_IS_IP4_CONFIG (config); - guint i; + NMDnsIPConfigData *ip_data; + NMDnsConfigData *data; + int ifindex; + NMDnsIPConfigData **p_best; g_return_val_if_fail (NM_IS_DNS_MANAGER (self), FALSE); - g_return_val_if_fail (config, FALSE); - g_return_val_if_fail (iface && iface[0], FALSE); - nm_assert (NM_IS_IP_CONFIG (config)); + g_return_val_if_fail (NM_IS_IP_CONFIG (ip_config), FALSE); + + ifindex = nm_ip_config_get_ifindex (ip_config); + g_return_val_if_fail (ifindex > 0, FALSE); priv = NM_DNS_MANAGER_GET_PRIVATE (self); - for (i = 0; i < priv->ip_configs->len; i++) { - data = priv->ip_configs->pdata[i]; - if (data->config == config) { - if ( nm_streq (data->iface, iface) - && data->type == cfg_type) - return FALSE; - else { - forget_ip_data (self, data); - g_ptr_array_remove_index_fast (priv->ip_configs, i); - break; - } - } + data = g_hash_table_lookup (priv->configs, GINT_TO_POINTER (ifindex)); + if (!data) + ip_data = NULL; + else + ip_data = _config_data_find_ip_config (data, ip_config); + + if (ip_config_type == NM_DNS_IP_CONFIG_TYPE_REMOVED) { + if (!ip_data) + return FALSE; + if (priv->best_ip_config_4 == ip_data) + priv->best_ip_config_4 = NULL; + if (priv->best_ip_config_6 == ip_data) + priv->best_ip_config_6 = NULL; + /* deleting a config doesn't invalidate the configs' sort order. */ + _ip_config_data_free (ip_data); + if (c_list_is_empty (&data->data_lst_head)) + g_hash_table_remove (priv->configs, GINT_TO_POINTER (ifindex)); + goto changed; + } + + if ( ip_data + && ip_data->ip_config_type == ip_config_type) { + /* nothing to do. */ + return FALSE; } - data = ip_config_data_new (config, cfg_type, iface); - g_ptr_array_add (priv->ip_configs, data); - g_signal_connect (config, - v4 ? - "notify::" NM_IP4_CONFIG_DNS_PRIORITY : - "notify::" NM_IP6_CONFIG_DNS_PRIORITY, - (GCallback) ip_config_dns_priority_changed, self); - priv->need_sort = TRUE; + if (!data) { + data = g_slice_new0 (NMDnsConfigData); + data->ifindex = ifindex; + data->self = self; + c_list_init (&data->data_lst_head); + _ASSERT_config_data (data); + g_hash_table_insert (priv->configs, GINT_TO_POINTER (ifindex), data); + } + + if (!ip_data) + ip_data = _ip_config_data_new (data, ip_config, ip_config_type); + else + ip_data->ip_config_type = ip_config_type; + + priv->ip_config_lst_need_sort = TRUE; + + p_best = NM_IS_IP4_CONFIG (ip_config) + ? &priv->best_ip_config_4 + : &priv->best_ip_config_6; - if (cfg_type == NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE) { + if (ip_config_type == NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE) { /* Only one best-device per IP version is allowed */ - if (v4) { - if (priv->best_conf4) - priv->best_conf4->type = NM_DNS_IP_CONFIG_TYPE_DEFAULT; - priv->best_conf4 = data; - } else { - if (priv->best_conf6) - priv->best_conf6->type = NM_DNS_IP_CONFIG_TYPE_DEFAULT; - priv->best_conf6 = data; + if (*p_best != ip_data) { + if (*p_best) + (*p_best)->ip_config_type = NM_DNS_IP_CONFIG_TYPE_DEFAULT; + *p_best = ip_data; } + } else { + if (*p_best == ip_data) + *p_best = NULL; } - if (!priv->updates_queue && !update_dns (self, FALSE, &error)) { +changed: + if ( !priv->updates_queue + && !update_dns (self, FALSE, &error)) { _LOGW ("could not commit DNS changes: %s", error->message); g_clear_error (&error); } @@ -1357,38 +1407,6 @@ nm_dns_manager_add_ip_config (NMDnsManager *self, return TRUE; } -gboolean -nm_dns_manager_remove_ip_config (NMDnsManager *self, gpointer config) -{ - NMDnsManagerPrivate *priv; - GError *error = NULL; - NMDnsIPConfigData *data; - guint i; - - g_return_val_if_fail (NM_IS_DNS_MANAGER (self), FALSE); - g_return_val_if_fail (config, FALSE); - nm_assert (NM_IS_IP_CONFIG (config)); - - priv = NM_DNS_MANAGER_GET_PRIVATE (self); - - for (i = 0; i < priv->ip_configs->len; i++) { - data = priv->ip_configs->pdata[i]; - - if (data->config == config) { - forget_ip_data (self, data); - g_ptr_array_remove_index (priv->ip_configs, i); - - if (!priv->updates_queue && !update_dns (self, FALSE, &error)) { - _LOGW ("could not commit DNS changes: %s", error->message); - g_clear_error (&error); - } - - return TRUE; - } - } - return FALSE; -} - void nm_dns_manager_set_initial_hostname (NMDnsManager *self, const char *hostname) @@ -1432,78 +1450,6 @@ nm_dns_manager_set_hostname (NMDnsManager *self, } gboolean -nm_dns_manager_add_connection_config (NMDnsManager *self, - const char *iface, - int ifindex, - NMSettingConnectionMdns mdns) -{ - NMDnsConnectionConfigData *data; - NMDnsManagerPrivate *priv; - NMDnsPlugin *plugin; - guint i; - - g_return_val_if_fail (NM_IS_DNS_MANAGER (self), FALSE); - g_return_val_if_fail (ifindex > 0, FALSE); - g_return_val_if_fail (iface != NULL && iface[0], FALSE); - g_return_val_if_fail (NM_IN_SET (mdns, - NM_SETTING_CONNECTION_MDNS_NO, - NM_SETTING_CONNECTION_MDNS_YES, - NM_SETTING_CONNECTION_MDNS_RESOLVE), FALSE); - - priv = NM_DNS_MANAGER_GET_PRIVATE (self); - plugin = priv->plugin; - - for (i = 0; i < priv->connection_configs->len; i++) { - data = priv->connection_configs->pdata[i]; - if (nm_streq (data->iface, iface)) { - if (data->mdns == mdns) - /* already there */ - return FALSE; - else { - data->mdns = mdns; - return nm_dns_plugin_update_mdns (plugin, - ifindex, - mdns); - } - } - } - - data = connection_config_data_new (mdns, iface, ifindex); - g_ptr_array_add (priv->connection_configs, data); - - return nm_dns_plugin_update_mdns (plugin, ifindex, mdns); -} - -void -nm_dns_manager_remove_connection_config (NMDnsManager *self, - const char *iface, - int ifindex) -{ - NMDnsConnectionConfigData *data; - NMDnsManagerPrivate *priv; - NMDnsPlugin *plugin; - guint i; - - g_return_if_fail (NM_IS_DNS_MANAGER (self)); - g_return_if_fail (iface != NULL && iface[0]); - g_return_if_fail (ifindex > 0); - - priv = NM_DNS_MANAGER_GET_PRIVATE (self); - plugin = priv->plugin; - - for (i = 0; i < priv->connection_configs->len; i++) { - data = priv->connection_configs->pdata[i]; - if (nm_streq (data->iface, iface)) { - nm_dns_plugin_update_mdns (plugin, - ifindex, - NM_SETTING_CONNECTION_MDNS_UNKNOWN); - g_ptr_array_remove_index_fast (priv->connection_configs, i); - return; - } - } -} - -gboolean nm_dns_manager_get_resolv_conf_explicit (NMDnsManager *self) { NMDnsManagerPrivate *priv; @@ -1550,11 +1496,6 @@ nm_dns_manager_end_updates (NMDnsManager *self, const char *func) priv = NM_DNS_MANAGER_GET_PRIVATE (self); g_return_if_fail (priv->updates_queue > 0); - if (priv->need_sort) { - g_ptr_array_sort (priv->ip_configs, ip_config_data_ptr_compare); - priv->need_sort = FALSE; - } - compute_hash (self, nm_config_data_get_global_dns_config (nm_config_get_data (priv->config)), new); changed = (memcmp (new, priv->prev_hash, sizeof (new)) != 0) ? TRUE : FALSE; _LOGD ("(%s): DNS configuration %s", func, changed ? "changed" : "did not change"); @@ -1949,14 +1890,13 @@ _get_config_variant (NMDnsManager *self) NMGlobalDnsConfig *global_config; gs_free char *str = NULL; GVariantBuilder builder; - NMConfigData *data; - guint i, j; + NMDnsIPConfigData *ip_data; + const CList *head; if (priv->config_variant) return priv->config_variant; - data = nm_config_get_data (priv->config); - global_config = nm_config_data_get_global_dns_config (data); + global_config = nm_config_data_get_global_dns_config (nm_config_get_data (priv->config)); if (global_config) { priv->config_variant = _get_global_config_variant (global_config); _LOGT ("current configuration: %s", (str = g_variant_print (priv->config_variant, TRUE))); @@ -1965,25 +1905,26 @@ _get_config_variant (NMDnsManager *self) g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}")); - for (i = 0; i < priv->ip_configs->len; i++) { - NMDnsIPConfigData *current = priv->ip_configs->pdata[i]; - const NMIPConfig *config = current->config; + head = _ip_config_lst_head (self); + c_list_for_each_entry (ip_data, head, ip_config_lst) { + const NMIPConfig *ip_config = ip_data->ip_config; GVariantBuilder entry_builder; GVariantBuilder strv_builder; - guint num; - const int addr_family = nm_ip_config_get_addr_family (config); + guint i, num; + const int addr_family = nm_ip_config_get_addr_family (ip_config); char buf[NM_UTILS_INET_ADDRSTRLEN]; const NMIPAddr *addr; + const char *ifname; - num = nm_ip_config_get_num_nameservers (config); + num = nm_ip_config_get_num_nameservers (ip_config); if (!num) continue; g_variant_builder_init (&entry_builder, G_VARIANT_TYPE ("a{sv}")); g_variant_builder_init (&strv_builder, G_VARIANT_TYPE ("as")); - for (j = 0; j < num; j++) { - addr = nm_ip_config_get_nameserver (config, j); + for (i = 0; i < num; i++) { + addr = nm_ip_config_get_nameserver (ip_config, i); g_variant_builder_add (&strv_builder, "s", nm_utils_inet_ntop (addr_family, addr, buf)); @@ -1993,13 +1934,13 @@ _get_config_variant (NMDnsManager *self) "nameservers", g_variant_builder_end (&strv_builder)); - num = nm_ip_config_get_num_domains (config); + num = nm_ip_config_get_num_domains (ip_config); if (num > 0) { g_variant_builder_init (&strv_builder, G_VARIANT_TYPE ("as")); - for (j = 0; j < num; j++) { + for (i = 0; i < num; i++) { g_variant_builder_add (&strv_builder, "s", - nm_ip_config_get_domain (config, j)); + nm_ip_config_get_domain (ip_config, i)); } g_variant_builder_add (&entry_builder, "{sv}", @@ -2007,22 +1948,23 @@ _get_config_variant (NMDnsManager *self) g_variant_builder_end (&strv_builder)); } - if (current->iface) { + ifname = nm_platform_link_get_name (NM_PLATFORM_GET, ip_data->data->ifindex); + if (ifname) { g_variant_builder_add (&entry_builder, "{sv}", "interface", - g_variant_new_string (current->iface)); + g_variant_new_string (ifname)); } g_variant_builder_add (&entry_builder, "{sv}", "priority", - g_variant_new_int32 (nm_ip_config_get_dns_priority (config))); + g_variant_new_int32 (nm_ip_config_get_dns_priority (ip_config))); g_variant_builder_add (&entry_builder, "{sv}", "vpn", - g_variant_new_boolean (current->type == NM_DNS_IP_CONFIG_TYPE_VPN)); + g_variant_new_boolean (ip_data->ip_config_type == NM_DNS_IP_CONFIG_TYPE_VPN)); g_variant_builder_add (&builder, "a{sv}", &entry_builder); } @@ -2063,9 +2005,12 @@ nm_dns_manager_init (NMDnsManager *self) _LOGT ("creating..."); + c_list_init (&priv->ip_config_lst_head); + priv->config = g_object_ref (nm_config_get ()); - priv->ip_configs = g_ptr_array_new_full (8, ip_config_data_destroy); - priv->connection_configs = g_ptr_array_new_full (8, connection_config_data_destroy); + + priv->configs = g_hash_table_new_full (nm_direct_hash, NULL, + NULL, (GDestroyNotify) _config_data_free); /* Set the initial hash */ compute_hash (self, NULL, NM_DNS_MANAGER_GET_PRIVATE (self)->hash); @@ -2082,37 +2027,30 @@ dispose (GObject *object) { NMDnsManager *self = NM_DNS_MANAGER (object); NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self); - NMDnsIPConfigData *ip_data; - guint i; + NMDnsIPConfigData *ip_data, *ip_data_safe; _LOGT ("disposing"); if (!priv->is_stopped) nm_dns_manager_stop (self); + if (priv->config) + g_signal_handlers_disconnect_by_func (priv->config, config_changed_cb, self); + _clear_plugin (self); - if (priv->config) { - g_signal_handlers_disconnect_by_func (priv->config, config_changed_cb, self); - g_clear_object (&priv->config); - } + priv->best_ip_config_4 = NULL; + priv->best_ip_config_6 = NULL; - if (priv->ip_configs) { - for (i = 0; i < priv->ip_configs->len; i++) { - ip_data = priv->ip_configs->pdata[i]; - forget_ip_data (self, ip_data); - } - g_ptr_array_free (priv->ip_configs, TRUE); - priv->ip_configs = NULL; - } + c_list_for_each_entry_safe (ip_data, ip_data_safe, &priv->ip_config_lst_head, ip_config_lst) + _ip_config_data_free (ip_data); - if (priv->connection_configs) { - g_ptr_array_free (priv->connection_configs, TRUE); - priv->connection_configs = NULL; - } + g_clear_pointer (&priv->configs, g_hash_table_destroy); nm_clear_g_source (&priv->plugin_ratelimit.timer); + g_clear_object (&priv->config); + G_OBJECT_CLASS (nm_dns_manager_parent_class)->dispose (object); } diff --git a/src/dns/nm-dns-manager.h b/src/dns/nm-dns-manager.h index d2afe8143b..663a3ad258 100644 --- a/src/dns/nm-dns-manager.h +++ b/src/dns/nm-dns-manager.h @@ -29,9 +29,11 @@ #include "nm-setting-connection.h" typedef enum { + NM_DNS_IP_CONFIG_TYPE_REMOVED = -1, + NM_DNS_IP_CONFIG_TYPE_DEFAULT = 0, NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE, - NM_DNS_IP_CONFIG_TYPE_VPN + NM_DNS_IP_CONFIG_TYPE_VPN, } NMDnsIPConfigType; enum { @@ -39,17 +41,22 @@ enum { NM_DNS_PRIORITY_DEFAULT_VPN = 50, }; +struct _NMDnsConfigData; +struct _NMDnsManager; + typedef struct { - gpointer config; - NMDnsIPConfigType type; - char *iface; + struct _NMDnsConfigData *data; + NMIPConfig *ip_config; + CList data_lst; + CList ip_config_lst; + NMDnsIPConfigType ip_config_type; } NMDnsIPConfigData; -typedef struct { - NMSettingConnectionMdns mdns; - char *iface; +typedef struct _NMDnsConfigData { + struct _NMDnsManager *self; + CList data_lst_head; int ifindex; -} NMDnsConnectionConfigData; +} NMDnsConfigData; #define NM_TYPE_DNS_MANAGER (nm_dns_manager_get_type ()) #define NM_DNS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NM_TYPE_DNS_MANAGER, NMDnsManager)) @@ -77,28 +84,15 @@ NMDnsManager * nm_dns_manager_get (void); void nm_dns_manager_begin_updates (NMDnsManager *self, const char *func); void nm_dns_manager_end_updates (NMDnsManager *self, const char *func); -gboolean nm_dns_manager_add_ip_config (NMDnsManager *self, - const char *iface, - gpointer config, - NMDnsIPConfigType cfg_type); - -gboolean nm_dns_manager_remove_ip_config (NMDnsManager *self, gpointer config); +gboolean nm_dns_manager_set_ip_config (NMDnsManager *self, + NMIPConfig *ip_config, + NMDnsIPConfigType ip_config_type); void nm_dns_manager_set_initial_hostname (NMDnsManager *self, const char *hostname); void nm_dns_manager_set_hostname (NMDnsManager *self, const char *hostname, gboolean skip_update); -gboolean nm_dns_manager_add_connection_config (NMDnsManager *self, - const char *iface, - int ifindex, - NMSettingConnectionMdns mdns); -void nm_dns_manager_remove_connection_config (NMDnsManager *self, - const char *iface, - int ifindex); -void nm_dns_manager_update_ifindex (NMDnsManager *self, - const char *ip_iface, - int new_ifindex); /** * NMDnsManagerResolvConfManager diff --git a/src/dns/nm-dns-plugin.c b/src/dns/nm-dns-plugin.c index 7ac57ce8b1..d9400e3e97 100644 --- a/src/dns/nm-dns-plugin.c +++ b/src/dns/nm-dns-plugin.c @@ -77,30 +77,18 @@ G_DEFINE_TYPE_EXTENDED (NMDnsPlugin, nm_dns_plugin, G_TYPE_OBJECT, G_TYPE_FLAG_A gboolean nm_dns_plugin_update (NMDnsPlugin *self, - const GPtrArray *configs, const NMGlobalDnsConfig *global_config, + const CList *ip_config_lst_head, const char *hostname) { g_return_val_if_fail (NM_DNS_PLUGIN_GET_CLASS (self)->update != NULL, FALSE); return NM_DNS_PLUGIN_GET_CLASS (self)->update (self, - configs, global_config, + ip_config_lst_head, hostname); } -gboolean -nm_dns_plugin_update_mdns (NMDnsPlugin *self, - int ifindex, - NMSettingConnectionMdns mdns) -{ - g_return_val_if_fail (NM_DNS_PLUGIN_GET_CLASS (self)->update_mdns != NULL, FALSE); - - return NM_DNS_PLUGIN_GET_CLASS (self)->update_mdns (self, - ifindex, - mdns); -} - static gboolean is_caching (NMDnsPlugin *self) { diff --git a/src/dns/nm-dns-plugin.h b/src/dns/nm-dns-plugin.h index f6008270c8..80b77d95c6 100644 --- a/src/dns/nm-dns-plugin.h +++ b/src/dns/nm-dns-plugin.h @@ -50,8 +50,8 @@ typedef struct { * configuration. */ gboolean (*update) (NMDnsPlugin *self, - const GPtrArray *configs, const NMGlobalDnsConfig *global_config, + const CList *ip_config_lst_head, const char *hostname); /* Subclasses should override and return TRUE if they start a local @@ -60,11 +60,6 @@ typedef struct { */ gboolean (*is_caching) (NMDnsPlugin *self); - /* Subclasses wishing to control interface mDNS status should override. */ - gboolean (*update_mdns) (NMDnsPlugin *self, - int ifindex, - NMSettingConnectionMdns mdns); - /* Subclasses should override this and return their plugin name */ const char *(*get_name) (NMDnsPlugin *self); @@ -85,14 +80,10 @@ 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 GPtrArray *configs, const NMGlobalDnsConfig *global_config, + const CList *ip_config_lst_head, const char *hostname); -gboolean nm_dns_plugin_update_mdns (NMDnsPlugin *self, - int ifindex, - NMSettingConnectionMdns mdns); - void nm_dns_plugin_stop (NMDnsPlugin *self); /* For subclasses/plugins */ diff --git a/src/dns/nm-dns-systemd-resolved.c b/src/dns/nm-dns-systemd-resolved.c index 73a0977cc9..da049726dc 100644 --- a/src/dns/nm-dns-systemd-resolved.c +++ b/src/dns/nm-dns-systemd-resolved.c @@ -282,8 +282,8 @@ send_updates (NMDnsSystemdResolved *self) static gboolean update (NMDnsPlugin *plugin, - const GPtrArray *configs, const NMGlobalDnsConfig *global_config, + const CList *ip_config_lst_head, const char *hostname) { NMDnsSystemdResolved *self = NM_DNS_SYSTEMD_RESOLVED (plugin); @@ -292,23 +292,26 @@ update (NMDnsPlugin *plugin, guint interfaces_len; guint i; int prio, first_prio = 0; + NMDnsIPConfigData *ip_data; + gboolean is_first = TRUE; interfaces = g_hash_table_new_full (nm_direct_hash, NULL, NULL, (GDestroyNotify) _interface_config_free); - for (i = 0; i < configs->len; i++) { - const NMDnsIPConfigData *data = configs->pdata[i]; + c_list_for_each_entry (ip_data, ip_config_lst_head, ip_config_lst) { gboolean skip = FALSE; InterfaceConfig *ic = NULL; int ifindex; - prio = nm_ip_config_get_dns_priority (data->config); - if (i == 0) + prio = nm_ip_config_get_dns_priority (ip_data->ip_config); + if (is_first) { + is_first = FALSE; first_prio = prio; - else if (first_prio < 0 && first_prio != prio) + } else if (first_prio < 0 && first_prio != prio) skip = TRUE; - ifindex = nm_ip_config_get_ifindex (data->config); + ifindex = ip_data->data->ifindex; + nm_assert (ifindex == nm_ip_config_get_ifindex (ip_data->ip_config)); ic = g_hash_table_lookup (interfaces, GINT_TO_POINTER (ifindex)); if (!ic) { @@ -320,7 +323,7 @@ update (NMDnsPlugin *plugin, if (!skip) { c_list_link_tail (&ic->configs_lst_head, - &nm_c_list_elem_new_stale (data->config)->lst); + &nm_c_list_elem_new_stale (ip_data->ip_config)->lst); } } @@ -345,45 +348,6 @@ update (NMDnsPlugin *plugin, return TRUE; } -static gboolean -update_mdns (NMDnsPlugin *plugin, int ifindex, NMSettingConnectionMdns mdns) -{ - NMDnsSystemdResolved *self = NM_DNS_SYSTEMD_RESOLVED (plugin); - NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self); - char *value; - - _LOGI ("update_mdns: %i/%d", ifindex, mdns); - - nm_clear_g_cancellable (&priv->mdns_cancellable); - - if (!priv->resolve) - return FALSE; - - priv->mdns_cancellable = g_cancellable_new (); - - switch (mdns) { - case NM_SETTING_CONNECTION_MDNS_YES: - value = "yes"; - break; - case NM_SETTING_CONNECTION_MDNS_NO: - value = "no"; - break; - case NM_SETTING_CONNECTION_MDNS_RESOLVE: - value = "resolve"; - break; - default: - /* reset to system default */ - value = ""; - } - - g_dbus_proxy_call (priv->resolve, "SetLinkMulticastDNS", - g_variant_new ("(is)", ifindex, value), - G_DBUS_CALL_FLAGS_NONE, - -1, priv->mdns_cancellable, call_done, self); - - return TRUE; -} - /*****************************************************************************/ static gboolean @@ -486,6 +450,5 @@ nm_dns_systemd_resolved_class_init (NMDnsSystemdResolvedClass *dns_class) plugin_class->is_caching = is_caching; plugin_class->update = update; - plugin_class->update_mdns = update_mdns; plugin_class->get_name = get_name; } diff --git a/src/dns/nm-dns-unbound.c b/src/dns/nm-dns-unbound.c index 0b80055f1b..e06128aa91 100644 --- a/src/dns/nm-dns-unbound.c +++ b/src/dns/nm-dns-unbound.c @@ -39,8 +39,8 @@ G_DEFINE_TYPE (NMDnsUnbound, nm_dns_unbound, NM_TYPE_DNS_PLUGIN) static gboolean update (NMDnsPlugin *plugin, - const GPtrArray *configs, const NMGlobalDnsConfig *global_config, + const CList *ip_config_lst_head, const char *hostname) { char *argv[] = { DNSSEC_TRIGGER_SCRIPT, "--async", "--update", NULL }; diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h index 4f541ce000..ba2d6ad981 100644 --- a/src/nm-ip4-config.h +++ b/src/nm-ip4-config.h @@ -380,6 +380,12 @@ nm_ip_config_get_ifindex (const NMIPConfig *self) } static inline void +nm_ip_config_hash (const NMIPConfig *self, GChecksum *sum, gboolean dns_only) +{ + _NM_IP_CONFIG_DISPATCH_VOID (self, nm_ip4_config_hash, nm_ip6_config_hash, sum, dns_only); +} + +static inline void nm_ip_config_add_address (NMIPConfig *self, const NMPlatformIPAddress *address) { _NM_IP_CONFIG_DISPATCH_VOID (self, nm_ip4_config_add_address, nm_ip6_config_add_address, (gconstpointer) address); diff --git a/src/nm-policy.c b/src/nm-policy.c index dfc50a8463..90f13c7580 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -1060,57 +1060,24 @@ update_ip6_routing (NMPolicy *self, gboolean force_update) } static void -add_connection_dns (NMPolicy *self, NMConnection *connection, const char *iface, int ifindex) -{ - NMSettingConnection *s_con = NULL; - - if (connection == NULL) - return; - - s_con = nm_connection_get_setting_connection (connection); - - if (s_con) { - NMSettingConnectionMdns mdns = nm_setting_connection_get_mdns (s_con); - - if (mdns != NM_SETTING_CONNECTION_MDNS_DEFAULT) { - nm_dns_manager_add_connection_config (NM_POLICY_GET_PRIVATE (self)->dns_manager, - iface, - ifindex, - mdns); - } - } -} - -static void -remove_connection_dns (NMPolicy *self, const char *iface, int ifindex) -{ - nm_dns_manager_remove_connection_config (NM_POLICY_GET_PRIVATE (self)->dns_manager, - iface, - ifindex); -} - -static void update_ip_dns (NMPolicy *self, int addr_family) { gpointer ip_config; const char *ip_iface = NULL; NMVpnConnection *vpn = NULL; - NMDnsIPConfigType dns_type = NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE; nm_assert_addr_family (addr_family); ip_config = get_best_ip_config (self, addr_family, &ip_iface, NULL, NULL, &vpn); if (ip_config) { - if (vpn) - dns_type = NM_DNS_IP_CONFIG_TYPE_VPN; - /* Tell the DNS manager this config is preferred by re-adding it with * a different IP config type. */ - nm_dns_manager_add_ip_config (NM_POLICY_GET_PRIVATE (self)->dns_manager, - ip_iface, + nm_dns_manager_set_ip_config (NM_POLICY_GET_PRIVATE (self)->dns_manager, ip_config, - dns_type); + vpn + ? NM_DNS_IP_CONFIG_TYPE_VPN + : NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE); } if (addr_family == AF_INET6) @@ -1741,7 +1708,6 @@ device_state_changed (NMDevice *device, NMPolicy *self = _PRIV_TO_SELF (priv); NMActiveConnection *ac; NMSettingsConnection *connection = nm_device_get_settings_connection (device); - const char *ip_iface = nm_device_get_ip_iface (device); NMIP4Config *ip4_config; NMIP6Config *ip6_config; NMSettingConnection *s_con = NULL; @@ -1824,9 +1790,6 @@ device_state_changed (NMDevice *device, */ nm_connection_clear_secrets (NM_CONNECTION (connection)); - - /* Add connection settings (currently link mDNS state) */ - add_connection_dns (self, NM_CONNECTION (connection), ip_iface, nm_device_get_ip_ifindex (device)); } /* Add device's new IPv4 and IPv6 configs to DNS */ @@ -1835,10 +1798,10 @@ device_state_changed (NMDevice *device, ip4_config = nm_device_get_ip4_config (device); if (ip4_config) - nm_dns_manager_add_ip_config (priv->dns_manager, ip_iface, ip4_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT); + nm_dns_manager_set_ip_config (priv->dns_manager, NM_IP_CONFIG_CAST (ip4_config), NM_DNS_IP_CONFIG_TYPE_DEFAULT); ip6_config = nm_device_get_ip6_config (device); if (ip6_config) - nm_dns_manager_add_ip_config (priv->dns_manager, ip_iface, ip6_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT); + nm_dns_manager_set_ip_config (priv->dns_manager, NM_IP_CONFIG_CAST (ip6_config), NM_DNS_IP_CONFIG_TYPE_DEFAULT); update_routing_and_dns (self, FALSE); @@ -1881,12 +1844,8 @@ device_state_changed (NMDevice *device, && old_state == NM_DEVICE_STATE_UNAVAILABLE) reset_autoconnect_all (self, device, FALSE); - if (old_state > NM_DEVICE_STATE_DISCONNECTED) { + if (old_state > NM_DEVICE_STATE_DISCONNECTED) update_routing_and_dns (self, FALSE); - /* Remove connection settings (currently link mDNS state) */ - remove_connection_dns (self, ip_iface, nm_device_get_ip_ifindex (device)); - } - /* Device is now available for auto-activation */ schedule_activate_check (self, device); @@ -1942,7 +1901,6 @@ device_ip4_config_changed (NMDevice *device, { NMPolicyPrivate *priv = user_data; NMPolicy *self = _PRIV_TO_SELF (priv); - const char *ip_iface = nm_device_get_ip_iface (device); nm_dns_manager_begin_updates (priv->dns_manager, __func__); @@ -1953,10 +1911,10 @@ device_ip4_config_changed (NMDevice *device, */ if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) { if (old_config != new_config) { - if (old_config) - nm_dns_manager_remove_ip_config (priv->dns_manager, old_config); if (new_config) - nm_dns_manager_add_ip_config (priv->dns_manager, ip_iface, new_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT); + nm_dns_manager_set_ip_config (priv->dns_manager, NM_IP_CONFIG_CAST (new_config), NM_DNS_IP_CONFIG_TYPE_DEFAULT); + if (old_config) + nm_dns_manager_set_ip_config (priv->dns_manager, NM_IP_CONFIG_CAST (old_config), NM_DNS_IP_CONFIG_TYPE_REMOVED); } update_ip_dns (self, AF_INET); update_ip4_routing (self, TRUE); @@ -1964,7 +1922,7 @@ device_ip4_config_changed (NMDevice *device, } else { /* Old configs get removed immediately */ if (old_config) - nm_dns_manager_remove_ip_config (priv->dns_manager, old_config); + nm_dns_manager_set_ip_config (priv->dns_manager, NM_IP_CONFIG_CAST (old_config), NM_DNS_IP_CONFIG_TYPE_REMOVED); } nm_dns_manager_end_updates (priv->dns_manager, __func__); @@ -1978,7 +1936,6 @@ device_ip6_config_changed (NMDevice *device, { NMPolicyPrivate *priv = user_data; NMPolicy *self = _PRIV_TO_SELF (priv); - const char *ip_iface = nm_device_get_ip_iface (device); nm_dns_manager_begin_updates (priv->dns_manager, __func__); @@ -1989,10 +1946,10 @@ device_ip6_config_changed (NMDevice *device, */ if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) { if (old_config != new_config) { - if (old_config) - nm_dns_manager_remove_ip_config (priv->dns_manager, old_config); if (new_config) - nm_dns_manager_add_ip_config (priv->dns_manager, ip_iface, new_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT); + nm_dns_manager_set_ip_config (priv->dns_manager, NM_IP_CONFIG_CAST (new_config), NM_DNS_IP_CONFIG_TYPE_DEFAULT); + if (old_config) + nm_dns_manager_set_ip_config (priv->dns_manager, NM_IP_CONFIG_CAST (old_config), NM_DNS_IP_CONFIG_TYPE_REMOVED); } update_ip_dns (self, AF_INET6); update_ip6_routing (self, TRUE); @@ -2000,7 +1957,7 @@ device_ip6_config_changed (NMDevice *device, } else { /* Old configs get removed immediately */ if (old_config) - nm_dns_manager_remove_ip_config (priv->dns_manager, old_config); + nm_dns_manager_set_ip_config (priv->dns_manager, NM_IP_CONFIG_CAST (old_config), NM_DNS_IP_CONFIG_TYPE_REMOVED); } nm_dns_manager_end_updates (priv->dns_manager, __func__); @@ -2020,19 +1977,6 @@ device_autoconnect_changed (NMDevice *device, } static void -device_ifindex_changed (NMDevice *device, - GParamSpec *pspec, - gpointer user_data) -{ - NMPolicyPrivate *priv = user_data; - const char *ip_iface = nm_device_get_ip_iface (device); - int ifindex = nm_device_get_ifindex (device); - - /* update ifindex mapping in DNS manager */ - nm_dns_manager_update_ifindex (priv->dns_manager, ip_iface, ifindex); -} - -static void device_recheck_auto_activate (NMDevice *device, gpointer user_data) { NMPolicyPrivate *priv = user_data; @@ -2060,7 +2004,6 @@ devices_list_register (NMPolicy *self, NMDevice *device) g_signal_connect (device, NM_DEVICE_IP6_CONFIG_CHANGED, (GCallback) device_ip6_config_changed, priv); g_signal_connect (device, NM_DEVICE_IP6_PREFIX_DELEGATED, (GCallback) device_ip6_prefix_delegated, priv); g_signal_connect (device, NM_DEVICE_IP6_SUBNET_NEEDED, (GCallback) device_ip6_subnet_needed, priv); - g_signal_connect (device, "notify::" NM_DEVICE_IFINDEX, (GCallback) device_ifindex_changed, priv); g_signal_connect (device, "notify::" NM_DEVICE_AUTOCONNECT, (GCallback) device_autoconnect_changed, priv); g_signal_connect (device, NM_DEVICE_RECHECK_AUTO_ACTIVATE, (GCallback) device_recheck_auto_activate, priv); } @@ -2113,30 +2056,20 @@ vpn_connection_activated (NMPolicy *self, NMVpnConnection *vpn) NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); NMIP4Config *ip4_config; NMIP6Config *ip6_config; - const char *ip_iface; - NMConnection *connection; nm_dns_manager_begin_updates (priv->dns_manager, __func__); - ip_iface = nm_vpn_connection_get_ip_iface (vpn, TRUE); - - /* Add the VPN connection's IP configs from DNS */ - ip4_config = nm_vpn_connection_get_ip4_config (vpn); if (ip4_config) - nm_dns_manager_add_ip_config (priv->dns_manager, ip_iface, ip4_config, NM_DNS_IP_CONFIG_TYPE_VPN); + nm_dns_manager_set_ip_config (priv->dns_manager, NM_IP_CONFIG_CAST (ip4_config), NM_DNS_IP_CONFIG_TYPE_VPN); ip6_config = nm_vpn_connection_get_ip6_config (vpn); if (ip6_config) - nm_dns_manager_add_ip_config (priv->dns_manager, ip_iface, ip6_config, NM_DNS_IP_CONFIG_TYPE_VPN); + nm_dns_manager_set_ip_config (priv->dns_manager, NM_IP_CONFIG_CAST (ip6_config), NM_DNS_IP_CONFIG_TYPE_VPN); update_routing_and_dns (self, TRUE); nm_dns_manager_end_updates (priv->dns_manager, __func__); - - /* Make sure the connection settings are set */ - connection = nm_active_connection_get_applied_connection (NM_ACTIVE_CONNECTION (vpn)); - add_connection_dns (self, connection, ip_iface, nm_vpn_connection_get_ip_ifindex (vpn, TRUE)); } static void @@ -2149,24 +2082,16 @@ vpn_connection_deactivated (NMPolicy *self, NMVpnConnection *vpn) nm_dns_manager_begin_updates (priv->dns_manager, __func__); ip4_config = nm_vpn_connection_get_ip4_config (vpn); - if (ip4_config) { - /* Remove the VPN connection's IP4 config from DNS */ - nm_dns_manager_remove_ip_config (priv->dns_manager, ip4_config); - } + if (ip4_config) + nm_dns_manager_set_ip_config (priv->dns_manager, NM_IP_CONFIG_CAST (ip4_config), NM_DNS_IP_CONFIG_TYPE_REMOVED); ip6_config = nm_vpn_connection_get_ip6_config (vpn); - if (ip6_config) { - /* Remove the VPN connection's IP6 config from DNS */ - nm_dns_manager_remove_ip_config (priv->dns_manager, ip6_config); - } + if (ip6_config) + nm_dns_manager_set_ip_config (priv->dns_manager, NM_IP_CONFIG_CAST (ip6_config), NM_DNS_IP_CONFIG_TYPE_REMOVED); update_routing_and_dns (self, TRUE); nm_dns_manager_end_updates (priv->dns_manager, __func__); - - remove_connection_dns (self, - nm_vpn_connection_get_ip_iface (vpn, TRUE), - nm_vpn_connection_get_ip_ifindex (vpn, TRUE)); } static void |