diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2020-12-17 14:13:45 +0100 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2020-12-18 11:13:19 +0100 |
commit | 12df3efccdff81a26fec8cb1893964564f476a7d (patch) | |
tree | ffe84048aad74884357a6ce29b936e8265faa225 | |
parent | 785aef7103ab4de2ef5dd8d8bcadf004e4e60f47 (diff) | |
download | NetworkManager-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.c | 10 | ||||
-rw-r--r-- | src/devices/nm-device.h | 2 | ||||
-rw-r--r-- | src/nm-policy.c | 41 |
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)) { |