summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dns/nm-dns-dnsmasq.c131
-rw-r--r--src/dns/nm-dns-manager.c586
-rw-r--r--src/dns/nm-dns-manager.h42
-rw-r--r--src/dns/nm-dns-plugin.c16
-rw-r--r--src/dns/nm-dns-plugin.h13
-rw-r--r--src/dns/nm-dns-systemd-resolved.c59
-rw-r--r--src/dns/nm-dns-unbound.c2
-rw-r--r--src/nm-ip4-config.h6
-rw-r--r--src/nm-policy.c117
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