2 This file is part of systemd.
4 Copyright 2014 Tom Gundersen <teg@jklm.no>
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 #include "alloc-util.h"
21 #include "conf-parser.h"
23 #include "extract-word.h"
24 #include "parse-util.h"
25 #include "resolved-conf.h"
26 #include "string-table.h"
27 #include "string-util.h"
29 DEFINE_CONFIG_PARSE_ENUM(config_parse_dns_stub_listener_mode
, dns_stub_listener_mode
, DnsStubListenerMode
, "Failed to parse DNS stub listener mode setting");
31 static const char* const dns_stub_listener_mode_table
[_DNS_STUB_LISTENER_MODE_MAX
] = {
32 [DNS_STUB_LISTENER_NO
] = "no",
33 [DNS_STUB_LISTENER_UDP
] = "udp",
34 [DNS_STUB_LISTENER_TCP
] = "tcp",
35 [DNS_STUB_LISTENER_YES
] = "yes",
37 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dns_stub_listener_mode
, DnsStubListenerMode
, DNS_STUB_LISTENER_YES
);
39 int manager_add_dns_server_by_string(Manager
*m
, DnsServerType type
, const char *word
) {
40 union in_addr_union address
;
41 int family
, r
, ifindex
= 0;
47 r
= in_addr_ifindex_from_string_auto(word
, &family
, &address
, &ifindex
);
51 /* Silently filter out 0.0.0.0 and 127.0.0.53 (our own stub DNS listener) */
52 if (!dns_server_address_valid(family
, &address
))
55 /* Filter out duplicates */
56 s
= dns_server_find(manager_get_first_dns_server(m
, type
), family
, &address
, ifindex
);
59 * Drop the marker. This is used to find the servers
60 * that ceased to exist, see
61 * manager_mark_dns_servers() and
62 * manager_flush_marked_dns_servers().
64 dns_server_move_back_and_unmark(s
);
68 return dns_server_new(m
, NULL
, type
, NULL
, family
, &address
, ifindex
);
71 int manager_parse_dns_server_string_and_warn(Manager
*m
, DnsServerType type
, const char *string
) {
78 _cleanup_free_
char *word
= NULL
;
80 r
= extract_first_word(&string
, &word
, NULL
, 0);
86 r
= manager_add_dns_server_by_string(m
, type
, word
);
88 log_warning_errno(r
, "Failed to add DNS server address '%s', ignoring: %m", word
);
94 int manager_add_search_domain_by_string(Manager
*m
, const char *domain
) {
102 route_only
= *domain
== '~';
106 if (dns_name_is_root(domain
) || streq(domain
, "*")) {
111 r
= dns_search_domain_find(m
->search_domains
, domain
, &d
);
115 dns_search_domain_move_back_and_unmark(d
);
117 r
= dns_search_domain_new(m
, &d
, DNS_SEARCH_DOMAIN_SYSTEM
, NULL
, domain
);
122 d
->route_only
= route_only
;
126 int manager_parse_search_domains_and_warn(Manager
*m
, const char *string
) {
133 _cleanup_free_
char *word
= NULL
;
135 r
= extract_first_word(&string
, &word
, NULL
, EXTRACT_QUOTES
);
141 r
= manager_add_search_domain_by_string(m
, word
);
143 log_warning_errno(r
, "Failed to add search domain '%s', ignoring: %m", word
);
149 int config_parse_dns_servers(
151 const char *filename
,
154 unsigned section_line
,
161 Manager
*m
= userdata
;
170 /* Empty assignment means clear the list */
171 dns_server_unlink_all(manager_get_first_dns_server(m
, ltype
));
173 /* Otherwise, add to the list */
174 r
= manager_parse_dns_server_string_and_warn(m
, ltype
, rvalue
);
176 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to parse DNS server string '%s'. Ignoring.", rvalue
);
181 /* If we have a manual setting, then we stop reading
182 * /etc/resolv.conf */
183 if (ltype
== DNS_SERVER_SYSTEM
)
184 m
->read_resolv_conf
= false;
185 if (ltype
== DNS_SERVER_FALLBACK
)
186 m
->need_builtin_fallbacks
= false;
191 int config_parse_search_domains(
193 const char *filename
,
196 unsigned section_line
,
203 Manager
*m
= userdata
;
212 /* Empty assignment means clear the list */
213 dns_search_domain_unlink_all(m
->search_domains
);
215 /* Otherwise, add to the list */
216 r
= manager_parse_search_domains_and_warn(m
, rvalue
);
218 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to parse search domains string '%s'. Ignoring.", rvalue
);
223 /* If we have a manual setting, then we stop reading
224 * /etc/resolv.conf */
225 m
->read_resolv_conf
= false;
230 int manager_parse_config_file(Manager
*m
) {
235 r
= config_parse_many_nulstr(PKGSYSCONFDIR
"/resolved.conf",
236 CONF_PATHS_NULSTR("systemd/resolved.conf.d"),
238 config_item_perf_lookup
, resolved_gperf_lookup
,
243 if (m
->need_builtin_fallbacks
) {
244 r
= manager_parse_dns_server_string_and_warn(m
, DNS_SERVER_FALLBACK
, DNS_SERVERS
);