diff options
-rw-r--r-- | src/resolve/resolved-bus.c | 10 | ||||
-rw-r--r-- | src/resolve/resolved-dns-query.c | 13 | ||||
-rw-r--r-- | src/resolve/resolved-dns-search-domain.c | 3 | ||||
-rw-r--r-- | src/resolve/resolved-dns-search-domain.h | 1 | ||||
-rw-r--r-- | src/resolve/resolved-link-bus.c | 52 | ||||
-rw-r--r-- | src/resolve/resolved-link.c | 56 |
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); |