summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2016-01-25 23:19:49 +0100
committerLennart Poettering <lennart@poettering.net>2016-01-26 14:42:04 +0100
commitad44b56b0f4a12a8811b3867f42df7370f2fa8e0 (patch)
tree171629936ad9f4bbe276ce9c8e0c85d5467e93ee
parentd390f8ef2dc0cd041914d3c2fd3e1081605cbfc8 (diff)
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.
-rw-r--r--src/resolve/resolved-bus.c10
-rw-r--r--src/resolve/resolved-dns-query.c13
-rw-r--r--src/resolve/resolved-dns-search-domain.c3
-rw-r--r--src/resolve/resolved-dns-search-domain.h1
-rw-r--r--src/resolve/resolved-link-bus.c52
-rw-r--r--src/resolve/resolved-link.c56
6 files changed, 91 insertions, 44 deletions
diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c
index d8e8638327..834ae837de 100644
--- a/src/resolve/resolved-bus.c
+++ b/src/resolve/resolved-bus.c
@@ -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),
diff --git a/src/resolve/resolved-dns-query.c b/src/resolve/resolved-dns-query.c
index ef977b0948..a00851658e 100644
--- a/src/resolve/resolved-dns-query.c
+++ b/src/resolve/resolved-dns-query.c
@@ -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);
diff --git a/src/resolve/resolved-dns-search-domain.c b/src/resolve/resolved-dns-search-domain.c
index f9d966abb1..356c05b9a4 100644
--- a/src/resolve/resolved-dns-search-domain.c
+++ b/src/resolve/resolved-dns-search-domain.c
@@ -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;
diff --git a/src/resolve/resolved-dns-search-domain.h b/src/resolve/resolved-dns-search-domain.h
index 2e0af31dda..c1903b334f 100644
--- a/src/resolve/resolved-dns-search-domain.h
+++ b/src/resolve/resolved-dns-search-domain.h
@@ -44,6 +44,7 @@ struct DnsSearchDomain {
char *name;
bool marked:1;
+ bool route_only:1;
bool linked:1;
LIST_FIELDS(DnsSearchDomain, domains);
diff --git a/src/resolve/resolved-link-bus.c b/src/resolve/resolved-link-bus.c
index 2ca7ece851..e6b087f412 100644
--- a/src/resolve/resolved-link-bus.c
+++ b/src/resolve/resolved-link-bus.c
@@ -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) {
+ r = sd_bus_message_rewind(message, false);
+ if (r < 0)
+ return r;
+
+ for (;;) {
DnsSearchDomain *d;
+ const char *name;
+ int route_only;
- r = dns_search_domain_find(l->search_domains, *i, &d);
+ 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),
diff --git a/src/resolve/resolved-link.c b/src/resolve/resolved-link.c
index 8f0afc185b..37dd4a6e78 100644
--- a/src/resolve/resolved-link.c
+++ b/src/resolve/resolved-link.c
@@ -377,38 +377,60 @@ clear:
return r;
}
+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 **domains = NULL;
+ _cleanup_strv_free_ char **sdomains = NULL, **rdomains = NULL;
char **i;
- int r;
+ 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);