diff options
| author | Michael Biebl <biebl@debian.org> | 2013-02-20 23:06:45 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2013-02-20 23:06:45 +0100 |
| commit | 8d275584fc94f398f0a7c990dcd057533d9a5856 (patch) | |
| tree | 1bf4a928e201222a008e6776799d174ee3223be3 /src/nm-policy.c | |
| parent | e17c5736fc3722ce51cb33f3edb203960125a4c1 (diff) | |
Imported Upstream version 0.9.8.0 upstream/0.9.8.0
Diffstat (limited to 'src/nm-policy.c')
| -rw-r--r-- | src/nm-policy.c | 110 |
1 files changed, 79 insertions, 31 deletions
diff --git a/src/nm-policy.c b/src/nm-policy.c index 752cf44e..38a03613 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2004 - 2012 Red Hat, Inc. + * Copyright (C) 2004 - 2013 Red Hat, Inc. * Copyright (C) 2007 - 2008 Novell, Inc. */ @@ -62,6 +62,10 @@ struct NMPolicy { NMDevice *default_device6; HostnameThread *lookup; + guint32 lookup_ipv4_addr; /* IPv4 for reverse lookup */ + struct in6_addr *lookup_ipv6_addr; /* IPv6 for reverse lookup */ + NMDnsManager *dns_manager; + gulong config_changed_id; gint reset_retries_id; /* idle handler for resetting the retries count */ @@ -229,14 +233,21 @@ _set_hostname (NMPolicy *policy, const char *new_hostname, const char *msg) { - NMDnsManager *dns_mgr; - /* The incoming hostname *can* be NULL, which will get translated to * 'localhost.localdomain' or such in the hostname policy code, but we * keep cur_hostname = NULL in the case because we need to know that * there was no valid hostname to start with. */ + /* Clear lookup adresses if we have a hostname, so that we didn't + * restart reverse lookup thread later. + */ + if (new_hostname) { + policy->lookup_ipv4_addr = 0; + g_free (policy->lookup_ipv6_addr); + policy->lookup_ipv6_addr = NULL; + } + /* Don't change the hostname or update DNS this is the first time we're * trying to change the hostname, and it's not actually changing. */ @@ -255,9 +266,7 @@ _set_hostname (NMPolicy *policy, policy->cur_hostname = g_strdup (new_hostname); policy->hostname_changed = TRUE; - dns_mgr = nm_dns_manager_get (NULL); - nm_dns_manager_set_hostname (dns_mgr, policy->cur_hostname); - g_object_unref (dns_mgr); + nm_dns_manager_set_hostname (policy->dns_manager, policy->cur_hostname); if (nm_policy_set_system_hostname (policy->cur_hostname, msg)) nm_dispatcher_call (DISPATCHER_ACTION_HOSTNAME, NULL, NULL, NULL, NULL); @@ -398,7 +407,8 @@ update_system_hostname (NMPolicy *policy, NMDevice *best4, NMDevice *best6) g_assert (addr4); /* checked for > 1 address above */ /* Start the hostname lookup thread */ - policy->lookup = hostname4_thread_new (nm_ip4_address_get_address (addr4), lookup_callback, policy); + policy->lookup_ipv4_addr = nm_ip4_address_get_address (addr4); + policy->lookup = hostname4_thread_new (policy->lookup_ipv4_addr, lookup_callback, policy); } else if (best6) { NMIP6Config *ip6_config; NMIP6Address *addr6; @@ -416,7 +426,9 @@ update_system_hostname (NMPolicy *policy, NMDevice *best4, NMDevice *best6) g_assert (addr6); /* checked for > 1 address above */ /* Start the hostname lookup thread */ - policy->lookup = hostname6_thread_new (nm_ip6_address_get_address (addr6), lookup_callback, policy); + policy->lookup_ipv6_addr = g_malloc0 (sizeof (struct in6_addr)); + memcpy (policy->lookup_ipv6_addr, nm_ip6_address_get_address (addr6), sizeof (struct in6_addr)); + policy->lookup = hostname6_thread_new (policy->lookup_ipv6_addr, lookup_callback, policy); } if (!policy->lookup) { @@ -1264,7 +1276,6 @@ device_state_changed (NMDevice *device, NMIP4Config *ip4_config; NMIP6Config *ip6_config; NMSettingConnection *s_con; - NMDnsManager *dns_mgr; if (connection) g_object_set_data (G_OBJECT (connection), FAILURE_REASON_TAG, GUINT_TO_POINTER (0)); @@ -1322,20 +1333,18 @@ device_state_changed (NMDevice *device, /* Add device's new IPv4 and IPv6 configs to DNS */ - dns_mgr = nm_dns_manager_get (NULL); - nm_dns_manager_begin_updates (dns_mgr, __func__); + nm_dns_manager_begin_updates (policy->dns_manager, __func__); ip4_config = nm_device_get_ip4_config (device); if (ip4_config) - nm_dns_manager_add_ip4_config (dns_mgr, ip_iface, ip4_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT); + nm_dns_manager_add_ip4_config (policy->dns_manager, ip_iface, ip4_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT); ip6_config = nm_device_get_ip6_config (device); if (ip6_config) - nm_dns_manager_add_ip6_config (dns_mgr, ip_iface, ip6_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT); + nm_dns_manager_add_ip6_config (policy->dns_manager, ip_iface, ip6_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT); update_routing_and_dns (policy, FALSE); - nm_dns_manager_end_updates (dns_mgr, __func__); - g_object_unref (dns_mgr); + nm_dns_manager_end_updates (policy->dns_manager, __func__); break; case NM_DEVICE_STATE_UNMANAGED: case NM_DEVICE_STATE_UNAVAILABLE: @@ -1387,16 +1396,14 @@ device_ip4_config_changed (NMDevice *device, gpointer user_data) { NMPolicy *policy = user_data; - NMDnsManager *dns_mgr; const char *ip_iface = nm_device_get_ip_iface (device); NMIP4ConfigCompareFlags diff = NM_IP4_COMPARE_FLAG_ALL; - dns_mgr = nm_dns_manager_get (NULL); - nm_dns_manager_begin_updates (dns_mgr, __func__); + nm_dns_manager_begin_updates (policy->dns_manager, __func__); /* Old configs get removed immediately */ if (old_config) - nm_dns_manager_remove_ip4_config (dns_mgr, old_config); + nm_dns_manager_remove_ip4_config (policy->dns_manager, old_config); /* Ignore IP config changes while the device is activating, because we'll * catch all the changes when the device moves to ACTIVATED state. @@ -1404,8 +1411,8 @@ device_ip4_config_changed (NMDevice *device, */ if (!nm_device_is_activating (device)) { if (new_config) - nm_dns_manager_add_ip4_config (dns_mgr, ip_iface, new_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT); - update_ip4_dns (policy, dns_mgr); + nm_dns_manager_add_ip4_config (policy->dns_manager, ip_iface, new_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT); + update_ip4_dns (policy, policy->dns_manager); /* Only change routing if something actually changed */ diff = nm_ip4_config_diff (new_config, old_config); @@ -1413,8 +1420,7 @@ device_ip4_config_changed (NMDevice *device, update_ip4_routing (policy, TRUE); } - nm_dns_manager_end_updates (dns_mgr, __func__); - g_object_unref (dns_mgr); + nm_dns_manager_end_updates (policy->dns_manager, __func__); } static void @@ -1424,16 +1430,14 @@ device_ip6_config_changed (NMDevice *device, gpointer user_data) { NMPolicy *policy = user_data; - NMDnsManager *dns_mgr; const char *ip_iface = nm_device_get_ip_iface (device); NMIP4ConfigCompareFlags diff = NM_IP4_COMPARE_FLAG_ALL; - dns_mgr = nm_dns_manager_get (NULL); - nm_dns_manager_begin_updates (dns_mgr, __func__); + nm_dns_manager_begin_updates (policy->dns_manager, __func__); /* Old configs get removed immediately */ if (old_config) - nm_dns_manager_remove_ip6_config (dns_mgr, old_config); + nm_dns_manager_remove_ip6_config (policy->dns_manager, old_config); /* Ignore IP config changes while the device is activating, because we'll * catch all the changes when the device moves to ACTIVATED state. @@ -1441,8 +1445,8 @@ device_ip6_config_changed (NMDevice *device, */ if (!nm_device_is_activating (device)) { if (new_config) - nm_dns_manager_add_ip6_config (dns_mgr, ip_iface, new_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT); - update_ip6_dns (policy, dns_mgr); + nm_dns_manager_add_ip6_config (policy->dns_manager, ip_iface, new_config, NM_DNS_IP_CONFIG_TYPE_DEFAULT); + update_ip6_dns (policy, policy->dns_manager); /* Only change routing if something actually changed */ diff = nm_ip6_config_diff (new_config, old_config); @@ -1450,8 +1454,7 @@ device_ip6_config_changed (NMDevice *device, update_ip6_routing (policy, TRUE); } - nm_dns_manager_end_updates (dns_mgr, __func__); - g_object_unref (dns_mgr); + nm_dns_manager_end_updates (policy->dns_manager, __func__); } static void @@ -1792,6 +1795,43 @@ firewall_started (NMFirewallManager *manager, } static void +dns_config_changed (NMDnsManager *dns_manager, gpointer user_data) +{ + NMPolicy *policy = (NMPolicy *) user_data; + + /* Restart a thread for reverse-DNS lookup after we are signalled that + * DNS changed. Because the result from a previous run may not be right + * (race in updating DNS and doing the reverse lookup). + */ + + /* Stop a lookup thread if any. */ + if (policy->lookup) { + hostname_thread_kill (policy->lookup); + policy->lookup = NULL; + } + + /* Re-start the hostname lookup thread if we don't have hostname yet. */ + if (policy->lookup_ipv4_addr) { + char buf[INET_ADDRSTRLEN]; + struct in_addr addr = { .s_addr = policy->lookup_ipv4_addr }; + + if (!inet_ntop (AF_INET, &addr, buf, sizeof (buf))) + strcpy (buf, "(unknown)"); + nm_log_dbg (LOGD_DNS, "restarting IPv4 reverse-lookup thread for address %s'", buf); + + policy->lookup = hostname4_thread_new (policy->lookup_ipv4_addr, lookup_callback, policy); + } else if (policy->lookup_ipv6_addr) { + char buf[INET6_ADDRSTRLEN]; + + if (!inet_ntop (AF_INET6, policy->lookup_ipv6_addr, buf, sizeof (buf))) + strcpy (buf, "(unknown)"); + nm_log_dbg (LOGD_DNS, "restarting IPv6 reverse-lookup thread for address %s'", buf); + + policy->lookup = hostname6_thread_new (policy->lookup_ipv6_addr, lookup_callback, policy); + } +} + +static void connection_updated (NMSettings *settings, NMConnection *connection, gpointer user_data) @@ -1917,6 +1957,10 @@ nm_policy_new (NMManager *manager, NMSettings *settings) G_CALLBACK (firewall_started), policy); policy->fw_started_id = id; + policy->dns_manager = nm_dns_manager_get (NULL); + policy->config_changed_id = g_signal_connect (policy->dns_manager, "config-changed", + G_CALLBACK (dns_config_changed), policy); + _connect_manager_signal (policy, "state-changed", global_state_changed); _connect_manager_signal (policy, "notify::" NM_MANAGER_HOSTNAME, hostname_changed); _connect_manager_signal (policy, "notify::" NM_MANAGER_SLEEPING, sleeping_changed); @@ -1955,6 +1999,7 @@ nm_policy_destroy (NMPolicy *policy) hostname_thread_kill (policy->lookup); policy->lookup = NULL; } + g_free (policy->lookup_ipv6_addr); g_slist_foreach (policy->pending_activation_checks, (GFunc) activate_data_free, NULL); g_slist_free (policy->pending_activation_checks); @@ -1965,6 +2010,9 @@ nm_policy_destroy (NMPolicy *policy) g_signal_handler_disconnect (policy->fw_manager, policy->fw_started_id); g_object_unref (policy->fw_manager); + g_signal_handler_disconnect (policy->dns_manager, policy->config_changed_id); + g_object_unref (policy->dns_manager); + for (iter = policy->manager_ids; iter; iter = g_slist_next (iter)) g_signal_handler_disconnect (policy->manager, GPOINTER_TO_UINT (iter->data)); g_slist_free (policy->manager_ids); |