diff options
Diffstat (limited to 'src/resolve')
-rw-r--r-- | src/resolve/resolved-conf.c | 40 | ||||
-rw-r--r-- | src/resolve/resolved-conf.h | 2 | ||||
-rw-r--r-- | src/resolve/resolved-dns-server.c | 11 | ||||
-rw-r--r-- | src/resolve/resolved-manager.c | 23 | ||||
-rw-r--r-- | src/resolve/resolved-manager.h | 1 | ||||
-rw-r--r-- | src/resolve/resolved-resolv-conf.c | 3 |
6 files changed, 46 insertions, 34 deletions
diff --git a/src/resolve/resolved-conf.c b/src/resolve/resolved-conf.c index a4e44f29be..7873c363b3 100644 --- a/src/resolve/resolved-conf.c +++ b/src/resolve/resolved-conf.c @@ -35,15 +35,16 @@ static int manager_add_dns_server_by_string(Manager *m, DnsServerType type, cons if (r < 0) return r; - /* Silently filter out 0.0.0.0, 127.0.0.53, 127.0.0.54 (our own stub DNS listener) */ - if (!dns_server_address_valid(family, &address)) - return 0; - - /* By default, the port number is determined with the transaction feature level. + /* By default, the port number is determined by the transaction feature level. * See dns_transaction_port() and dns_server_port(). */ if (IN_SET(port, 53, 853)) port = 0; + /* Refuse 0.0.0.0, 127.0.0.53, 127.0.0.54 and the rest of our own stub DNS listeners. */ + if (!dns_server_address_valid(family, &address) || + manager_server_address_is_stub(m, family, &address, port ?: 53)) + return -ELOOP; + /* Filter out duplicates */ s = dns_server_find(manager_get_first_dns_server(m, type), family, &address, port, ifindex, server_name); if (s) { @@ -56,7 +57,7 @@ static int manager_add_dns_server_by_string(Manager *m, DnsServerType type, cons return dns_server_new(m, NULL, type, NULL, family, &address, port, ifindex, server_name); } -int manager_parse_dns_server_string_and_warn(Manager *m, DnsServerType type, const char *string) { +int manager_parse_dns_server_string_and_warn(Manager *m, DnsServerType type, const char *string, bool ignore_self_quietly) { int r; assert(m); @@ -66,17 +67,16 @@ int manager_parse_dns_server_string_and_warn(Manager *m, DnsServerType type, con _cleanup_free_ char *word = NULL; r = extract_first_word(&string, &word, NULL, 0); - if (r < 0) + if (r <= 0) return r; - if (r == 0) - break; r = manager_add_dns_server_by_string(m, type, word); - if (r < 0) + if (r == -ELOOP) + log_full(ignore_self_quietly ? LOG_DEBUG : LOG_INFO, + "DNS server string '%s' points to our own listener, ignoring.", word); + else if (r < 0) log_warning_errno(r, "Failed to add DNS server address '%s', ignoring: %m", word); } - - return 0; } static int manager_add_search_domain_by_string(Manager *m, const char *domain) { @@ -121,17 +121,13 @@ int manager_parse_search_domains_and_warn(Manager *m, const char *string) { _cleanup_free_ char *word = NULL; r = extract_first_word(&string, &word, NULL, EXTRACT_UNQUOTE); - if (r < 0) + if (r <= 0) return r; - if (r == 0) - break; r = manager_add_search_domain_by_string(m, word); if (r < 0) log_warning_errno(r, "Failed to add search domain '%s', ignoring: %m", word); } - - return 0; } int config_parse_dns_servers( @@ -159,7 +155,7 @@ int config_parse_dns_servers( dns_server_unlink_all(manager_get_first_dns_server(m, ltype)); else { /* Otherwise, add to the list */ - r = manager_parse_dns_server_string_and_warn(m, ltype, rvalue); + r = manager_parse_dns_server_string_and_warn(m, ltype, rvalue, false); if (r < 0) { log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse DNS server string '%s', ignoring.", rvalue); @@ -167,8 +163,7 @@ int config_parse_dns_servers( } } - /* If we have a manual setting, then we stop reading - * /etc/resolv.conf */ + /* If we have a manual setting, then we stop reading /etc/resolv.conf */ if (ltype == DNS_SERVER_SYSTEM) m->read_resolv_conf = false; if (ltype == DNS_SERVER_FALLBACK) @@ -210,8 +205,7 @@ int config_parse_search_domains( } } - /* If we have a manual setting, then we stop reading - * /etc/resolv.conf */ + /* If we have a manual setting, then we stop reading /etc/resolv.conf */ m->read_resolv_conf = false; return 0; @@ -493,7 +487,7 @@ int manager_parse_config_file(Manager *m) { return r; if (m->need_builtin_fallbacks) { - r = manager_parse_dns_server_string_and_warn(m, DNS_SERVER_FALLBACK, DNS_SERVERS); + r = manager_parse_dns_server_string_and_warn(m, DNS_SERVER_FALLBACK, DNS_SERVERS, false); if (r < 0) return r; } diff --git a/src/resolve/resolved-conf.h b/src/resolve/resolved-conf.h index 07ce2591a9..4639cefbd8 100644 --- a/src/resolve/resolved-conf.h +++ b/src/resolve/resolved-conf.h @@ -8,7 +8,7 @@ int manager_parse_config_file(Manager *m); int manager_parse_search_domains_and_warn(Manager *m, const char *string); -int manager_parse_dns_server_string_and_warn(Manager *m, DnsServerType type, const char *string); +int manager_parse_dns_server_string_and_warn(Manager *m, DnsServerType type, const char *string, bool ignore_self_quietly); const struct ConfigPerfItem* resolved_gperf_lookup(const char *key, GPERF_LEN_TYPE length); const struct ConfigPerfItem* resolved_dnssd_gperf_lookup(const char *key, GPERF_LEN_TYPE length); diff --git a/src/resolve/resolved-dns-server.c b/src/resolve/resolved-dns-server.c index 7d180378b6..cd755b13d4 100644 --- a/src/resolve/resolved-dns-server.c +++ b/src/resolve/resolved-dns-server.c @@ -875,9 +875,18 @@ DnsServer *manager_get_dns_server(Manager *m) { manager_read_resolv_conf(m); /* If no DNS server was chosen so far, pick the first one */ - if (!m->current_dns_server) + if (!m->current_dns_server || + /* In case m->current_dns_server != m->dns_servers */ + manager_server_is_stub(m, m->current_dns_server)) manager_set_dns_server(m, m->dns_servers); + while (m->current_dns_server && + manager_server_is_stub(m, m->current_dns_server)) { + manager_next_dns_server(m, NULL); + if (m->current_dns_server == m->dns_servers) + manager_set_dns_server(m, NULL); + } + if (!m->current_dns_server) { bool found = false; diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c index 6b32ee4cf0..223ef36691 100644 --- a/src/resolve/resolved-manager.c +++ b/src/resolve/resolved-manager.c @@ -1620,30 +1620,37 @@ bool manager_next_dnssd_names(Manager *m) { return tried; } -bool manager_server_is_stub(Manager *m, DnsServer *s) { +bool manager_server_address_is_stub(Manager *m, int family, const union in_addr_union *address, uint16_t port) { DnsStubListenerExtra *l; assert(m); - assert(s); + assert(address); /* Safety check: we generally already skip the main stub when parsing configuration. But let's be * extra careful, and check here again */ - if (s->family == AF_INET && - s->address.in.s_addr == htobe32(INADDR_DNS_STUB) && - dns_server_port(s) == 53) + if (family == AF_INET && + address->in.s_addr == htobe32(INADDR_DNS_STUB) && + port == 53) return true; /* Main reason to call this is to check server data against the extra listeners, and filter things * out. */ ORDERED_SET_FOREACH(l, m->dns_extra_stub_listeners) - if (s->family == l->family && - in_addr_equal(s->family, &s->address, &l->address) && - dns_server_port(s) == dns_stub_listener_extra_port(l)) + if (family == l->family && + in_addr_equal(family, address, &l->address) && + port == dns_stub_listener_extra_port(l)) return true; return false; } +bool manager_server_is_stub(Manager *m, DnsServer *s) { + assert(m); + assert(s); + + return manager_server_address_is_stub(m, s->family, &s->address, dns_server_port(s)); +} + int socket_disable_pmtud(int fd, int af) { int r; diff --git a/src/resolve/resolved-manager.h b/src/resolve/resolved-manager.h index 35e0068a83..e969738978 100644 --- a/src/resolve/resolved-manager.h +++ b/src/resolve/resolved-manager.h @@ -207,6 +207,7 @@ void manager_cleanup_saved_user(Manager *m); bool manager_next_dnssd_names(Manager *m); +bool manager_server_address_is_stub(Manager *m, int family, const union in_addr_union *address, uint16_t port); bool manager_server_is_stub(Manager *m, DnsServer *s); int socket_disable_pmtud(int fd, int af); diff --git a/src/resolve/resolved-resolv-conf.c b/src/resolve/resolved-resolv-conf.c index 100894d6b2..e9785ab964 100644 --- a/src/resolve/resolved-resolv-conf.c +++ b/src/resolve/resolved-resolv-conf.c @@ -143,7 +143,8 @@ int manager_read_resolv_conf(Manager *m) { a = first_word(l, "nameserver"); if (a) { - r = manager_parse_dns_server_string_and_warn(m, DNS_SERVER_SYSTEM, a); + r = manager_parse_dns_server_string_and_warn(m, DNS_SERVER_SYSTEM, a, + true /* don't warn about loops to our own stub listeners */); if (r < 0) log_warning_errno(r, "Failed to parse DNS server address '%s', ignoring.", a); |