diff options
| author | Michael Biebl <biebl@debian.org> | 2023-08-09 21:55:35 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2023-08-09 21:55:35 +0200 |
| commit | 05e4a733f2141995181a551854d5df929f084adf (patch) | |
| tree | 83bb937740a6667525ba0df046748ecaa829c269 /src/core/dns/nm-dns-manager.c | |
| parent | 14b0f3a9dc9ea90d60a3b057350fd4d637dc021a (diff) | |
New upstream version 1.44.0 upstream/1.44.0
Diffstat (limited to 'src/core/dns/nm-dns-manager.c')
| -rw-r--r-- | src/core/dns/nm-dns-manager.c | 90 |
1 files changed, 78 insertions, 12 deletions
diff --git a/src/core/dns/nm-dns-manager.c b/src/core/dns/nm-dns-manager.c index 6ee2e816..53564693 100644 --- a/src/core/dns/nm-dns-manager.c +++ b/src/core/dns/nm-dns-manager.c @@ -125,6 +125,9 @@ typedef struct { NMConfig *config; + NMDnsConfigIPData *best_ip_config_4; + NMDnsConfigIPData *best_ip_config_6; + struct { guint64 ts; guint num_restarts; @@ -173,14 +176,46 @@ NM_DEFINE_SINGLETON_GETTER(NMDnsManager, nm_dns_manager_get, NM_TYPE_DNS_MANAGER /*****************************************************************************/ static gboolean -domain_is_valid(const char *domain, gboolean check_public_suffix) +domain_is_valid(const char *domain, + gboolean reject_public_suffix, + gboolean assume_any_tld_is_public) { if (*domain == '\0') return FALSE; -#if WITH_LIBPSL - if (check_public_suffix && psl_is_public_suffix(psl_builtin(), domain)) - return FALSE; + + if (reject_public_suffix) { + int is_pub; + +#if !WITH_LIBPSL + /* Without libpsl, we cannot detect that the domain is a public suffix, we assume + * the domain is not and valid. */ + is_pub = FALSE; +#elif defined(PSL_TYPE_NO_STAR_RULE) + /* + * If we use PSL_TYPE_ANY, any TLD (top-level domain, i.e., domain + * with no dots) is considered *public* by the PSL library even if + * it is *not* on the official suffix list. This is the implicit + * behavior of the older API function psl_is_public_suffix(). + * To inhibit that and only deem TLDs explicitly listed in the PSL + * as public, we need to turn off the "prevailing star rule" with + * PSL_TYPE_NO_STAR_RULE. + * For documentation on psl_is_public_suffix2(), see: + * https://rockdaboot.github.io/libpsl/libpsl-Public-Suffix-List-functions.html#psl-is-public-suffix2 + * For more on the public suffix format, including wildcards: + * https://github.com/publicsuffix/list/wiki/Format#format + */ + is_pub = + psl_is_public_suffix2(psl_builtin(), + domain, + assume_any_tld_is_public ? PSL_TYPE_ANY : PSL_TYPE_NO_STAR_RULE); +#else + is_pub = psl_is_public_suffix(psl_builtin(), domain); #endif + + if (is_pub) + return FALSE; + } + return TRUE; } @@ -533,7 +568,7 @@ add_dns_domains(GPtrArray *array, str = searches[i]; if (!include_routing && domain_is_routing(str)) continue; - if (!domain_is_valid(nm_utils_parse_dns_domain(str, NULL), FALSE)) + if (!domain_is_valid(nm_utils_parse_dns_domain(str, NULL), FALSE, TRUE)) continue; add_string_item(array, str, dup); } @@ -542,7 +577,7 @@ add_dns_domains(GPtrArray *array, str = domains[i]; if (!include_routing && domain_is_routing(str)) continue; - if (!domain_is_valid(nm_utils_parse_dns_domain(str, NULL), FALSE)) + if (!domain_is_valid(nm_utils_parse_dns_domain(str, NULL), FALSE, TRUE)) continue; add_string_item(array, str, dup); } @@ -647,7 +682,7 @@ run_netconfig(NMDnsManager *self, GError **error, int *stdin_fd) if (!g_spawn_async_with_pipes(NULL, argv, NULL, - G_SPAWN_DO_NOT_REAP_CHILD, + G_SPAWN_CLOEXEC_PIPES | G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, @@ -1236,7 +1271,7 @@ merge_global_dns_config(NMResolvConfData *rc, NMGlobalDnsConfig *global_conf) for (i = 0; searches[i]; i++) { if (domain_is_routing(searches[i])) continue; - if (!domain_is_valid(searches[i], FALSE)) + if (!domain_is_valid(searches[i], FALSE, TRUE)) continue; add_string_item(rc->searches, searches[i], TRUE); } @@ -1946,6 +1981,7 @@ nm_dns_manager_set_ip_config(NMDnsManager *self, NMDnsConfigIPData *ip_data = NULL; int dns_priority; gboolean any_removed = FALSE; + NMDnsConfigIPData **p_best; g_return_val_if_fail(NM_IS_DNS_MANAGER(self), FALSE); g_return_val_if_fail(!l3cd || NM_IS_L3_CONFIG_DATA(l3cd), FALSE); @@ -2013,6 +2049,12 @@ nm_dns_manager_set_ip_config(NMDnsManager *self, } any_removed = TRUE; + + if (priv->best_ip_config_4 == ip_data_iter) + priv->best_ip_config_4 = NULL; + if (priv->best_ip_config_6 == ip_data_iter) + priv->best_ip_config_6 = NULL; + _dns_config_ip_data_free(ip_data_iter); } } @@ -2063,6 +2105,19 @@ nm_dns_manager_set_ip_config(NMDnsManager *self, changed = TRUE; } + p_best = NM_IS_IPv4(addr_family) ? &priv->best_ip_config_4 : &priv->best_ip_config_6; + if (ip_config_type == NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE) { + /* Only one best-device per IP version is allowed */ + 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 (changed) priv->ip_data_lst_need_sort = TRUE; @@ -2100,7 +2155,8 @@ nm_dns_manager_set_hostname(NMDnsManager *self, const char *hostname, gboolean s /* Certain hostnames we don't want to include in resolv.conf 'searches' */ if (hostname && nm_utils_is_specific_hostname(hostname) - && !g_str_has_suffix(hostname, ".in-addr.arpa") && !nm_inet_is_valid(AF_UNSPEC, hostname)) { + && !NM_STR_HAS_SUFFIX(hostname, ".in-addr.arpa") + && !nm_inet_is_valid(AF_UNSPEC, hostname)) { domain = strchr(hostname, '.'); if (domain) { domain++; @@ -2111,11 +2167,16 @@ nm_dns_manager_set_hostname(NMDnsManager *self, const char *hostname, gboolean s * specified, this makes a good default.) However, if the * hostname is the top level of a domain (eg, "example.com"), * then use the hostname itself as the search (since the user - * is unlikely to want "com" as a search domain).a + * is unlikely to want "com" as a search domain). + * + * Because that logic only applies to public domains, the + * "assume_any_tld_is_public" parameter is FALSE. For + * example, it is likely that the user *does* want "local" + * or "localdomain" as a search domain. */ - if (domain_is_valid(domain, TRUE)) { + if (domain_is_valid(domain, TRUE, FALSE)) { /* pass */ - } else if (domain_is_valid(hostname, TRUE)) { + } else if (domain_is_valid(hostname, TRUE, FALSE)) { domain = hostname; } @@ -2127,6 +2188,8 @@ nm_dns_manager_set_hostname(NMDnsManager *self, const char *hostname, gboolean s if (!nm_strdup_reset(&priv->hostdomain, domain)) return; + _LOGT("set host domain to %s%s%s", NM_PRINT_FMT_QUOTE_STRING(priv->hostdomain)); + if (skip_update) return; @@ -2779,6 +2842,9 @@ dispose(GObject *object) nm_clear_g_source_inst(&priv->update_pending_unblock); + priv->best_ip_config_4 = NULL; + priv->best_ip_config_6 = NULL; + c_list_for_each_entry_safe (ip_data, ip_data_safe, &priv->ip_data_lst_head, ip_data_lst) _dns_config_ip_data_free(ip_data); |