From 9176a57c101d51b4a7fb4141240b5ce03abac57d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 24 Nov 2015 21:55:00 +0100 Subject: [PATCH] resolved: split out calls to compile full list of dns servers and search domains Let's split this out from the resolv.conf parser, so that this becomes generically useful. --- src/resolve/resolved-manager.c | 82 ++++++++++++++++++++++++++++++ src/resolve/resolved-manager.h | 4 ++ src/resolve/resolved-resolv-conf.c | 75 +++++---------------------- 3 files changed, 99 insertions(+), 62 deletions(-) diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c index 31f042e066b..64703ab713e 100644 --- a/src/resolve/resolved-manager.c +++ b/src/resolve/resolved-manager.c @@ -1055,6 +1055,88 @@ int manager_is_own_hostname(Manager *m, const char *name) { return 0; } +int manager_compile_dns_servers(Manager *m, OrderedSet **dns) { + DnsServer *s; + Iterator i; + Link *l; + int r; + + assert(m); + assert(dns); + + r = ordered_set_ensure_allocated(dns, &dns_server_hash_ops); + if (r < 0) + return r; + + /* First add the system-wide servers and domains */ + LIST_FOREACH(servers, s, m->dns_servers) { + r = ordered_set_put(*dns, s); + if (r == -EEXIST) + continue; + if (r < 0) + return r; + } + + /* Then, add the per-link servers */ + HASHMAP_FOREACH(l, m->links, i) { + LIST_FOREACH(servers, s, l->dns_servers) { + r = ordered_set_put(*dns, s); + if (r == -EEXIST) + continue; + if (r < 0) + return r; + } + } + + /* If we found nothing, add the fallback servers */ + if (ordered_set_isempty(*dns)) { + LIST_FOREACH(servers, s, m->fallback_dns_servers) { + r = ordered_set_put(*dns, s); + if (r == -EEXIST) + continue; + if (r < 0) + return r; + } + } + + return 0; +} + +int manager_compile_search_domains(Manager *m, OrderedSet **domains) { + DnsSearchDomain *d; + Iterator i; + Link *l; + int r; + + assert(m); + assert(domains); + + r = ordered_set_ensure_allocated(domains, &dns_name_hash_ops); + if (r < 0) + return r; + + LIST_FOREACH(domains, d, m->search_domains) { + r = ordered_set_put(*domains, d->name); + if (r == -EEXIST) + continue; + if (r < 0) + return r; + } + + HASHMAP_FOREACH(l, m->links, i) { + + LIST_FOREACH(domains, d, l->search_domains) { + r = ordered_set_put(*domains, d->name); + if (r == -EEXIST) + continue; + if (r < 0) + return r; + } + } + + return 0; +} + static const char* const support_table[_SUPPORT_MAX] = { [SUPPORT_NO] = "no", [SUPPORT_YES] = "yes", diff --git a/src/resolve/resolved-manager.h b/src/resolve/resolved-manager.h index 2bbd5d08e96..d00c4445839 100644 --- a/src/resolve/resolved-manager.h +++ b/src/resolve/resolved-manager.h @@ -27,6 +27,7 @@ #include "hashmap.h" #include "list.h" +#include "ordered-set.h" typedef struct Manager Manager; typedef enum Support Support; @@ -148,5 +149,8 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free); int manager_is_own_hostname(Manager *m, const char *name); +int manager_compile_dns_servers(Manager *m, OrderedSet **servers); +int manager_compile_search_domains(Manager *m, OrderedSet **domains); + const char* support_to_string(Support p) _const_; int support_from_string(const char *s) _pure_; diff --git a/src/resolve/resolved-resolv-conf.c b/src/resolve/resolved-resolv-conf.c index f5cce670f0e..744969b7453 100644 --- a/src/resolve/resolved-resolv-conf.c +++ b/src/resolve/resolved-resolv-conf.c @@ -220,14 +220,12 @@ static int write_resolv_conf_contents(FILE *f, OrderedSet *dns, OrderedSet *doma } int manager_write_resolv_conf(Manager *m) { - static const char path[] = "/run/systemd/resolve/resolv.conf"; + + #define PRIVATE_RESOLV_CONF "/run/systemd/resolve/resolv.conf" + + _cleanup_ordered_set_free_ OrderedSet *dns = NULL, *domains = NULL; _cleanup_free_ char *temp_path = NULL; _cleanup_fclose_ FILE *f = NULL; - _cleanup_ordered_set_free_ OrderedSet *dns = NULL, *domains = NULL; - DnsSearchDomain *d; - DnsServer *s; - Iterator i; - Link *l; int r; assert(m); @@ -236,62 +234,15 @@ int manager_write_resolv_conf(Manager *m) { manager_read_resolv_conf(m); /* Add the full list to a set, to filter out duplicates */ - dns = ordered_set_new(&dns_server_hash_ops); - if (!dns) - return -ENOMEM; - - domains = ordered_set_new(&dns_name_hash_ops); - if (!domains) - return -ENOMEM; - - /* First add the system-wide servers and domains */ - LIST_FOREACH(servers, s, m->dns_servers) { - r = ordered_set_put(dns, s); - if (r == -EEXIST) - continue; - if (r < 0) - return r; - } - - LIST_FOREACH(domains, d, m->search_domains) { - r = ordered_set_put(domains, d->name); - if (r == -EEXIST) - continue; - if (r < 0) - return r; - } - - /* Then, add the per-link servers and domains */ - HASHMAP_FOREACH(l, m->links, i) { - LIST_FOREACH(servers, s, l->dns_servers) { - r = ordered_set_put(dns, s); - if (r == -EEXIST) - continue; - if (r < 0) - return r; - } - - LIST_FOREACH(domains, d, l->search_domains) { - r = ordered_set_put(domains, d->name); - if (r == -EEXIST) - continue; - if (r < 0) - return r; - } - } + r = manager_compile_dns_servers(m, &dns); + if (r < 0) + return r; - /* If we found nothing, add the fallback servers */ - if (ordered_set_isempty(dns)) { - LIST_FOREACH(servers, s, m->fallback_dns_servers) { - r = ordered_set_put(dns, s); - if (r == -EEXIST) - continue; - if (r < 0) - return r; - } - } + r = manager_compile_search_domains(m, &domains); + if (r < 0) + return r; - r = fopen_temporary_label(path, path, &f, &temp_path); + r = fopen_temporary_label(PRIVATE_RESOLV_CONF, PRIVATE_RESOLV_CONF, &f, &temp_path); if (r < 0) return r; @@ -301,7 +252,7 @@ int manager_write_resolv_conf(Manager *m) { if (r < 0) goto fail; - if (rename(temp_path, path) < 0) { + if (rename(temp_path, PRIVATE_RESOLV_CONF) < 0) { r = -errno; goto fail; } @@ -309,7 +260,7 @@ int manager_write_resolv_conf(Manager *m) { return 0; fail: - (void) unlink(path); + (void) unlink(PRIVATE_RESOLV_CONF); (void) unlink(temp_path); return r; } -- 2.39.2