return r;
/* If this a single-label domain on DNS, we might append a suitable search domain first. */
- if ((q->flags & SD_RESOLVED_NO_SEARCH) == 0 &&
- dns_scope_name_needs_search_domain(s, dns_question_first_name(q->question_idna))) {
- /* OK, we need a search domain now. Let's find one for this scope */
+ if (!FLAGS_SET(q->flags, SD_RESOLVED_NO_SEARCH) &&
+ dns_scope_name_wants_search_domain(s, dns_question_first_name(q->question_idna))) {
+ /* OK, we want a search domain now. Let's find one for this scope */
r = dns_query_candidate_next_search_domain(c);
- if (r <= 0) /* if there's no search domain, then we won't add any transaction. */
+ if (r < 0)
return r;
}
manager_is_own_hostname(s->manager, domain) <= 0)) /* never resolve the local hostname via LLMNR */
return DNS_SCOPE_YES_BASE + 1; /* Return +1, as we consider ourselves authoritative
* for single-label names, i.e. one label. This is
- * particular relevant as it means a "." route on some
+ * particularly relevant as it means a "." route on some
* other scope won't pull all traffic away from
* us. (If people actually want to pull traffic away
* from us they should turn off LLMNR on the
if (s->protocol == DNS_PROTOCOL_DNS) {
- /* On classic DNS, looking up non-address RRs is always
- * fine. (Specifically, we want to permit looking up
- * DNSKEY and DS records on the root and top-level
- * domains.) */
+ /* On classic DNS, looking up non-address RRs is always fine. (Specifically, we want to
+ * permit looking up DNSKEY and DS records on the root and top-level domains.) */
if (!dns_resource_key_is_address(key))
return true;
- /* However, we refuse to look up A and AAAA RRs on the
- * root and single-label domains, under the assumption
- * that those should be resolved via LLMNR or search
- * path only, and should not be leaked onto the
- * internet. */
- return !(dns_name_is_single_label(dns_resource_key_name(key)) ||
- dns_name_is_root(dns_resource_key_name(key)));
+ /* Unless explicitly overridden, we refuse to look up A and AAAA RRs on the root and
+ * single-label domains, under the assumption that those should be resolved via LLMNR or
+ * search path only, and should not be leaked onto the internet. */
+ const char* name = dns_resource_key_name(key);
+
+ if (!s->manager->resolve_unicast_single_label &&
+ dns_name_is_single_label(name))
+ return false;
+
+ return !dns_name_is_root(name);
}
/* On mDNS and LLMNR, send A and AAAA queries only on the
return s->manager->search_domains;
}
-bool dns_scope_name_needs_search_domain(DnsScope *s, const char *name) {
+bool dns_scope_name_wants_search_domain(DnsScope *s, const char *name) {
assert(s);
if (s->protocol != DNS_PROTOCOL_DNS)
DnsSearchDomain *dns_scope_get_search_domains(DnsScope *s);
-bool dns_scope_name_needs_search_domain(DnsScope *s, const char *name);
+bool dns_scope_name_wants_search_domain(DnsScope *s, const char *name);
bool dns_scope_network_good(DnsScope *s);
%struct-type
%includes
%%
-Resolve.DNS, config_parse_dns_servers, DNS_SERVER_SYSTEM, 0
-Resolve.FallbackDNS, config_parse_dns_servers, DNS_SERVER_FALLBACK, 0
-Resolve.Domains, config_parse_search_domains, 0, 0
-Resolve.LLMNR, config_parse_resolve_support, 0, offsetof(Manager, llmnr_support)
-Resolve.MulticastDNS, config_parse_resolve_support, 0, offsetof(Manager, mdns_support)
-Resolve.DNSSEC, config_parse_dnssec_mode, 0, offsetof(Manager, dnssec_mode)
-Resolve.DNSOverTLS, config_parse_dns_over_tls_mode, 0, offsetof(Manager, dns_over_tls_mode)
-Resolve.Cache, config_parse_dns_cache_mode, DNS_CACHE_MODE_YES, offsetof(Manager, enable_cache)
-Resolve.DNSStubListener, config_parse_dns_stub_listener_mode, 0, offsetof(Manager, dns_stub_listener_mode)
-Resolve.ReadEtcHosts, config_parse_bool, 0, offsetof(Manager, read_etc_hosts)
+Resolve.DNS, config_parse_dns_servers, DNS_SERVER_SYSTEM, 0
+Resolve.FallbackDNS, config_parse_dns_servers, DNS_SERVER_FALLBACK, 0
+Resolve.Domains, config_parse_search_domains, 0, 0
+Resolve.LLMNR, config_parse_resolve_support, 0, offsetof(Manager, llmnr_support)
+Resolve.MulticastDNS, config_parse_resolve_support, 0, offsetof(Manager, mdns_support)
+Resolve.DNSSEC, config_parse_dnssec_mode, 0, offsetof(Manager, dnssec_mode)
+Resolve.DNSOverTLS, config_parse_dns_over_tls_mode, 0, offsetof(Manager, dns_over_tls_mode)
+Resolve.Cache, config_parse_dns_cache_mode, DNS_CACHE_MODE_YES, offsetof(Manager, enable_cache)
+Resolve.DNSStubListener, config_parse_dns_stub_listener_mode, 0, offsetof(Manager, dns_stub_listener_mode)
+Resolve.ReadEtcHosts, config_parse_bool, 0, offsetof(Manager, read_etc_hosts)
+Resolve.ResolveUnicastSingleLabel, config_parse_bool, 0, offsetof(Manager, resolve_unicast_single_label)
bool need_builtin_fallbacks;
bool read_resolv_conf;
+ bool resolve_unicast_single_label;
struct stat resolv_conf_stat;
#Cache=yes
#DNSStubListener=yes
#ReadEtcHosts=yes
+#ResolveUnicastSingleLabel=no