mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-23 17:34:00 +03:00
Merge pull request #20559 from tomty89/stub_check_in_get
resolved: filter stub listeners in manager_get_dns_server()
This commit is contained in:
commit
1c9b72f38e
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user