]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/resolved-conf.c
resolved: make sure order of dns servers is stable
[thirdparty/systemd.git] / src / resolve / resolved-conf.c
CommitLineData
4e945a6f
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2014 Tom Gundersen <teg@jklm.no>
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
b5efdb8a 22#include "alloc-util.h"
4e945a6f 23#include "conf-parser.h"
a0f29c76 24#include "def.h"
b5efdb8a 25#include "extract-word.h"
6bedfcbb 26#include "parse-util.h"
4e945a6f 27#include "resolved-conf.h"
6bedfcbb 28#include "string-util.h"
4e945a6f 29
636e813d
LP
30int manager_add_dns_server_by_string(Manager *m, DnsServerType type, const char *word) {
31 union in_addr_union address;
636e813d 32 int family, r;
0eac4623 33 DnsServer *s;
4e945a6f
LP
34
35 assert(m);
636e813d
LP
36 assert(word);
37
38 r = in_addr_from_string_auto(word, &family, &address);
39 if (r < 0)
40 return r;
4e945a6f 41
636e813d 42 /* Filter out duplicates */
0eac4623 43 s = manager_find_dns_server(m, type, family, &address);
636e813d
LP
44 if (s) {
45 /*
46 * Drop the marker. This is used to find the servers
47 * that ceased to exist, see
48 * manager_mark_dns_servers() and
49 * manager_flush_marked_dns_servers().
50 */
0b58db65 51 dns_server_move_back_and_unmark(s);
636e813d
LP
52 return 0;
53 }
54
55 return dns_server_new(m, NULL, type, NULL, family, &address);
56}
57
58int manager_parse_dns_server_string_and_warn(Manager *m, DnsServerType type, const char *string) {
59 int r;
60
61 assert(m);
62 assert(string);
63
880603a1 64 for(;;) {
b5efdb8a 65 _cleanup_free_ char *word = NULL;
880603a1
SS
66
67 r = extract_first_word(&string, &word, NULL, 0);
68 if (r < 0)
636e813d 69 return r;
880603a1
SS
70 if (r == 0)
71 break;
4e945a6f 72
636e813d 73 r = manager_add_dns_server_by_string(m, type, word);
4e945a6f 74 if (r < 0) {
636e813d 75 log_warning_errno(r, "Failed to add DNS server address '%s', ignoring.", word);
4e945a6f
LP
76 continue;
77 }
4e945a6f
LP
78 }
79
80 return 0;
81}
82
636e813d 83int config_parse_dns_servers(
4e945a6f
LP
84 const char *unit,
85 const char *filename,
86 unsigned line,
87 const char *section,
88 unsigned section_line,
89 const char *lvalue,
90 int ltype,
91 const char *rvalue,
92 void *data,
93 void *userdata) {
94
95 Manager *m = userdata;
4e945a6f
LP
96 int r;
97
98 assert(filename);
99 assert(lvalue);
100 assert(rvalue);
101 assert(m);
102
3e684349 103 if (isempty(rvalue))
5cb36f41 104 /* Empty assignment means clear the list */
3e684349
LP
105 manager_flush_dns_servers(m, ltype);
106 else {
b938cb90 107 /* Otherwise, add to the list */
636e813d 108 r = manager_parse_dns_server_string_and_warn(m, ltype, rvalue);
5cb36f41 109 if (r < 0) {
12ca818f 110 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse DNS server string '%s'. Ignoring.", rvalue);
5cb36f41
LP
111 return 0;
112 }
4e945a6f
LP
113 }
114
5cb36f41
LP
115 /* If we have a manual setting, then we stop reading
116 * /etc/resolv.conf */
117 if (ltype == DNS_SERVER_SYSTEM)
118 m->read_resolv_conf = false;
00fa60ae
LP
119 if (ltype == DNS_SERVER_FALLBACK)
120 m->need_builtin_fallbacks = false;
5cb36f41 121
4e945a6f
LP
122 return 0;
123}
124
125int config_parse_support(
126 const char *unit,
127 const char *filename,
128 unsigned line,
129 const char *section,
130 unsigned section_line,
131 const char *lvalue,
132 int ltype,
133 const char *rvalue,
134 void *data,
135 void *userdata) {
136
4e945a6f
LP
137 Support support, *v = data;
138 int r;
139
140 assert(filename);
141 assert(lvalue);
142 assert(rvalue);
4e945a6f
LP
143
144 support = support_from_string(rvalue);
145 if (support < 0) {
146 r = parse_boolean(rvalue);
147 if (r < 0) {
12ca818f 148 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse support level '%s'. Ignoring.", rvalue);
4e945a6f
LP
149 return 0;
150 }
151
152 support = r ? SUPPORT_YES : SUPPORT_NO;
153 }
154
155 *v = support;
156 return 0;
157}
158
159int manager_parse_config_file(Manager *m) {
00fa60ae
LP
160 int r;
161
4e945a6f
LP
162 assert(m);
163
00fa60ae
LP
164 r = config_parse_many(PKGSYSCONFDIR "/resolved.conf",
165 CONF_PATHS_NULSTR("systemd/resolved.conf.d"),
166 "Resolve\0",
167 config_item_perf_lookup, resolved_gperf_lookup,
168 false, m);
169 if (r < 0)
170 return r;
171
172 if (m->need_builtin_fallbacks) {
173 r = manager_parse_dns_server_string_and_warn(m, DNS_SERVER_FALLBACK, DNS_SERVERS);
174 if (r < 0)
175 return r;
176 }
177
178 return 0;
179
4e945a6f 180}