summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2020-12-17 14:13:45 +0100
committerBeniamino Galvani <bgalvani@redhat.com>2020-12-18 11:13:19 +0100
commit12df3efccdff81a26fec8cb1893964564f476a7d (patch)
treeffe84048aad74884357a6ce29b936e8265faa225
parent785aef7103ab4de2ef5dd8d8bcadf004e4e60f47 (diff)
downloadNetworkManager-bg/hostname-dns-fix.tar.gz
hostname: start a new lookup every time the DNS configuration changesbg/hostname-dns-fix
If the DNS configuration changes, the hostname previously determined via reverse DNS lookup could be stale. Clear the resolver data of every interface and try again. Fixes: 09c83871144a ('policy: use the hostname setting')
-rw-r--r--src/devices/nm-device.c10
-rw-r--r--src/devices/nm-device.h2
-rw-r--r--src/nm-policy.c41
3 files changed, 49 insertions, 4 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 84d43e245e..21662aaa61 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -17580,6 +17580,16 @@ _resolver_state_to_string(ResolverState state)
}
}
+void
+nm_device_clear_dns_lookup_data(NMDevice *self)
+{
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
+ guint i;
+
+ for (i = 0; i < 2; i++)
+ nm_clear_pointer(&priv->hostname_resolver_x[i], _hostname_resolver_free);
+}
+
/* return value is valid only immediately */
const char *
nm_device_get_hostname_from_dns_lookup(NMDevice *self, int addr_family, gboolean *out_wait)
diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h
index 2885bcbb80..2d53e7b566 100644
--- a/src/devices/nm-device.h
+++ b/src/devices/nm-device.h
@@ -869,4 +869,6 @@ gboolean nm_device_is_vpn(NMDevice *self);
const char *
nm_device_get_hostname_from_dns_lookup(NMDevice *self, int addr_family, gboolean *out_pending);
+void nm_device_clear_dns_lookup_data(NMDevice *self);
+
#endif /* __NETWORKMANAGER_DEVICE_H__ */
diff --git a/src/nm-policy.c b/src/nm-policy.c
index 568c55eefb..114cd7790a 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -65,6 +65,7 @@ typedef struct {
NMActiveConnection *default_ac6, *activating_ac6;
NMDnsManager *dns_manager;
+ gulong config_changed_id;
guint reset_retries_id; /* idle handler for resetting the retries count */
@@ -75,8 +76,10 @@ typedef struct {
char * cur_hostname; /* hostname we want to assign */
char *
last_hostname; /* last hostname NM set (to detect if someone else changed it in the meanwhile) */
- gboolean changing_hostname; /* hostname set operation still in progress */
- gboolean dhcp_hostname; /* current hostname was set from dhcp */
+
+ bool changing_hostname : 1; /* hostname set operation in progress */
+ bool dhcp_hostname : 1; /* current hostname was set from dhcp */
+ bool updating_dns : 1;
GArray *ip6_prefix_delegations; /* pool of ip6 prefixes delegated to all devices */
} NMPolicyPrivate;
@@ -592,11 +595,14 @@ _set_hostname(NMPolicy *self, const char *new_hostname, const char *msg)
priv->cur_hostname = g_strdup(new_hostname);
/* Notify the DNS manager of the hostname change so that the domain part, if
- * present, can be added to the search list.
+ * present, can be added to the search list. Set the @updating_dns flag
+ * so that dns_config_changed() doesn't try again to restart DNS lookup.
*/
+ priv->updating_dns = TRUE;
nm_dns_manager_set_hostname(priv->dns_manager,
priv->cur_hostname,
all_devices_not_active(self));
+ priv->updating_dns = FALSE;
}
/* Finally, set kernel hostname */
@@ -2516,6 +2522,26 @@ firewall_state_changed(NMFirewallManager *manager, gboolean initialized_now, gpo
}
static void
+dns_config_changed(NMDnsManager *dns_manager, gpointer user_data)
+{
+ NMPolicy * self = (NMPolicy *) user_data;
+ NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self);
+ NMDevice * device;
+ const CList * tmp_lst;
+
+ /* We are currently updating the hostname in the DNS manager.
+ * This doesn't warrant a new DNS lookup.*/
+ if (priv->updating_dns)
+ return;
+
+ nm_manager_for_each_device (priv->manager, device, tmp_lst) {
+ nm_device_clear_dns_lookup_data(device);
+ }
+
+ update_system_hostname(self, "DNS configuration changed");
+}
+
+static void
connection_updated(NMSettings * settings,
NMSettingsConnection *connection,
guint update_reason_u,
@@ -2747,6 +2773,10 @@ constructed(GObject *object)
priv->dns_manager = g_object_ref(nm_dns_manager_get());
nm_dns_manager_set_initial_hostname(priv->dns_manager, priv->orig_hostname);
+ priv->config_changed_id = g_signal_connect(priv->dns_manager,
+ NM_DNS_MANAGER_CONFIG_CHANGED,
+ G_CALLBACK(dns_config_changed),
+ self);
g_signal_connect(priv->hostname_manager,
"notify::" NM_HOSTNAME_MANAGER_HOSTNAME,
@@ -2850,7 +2880,10 @@ dispose(GObject *object)
g_clear_object(&priv->agent_mgr);
}
- g_clear_object(&priv->dns_manager);
+ if (priv->dns_manager) {
+ nm_clear_g_signal_handler(priv->dns_manager, &priv->config_changed_id);
+ g_clear_object(&priv->dns_manager);
+ }
g_hash_table_iter_init(&h_iter, priv->devices);
if (g_hash_table_iter_next(&h_iter, (gpointer *) &device, NULL)) {