From ee9c73a923909e23a649407be77e25235d769e25 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Fri, 11 May 2018 22:08:45 +0200 Subject: New upstream version 1.10.8 --- src/dns/nm-dns-systemd-resolved.c | 289 +++++++++++++++++--------------------- 1 file changed, 130 insertions(+), 159 deletions(-) (limited to 'src/dns/nm-dns-systemd-resolved.c') diff --git a/src/dns/nm-dns-systemd-resolved.c b/src/dns/nm-dns-systemd-resolved.c index 7da27e5f..6ab2ea18 100644 --- a/src/dns/nm-dns-systemd-resolved.c +++ b/src/dns/nm-dns-systemd-resolved.c @@ -31,15 +31,13 @@ #include #include -#include "nm-utils/nm-c-list.h" #include "nm-core-internal.h" #include "platform/nm-platform.h" #include "nm-utils.h" #include "nm-ip4-config.h" #include "nm-ip6-config.h" -#include "nm-dbus-manager.h" +#include "nm-bus-manager.h" #include "nm-manager.h" -#include "nm-setting-connection.h" #include "devices/nm-device.h" #include "NetworkManagerUtils.h" @@ -50,23 +48,17 @@ typedef struct { int ifindex; - CList configs_lst_head; + GList *configs; } InterfaceConfig; -typedef struct { - CList request_queue_lst; - const char *operation; - GVariant *argument; -} RequestItem; - /*****************************************************************************/ typedef struct { GDBusProxy *resolve; GCancellable *init_cancellable; GCancellable *update_cancellable; - GCancellable *mdns_cancellable; - CList request_queue_lst_head; + GQueue dns_updates; + GQueue domain_updates; } NMDnsSystemdResolvedPrivate; struct _NMDnsSystemdResolved { @@ -89,36 +81,6 @@ G_DEFINE_TYPE (NMDnsSystemdResolved, nm_dns_systemd_resolved, NM_TYPE_DNS_PLUGIN /*****************************************************************************/ -static void -_request_item_free (RequestItem *request_item) -{ - c_list_unlink_stale (&request_item->request_queue_lst); - g_variant_unref (request_item->argument); - g_slice_free (RequestItem, request_item); -} - -static void -_request_item_append (CList *request_queue_lst_head, - const char *operation, - GVariant *argument) -{ - RequestItem *request_item; - - request_item = g_slice_new (RequestItem); - request_item->operation = operation; - request_item->argument = g_variant_ref_sink (argument); - c_list_link_tail (request_queue_lst_head, &request_item->request_queue_lst); -} - -/*****************************************************************************/ - -static void -_interface_config_free (InterfaceConfig *config) -{ - nm_c_list_elem_free_all (&config->configs_lst_head, NULL); - g_slice_free (InterfaceConfig, config); -} - static void call_done (GObject *source, GAsyncResult *r, gpointer user_data) { @@ -127,58 +89,122 @@ call_done (GObject *source, GAsyncResult *r, gpointer user_data) NMDnsSystemdResolved *self = (NMDnsSystemdResolved *) user_data; v = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), r, &error); - if (!v) { - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; + + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + if (error != NULL) { _LOGW ("Failed: %s\n", error->message); g_error_free (error); } } +static void +add_interface_configuration (NMDnsSystemdResolved *self, + GArray *interfaces, + const NMDnsIPConfigData *data, + gboolean skip) +{ + int i; + InterfaceConfig *ic = NULL; + int ifindex; + + if (NM_IS_IP4_CONFIG (data->config)) + ifindex = nm_ip4_config_get_ifindex (data->config); + else if (NM_IS_IP6_CONFIG (data->config)) + ifindex = nm_ip6_config_get_ifindex (data->config); + else + g_return_if_reached (); + + for (i = 0; i < interfaces->len; i++) { + InterfaceConfig *tic = &g_array_index (interfaces, InterfaceConfig, i); + if (ifindex == tic->ifindex) { + ic = tic; + break; + } + } + + if (!ic) { + g_array_set_size (interfaces, interfaces->len + 1); + ic = &g_array_index (interfaces, InterfaceConfig, + interfaces->len - 1); + ic->ifindex = ifindex; + } + + if (!skip) + ic->configs = g_list_append (ic->configs, data->config); +} + static void update_add_ip_config (NMDnsSystemdResolved *self, GVariantBuilder *dns, GVariantBuilder *domains, - NMIPConfig *config) + gpointer config) { int addr_family; gsize addr_size; guint i, n; - gboolean is_routing; - const char *domain; + gboolean route_only; + + if (NM_IS_IP4_CONFIG (config)) + addr_family = AF_INET; + else if (NM_IS_IP6_CONFIG (config)) + addr_family = AF_INET6; + else + g_return_if_reached (); - addr_family = nm_ip_config_get_addr_family (config); addr_size = nm_utils_addr_family_to_size (addr_family); - n = nm_ip_config_get_num_nameservers (config); + n = addr_family == AF_INET + ? nm_ip4_config_get_num_nameservers (config) + : nm_ip6_config_get_num_nameservers (config); for (i = 0 ; i < n; i++) { + in_addr_t ns4; + gconstpointer ns; + + if (addr_family == AF_INET) { + ns4 = nm_ip4_config_get_nameserver (config, i); + ns = &ns4; + } else + ns = nm_ip6_config_get_nameserver (config, i); + g_variant_builder_open (dns, G_VARIANT_TYPE ("(iay)")); g_variant_builder_add (dns, "i", addr_family); g_variant_builder_add_value (dns, g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, - nm_ip_config_get_nameserver (config, i), + ns, addr_size, 1)); g_variant_builder_close (dns); } - n = nm_ip_config_get_num_searches (config); + /* If this link is never the default (e.g. only used for resources on this + * network) add a routing domain. */ + route_only = addr_family == AF_INET + ? !nm_ip4_config_best_default_route_get (config) + : !nm_ip6_config_best_default_route_get (config); + + n = addr_family == AF_INET + ? nm_ip4_config_get_num_searches (config) + : nm_ip6_config_get_num_searches (config); if (n > 0) { for (i = 0; i < n; i++) { - domain = nm_utils_parse_dns_domain (nm_ip_config_get_search (config, i), - &is_routing); g_variant_builder_add (domains, "(sb)", - domain, - is_routing); + addr_family == AF_INET + ? nm_ip4_config_get_search (config, i) + : nm_ip6_config_get_search (config, i), + route_only); } } else { - n = nm_ip_config_get_num_domains (config); + n = addr_family == AF_INET + ? nm_ip4_config_get_num_domains (config) + : nm_ip6_config_get_num_domains (config); for (i = 0; i < n; i++) { - domain = nm_utils_parse_dns_domain (nm_ip_config_get_domain (config, i), - &is_routing); g_variant_builder_add (domains, "(sb)", - domain, - is_routing); + addr_family == AF_INET + ? nm_ip4_config_get_domain (config, i) + : nm_ip6_config_get_domain (config, i), + route_only); } } } @@ -187,13 +213,13 @@ static void free_pending_updates (NMDnsSystemdResolved *self) { NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self); - RequestItem *request_item, *request_item_safe; + GVariant *v; - c_list_for_each_entry_safe (request_item, - request_item_safe, - &priv->request_queue_lst_head, - request_queue_lst) - _request_item_free (request_item); + while ((v = g_queue_pop_head (&priv->dns_updates)) != NULL) + g_variant_unref (v); + + while ((v = g_queue_pop_head (&priv->domain_updates)) != NULL) + g_variant_unref (v); } static void @@ -201,9 +227,7 @@ prepare_one_interface (NMDnsSystemdResolved *self, InterfaceConfig *ic) { NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self); GVariantBuilder dns, domains; - NMCListElem *elem; - NMSettingConnectionMdns mdns = NM_SETTING_CONNECTION_MDNS_DEFAULT; - const char *mdns_arg = NULL; + GList *l; g_variant_builder_init (&dns, G_VARIANT_TYPE ("(ia(iay))")); g_variant_builder_add (&dns, "i", ic->ifindex); @@ -213,50 +237,23 @@ prepare_one_interface (NMDnsSystemdResolved *self, InterfaceConfig *ic) g_variant_builder_add (&domains, "i", ic->ifindex); g_variant_builder_open (&domains, G_VARIANT_TYPE ("a(sb)")); - c_list_for_each_entry (elem, &ic->configs_lst_head, lst) { - NMIPConfig *ip_config = elem->data; - - update_add_ip_config (self, &dns, &domains, ip_config); - - if (NM_IS_IP4_CONFIG (ip_config)) - mdns = NM_MAX (mdns, nm_ip4_config_mdns_get (NM_IP4_CONFIG (ip_config))); - } + for (l = ic->configs; l; l = l->next) + update_add_ip_config (self, &dns, &domains, l->data); g_variant_builder_close (&dns); g_variant_builder_close (&domains); - switch (mdns) { - case NM_SETTING_CONNECTION_MDNS_NO: - mdns_arg = "no"; - break; - case NM_SETTING_CONNECTION_MDNS_RESOLVE: - mdns_arg = "resolve"; - break; - case NM_SETTING_CONNECTION_MDNS_YES: - mdns_arg = "yes"; - break; - case NM_SETTING_CONNECTION_MDNS_DEFAULT: - mdns_arg = ""; - break; - } - nm_assert (mdns_arg); - - _request_item_append (&priv->request_queue_lst_head, - "SetLinkDNS", - g_variant_builder_end (&dns)); - _request_item_append (&priv->request_queue_lst_head, - "SetLinkDomains", - g_variant_builder_end (&domains)); - _request_item_append (&priv->request_queue_lst_head, - "SetLinkMulticastDNS", - g_variant_new ("(is)", ic->ifindex, mdns_arg ?: "")); + g_queue_push_tail (&priv->dns_updates, + g_variant_ref_sink (g_variant_builder_end (&dns))); + g_queue_push_tail (&priv->domain_updates, + g_variant_ref_sink (g_variant_builder_end (&domains))); } static void send_updates (NMDnsSystemdResolved *self) { NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self); - RequestItem *request_item, *request_item_safe; + GVariant *v; nm_clear_g_cancellable (&priv->update_cancellable); @@ -265,81 +262,55 @@ send_updates (NMDnsSystemdResolved *self) priv->update_cancellable = g_cancellable_new (); - c_list_for_each_entry_safe (request_item, - request_item_safe, - &priv->request_queue_lst_head, - request_queue_lst) { - g_dbus_proxy_call (priv->resolve, - request_item->operation, - request_item->argument, + while ((v = g_queue_pop_head (&priv->dns_updates)) != NULL) { + g_dbus_proxy_call (priv->resolve, "SetLinkDNS", v, G_DBUS_CALL_FLAGS_NONE, - -1, - priv->update_cancellable, - call_done, - self); - _request_item_free (request_item); + -1, priv->update_cancellable, call_done, self); + g_variant_unref (v); + } + + while ((v = g_queue_pop_head (&priv->domain_updates)) != NULL) { + g_dbus_proxy_call (priv->resolve, "SetLinkDomains", v, + G_DBUS_CALL_FLAGS_NONE, + -1, priv->update_cancellable, call_done, self); + g_variant_unref (v); } } 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); - gs_unref_hashtable GHashTable *interfaces = NULL; - gs_free gpointer *interfaces_keys = NULL; - guint interfaces_len; + GArray *interfaces = g_array_new (TRUE, TRUE, sizeof (InterfaceConfig)); 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); - c_list_for_each_entry (ip_data, ip_config_lst_head, ip_config_lst) { + for (i = 0; i < configs->len; i++) { + const NMDnsIPConfigData *data = configs->pdata[i]; gboolean skip = FALSE; - InterfaceConfig *ic = NULL; - int ifindex; - prio = nm_ip_config_get_dns_priority (ip_data->ip_config); - if (is_first) { - is_first = FALSE; + prio = nm_ip_config_get_dns_priority (data->config); + if (i == 0) first_prio = prio; - } else if (first_prio < 0 && first_prio != prio) + else if (first_prio < 0 && first_prio != prio) skip = TRUE; - - 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) { - ic = g_slice_new (InterfaceConfig); - ic->ifindex = ifindex; - c_list_init (&ic->configs_lst_head); - g_hash_table_insert (interfaces, GINT_TO_POINTER (ifindex), ic); - } - - if (!skip) { - c_list_link_tail (&ic->configs_lst_head, - &nm_c_list_elem_new_stale (ip_data->ip_config)->lst); - } + add_interface_configuration (self, interfaces, data, skip); } free_pending_updates (self); - interfaces_keys = nm_utils_hash_keys_to_array (interfaces, - nm_cmp_int2ptr_p_with_data, - NULL, - &interfaces_len); - for (i = 0; i < interfaces_len; i++) { - InterfaceConfig *ic = g_hash_table_lookup (interfaces, GINT_TO_POINTER (interfaces_keys[i])); + for (i = 0; i < interfaces->len; i++) { + InterfaceConfig *ic = &g_array_index (interfaces, InterfaceConfig, i); prepare_one_interface (self, ic); + g_list_free (ic->configs); } + g_array_free (interfaces, TRUE); + send_updates (self); return TRUE; @@ -392,15 +363,16 @@ static void nm_dns_systemd_resolved_init (NMDnsSystemdResolved *self) { NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self); - NMDBusManager *dbus_mgr; + NMBusManager *dbus_mgr; GDBusConnection *connection; - c_list_init (&priv->request_queue_lst_head); + g_queue_init (&priv->dns_updates); + g_queue_init (&priv->domain_updates); - dbus_mgr = nm_dbus_manager_get (); + dbus_mgr = nm_bus_manager_get (); g_return_if_fail (dbus_mgr); - connection = nm_dbus_manager_get_connection (dbus_mgr); + connection = nm_bus_manager_get_connection (dbus_mgr); g_return_if_fail (connection); priv->init_cancellable = g_cancellable_new (); @@ -432,7 +404,6 @@ dispose (GObject *object) g_clear_object (&priv->resolve); nm_clear_g_cancellable (&priv->init_cancellable); nm_clear_g_cancellable (&priv->update_cancellable); - nm_clear_g_cancellable (&priv->mdns_cancellable); G_OBJECT_CLASS (nm_dns_systemd_resolved_parent_class)->dispose (object); } -- cgit 1.3.0-6-gf8a5 From 04bc9e1cd3544445d883ad29ea108c1645c8e7b7 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Mon, 4 Jun 2018 00:07:45 +0200 Subject: New upstream version 1.11.4 --- src/dns/nm-dns-systemd-resolved.c | 295 +++++++++++++++++++------------------- 1 file changed, 151 insertions(+), 144 deletions(-) (limited to 'src/dns/nm-dns-systemd-resolved.c') diff --git a/src/dns/nm-dns-systemd-resolved.c b/src/dns/nm-dns-systemd-resolved.c index 6ab2ea18..1a73aae1 100644 --- a/src/dns/nm-dns-systemd-resolved.c +++ b/src/dns/nm-dns-systemd-resolved.c @@ -31,13 +31,15 @@ #include #include +#include "nm-utils/nm-c-list.h" #include "nm-core-internal.h" #include "platform/nm-platform.h" #include "nm-utils.h" #include "nm-ip4-config.h" #include "nm-ip6-config.h" -#include "nm-bus-manager.h" +#include "nm-dbus-manager.h" #include "nm-manager.h" +#include "nm-setting-connection.h" #include "devices/nm-device.h" #include "NetworkManagerUtils.h" @@ -48,17 +50,23 @@ typedef struct { int ifindex; - GList *configs; + CList configs_lst_head; } InterfaceConfig; +typedef struct { + CList request_queue_lst; + const char *operation; + GVariant *argument; +} RequestItem; + /*****************************************************************************/ typedef struct { GDBusProxy *resolve; GCancellable *init_cancellable; GCancellable *update_cancellable; - GQueue dns_updates; - GQueue domain_updates; + GCancellable *mdns_cancellable; + CList request_queue_lst_head; } NMDnsSystemdResolvedPrivate; struct _NMDnsSystemdResolved { @@ -82,130 +90,85 @@ G_DEFINE_TYPE (NMDnsSystemdResolved, nm_dns_systemd_resolved, NM_TYPE_DNS_PLUGIN /*****************************************************************************/ static void -call_done (GObject *source, GAsyncResult *r, gpointer user_data) +_request_item_free (RequestItem *request_item) { - GVariant *v; - GError *error = NULL; - NMDnsSystemdResolved *self = (NMDnsSystemdResolved *) user_data; - - v = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), r, &error); + c_list_unlink_stale (&request_item->request_queue_lst); + g_variant_unref (request_item->argument); + g_slice_free (RequestItem, request_item); +} - if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - return; +static void +_request_item_append (CList *request_queue_lst_head, + const char *operation, + GVariant *argument) +{ + RequestItem *request_item; - if (error != NULL) { - _LOGW ("Failed: %s\n", error->message); - g_error_free (error); - } + request_item = g_slice_new (RequestItem); + request_item->operation = operation; + request_item->argument = g_variant_ref_sink (argument); + c_list_link_tail (request_queue_lst_head, &request_item->request_queue_lst); } +/*****************************************************************************/ + static void -add_interface_configuration (NMDnsSystemdResolved *self, - GArray *interfaces, - const NMDnsIPConfigData *data, - gboolean skip) +_interface_config_free (InterfaceConfig *config) { - int i; - InterfaceConfig *ic = NULL; - int ifindex; + nm_c_list_elem_free_all (&config->configs_lst_head, NULL); + g_slice_free (InterfaceConfig, config); +} - if (NM_IS_IP4_CONFIG (data->config)) - ifindex = nm_ip4_config_get_ifindex (data->config); - else if (NM_IS_IP6_CONFIG (data->config)) - ifindex = nm_ip6_config_get_ifindex (data->config); - else - g_return_if_reached (); - - for (i = 0; i < interfaces->len; i++) { - InterfaceConfig *tic = &g_array_index (interfaces, InterfaceConfig, i); - if (ifindex == tic->ifindex) { - ic = tic; - break; - } - } +static void +call_done (GObject *source, GAsyncResult *r, gpointer user_data) +{ + GVariant *v; + GError *error = NULL; + NMDnsSystemdResolved *self = (NMDnsSystemdResolved *) user_data; - if (!ic) { - g_array_set_size (interfaces, interfaces->len + 1); - ic = &g_array_index (interfaces, InterfaceConfig, - interfaces->len - 1); - ic->ifindex = ifindex; + v = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), r, &error); + if (!v) { + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + _LOGW ("Failed: %s\n", error->message); + g_error_free (error); } - - if (!skip) - ic->configs = g_list_append (ic->configs, data->config); } static void update_add_ip_config (NMDnsSystemdResolved *self, GVariantBuilder *dns, GVariantBuilder *domains, - gpointer config) + NMDnsIPConfigData *data) { int addr_family; gsize addr_size; guint i, n; - gboolean route_only; - - if (NM_IS_IP4_CONFIG (config)) - addr_family = AF_INET; - else if (NM_IS_IP6_CONFIG (config)) - addr_family = AF_INET6; - else - g_return_if_reached (); + gboolean is_routing; + const char **iter; + const char *domain; + addr_family = nm_ip_config_get_addr_family (data->ip_config); addr_size = nm_utils_addr_family_to_size (addr_family); - n = addr_family == AF_INET - ? nm_ip4_config_get_num_nameservers (config) - : nm_ip6_config_get_num_nameservers (config); - for (i = 0 ; i < n; i++) { - in_addr_t ns4; - gconstpointer ns; - - if (addr_family == AF_INET) { - ns4 = nm_ip4_config_get_nameserver (config, i); - ns = &ns4; - } else - ns = nm_ip6_config_get_nameserver (config, i); + if (!data->domains.search || !data->domains.search[0]) + return; + n = nm_ip_config_get_num_nameservers (data->ip_config); + for (i = 0 ; i < n; i++) { g_variant_builder_open (dns, G_VARIANT_TYPE ("(iay)")); g_variant_builder_add (dns, "i", addr_family); g_variant_builder_add_value (dns, g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, - ns, + nm_ip_config_get_nameserver (data->ip_config, i), addr_size, 1)); g_variant_builder_close (dns); } - /* If this link is never the default (e.g. only used for resources on this - * network) add a routing domain. */ - route_only = addr_family == AF_INET - ? !nm_ip4_config_best_default_route_get (config) - : !nm_ip6_config_best_default_route_get (config); - - n = addr_family == AF_INET - ? nm_ip4_config_get_num_searches (config) - : nm_ip6_config_get_num_searches (config); - if (n > 0) { - for (i = 0; i < n; i++) { - g_variant_builder_add (domains, "(sb)", - addr_family == AF_INET - ? nm_ip4_config_get_search (config, i) - : nm_ip6_config_get_search (config, i), - route_only); - } - } else { - n = addr_family == AF_INET - ? nm_ip4_config_get_num_domains (config) - : nm_ip6_config_get_num_domains (config); - for (i = 0; i < n; i++) { - g_variant_builder_add (domains, "(sb)", - addr_family == AF_INET - ? nm_ip4_config_get_domain (config, i) - : nm_ip6_config_get_domain (config, i), - route_only); - } + for (iter = data->domains.search; *iter; iter++) { + domain = nm_utils_parse_dns_domain (*iter, &is_routing); + g_variant_builder_add (domains, "(sb)", domain[0] ? domain : ".", is_routing); } } @@ -213,13 +176,13 @@ static void free_pending_updates (NMDnsSystemdResolved *self) { NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self); - GVariant *v; + RequestItem *request_item, *request_item_safe; - while ((v = g_queue_pop_head (&priv->dns_updates)) != NULL) - g_variant_unref (v); - - while ((v = g_queue_pop_head (&priv->domain_updates)) != NULL) - g_variant_unref (v); + c_list_for_each_entry_safe (request_item, + request_item_safe, + &priv->request_queue_lst_head, + request_queue_lst) + _request_item_free (request_item); } static void @@ -227,7 +190,9 @@ prepare_one_interface (NMDnsSystemdResolved *self, InterfaceConfig *ic) { NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self); GVariantBuilder dns, domains; - GList *l; + NMCListElem *elem; + NMSettingConnectionMdns mdns = NM_SETTING_CONNECTION_MDNS_DEFAULT; + const char *mdns_arg = NULL; g_variant_builder_init (&dns, G_VARIANT_TYPE ("(ia(iay))")); g_variant_builder_add (&dns, "i", ic->ifindex); @@ -237,23 +202,51 @@ prepare_one_interface (NMDnsSystemdResolved *self, InterfaceConfig *ic) g_variant_builder_add (&domains, "i", ic->ifindex); g_variant_builder_open (&domains, G_VARIANT_TYPE ("a(sb)")); - for (l = ic->configs; l; l = l->next) - update_add_ip_config (self, &dns, &domains, l->data); + c_list_for_each_entry (elem, &ic->configs_lst_head, lst) { + NMDnsIPConfigData *data = elem->data; + NMIPConfig *ip_config = data->ip_config; + + update_add_ip_config (self, &dns, &domains, data); + + if (NM_IS_IP4_CONFIG (ip_config)) + mdns = NM_MAX (mdns, nm_ip4_config_mdns_get (NM_IP4_CONFIG (ip_config))); + } g_variant_builder_close (&dns); g_variant_builder_close (&domains); - g_queue_push_tail (&priv->dns_updates, - g_variant_ref_sink (g_variant_builder_end (&dns))); - g_queue_push_tail (&priv->domain_updates, - g_variant_ref_sink (g_variant_builder_end (&domains))); + switch (mdns) { + case NM_SETTING_CONNECTION_MDNS_NO: + mdns_arg = "no"; + break; + case NM_SETTING_CONNECTION_MDNS_RESOLVE: + mdns_arg = "resolve"; + break; + case NM_SETTING_CONNECTION_MDNS_YES: + mdns_arg = "yes"; + break; + case NM_SETTING_CONNECTION_MDNS_DEFAULT: + mdns_arg = ""; + break; + } + nm_assert (mdns_arg); + + _request_item_append (&priv->request_queue_lst_head, + "SetLinkDNS", + g_variant_builder_end (&dns)); + _request_item_append (&priv->request_queue_lst_head, + "SetLinkDomains", + g_variant_builder_end (&domains)); + _request_item_append (&priv->request_queue_lst_head, + "SetLinkMulticastDNS", + g_variant_new ("(is)", ic->ifindex, mdns_arg ?: "")); } static void send_updates (NMDnsSystemdResolved *self) { NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self); - GVariant *v; + RequestItem *request_item, *request_item_safe; nm_clear_g_cancellable (&priv->update_cancellable); @@ -262,55 +255,69 @@ send_updates (NMDnsSystemdResolved *self) priv->update_cancellable = g_cancellable_new (); - while ((v = g_queue_pop_head (&priv->dns_updates)) != NULL) { - g_dbus_proxy_call (priv->resolve, "SetLinkDNS", v, + c_list_for_each_entry_safe (request_item, + request_item_safe, + &priv->request_queue_lst_head, + request_queue_lst) { + g_dbus_proxy_call (priv->resolve, + request_item->operation, + request_item->argument, G_DBUS_CALL_FLAGS_NONE, - -1, priv->update_cancellable, call_done, self); - g_variant_unref (v); - } - - while ((v = g_queue_pop_head (&priv->domain_updates)) != NULL) { - g_dbus_proxy_call (priv->resolve, "SetLinkDomains", v, - G_DBUS_CALL_FLAGS_NONE, - -1, priv->update_cancellable, call_done, self); - g_variant_unref (v); + -1, + priv->update_cancellable, + call_done, + self); + _request_item_free (request_item); } } 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); - GArray *interfaces = g_array_new (TRUE, TRUE, sizeof (InterfaceConfig)); + gs_unref_hashtable GHashTable *interfaces = NULL; + gs_free gpointer *interfaces_keys = NULL; + guint interfaces_len; guint i; - int prio, first_prio = 0; - - for (i = 0; i < configs->len; i++) { - const NMDnsIPConfigData *data = configs->pdata[i]; - gboolean skip = FALSE; - - prio = nm_ip_config_get_dns_priority (data->config); - if (i == 0) - first_prio = prio; - else if (first_prio < 0 && first_prio != prio) - skip = TRUE; - add_interface_configuration (self, interfaces, data, skip); + NMDnsIPConfigData *ip_data; + + interfaces = g_hash_table_new_full (nm_direct_hash, NULL, + NULL, (GDestroyNotify) _interface_config_free); + + c_list_for_each_entry (ip_data, ip_config_lst_head, ip_config_lst) { + InterfaceConfig *ic = NULL; + int ifindex; + + 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) { + ic = g_slice_new (InterfaceConfig); + ic->ifindex = ifindex; + c_list_init (&ic->configs_lst_head); + g_hash_table_insert (interfaces, GINT_TO_POINTER (ifindex), ic); + } + + c_list_link_tail (&ic->configs_lst_head, + &nm_c_list_elem_new_stale (ip_data)->lst); } free_pending_updates (self); - for (i = 0; i < interfaces->len; i++) { - InterfaceConfig *ic = &g_array_index (interfaces, InterfaceConfig, i); + interfaces_keys = nm_utils_hash_keys_to_array (interfaces, + nm_cmp_int2ptr_p_with_data, + NULL, + &interfaces_len); + for (i = 0; i < interfaces_len; i++) { + InterfaceConfig *ic = g_hash_table_lookup (interfaces, GINT_TO_POINTER (interfaces_keys[i])); prepare_one_interface (self, ic); - g_list_free (ic->configs); } - g_array_free (interfaces, TRUE); - send_updates (self); return TRUE; @@ -363,16 +370,15 @@ static void nm_dns_systemd_resolved_init (NMDnsSystemdResolved *self) { NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self); - NMBusManager *dbus_mgr; + NMDBusManager *dbus_mgr; GDBusConnection *connection; - g_queue_init (&priv->dns_updates); - g_queue_init (&priv->domain_updates); + c_list_init (&priv->request_queue_lst_head); - dbus_mgr = nm_bus_manager_get (); + dbus_mgr = nm_dbus_manager_get (); g_return_if_fail (dbus_mgr); - connection = nm_bus_manager_get_connection (dbus_mgr); + connection = nm_dbus_manager_get_connection (dbus_mgr); g_return_if_fail (connection); priv->init_cancellable = g_cancellable_new (); @@ -404,6 +410,7 @@ dispose (GObject *object) g_clear_object (&priv->resolve); nm_clear_g_cancellable (&priv->init_cancellable); nm_clear_g_cancellable (&priv->update_cancellable); + nm_clear_g_cancellable (&priv->mdns_cancellable); G_OBJECT_CLASS (nm_dns_systemd_resolved_parent_class)->dispose (object); } -- cgit 1.3.0-6-gf8a5