diff options
Diffstat (limited to 'src/dns')
| -rw-r--r-- | src/dns/nm-dns-dnsmasq.c | 32 | ||||
| -rw-r--r-- | src/dns/nm-dns-manager.c | 88 | ||||
| -rw-r--r-- | src/dns/nm-dns-systemd-resolved.c | 123 |
3 files changed, 136 insertions, 107 deletions
diff --git a/src/dns/nm-dns-dnsmasq.c b/src/dns/nm-dns-dnsmasq.c index a6204ae4..3ec1fd2d 100644 --- a/src/dns/nm-dns-dnsmasq.c +++ b/src/dns/nm-dns-dnsmasq.c @@ -80,22 +80,20 @@ get_ip4_rdns_domains (NMIP4Config *ip4) { char **strv; GPtrArray *domains = NULL; - int i; + NMDedupMultiIter ipconf_iter; + const NMPlatformIP4Address *address; + const NMPlatformIP4Route *route; g_return_val_if_fail (ip4 != NULL, NULL); domains = g_ptr_array_sized_new (5); - for (i = 0; i < nm_ip4_config_get_num_addresses (ip4); i++) { - const NMPlatformIP4Address *address = nm_ip4_config_get_address (ip4, i); - + nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, ip4, &address) nm_utils_get_reverse_dns_domains_ip4 (address->address, address->plen, domains); - } - - for (i = 0; i < nm_ip4_config_get_num_routes (ip4); i++) { - const NMPlatformIP4Route *route = nm_ip4_config_get_route (ip4, i); - nm_utils_get_reverse_dns_domains_ip4 (route->network, route->plen, domains); + nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, ip4, &route) { + if (!NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)) + nm_utils_get_reverse_dns_domains_ip4 (route->network, route->plen, domains); } /* Terminating NULL so we can use g_strfreev() to free it */ @@ -112,22 +110,20 @@ get_ip6_rdns_domains (NMIP6Config *ip6) { char **strv; GPtrArray *domains = NULL; - int i; + NMDedupMultiIter ipconf_iter; + const NMPlatformIP6Address *address; + const NMPlatformIP6Route *route; g_return_val_if_fail (ip6 != NULL, NULL); domains = g_ptr_array_sized_new (5); - for (i = 0; i < nm_ip6_config_get_num_addresses (ip6); i++) { - const NMPlatformIP6Address *address = nm_ip6_config_get_address (ip6, i); - + nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, ip6, &address) nm_utils_get_reverse_dns_domains_ip6 (&address->address, address->plen, domains); - } - - for (i = 0; i < nm_ip6_config_get_num_routes (ip6); i++) { - const NMPlatformIP6Route *route = nm_ip6_config_get_route (ip6, i); - nm_utils_get_reverse_dns_domains_ip6 (&route->network, route->plen, domains); + nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, ip6, &route) { + if (!NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)) + nm_utils_get_reverse_dns_domains_ip6 (&route->network, route->plen, domains); } /* Terminating NULL so we can use g_strfreev() to free it */ diff --git a/src/dns/nm-dns-manager.c b/src/dns/nm-dns-manager.c index 952468e3..d5392b7d 100644 --- a/src/dns/nm-dns-manager.c +++ b/src/dns/nm-dns-manager.c @@ -497,7 +497,7 @@ dispatch_netconfig (NMDnsManager *self, g_free (str); } - close (fd); + nm_close (fd); /* Wait until the process exits */ if (!nm_utils_kill_child_sync (pid, 0, LOGD_DNS, "netconfig", &status, 1000, 0)) { @@ -1167,9 +1167,16 @@ update_dns (NMDnsManager *self, * but only uses the local caching nameserver. */ if (caching) { + const char *lladdr = "127.0.0.1"; + + if (NM_IS_DNS_SYSTEMD_RESOLVED (priv->plugin)) { + /* systemd-resolved uses a different link-local address */ + lladdr = "127.0.0.53"; + } + g_strfreev (nameservers); - nameservers = g_new0 (char*, 2); - nameservers[0] = g_strdup ("127.0.0.1"); + nameservers = g_new0 (char *, 2); + nameservers[0] = g_strdup (lladdr); } if (update) { @@ -1427,6 +1434,7 @@ nm_dns_manager_set_initial_hostname (NMDnsManager *self, { NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self); + g_free (priv->hostname); priv->hostname = g_strdup (hostname); } @@ -1625,7 +1633,7 @@ _check_resconf_immutable (NMDnsManagerResolvConfManager rc_manager) if (fd != -1) { if (ioctl (fd, FS_IOC_GETFLAGS, &flags) != -1) immutable = NM_FLAGS_HAS (flags, FS_IMMUTABLE_FL); - close (fd); + nm_close (fd); } return immutable ? NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE : rc_manager; } @@ -1634,32 +1642,68 @@ _check_resconf_immutable (NMDnsManagerResolvConfManager rc_manager) static gboolean _resolvconf_resolved_managed (void) { - static const char *const resolved_paths[] = { + static const char *const RESOLVED_PATHS[] = { "/run/systemd/resolve/resolv.conf", "/lib/systemd/resolv.conf", "/usr/lib/systemd/resolv.conf", }; - GFile *f; - GFileInfo *info; - gboolean ret = FALSE; + struct stat st, st_test; + guint i; - f = g_file_new_for_path (_PATH_RESCONF); - info = g_file_query_info (f, - G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK","\ - G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - NULL, NULL); + if (lstat (_PATH_RESCONF, &st) != 0) + return FALSE; - if (info && g_file_info_get_is_symlink (info)) { - ret = nm_utils_strv_find_first ((gchar **) resolved_paths, - G_N_ELEMENTS (resolved_paths), - g_file_info_get_symlink_target (info)) >= 0; - } + if (S_ISLNK (st.st_mode)) { + gs_free char *full_path = NULL; + nm_auto_free char *real_path = NULL; + + /* see if resolv.conf is a symlink with a target that is + * exactly like one of the candidates. + * + * This check will work for symlinks, even if the target + * does not exist and realpath() cannot resolve anything. + * + * We want to handle that, because systemd-resolved might not + * have started yet. */ + full_path = g_file_read_link (_PATH_RESCONF, NULL); + if (nm_utils_strv_find_first ((char **) RESOLVED_PATHS, + G_N_ELEMENTS (RESOLVED_PATHS), + full_path) >= 0) + return TRUE; + + /* see if resolv.conf is a symlink that resolves exactly one + * of the candidate paths. + * + * This check will work for symlinks that can be resolved + * to a realpath, but the actual file might not exist. + * + * We want to handle that, because systemd-resolved might not + * have started yet. */ + real_path = realpath (_PATH_RESCONF, NULL); + if (nm_utils_strv_find_first ((char **) RESOLVED_PATHS, + G_N_ELEMENTS (RESOLVED_PATHS), + real_path) >= 0) + return TRUE; - g_clear_object(&info); - g_clear_object(&f); + /* fall-through and resolve the symlink, to check the file + * it points to (below). + * + * This check is the most reliable, but it only works if + * systemd-resolved already started and created the file. */ + if (stat (_PATH_RESCONF, &st) != 0) + return FALSE; + } + + /* see if resolv.conf resolves to one of the candidate + * paths (or whether it is hard-linked). */ + for (i = 0; i < G_N_ELEMENTS (RESOLVED_PATHS); i++) { + if ( stat (RESOLVED_PATHS[i], &st_test) == 0 + && st.st_dev == st_test.st_dev + && st.st_ino == st_test.st_ino) + return TRUE; + } - return ret; + return FALSE; } static void diff --git a/src/dns/nm-dns-systemd-resolved.c b/src/dns/nm-dns-systemd-resolved.c index fce1fef1..315f2c4d 100644 --- a/src/dns/nm-dns-systemd-resolved.c +++ b/src/dns/nm-dns-systemd-resolved.c @@ -136,81 +136,75 @@ add_interface_configuration (NMDnsSystemdResolved *self, } static void -add_domain (GVariantBuilder *domains, - const char *domain, - gboolean never_default) -{ - /* If this link is never the default (e.g. only used for resources on this - * network) add a routing domain. */ - g_variant_builder_add (domains, "(sb)", domain, never_default); -} - -static void -update_add_ip6_config (NMDnsSystemdResolved *self, - GVariantBuilder *dns, - GVariantBuilder *domains, - const NMIP6Config *config) +update_add_ip_config (NMDnsSystemdResolved *self, + GVariantBuilder *dns, + GVariantBuilder *domains, + gpointer config) { + int addr_family; + gsize addr_size; guint i, n; + gboolean route_only; - n = nm_ip6_config_get_num_nameservers (config); - for (i = 0 ; i < n; i++) { - const struct in6_addr *ip; - - g_variant_builder_open (dns, G_VARIANT_TYPE ("(iay)")); - g_variant_builder_add (dns, "i", AF_INET6); - ip = nm_ip6_config_get_nameserver (config, i), - - g_variant_builder_add_value (dns, g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, ip, 16, 1)); - g_variant_builder_close (dns); - } - - n = nm_ip6_config_get_num_searches (config); - if (n > 0) { - for (i = 0; i < n; i++) { - add_domain (domains, nm_ip6_config_get_search (config, i), - nm_ip6_config_get_never_default (config)); - } - } else { - n = nm_ip6_config_get_num_domains (config); - for (i = 0; i < n; i++) { - add_domain (domains, nm_ip6_config_get_domain (config, i), - nm_ip6_config_get_never_default (config)); - } - } -} + 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 (); -static void -update_add_ip4_config (NMDnsSystemdResolved *self, - GVariantBuilder *dns, - GVariantBuilder *domains, - const NMIP4Config *config) -{ - guint i, n; + addr_size = nm_utils_addr_family_to_size (addr_family); - n = nm_ip4_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++) { - guint32 ns; + in_addr_t ns4; + gconstpointer ns; - g_variant_builder_open (dns, G_VARIANT_TYPE ("(iay)")); - g_variant_builder_add (dns, "i", AF_INET); - ns = nm_ip4_config_get_nameserver (config, i), + 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_add_value (dns, g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, &ns, 4, 1)); + 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, + addr_size, + 1)); g_variant_builder_close (dns); } - n = nm_ip4_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++) { - add_domain (domains, nm_ip4_config_get_search (config, i), - nm_ip4_config_get_never_default (config)); + 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 = nm_ip4_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++) { - add_domain (domains, nm_ip4_config_get_domain (config, i), - nm_ip4_config_get_never_default (config)); + 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); } } } @@ -243,14 +237,9 @@ 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 != NULL ; l = g_list_next (l)) { - if (NM_IS_IP4_CONFIG (l->data)) - update_add_ip4_config (self, &dns, &domains, l->data); - else if (NM_IS_IP6_CONFIG (l->data)) - update_add_ip6_config (self, &dns, &domains, l->data); - else - g_assert_not_reached (); - } + 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); |