mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-10-27 18:55:09 +03:00
resolved: teach resolved the difference between "routing" and "search" domains
Following the changes to expose the "routing" and "search" domain concepts in networkd, actually make resolved use them. It will now use routing domains exclusively for making DNS routing decisions, and use search domains additionally for extending single-label names.
This commit is contained in:
parent
d390f8ef2d
commit
ad44b56b0f
@ -1217,19 +1217,19 @@ static int bus_property_get_search_domains(
|
||||
assert(reply);
|
||||
assert(m);
|
||||
|
||||
r = sd_bus_message_open_container(reply, 'a', "(is)");
|
||||
r = sd_bus_message_open_container(reply, 'a', "(isb)");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
LIST_FOREACH(domains, d, m->search_domains) {
|
||||
r = sd_bus_message_append(reply, "(is)", 0, d->name);
|
||||
r = sd_bus_message_append(reply, "(isb)", 0, d->name, d->route_only);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
HASHMAP_FOREACH(l, m->links, i) {
|
||||
LIST_FOREACH(domains, d, l->search_domains) {
|
||||
r = sd_bus_message_append(reply, "is", l->ifindex, d->name);
|
||||
r = sd_bus_message_append(reply, "(isb)", l->ifindex, d->name, d->route_only);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -1450,7 +1450,7 @@ static const sd_bus_vtable resolve_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
SD_BUS_PROPERTY("LLMNRHostname", "s", NULL, offsetof(Manager, llmnr_hostname), 0),
|
||||
SD_BUS_PROPERTY("DNS", "a(iiay)", bus_property_get_dns_servers, 0, 0),
|
||||
SD_BUS_PROPERTY("Domains", "a(is)", bus_property_get_search_domains, 0, 0),
|
||||
SD_BUS_PROPERTY("SearchDomains", "a(isb)", bus_property_get_search_domains, 0, 0),
|
||||
SD_BUS_PROPERTY("TransactionStatistics", "(tt)", bus_property_get_transaction_statistics, 0, 0),
|
||||
SD_BUS_PROPERTY("CacheStatistics", "(ttt)", bus_property_get_cache_statistics, 0, 0),
|
||||
SD_BUS_PROPERTY("DNSSECStatistics", "(tttt)", bus_property_get_dnssec_statistics, 0, 0),
|
||||
@ -1463,7 +1463,7 @@ static const sd_bus_vtable resolve_vtable[] = {
|
||||
SD_BUS_METHOD("ResetStatistics", NULL, NULL, bus_method_reset_statistics, 0),
|
||||
SD_BUS_METHOD("GetLink", "i", "o", bus_method_get_link, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("SetLinkDNS", "ia(iay)", NULL, bus_method_set_link_dns_servers, 0),
|
||||
SD_BUS_METHOD("SetLinkDomains", "ias", NULL, bus_method_set_link_search_domains, 0),
|
||||
SD_BUS_METHOD("SetLinkDomains", "ia(sb)", NULL, bus_method_set_link_search_domains, 0),
|
||||
SD_BUS_METHOD("SetLinkLLMNR", "is", NULL, bus_method_set_link_llmnr, 0),
|
||||
SD_BUS_METHOD("SetLinkMulticastDNS", "is", NULL, bus_method_set_link_mdns, 0),
|
||||
SD_BUS_METHOD("SetLinkDNSSEC", "is", NULL, bus_method_set_link_dnssec, 0),
|
||||
|
@ -93,17 +93,20 @@ static int dns_query_candidate_next_search_domain(DnsQueryCandidate *c) {
|
||||
|
||||
assert(c);
|
||||
|
||||
if (c->search_domain && c->search_domain->linked) {
|
||||
if (c->search_domain && c->search_domain->linked)
|
||||
next = c->search_domain->domains_next;
|
||||
else
|
||||
next = dns_scope_get_search_domains(c->scope);
|
||||
|
||||
for (;;) {
|
||||
if (!next) /* We hit the end of the list */
|
||||
return 0;
|
||||
|
||||
} else {
|
||||
next = dns_scope_get_search_domains(c->scope);
|
||||
if (!next->route_only)
|
||||
break;
|
||||
|
||||
if (!next) /* OK, there's nothing. */
|
||||
return 0;
|
||||
/* Skip over route-only domains */
|
||||
next = next->domains_next;
|
||||
}
|
||||
|
||||
dns_search_domain_unref(c->search_domain);
|
||||
|
@ -42,9 +42,6 @@ int dns_search_domain_new(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (dns_name_is_root(normalized))
|
||||
return -EINVAL;
|
||||
|
||||
if (l) {
|
||||
if (l->n_search_domains >= LINK_SEARCH_DOMAINS_MAX)
|
||||
return -E2BIG;
|
||||
|
@ -44,6 +44,7 @@ struct DnsSearchDomain {
|
||||
char *name;
|
||||
|
||||
bool marked:1;
|
||||
bool route_only:1;
|
||||
|
||||
bool linked:1;
|
||||
LIST_FIELDS(DnsSearchDomain, domains);
|
||||
|
@ -75,12 +75,12 @@ static int property_get_domains(
|
||||
assert(reply);
|
||||
assert(l);
|
||||
|
||||
r = sd_bus_message_open_container(reply, 'a', "s");
|
||||
r = sd_bus_message_open_container(reply, 'a', "(sb)");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
LIST_FOREACH(domains, d, l->search_domains) {
|
||||
r = sd_bus_message_append(reply, "s", d->name);
|
||||
r = sd_bus_message_append(reply, "(sb)", d->name, d->route_only);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -242,47 +242,71 @@ clear:
|
||||
}
|
||||
|
||||
int bus_link_method_set_search_domains(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||
_cleanup_free_ char **domains = NULL;
|
||||
Link *l = userdata;
|
||||
char **i;
|
||||
int r;
|
||||
|
||||
assert(message);
|
||||
assert(l);
|
||||
|
||||
r = sd_bus_message_read_strv(message, &domains);
|
||||
r = sd_bus_message_enter_container(message, 'a', "(sb)");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
STRV_FOREACH(i, domains) {
|
||||
for (;;) {
|
||||
const char *name;
|
||||
int route_only;
|
||||
|
||||
r = dns_name_is_valid(*i);
|
||||
r = sd_bus_message_read(message, "(sb)", &name, &route_only);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid search domain %s", *i);
|
||||
if (dns_name_is_root(*i))
|
||||
break;
|
||||
|
||||
r = dns_name_is_valid(name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid search domain %s", name);
|
||||
if (!route_only && dns_name_is_root(name))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Root domain is not suitable as search domain");
|
||||
}
|
||||
|
||||
dns_search_domain_mark_all(l->search_domains);
|
||||
|
||||
STRV_FOREACH(i, domains) {
|
||||
DnsSearchDomain *d;
|
||||
r = sd_bus_message_rewind(message, false);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = dns_search_domain_find(l->search_domains, *i, &d);
|
||||
for (;;) {
|
||||
DnsSearchDomain *d;
|
||||
const char *name;
|
||||
int route_only;
|
||||
|
||||
r = sd_bus_message_read(message, "(sb)", &name, &route_only);
|
||||
if (r < 0)
|
||||
goto clear;
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
r = dns_search_domain_find(l->search_domains, name, &d);
|
||||
if (r < 0)
|
||||
goto clear;
|
||||
|
||||
if (r > 0)
|
||||
dns_search_domain_move_back_and_unmark(d);
|
||||
else {
|
||||
r = dns_search_domain_new(l->manager, NULL, DNS_SEARCH_DOMAIN_LINK, l, *i);
|
||||
r = dns_search_domain_new(l->manager, &d, DNS_SEARCH_DOMAIN_LINK, l, name);
|
||||
if (r < 0)
|
||||
goto clear;
|
||||
}
|
||||
|
||||
d->route_only = route_only;
|
||||
}
|
||||
|
||||
r = sd_bus_message_exit_container(message);
|
||||
if (r < 0)
|
||||
goto clear;
|
||||
|
||||
dns_search_domain_unlink_marked(l->search_domains);
|
||||
return sd_bus_reply_method_return(message, NULL);
|
||||
|
||||
@ -430,7 +454,7 @@ const sd_bus_vtable link_vtable[] = {
|
||||
|
||||
SD_BUS_PROPERTY("ScopesMask", "t", property_get_scopes_mask, 0, 0),
|
||||
SD_BUS_PROPERTY("DNS", "a(iay)", property_get_dns, 0, 0),
|
||||
SD_BUS_PROPERTY("Domains", "as", property_get_domains, 0, 0),
|
||||
SD_BUS_PROPERTY("Domains", "a(sb)", property_get_domains, 0, 0),
|
||||
SD_BUS_PROPERTY("LLMNR", "s", property_get_resolve_support, offsetof(Link, llmnr_support), 0),
|
||||
SD_BUS_PROPERTY("MulticastDNS", "s", property_get_resolve_support, offsetof(Link, mdns_support), 0),
|
||||
SD_BUS_PROPERTY("DNSSEC", "s", property_get_dnssec_mode, offsetof(Link, dnssec_mode), 0),
|
||||
@ -438,7 +462,7 @@ const sd_bus_vtable link_vtable[] = {
|
||||
SD_BUS_PROPERTY("DNSSECSupport", "b", property_get_dnssec_supported, 0, 0),
|
||||
|
||||
SD_BUS_METHOD("SetDNS", "a(iay)", NULL, bus_link_method_set_dns_servers, 0),
|
||||
SD_BUS_METHOD("SetDomains", "as", NULL, bus_link_method_set_search_domains, 0),
|
||||
SD_BUS_METHOD("SetDomains", "a(sb)", NULL, bus_link_method_set_search_domains, 0),
|
||||
SD_BUS_METHOD("SetLLMNR", "s", NULL, bus_link_method_set_llmnr, 0),
|
||||
SD_BUS_METHOD("SetMulticastDNS", "s", NULL, bus_link_method_set_mdns, 0),
|
||||
SD_BUS_METHOD("SetDNSSEC", "s", NULL, bus_link_method_set_dnssec, 0),
|
||||
|
@ -377,38 +377,60 @@ clear:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int link_update_search_domains(Link *l) {
|
||||
_cleanup_strv_free_ char **domains = NULL;
|
||||
char **i;
|
||||
static int link_update_search_domain_one(Link *l, const char *name, bool route_only) {
|
||||
DnsSearchDomain *d;
|
||||
int r;
|
||||
|
||||
r = dns_search_domain_find(l->search_domains, name, &d);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r > 0)
|
||||
dns_search_domain_move_back_and_unmark(d);
|
||||
else {
|
||||
r = dns_search_domain_new(l->manager, &d, DNS_SEARCH_DOMAIN_LINK, l, name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
d->route_only = route_only;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int link_update_search_domains(Link *l) {
|
||||
_cleanup_strv_free_ char **sdomains = NULL, **rdomains = NULL;
|
||||
char **i;
|
||||
int r, q;
|
||||
|
||||
assert(l);
|
||||
|
||||
r = sd_network_link_get_search_domains(l->ifindex, &domains);
|
||||
if (r == -ENODATA) {
|
||||
r = sd_network_link_get_search_domains(l->ifindex, &sdomains);
|
||||
if (r < 0 && r != -ENODATA)
|
||||
goto clear;
|
||||
|
||||
q = sd_network_link_get_route_domains(l->ifindex, &rdomains);
|
||||
if (q < 0 && q != -ENODATA) {
|
||||
r = q;
|
||||
goto clear;
|
||||
}
|
||||
|
||||
if (r == -ENODATA && q == -ENODATA) {
|
||||
/* networkd knows nothing about this interface, and that's fine. */
|
||||
r = 0;
|
||||
goto clear;
|
||||
}
|
||||
if (r < 0)
|
||||
goto clear;
|
||||
|
||||
dns_search_domain_mark_all(l->search_domains);
|
||||
|
||||
STRV_FOREACH(i, domains) {
|
||||
DnsSearchDomain *d;
|
||||
|
||||
r = dns_search_domain_find(l->search_domains, *i, &d);
|
||||
STRV_FOREACH(i, sdomains) {
|
||||
r = link_update_search_domain_one(l, *i, false);
|
||||
if (r < 0)
|
||||
goto clear;
|
||||
}
|
||||
|
||||
if (r > 0)
|
||||
dns_search_domain_move_back_and_unmark(d);
|
||||
else {
|
||||
r = dns_search_domain_new(l->manager, NULL, DNS_SEARCH_DOMAIN_LINK, l, *i);
|
||||
if (r < 0)
|
||||
goto clear;
|
||||
}
|
||||
STRV_FOREACH(i, rdomains) {
|
||||
r = link_update_search_domain_one(l, *i, true);
|
||||
if (r < 0)
|
||||
goto clear;
|
||||
}
|
||||
|
||||
dns_search_domain_unlink_marked(l->search_domains);
|
||||
|
Loading…
Reference in New Issue
Block a user