diff options
author | Lennart Poettering <lennart@poettering.net> | 2014-08-01 16:04:12 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2014-08-01 16:06:39 +0200 |
commit | 4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4 (patch) | |
tree | b36f290a2aeda5bfb77d20b2953898c3d3c36382 /src/resolve/resolved-conf.c | |
parent | e70df46b9721a3d025e7a0b4ffb5893cbde5e55d (diff) |
resolved: beef up DNS server configuration logic
We now maintain two lists of DNS servers: system servers and fallback
servers.
system servers are used in combination with any per-link servers.
fallback servers are only used if there are no system servers or
per-link servers configured.
The system server list is supposed to be populated from a foreign tool's
/etc/resolv.conf (not implemented yet).
Also adds a configuration switch for LLMNR, that allows configuring
whether LLMNR shall be used simply for resolving or also for responding.
Diffstat (limited to 'src/resolve/resolved-conf.c')
-rw-r--r-- | src/resolve/resolved-conf.c | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/src/resolve/resolved-conf.c b/src/resolve/resolved-conf.c new file mode 100644 index 0000000000..0def80e3a5 --- /dev/null +++ b/src/resolve/resolved-conf.c @@ -0,0 +1,157 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2014 Tom Gundersen <teg@jklm.no> + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. + ***/ + +#include "conf-parser.h" + +#include "resolved-conf.h" + +int manager_parse_dns_server(Manager *m, DnsServerType type, const char *string) { + const char *word, *state; + size_t length; + DnsServer *first; + int r; + + assert(m); + assert(string); + + first = type == DNS_SERVER_FALLBACK ? m->fallback_dns_servers : m->dns_servers; + + FOREACH_WORD_QUOTED(word, length, string, state) { + char buffer[length+1]; + int family; + union in_addr_union addr; + bool found = false; + DnsServer *s; + + memcpy(buffer, word, length); + buffer[length] = 0; + + r = in_addr_from_string_auto(buffer, &family, &addr); + if (r < 0) { + log_warning("Ignoring invalid DNS address '%s'", buffer); + continue; + } + + /* Filter out duplicates */ + LIST_FOREACH(servers, s, first) + if (s->family == family && in_addr_equal(family, &s->address, &addr)) { + found = true; + break; + } + + if (found) + continue; + + r = dns_server_new(m, NULL, type, NULL, family, &addr); + if (r < 0) + return r; + } + + return 0; +} + +int config_parse_dnsv( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Manager *m = userdata; + DnsServer **l; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(m); + + if (ltype == DNS_SERVER_FALLBACK) + l = &m->fallback_dns_servers; + else + l = &m->dns_servers; + + /* Empty assignment means clear the list */ + if (isempty(rvalue)) { + while (*l) + dns_server_free(*l); + + return 0; + } + + r = manager_parse_dns_server(m, ltype, rvalue); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to parse DNS server string '%s'. Ignoring.", rvalue); + return 0; + } + + return 0; +} + +int config_parse_support( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Manager *m = userdata; + Support support, *v = data; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(m); + + support = support_from_string(rvalue); + if (support < 0) { + r = parse_boolean(rvalue); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to parse support level '%s'. Ignoring.", rvalue); + return 0; + } + + support = r ? SUPPORT_YES : SUPPORT_NO; + } + + *v = support; + return 0; +} + +int manager_parse_config_file(Manager *m) { + assert(m); + + return config_parse(NULL, "/etc/systemd/resolved.conf", NULL, + "Resolve\0", + config_item_perf_lookup, resolved_gperf_lookup, + false, false, true, m); +} |