]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/resolved-manager.c
tree-wide: use TAKE_PTR() and TAKE_FD() macros
[thirdparty/systemd.git] / src / resolve / resolved-manager.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
091a364c
TG
2/***
3 This file is part of systemd.
4
5 Copyright 2014 Tom Gundersen <teg@jklm.no>
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19 ***/
20
07630cea
LP
21#include <netinet/in.h>
22#include <poll.h>
0d536673 23#include <stdio_ext.h>
74b2466e 24#include <sys/ioctl.h>
091a364c 25
349cc4a5 26#if HAVE_LIBIDN2
87057e24
ZJS
27#include <idn2.h>
28#endif
29
a2a416f7 30#include "af-list.h"
b5efdb8a 31#include "alloc-util.h"
943ef07c 32#include "dirent-util.h"
07630cea 33#include "dns-domain.h"
3ffd4af2 34#include "fd-util.h"
a5a807e6 35#include "fileio-label.h"
07630cea 36#include "hostname-util.h"
c004493c 37#include "io-util.h"
07630cea
LP
38#include "netlink-util.h"
39#include "network-internal.h"
822db23c 40#include "ordered-set.h"
6bedfcbb 41#include "parse-util.h"
3df3e884 42#include "random-util.h"
39d8db04 43#include "resolved-bus.h"
07630cea 44#include "resolved-conf.h"
6501dd31 45#include "resolved-dnssd.h"
b30bf55d 46#include "resolved-dns-stub.h"
dd0bc0f1 47#include "resolved-etc-hosts.h"
5f402ae8 48#include "resolved-llmnr.h"
07630cea 49#include "resolved-manager.h"
bc7702b0 50#include "resolved-mdns.h"
dd0bc0f1 51#include "resolved-resolv-conf.h"
07630cea 52#include "socket-util.h"
8b43440b 53#include "string-table.h"
07630cea
LP
54#include "string-util.h"
55#include "utf8.h"
74b2466e
LP
56
57#define SEND_TIMEOUT_USEC (200 * USEC_PER_MSEC)
58
1c4baffc 59static int manager_process_link(sd_netlink *rtnl, sd_netlink_message *mm, void *userdata) {
74b2466e
LP
60 Manager *m = userdata;
61 uint16_t type;
62 Link *l;
63 int ifindex, r;
64
65 assert(rtnl);
66 assert(m);
67 assert(mm);
68
1c4baffc 69 r = sd_netlink_message_get_type(mm, &type);
74b2466e
LP
70 if (r < 0)
71 goto fail;
72
73 r = sd_rtnl_message_link_get_ifindex(mm, &ifindex);
74 if (r < 0)
75 goto fail;
76
77 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
78
79 switch (type) {
80
a2a416f7
LP
81 case RTM_NEWLINK:{
82 bool is_new = !l;
74b2466e 83
a2a416f7 84 if (!l) {
74b2466e
LP
85 r = link_new(m, &l, ifindex);
86 if (r < 0)
87 goto fail;
88 }
89
943ef07c 90 r = link_process_rtnl(l, mm);
74b2466e
LP
91 if (r < 0)
92 goto fail;
93
943ef07c 94 r = link_update(l);
21d73c87
LP
95 if (r < 0)
96 goto fail;
97
a2a416f7
LP
98 if (is_new)
99 log_debug("Found new link %i/%s", ifindex, l->name);
100
74b2466e 101 break;
a2a416f7 102 }
74b2466e
LP
103
104 case RTM_DELLINK:
105 if (l) {
a2a416f7 106 log_debug("Removing link %i/%s", l->ifindex, l->name);
943ef07c 107 link_remove_user(l);
74b2466e
LP
108 link_free(l);
109 }
110
111 break;
112 }
113
114 return 0;
115
116fail:
da927ba9 117 log_warning_errno(r, "Failed to process RTNL link message: %m");
74b2466e
LP
118 return 0;
119}
120
1c4baffc 121static int manager_process_address(sd_netlink *rtnl, sd_netlink_message *mm, void *userdata) {
74b2466e
LP
122 Manager *m = userdata;
123 union in_addr_union address;
74b2466e 124 uint16_t type;
0dd25fb9 125 int r, ifindex, family;
74b2466e
LP
126 LinkAddress *a;
127 Link *l;
128
129 assert(rtnl);
130 assert(mm);
131 assert(m);
132
1c4baffc 133 r = sd_netlink_message_get_type(mm, &type);
74b2466e
LP
134 if (r < 0)
135 goto fail;
136
137 r = sd_rtnl_message_addr_get_ifindex(mm, &ifindex);
138 if (r < 0)
139 goto fail;
140
141 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
142 if (!l)
143 return 0;
144
145 r = sd_rtnl_message_addr_get_family(mm, &family);
146 if (r < 0)
147 goto fail;
148
149 switch (family) {
150
151 case AF_INET:
1c4baffc 152 r = sd_netlink_message_read_in_addr(mm, IFA_LOCAL, &address.in);
74b2466e 153 if (r < 0) {
1c4baffc 154 r = sd_netlink_message_read_in_addr(mm, IFA_ADDRESS, &address.in);
74b2466e
LP
155 if (r < 0)
156 goto fail;
157 }
158
159 break;
160
161 case AF_INET6:
1c4baffc 162 r = sd_netlink_message_read_in6_addr(mm, IFA_LOCAL, &address.in6);
74b2466e 163 if (r < 0) {
1c4baffc 164 r = sd_netlink_message_read_in6_addr(mm, IFA_ADDRESS, &address.in6);
74b2466e
LP
165 if (r < 0)
166 goto fail;
167 }
168
169 break;
170
171 default:
172 return 0;
173 }
174
175 a = link_find_address(l, family, &address);
176
177 switch (type) {
178
179 case RTM_NEWADDR:
180
181 if (!a) {
182 r = link_address_new(l, &a, family, &address);
183 if (r < 0)
184 return r;
185 }
186
187 r = link_address_update_rtnl(a, mm);
188 if (r < 0)
189 return r;
190
191 break;
192
193 case RTM_DELADDR:
3e044c49 194 link_address_free(a);
74b2466e
LP
195 break;
196 }
197
198 return 0;
199
200fail:
da927ba9 201 log_warning_errno(r, "Failed to process RTNL address message: %m");
74b2466e
LP
202 return 0;
203}
204
74b2466e 205static int manager_rtnl_listen(Manager *m) {
4afd3348 206 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
1c4baffc 207 sd_netlink_message *i;
74b2466e
LP
208 int r;
209
210 assert(m);
211
cc98b302 212 /* First, subscribe to interfaces coming and going */
1c4baffc 213 r = sd_netlink_open(&m->rtnl);
74b2466e
LP
214 if (r < 0)
215 return r;
216
2d895038 217 r = sd_netlink_attach_event(m->rtnl, m->event, SD_EVENT_PRIORITY_IMPORTANT);
74b2466e
LP
218 if (r < 0)
219 return r;
220
1c4baffc 221 r = sd_netlink_add_match(m->rtnl, RTM_NEWLINK, manager_process_link, m);
74b2466e
LP
222 if (r < 0)
223 return r;
224
1c4baffc 225 r = sd_netlink_add_match(m->rtnl, RTM_DELLINK, manager_process_link, m);
74b2466e
LP
226 if (r < 0)
227 return r;
228
1c4baffc 229 r = sd_netlink_add_match(m->rtnl, RTM_NEWADDR, manager_process_address, m);
74b2466e
LP
230 if (r < 0)
231 return r;
091a364c 232
1c4baffc 233 r = sd_netlink_add_match(m->rtnl, RTM_DELADDR, manager_process_address, m);
74b2466e
LP
234 if (r < 0)
235 return r;
236
237 /* Then, enumerate all links */
238 r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
239 if (r < 0)
240 return r;
241
1c4baffc 242 r = sd_netlink_message_request_dump(req, true);
74b2466e
LP
243 if (r < 0)
244 return r;
245
1c4baffc 246 r = sd_netlink_call(m->rtnl, req, 0, &reply);
74b2466e
LP
247 if (r < 0)
248 return r;
249
1c4baffc 250 for (i = reply; i; i = sd_netlink_message_next(i)) {
74b2466e
LP
251 r = manager_process_link(m->rtnl, i, m);
252 if (r < 0)
253 return r;
254 }
255
1c4baffc
TG
256 req = sd_netlink_message_unref(req);
257 reply = sd_netlink_message_unref(reply);
74b2466e
LP
258
259 /* Finally, enumerate all addresses, too */
260 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, AF_UNSPEC);
261 if (r < 0)
262 return r;
263
1c4baffc 264 r = sd_netlink_message_request_dump(req, true);
74b2466e
LP
265 if (r < 0)
266 return r;
267
1c4baffc 268 r = sd_netlink_call(m->rtnl, req, 0, &reply);
74b2466e
LP
269 if (r < 0)
270 return r;
271
1c4baffc 272 for (i = reply; i; i = sd_netlink_message_next(i)) {
74b2466e
LP
273 r = manager_process_address(m->rtnl, i, m);
274 if (r < 0)
275 return r;
276 }
277
278 return r;
279}
280
281static int on_network_event(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
282 Manager *m = userdata;
283 Iterator i;
284 Link *l;
285 int r;
286
287 assert(m);
288
289 sd_network_monitor_flush(m->network_monitor);
290
291 HASHMAP_FOREACH(l, m->links, i) {
943ef07c 292 r = link_update(l);
74b2466e 293 if (r < 0)
da927ba9 294 log_warning_errno(r, "Failed to update monitor information for %i: %m", l->ifindex);
74b2466e
LP
295 }
296
7207052d 297 (void) manager_write_resolv_conf(m);
74b2466e
LP
298
299 return 0;
300}
301
302static int manager_network_monitor_listen(Manager *m) {
303 int r, fd, events;
304
305 assert(m);
306
0014a4ad 307 r = sd_network_monitor_new(&m->network_monitor, NULL);
74b2466e
LP
308 if (r < 0)
309 return r;
310
311 fd = sd_network_monitor_get_fd(m->network_monitor);
312 if (fd < 0)
313 return fd;
314
315 events = sd_network_monitor_get_events(m->network_monitor);
316 if (events < 0)
317 return events;
318
319 r = sd_event_add_io(m->event, &m->network_event_source, fd, events, &on_network_event, m);
320 if (r < 0)
2d895038
LP
321 return r;
322
323 r = sd_event_source_set_priority(m->network_event_source, SD_EVENT_PRIORITY_IMPORTANT+5);
324 if (r < 0)
74b2466e
LP
325 return r;
326
aa4a9deb
LP
327 (void) sd_event_source_set_description(m->network_event_source, "network-monitor");
328
74b2466e
LP
329 return 0;
330}
331
e96de0ce 332static int determine_hostname(char **full_hostname, char **llmnr_hostname, char **mdns_hostname) {
eb60f9cd 333 _cleanup_free_ char *h = NULL, *n = NULL;
349cc4a5 334#if HAVE_LIBIDN2
87057e24 335 _cleanup_free_ char *utf8 = NULL;
349cc4a5 336#elif HAVE_LIBIDN
87057e24
ZJS
337 int k;
338#endif
78c6a153 339 char label[DNS_LABEL_MAX];
87057e24
ZJS
340 const char *p, *decoded;
341 int r;
eb60f9cd 342
e96de0ce 343 assert(full_hostname);
78c6a153
LP
344 assert(llmnr_hostname);
345 assert(mdns_hostname);
346
a25b0dc8 347 /* Extract and normalize the first label of the locally configured hostname, and check it's not "localhost". */
eb60f9cd 348
a25b0dc8
LP
349 r = gethostname_strict(&h);
350 if (r < 0)
351 return log_debug_errno(r, "Can't determine system hostname: %m");
eb60f9cd 352
78c6a153 353 p = h;
87057e24 354 r = dns_label_unescape(&p, label, sizeof label);
78c6a153
LP
355 if (r < 0)
356 return log_error_errno(r, "Failed to unescape host name: %m");
357 if (r == 0) {
a25b0dc8 358 log_error("Couldn't find a single label in hostname.");
78c6a153
LP
359 return -EINVAL;
360 }
361
349cc4a5 362#if HAVE_LIBIDN2
87057e24
ZJS
363 r = idn2_to_unicode_8z8z(label, &utf8, 0);
364 if (r != IDN2_OK)
365 return log_error("Failed to undo IDNA: %s", idn2_strerror(r));
366 assert(utf8_is_valid(utf8));
367
368 r = strlen(utf8);
369 decoded = utf8;
349cc4a5 370#elif HAVE_LIBIDN
87057e24 371 k = dns_label_undo_idna(label, r, label, sizeof label);
78c6a153
LP
372 if (k < 0)
373 return log_error_errno(k, "Failed to undo IDNA: %m");
374 if (k > 0)
375 r = k;
376
377 if (!utf8_is_valid(label)) {
eb60f9cd
LP
378 log_error("System hostname is not UTF-8 clean.");
379 return -EINVAL;
380 }
87057e24
ZJS
381 decoded = label;
382#else
383 decoded = label; /* no decoding */
384#endif
eb60f9cd 385
87057e24 386 r = dns_label_escape_new(decoded, r, &n);
78c6a153
LP
387 if (r < 0)
388 return log_error_errno(r, "Failed to escape host name: %m");
389
390 if (is_localhost(n)) {
391 log_debug("System hostname is 'localhost', ignoring.");
392 return -EINVAL;
eb60f9cd
LP
393 }
394
78c6a153
LP
395 r = dns_name_concat(n, "local", mdns_hostname);
396 if (r < 0)
397 return log_error_errno(r, "Failed to determine mDNS hostname: %m");
398
ae2a15bc
LP
399 *llmnr_hostname = TAKE_PTR(n);
400 *full_hostname = TAKE_PTR(h);
e96de0ce 401
eb60f9cd
LP
402 return 0;
403}
404
a25b0dc8
LP
405static const char *fallback_hostname(void) {
406
407 /* Determine the fall back hostname. For exposing this system to the outside world, we cannot have it to be
408 * "localhost" even if that's the compiled in hostname. In this case, let's revert to "linux" instead. */
409
410 if (is_localhost(FALLBACK_HOSTNAME))
411 return "linux";
412
413 return FALLBACK_HOSTNAME;
414}
415
416static int make_fallback_hostnames(char **full_hostname, char **llmnr_hostname, char **mdns_hostname) {
417 _cleanup_free_ char *n = NULL, *m = NULL;
418 char label[DNS_LABEL_MAX], *h;
419 const char *p;
420 int r;
421
422 assert(full_hostname);
423 assert(llmnr_hostname);
424 assert(mdns_hostname);
425
426 p = fallback_hostname();
427 r = dns_label_unescape(&p, label, sizeof(label));
428 if (r < 0)
429 return log_error_errno(r, "Failed to unescape fallback host name: %m");
430
431 assert(r > 0); /* The fallback hostname must have at least one label */
432
433 r = dns_label_escape_new(label, r, &n);
434 if (r < 0)
435 return log_error_errno(r, "Failed to escape fallback hostname: %m");
436
437 r = dns_name_concat(n, "local", &m);
438 if (r < 0)
439 return log_error_errno(r, "Failed to concatenate mDNS hostname: %m");
440
441 h = strdup(fallback_hostname());
442 if (!h)
443 return log_oom();
444
ae2a15bc
LP
445 *llmnr_hostname = TAKE_PTR(n);
446 *mdns_hostname = TAKE_PTR(m);
a25b0dc8
LP
447
448 *full_hostname = h;
449
450 return 0;
451}
452
eb60f9cd 453static int on_hostname_change(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
e96de0ce 454 _cleanup_free_ char *full_hostname = NULL, *llmnr_hostname = NULL, *mdns_hostname = NULL;
eb60f9cd
LP
455 Manager *m = userdata;
456 int r;
457
458 assert(m);
459
e96de0ce 460 r = determine_hostname(&full_hostname, &llmnr_hostname, &mdns_hostname);
eb60f9cd
LP
461 if (r < 0)
462 return 0; /* ignore invalid hostnames */
463
e96de0ce
LP
464 if (streq(full_hostname, m->full_hostname) &&
465 streq(llmnr_hostname, m->llmnr_hostname) &&
466 streq(mdns_hostname, m->mdns_hostname))
eb60f9cd
LP
467 return 0;
468
e96de0ce 469 log_info("System hostname changed to '%s'.", full_hostname);
78c6a153 470
e96de0ce
LP
471 free_and_replace(m->full_hostname, full_hostname);
472 free_and_replace(m->llmnr_hostname, llmnr_hostname);
473 free_and_replace(m->mdns_hostname, mdns_hostname);
eb60f9cd
LP
474
475 manager_refresh_rrs(m);
476
477 return 0;
478}
479
480static int manager_watch_hostname(Manager *m) {
eb60f9cd
LP
481 int r;
482
483 assert(m);
484
db4a47e9
LP
485 m->hostname_fd = open("/proc/sys/kernel/hostname",
486 O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
eb60f9cd 487 if (m->hostname_fd < 0) {
56f64d95 488 log_warning_errno(errno, "Failed to watch hostname: %m");
eb60f9cd
LP
489 return 0;
490 }
491
492 r = sd_event_add_io(m->event, &m->hostname_event_source, m->hostname_fd, 0, on_hostname_change, m);
493 if (r < 0) {
494 if (r == -EPERM)
495 /* kernels prior to 3.2 don't support polling this file. Ignore the failure. */
496 m->hostname_fd = safe_close(m->hostname_fd);
8d3d7072
MS
497 else
498 return log_error_errno(r, "Failed to add hostname event source: %m");
eb60f9cd
LP
499 }
500
aa4a9deb
LP
501 (void) sd_event_source_set_description(m->hostname_event_source, "hostname");
502
e96de0ce 503 r = determine_hostname(&m->full_hostname, &m->llmnr_hostname, &m->mdns_hostname);
eb60f9cd 504 if (r < 0) {
a25b0dc8 505 log_info("Defaulting to hostname '%s'.", fallback_hostname());
78c6a153 506
a25b0dc8
LP
507 r = make_fallback_hostnames(&m->full_hostname, &m->llmnr_hostname, &m->mdns_hostname);
508 if (r < 0)
509 return r;
eb60f9cd 510 } else
e96de0ce 511 log_info("Using system hostname '%s'.", m->full_hostname);
eb60f9cd
LP
512
513 return 0;
514}
515
4d506d6b
LP
516static int manager_sigusr1(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
517 _cleanup_free_ char *buffer = NULL;
518 _cleanup_fclose_ FILE *f = NULL;
519 Manager *m = userdata;
cf84484a 520 DnsServer *server;
4d506d6b
LP
521 size_t size = 0;
522 DnsScope *scope;
cf84484a
LP
523 Iterator i;
524 Link *l;
4d506d6b
LP
525
526 assert(s);
527 assert(si);
528 assert(m);
529
530 f = open_memstream(&buffer, &size);
531 if (!f)
532 return log_oom();
533
0d536673
LP
534 (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
535
4d506d6b
LP
536 LIST_FOREACH(scopes, scope, m->dns_scopes)
537 dns_scope_dump(scope, f);
538
cf84484a
LP
539 LIST_FOREACH(servers, server, m->dns_servers)
540 dns_server_dump(server, f);
541 LIST_FOREACH(servers, server, m->fallback_dns_servers)
542 dns_server_dump(server, f);
543 HASHMAP_FOREACH(l, m->links, i)
544 LIST_FOREACH(servers, server, l->dns_servers)
545 dns_server_dump(server, f);
546
4d506d6b
LP
547 if (fflush_and_check(f) < 0)
548 return log_oom();
549
550 log_dump(LOG_INFO, buffer);
551 return 0;
552}
553
bc81447e
LP
554static int manager_sigusr2(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
555 Manager *m = userdata;
bc81447e
LP
556
557 assert(s);
558 assert(si);
559 assert(m);
560
ba35662f 561 manager_flush_caches(m);
ba35662f 562
bc81447e
LP
563 return 0;
564}
565
d55b0463
LP
566static int manager_sigrtmin1(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
567 Manager *m = userdata;
568
569 assert(s);
570 assert(si);
571 assert(m);
572
573 manager_reset_server_features(m);
574 return 0;
575}
576
091a364c 577int manager_new(Manager **ret) {
74b2466e 578 _cleanup_(manager_freep) Manager *m = NULL;
091a364c
TG
579 int r;
580
c92e531c
LP
581 assert(ret);
582
091a364c
TG
583 m = new0(Manager, 1);
584 if (!m)
585 return -ENOMEM;
586
1716f6dc 587 m->llmnr_ipv4_udp_fd = m->llmnr_ipv6_udp_fd = -1;
623a4c97 588 m->llmnr_ipv4_tcp_fd = m->llmnr_ipv6_tcp_fd = -1;
bc7702b0 589 m->mdns_ipv4_fd = m->mdns_ipv6_fd = -1;
b30bf55d 590 m->dns_stub_udp_fd = m->dns_stub_tcp_fd = -1;
eb60f9cd 591 m->hostname_fd = -1;
1716f6dc 592
af49ca27 593 m->llmnr_support = RESOLVE_SUPPORT_YES;
7bef8e8e 594 m->mdns_support = RESOLVE_SUPPORT_YES;
61ecb465 595 m->dnssec_mode = DEFAULT_DNSSEC_MODE;
ceeddf79 596 m->enable_cache = true;
1ae43295 597 m->dns_stub_listener_mode = DNS_STUB_LISTENER_UDP;
5cb36f41 598 m->read_resolv_conf = true;
00fa60ae 599 m->need_builtin_fallbacks = true;
dd0bc0f1 600 m->etc_hosts_last = m->etc_hosts_mtime = USEC_INFINITY;
091a364c 601
0d2cd476
LP
602 r = dns_trust_anchor_load(&m->trust_anchor);
603 if (r < 0)
604 return r;
605
ad6c0475
LP
606 r = manager_parse_config_file(m);
607 if (r < 0)
5ce497b5 608 log_warning_errno(r, "Failed to parse configuration file: %m");
ad6c0475 609
091a364c
TG
610 r = sd_event_default(&m->event);
611 if (r < 0)
612 return r;
613
614 sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
615 sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
616
617 sd_event_set_watchdog(m->event, true);
618
eb60f9cd
LP
619 r = manager_watch_hostname(m);
620 if (r < 0)
621 return r;
622
6501dd31
DR
623 r = dnssd_load(m);
624 if (r < 0)
625 log_warning_errno(r, "Failed to load DNS-SD configuration files: %m");
626
1716f6dc 627 r = dns_scope_new(m, &m->unicast_scope, NULL, DNS_PROTOCOL_DNS, AF_UNSPEC);
74b2466e
LP
628 if (r < 0)
629 return r;
630
631 r = manager_network_monitor_listen(m);
632 if (r < 0)
633 return r;
634
635 r = manager_rtnl_listen(m);
636 if (r < 0)
637 return r;
638
639 r = manager_connect_bus(m);
640 if (r < 0)
641 return r;
642
4d506d6b 643 (void) sd_event_add_signal(m->event, &m->sigusr1_event_source, SIGUSR1, manager_sigusr1, m);
bc81447e 644 (void) sd_event_add_signal(m->event, &m->sigusr2_event_source, SIGUSR2, manager_sigusr2, m);
d55b0463 645 (void) sd_event_add_signal(m->event, &m->sigrtmin1_event_source, SIGRTMIN+1, manager_sigrtmin1, m);
4d506d6b 646
943ef07c
LP
647 manager_cleanup_saved_user(m);
648
1cc6c93a 649 *ret = TAKE_PTR(m);
091a364c
TG
650
651 return 0;
652}
653
edc501d4
LP
654int manager_start(Manager *m) {
655 int r;
656
657 assert(m);
658
b30bf55d
LP
659 r = manager_dns_stub_start(m);
660 if (r < 0)
661 return r;
662
edc501d4
LP
663 return 0;
664}
665
74b2466e
LP
666Manager *manager_free(Manager *m) {
667 Link *l;
6501dd31 668 DnssdService *s;
091a364c
TG
669
670 if (!m)
74b2466e
LP
671 return NULL;
672
4b95f179
LP
673 dns_server_unlink_all(m->dns_servers);
674 dns_server_unlink_all(m->fallback_dns_servers);
a51c1048
LP
675 dns_search_domain_unlink_all(m->search_domains);
676
74b2466e
LP
677 while ((l = hashmap_first(m->links)))
678 link_free(l);
f0e15467
LP
679
680 while (m->dns_queries)
681 dns_query_free(m->dns_queries);
74b2466e 682
cab5b059
LP
683 dns_scope_free(m->unicast_scope);
684
b30bf55d
LP
685 /* At this point only orphaned streams should remain. All others should have been freed already by their
686 * owners */
687 while (m->dns_streams)
688 dns_stream_unref(m->dns_streams);
689
f0e15467
LP
690 hashmap_free(m->links);
691 hashmap_free(m->dns_transactions);
692
096b6773
LP
693 sd_event_source_unref(m->network_event_source);
694 sd_network_monitor_unref(m->network_monitor);
091a364c 695
a564ca2f
LP
696 sd_netlink_unref(m->rtnl);
697 sd_event_source_unref(m->rtnl_event_source);
698
edc501d4 699 manager_llmnr_stop(m);
bc7702b0 700 manager_mdns_stop(m);
b30bf55d 701 manager_dns_stub_stop(m);
623a4c97 702
902bb5d8 703 sd_bus_slot_unref(m->prepare_for_sleep_slot);
74b2466e
LP
704 sd_event_source_unref(m->bus_retry_event_source);
705 sd_bus_unref(m->bus);
091a364c 706
4d506d6b 707 sd_event_source_unref(m->sigusr1_event_source);
bc81447e 708 sd_event_source_unref(m->sigusr2_event_source);
d55b0463 709 sd_event_source_unref(m->sigrtmin1_event_source);
4d506d6b 710
74b2466e 711 sd_event_unref(m->event);
623a4c97 712
78c6a153
LP
713 dns_resource_key_unref(m->llmnr_host_ipv4_key);
714 dns_resource_key_unref(m->llmnr_host_ipv6_key);
400cb36e
DR
715 dns_resource_key_unref(m->mdns_host_ipv4_key);
716 dns_resource_key_unref(m->mdns_host_ipv6_key);
eb60f9cd 717
eb60f9cd 718 sd_event_source_unref(m->hostname_event_source);
d9fcf2ba 719 safe_close(m->hostname_fd);
e96de0ce
LP
720
721 free(m->full_hostname);
78c6a153
LP
722 free(m->llmnr_hostname);
723 free(m->mdns_hostname);
eb60f9cd 724
6501dd31
DR
725 while ((s = hashmap_first(m->dnssd_services)))
726 dnssd_service_free(s);
727 hashmap_free(m->dnssd_services);
728
0d2cd476 729 dns_trust_anchor_flush(&m->trust_anchor);
dd0bc0f1 730 manager_etc_hosts_flush(m);
0d2cd476 731
6b430fdb 732 return mfree(m);
091a364c
TG
733}
734
1716f6dc 735int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) {
74b2466e 736 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
1716f6dc
LP
737 union {
738 struct cmsghdr header; /* For alignment */
40a1eebd 739 uint8_t buffer[CMSG_SPACE(MAXSIZE(struct in_pktinfo, struct in6_pktinfo))
1716f6dc 740 + CMSG_SPACE(int) /* ttl/hoplimit */
623a4c97 741 + EXTRA_CMSG_SPACE /* kernel appears to require extra buffer space */];
1716f6dc
LP
742 } control;
743 union sockaddr_union sa;
74b2466e 744 struct msghdr mh = {};
1716f6dc 745 struct cmsghdr *cmsg;
74b2466e 746 struct iovec iov;
4edc2c9b
LP
747 ssize_t ms, l;
748 int r;
74b2466e
LP
749
750 assert(m);
1716f6dc 751 assert(fd >= 0);
74b2466e
LP
752 assert(ret);
753
4edc2c9b 754 ms = next_datagram_size_fd(fd);
74b2466e 755 if (ms < 0)
4edc2c9b 756 return ms;
74b2466e 757
51027656 758 r = dns_packet_new(&p, protocol, ms, DNS_PACKET_SIZE_MAX);
74b2466e
LP
759 if (r < 0)
760 return r;
761
762 iov.iov_base = DNS_PACKET_DATA(p);
763 iov.iov_len = p->allocated;
764
1716f6dc
LP
765 mh.msg_name = &sa.sa;
766 mh.msg_namelen = sizeof(sa);
74b2466e
LP
767 mh.msg_iov = &iov;
768 mh.msg_iovlen = 1;
1716f6dc
LP
769 mh.msg_control = &control;
770 mh.msg_controllen = sizeof(control);
74b2466e 771
a38d9945 772 l = recvmsg(fd, &mh, 0);
f134289a
EV
773 if (l == 0)
774 return 0;
74b2466e 775 if (l < 0) {
4c701096 776 if (IN_SET(errno, EAGAIN, EINTR))
74b2466e
LP
777 return 0;
778
779 return -errno;
091a364c
TG
780 }
781
1716f6dc
LP
782 assert(!(mh.msg_flags & MSG_CTRUNC));
783 assert(!(mh.msg_flags & MSG_TRUNC));
784
74b2466e 785 p->size = (size_t) l;
091a364c 786
1716f6dc 787 p->family = sa.sa.sa_family;
623a4c97
LP
788 p->ipproto = IPPROTO_UDP;
789 if (p->family == AF_INET) {
1716f6dc 790 p->sender.in = sa.in.sin_addr;
623a4c97
LP
791 p->sender_port = be16toh(sa.in.sin_port);
792 } else if (p->family == AF_INET6) {
1716f6dc 793 p->sender.in6 = sa.in6.sin6_addr;
623a4c97
LP
794 p->sender_port = be16toh(sa.in6.sin6_port);
795 p->ifindex = sa.in6.sin6_scope_id;
796 } else
1716f6dc 797 return -EAFNOSUPPORT;
74b2466e 798
2a1288ff 799 CMSG_FOREACH(cmsg, &mh) {
74b2466e 800
1716f6dc
LP
801 if (cmsg->cmsg_level == IPPROTO_IPV6) {
802 assert(p->family == AF_INET6);
74b2466e 803
1716f6dc 804 switch (cmsg->cmsg_type) {
74b2466e 805
1716f6dc
LP
806 case IPV6_PKTINFO: {
807 struct in6_pktinfo *i = (struct in6_pktinfo*) CMSG_DATA(cmsg);
74b2466e 808
623a4c97
LP
809 if (p->ifindex <= 0)
810 p->ifindex = i->ipi6_ifindex;
811
1716f6dc
LP
812 p->destination.in6 = i->ipi6_addr;
813 break;
814 }
74b2466e 815
1716f6dc
LP
816 case IPV6_HOPLIMIT:
817 p->ttl = *(int *) CMSG_DATA(cmsg);
818 break;
74b2466e 819
1716f6dc
LP
820 }
821 } else if (cmsg->cmsg_level == IPPROTO_IP) {
822 assert(p->family == AF_INET);
74b2466e 823
1716f6dc 824 switch (cmsg->cmsg_type) {
74b2466e 825
1716f6dc
LP
826 case IP_PKTINFO: {
827 struct in_pktinfo *i = (struct in_pktinfo*) CMSG_DATA(cmsg);
091a364c 828
623a4c97
LP
829 if (p->ifindex <= 0)
830 p->ifindex = i->ipi_ifindex;
831
1716f6dc
LP
832 p->destination.in = i->ipi_addr;
833 break;
834 }
74b2466e 835
623a4c97 836 case IP_TTL:
1716f6dc
LP
837 p->ttl = *(int *) CMSG_DATA(cmsg);
838 break;
839 }
840 }
841 }
74b2466e 842
623a4c97
LP
843 /* The Linux kernel sets the interface index to the loopback
844 * device if the packet came from the local host since it
845 * avoids the routing table in such a case. Let's unset the
846 * interface index in such a case. */
a5f03596 847 if (p->ifindex == LOOPBACK_IFINDEX)
623a4c97
LP
848 p->ifindex = 0;
849
86ad4cd7
TG
850 if (protocol != DNS_PROTOCOL_DNS) {
851 /* If we don't know the interface index still, we look for the
852 * first local interface with a matching address. Yuck! */
853 if (p->ifindex <= 0)
854 p->ifindex = manager_find_ifindex(m, p->family, &p->destination);
855 }
623a4c97 856
1cc6c93a 857 *ret = TAKE_PTR(p);
74b2466e
LP
858
859 return 1;
860}
861
74b2466e
LP
862static int sendmsg_loop(int fd, struct msghdr *mh, int flags) {
863 int r;
864
865 assert(fd >= 0);
866 assert(mh);
867
868 for (;;) {
869 if (sendmsg(fd, mh, flags) >= 0)
870 return 0;
871
872 if (errno == EINTR)
873 continue;
874
875 if (errno != EAGAIN)
876 return -errno;
877
878 r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
879 if (r < 0)
880 return r;
881 if (r == 0)
882 return -ETIMEDOUT;
883 }
884}
885
72290734
TG
886static int write_loop(int fd, void *message, size_t length) {
887 int r;
888
889 assert(fd >= 0);
890 assert(message);
891
892 for (;;) {
893 if (write(fd, message, length) >= 0)
894 return 0;
895
896 if (errno == EINTR)
897 continue;
898
899 if (errno != EAGAIN)
900 return -errno;
901
902 r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
903 if (r < 0)
904 return r;
905 if (r == 0)
906 return -ETIMEDOUT;
907 }
908}
909
910int manager_write(Manager *m, int fd, DnsPacket *p) {
911 int r;
912
deb3f3d3 913 log_debug("Sending %s packet with id %" PRIu16 ".", DNS_PACKET_QR(p) ? "response" : "query", DNS_PACKET_ID(p));
72290734
TG
914
915 r = write_loop(fd, DNS_PACKET_DATA(p), p->size);
916 if (r < 0)
917 return r;
918
919 return 0;
920}
921
b30bf55d
LP
922static int manager_ipv4_send(
923 Manager *m,
924 int fd,
925 int ifindex,
926 const struct in_addr *destination,
927 uint16_t port,
928 const struct in_addr *source,
929 DnsPacket *p) {
74b2466e
LP
930 union sockaddr_union sa = {
931 .in.sin_family = AF_INET,
74b2466e 932 };
1716f6dc
LP
933 union {
934 struct cmsghdr header; /* For alignment */
935 uint8_t buffer[CMSG_SPACE(sizeof(struct in_pktinfo))];
936 } control;
74b2466e
LP
937 struct msghdr mh = {};
938 struct iovec iov;
74b2466e
LP
939
940 assert(m);
1716f6dc 941 assert(fd >= 0);
b30bf55d 942 assert(destination);
1716f6dc 943 assert(port > 0);
74b2466e
LP
944 assert(p);
945
74b2466e
LP
946 iov.iov_base = DNS_PACKET_DATA(p);
947 iov.iov_len = p->size;
091a364c 948
b30bf55d 949 sa.in.sin_addr = *destination;
1716f6dc 950 sa.in.sin_port = htobe16(port),
091a364c 951
74b2466e
LP
952 mh.msg_iov = &iov;
953 mh.msg_iovlen = 1;
954 mh.msg_name = &sa.sa;
955 mh.msg_namelen = sizeof(sa.in);
091a364c 956
74b2466e
LP
957 if (ifindex > 0) {
958 struct cmsghdr *cmsg;
959 struct in_pktinfo *pi;
960
961 zero(control);
962
1716f6dc 963 mh.msg_control = &control;
74b2466e
LP
964 mh.msg_controllen = CMSG_LEN(sizeof(struct in_pktinfo));
965
966 cmsg = CMSG_FIRSTHDR(&mh);
967 cmsg->cmsg_len = mh.msg_controllen;
968 cmsg->cmsg_level = IPPROTO_IP;
969 cmsg->cmsg_type = IP_PKTINFO;
970
971 pi = (struct in_pktinfo*) CMSG_DATA(cmsg);
972 pi->ipi_ifindex = ifindex;
b30bf55d
LP
973
974 if (source)
975 pi->ipi_spec_dst = *source;
74b2466e
LP
976 }
977
978 return sendmsg_loop(fd, &mh, 0);
979}
980
b30bf55d
LP
981static int manager_ipv6_send(
982 Manager *m,
983 int fd,
984 int ifindex,
985 const struct in6_addr *destination,
986 uint16_t port,
987 const struct in6_addr *source,
988 DnsPacket *p) {
989
74b2466e
LP
990 union sockaddr_union sa = {
991 .in6.sin6_family = AF_INET6,
74b2466e 992 };
1716f6dc
LP
993 union {
994 struct cmsghdr header; /* For alignment */
995 uint8_t buffer[CMSG_SPACE(sizeof(struct in6_pktinfo))];
996 } control;
74b2466e
LP
997 struct msghdr mh = {};
998 struct iovec iov;
74b2466e
LP
999
1000 assert(m);
1716f6dc 1001 assert(fd >= 0);
b30bf55d 1002 assert(destination);
1716f6dc 1003 assert(port > 0);
74b2466e
LP
1004 assert(p);
1005
74b2466e
LP
1006 iov.iov_base = DNS_PACKET_DATA(p);
1007 iov.iov_len = p->size;
1008
b30bf55d 1009 sa.in6.sin6_addr = *destination;
1716f6dc 1010 sa.in6.sin6_port = htobe16(port),
74b2466e
LP
1011 sa.in6.sin6_scope_id = ifindex;
1012
1013 mh.msg_iov = &iov;
1014 mh.msg_iovlen = 1;
1015 mh.msg_name = &sa.sa;
1016 mh.msg_namelen = sizeof(sa.in6);
1017
1018 if (ifindex > 0) {
1019 struct cmsghdr *cmsg;
1020 struct in6_pktinfo *pi;
1021
1022 zero(control);
1023
1716f6dc 1024 mh.msg_control = &control;
74b2466e
LP
1025 mh.msg_controllen = CMSG_LEN(sizeof(struct in6_pktinfo));
1026
1027 cmsg = CMSG_FIRSTHDR(&mh);
1028 cmsg->cmsg_len = mh.msg_controllen;
1029 cmsg->cmsg_level = IPPROTO_IPV6;
1030 cmsg->cmsg_type = IPV6_PKTINFO;
1031
1032 pi = (struct in6_pktinfo*) CMSG_DATA(cmsg);
1033 pi->ipi6_ifindex = ifindex;
b30bf55d
LP
1034
1035 if (source)
1036 pi->ipi6_addr = *source;
74b2466e
LP
1037 }
1038
1039 return sendmsg_loop(fd, &mh, 0);
1040}
1041
b30bf55d
LP
1042int manager_send(
1043 Manager *m,
1044 int fd,
1045 int ifindex,
1046 int family,
1047 const union in_addr_union *destination,
1048 uint16_t port,
1049 const union in_addr_union *source,
1050 DnsPacket *p) {
1051
1716f6dc
LP
1052 assert(m);
1053 assert(fd >= 0);
b30bf55d 1054 assert(destination);
1716f6dc
LP
1055 assert(port > 0);
1056 assert(p);
1057
deb3f3d3 1058 log_debug("Sending %s packet with id %" PRIu16 " on interface %i/%s.", DNS_PACKET_QR(p) ? "response" : "query", DNS_PACKET_ID(p), ifindex, af_to_name(family));
a2a416f7 1059
1716f6dc 1060 if (family == AF_INET)
b30bf55d 1061 return manager_ipv4_send(m, fd, ifindex, &destination->in, port, &source->in, p);
2817157b 1062 if (family == AF_INET6)
b30bf55d 1063 return manager_ipv6_send(m, fd, ifindex, &destination->in6, port, &source->in6, p);
1716f6dc
LP
1064
1065 return -EAFNOSUPPORT;
1066}
1067
e1c95994
LP
1068uint32_t manager_find_mtu(Manager *m) {
1069 uint32_t mtu = 0;
1070 Link *l;
1071 Iterator i;
1072
1073 /* If we don't know on which link a DNS packet would be
1074 * delivered, let's find the largest MTU that works on all
1075 * interfaces we know of */
1076
1077 HASHMAP_FOREACH(l, m->links, i) {
1078 if (l->mtu <= 0)
1079 continue;
1080
1081 if (mtu <= 0 || l->mtu < mtu)
1082 mtu = l->mtu;
1083 }
1084
1085 return mtu;
1086}
1716f6dc 1087
623a4c97 1088int manager_find_ifindex(Manager *m, int family, const union in_addr_union *in_addr) {
ec2c5e43
LP
1089 LinkAddress *a;
1090
1091 assert(m);
1092
4e945a6f 1093 a = manager_find_link_address(m, family, in_addr);
ec2c5e43
LP
1094 if (a)
1095 return a->link->ifindex;
1096
1097 return 0;
1098}
1099
eb60f9cd
LP
1100void manager_refresh_rrs(Manager *m) {
1101 Iterator i;
1102 Link *l;
6db6a464 1103 DnssdService *s;
eb60f9cd
LP
1104
1105 assert(m);
1106
78c6a153
LP
1107 m->llmnr_host_ipv4_key = dns_resource_key_unref(m->llmnr_host_ipv4_key);
1108 m->llmnr_host_ipv6_key = dns_resource_key_unref(m->llmnr_host_ipv6_key);
400cb36e
DR
1109 m->mdns_host_ipv4_key = dns_resource_key_unref(m->mdns_host_ipv4_key);
1110 m->mdns_host_ipv6_key = dns_resource_key_unref(m->mdns_host_ipv6_key);
eb60f9cd 1111
6db6a464
DR
1112 if (m->mdns_support == RESOLVE_SUPPORT_YES)
1113 HASHMAP_FOREACH(s, m->dnssd_services, i)
1114 if (dnssd_update_rrs(s) < 0)
1115 log_warning("Failed to refresh DNS-SD service '%s'", s->name);
1116
eb60f9cd
LP
1117 HASHMAP_FOREACH(l, m->links, i) {
1118 link_add_rrs(l, true);
1119 link_add_rrs(l, false);
1120 }
1121}
1122
e7c1b0e4 1123static int manager_next_random_name(const char *old, char **ret_new) {
ec2c5e43 1124 const char *p;
556a2294 1125 uint64_t u, a;
e7c1b0e4 1126 char *n;
623a4c97 1127
e7c1b0e4 1128 p = strchr(old, 0);
ec2c5e43
LP
1129 assert(p);
1130
e7c1b0e4
DR
1131 while (p > old) {
1132 if (!strchr(DIGITS, p[-1]))
ec2c5e43
LP
1133 break;
1134
1135 p--;
1136 }
1137
1138 if (*p == 0 || safe_atou64(p, &u) < 0 || u <= 0)
1139 u = 1;
1140
556a2294
LP
1141 /* Add a random number to the old value. This way we can avoid
1142 * that two hosts pick the same hostname, win on IPv4 and lose
1143 * on IPv6 (or vice versa), and pick the same hostname
1144 * replacement hostname, ad infinitum. We still want the
1145 * numbers to go up monotonically, hence we just add a random
1146 * value 1..10 */
1147
1148 random_bytes(&a, sizeof(a));
1149 u += 1 + a % 10;
ec2c5e43 1150
e7c1b0e4 1151 if (asprintf(&n, "%.*s%" PRIu64, (int) (p - old), old, u) < 0)
ec2c5e43
LP
1152 return -ENOMEM;
1153
e7c1b0e4
DR
1154 *ret_new = n;
1155
1156 return 0;
1157}
1158
1159int manager_next_hostname(Manager *m) {
1160 _cleanup_free_ char *h = NULL, *k = NULL;
1161 int r;
1162
1163 assert(m);
1164
1165 r = manager_next_random_name(m->llmnr_hostname, &h);
1166 if (r < 0)
1167 return r;
1168
78c6a153 1169 r = dns_name_concat(h, "local", &k);
e7c1b0e4 1170 if (r < 0)
78c6a153 1171 return r;
78c6a153
LP
1172
1173 log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m->llmnr_hostname, h);
1174
e7c1b0e4
DR
1175 free_and_replace(m->llmnr_hostname, h);
1176 free_and_replace(m->mdns_hostname, k);
ec2c5e43 1177
eb60f9cd 1178 manager_refresh_rrs(m);
623a4c97
LP
1179
1180 return 0;
1181}
ec2c5e43 1182
4e945a6f 1183LinkAddress* manager_find_link_address(Manager *m, int family, const union in_addr_union *in_addr) {
ec2c5e43
LP
1184 Iterator i;
1185 Link *l;
1186
1187 assert(m);
1188
1189 HASHMAP_FOREACH(l, m->links, i) {
1190 LinkAddress *a;
1191
1192 a = link_find_address(l, family, in_addr);
1193 if (a)
1194 return a;
1195 }
1196
1197 return NULL;
1198}
1199
a4076574 1200bool manager_our_packet(Manager *m, DnsPacket *p) {
ec2c5e43
LP
1201 assert(m);
1202 assert(p);
1203
4e945a6f 1204 return !!manager_find_link_address(m, p->family, &p->sender);
ec2c5e43 1205}
4e945a6f 1206
a4076574
LP
1207DnsScope* manager_find_scope(Manager *m, DnsPacket *p) {
1208 Link *l;
1209
1210 assert(m);
1211 assert(p);
1212
1213 l = hashmap_get(m->links, INT_TO_PTR(p->ifindex));
1214 if (!l)
1215 return NULL;
1216
b4f1862d
DM
1217 switch (p->protocol) {
1218 case DNS_PROTOCOL_LLMNR:
a4076574
LP
1219 if (p->family == AF_INET)
1220 return l->llmnr_ipv4_scope;
1221 else if (p->family == AF_INET6)
1222 return l->llmnr_ipv6_scope;
b4f1862d
DM
1223
1224 break;
1225
1226 case DNS_PROTOCOL_MDNS:
1227 if (p->family == AF_INET)
1228 return l->mdns_ipv4_scope;
1229 else if (p->family == AF_INET6)
1230 return l->mdns_ipv6_scope;
1231
1232 break;
1233
1234 default:
1235 break;
a4076574
LP
1236 }
1237
1238 return NULL;
1239}
1240
902bb5d8
LP
1241void manager_verify_all(Manager *m) {
1242 DnsScope *s;
1243
1244 assert(m);
1245
1246 LIST_FOREACH(scopes, s, m->dns_scopes)
1247 dns_zone_verify_all(&s->zone);
1248}
1249
78c6a153 1250int manager_is_own_hostname(Manager *m, const char *name) {
78c6a153
LP
1251 int r;
1252
1253 assert(m);
1254 assert(name);
1255
1256 if (m->llmnr_hostname) {
1257 r = dns_name_equal(name, m->llmnr_hostname);
1258 if (r != 0)
1259 return r;
1260 }
1261
e96de0ce
LP
1262 if (m->mdns_hostname) {
1263 r = dns_name_equal(name, m->mdns_hostname);
1264 if (r != 0)
1265 return r;
1266 }
1267
1268 if (m->full_hostname)
1269 return dns_name_equal(name, m->full_hostname);
78c6a153
LP
1270
1271 return 0;
1272}
1273
9176a57c
LP
1274int manager_compile_dns_servers(Manager *m, OrderedSet **dns) {
1275 DnsServer *s;
1276 Iterator i;
1277 Link *l;
1278 int r;
1279
1280 assert(m);
1281 assert(dns);
1282
1283 r = ordered_set_ensure_allocated(dns, &dns_server_hash_ops);
1284 if (r < 0)
1285 return r;
1286
1287 /* First add the system-wide servers and domains */
1288 LIST_FOREACH(servers, s, m->dns_servers) {
1289 r = ordered_set_put(*dns, s);
1290 if (r == -EEXIST)
1291 continue;
1292 if (r < 0)
1293 return r;
1294 }
1295
1296 /* Then, add the per-link servers */
1297 HASHMAP_FOREACH(l, m->links, i) {
1298 LIST_FOREACH(servers, s, l->dns_servers) {
1299 r = ordered_set_put(*dns, s);
1300 if (r == -EEXIST)
1301 continue;
1302 if (r < 0)
1303 return r;
1304 }
1305 }
1306
1307 /* If we found nothing, add the fallback servers */
1308 if (ordered_set_isempty(*dns)) {
1309 LIST_FOREACH(servers, s, m->fallback_dns_servers) {
1310 r = ordered_set_put(*dns, s);
1311 if (r == -EEXIST)
1312 continue;
1313 if (r < 0)
1314 return r;
1315 }
1316 }
1317
1318 return 0;
1319}
1320
94363cbb
MP
1321/* filter_route is a tri-state:
1322 * < 0: no filtering
1323 * = 0 or false: return only domains which should be used for searching
1324 * > 0 or true: return only domains which are for routing only
1325 */
6f7da49d 1326int manager_compile_search_domains(Manager *m, OrderedSet **domains, int filter_route) {
9176a57c
LP
1327 DnsSearchDomain *d;
1328 Iterator i;
1329 Link *l;
1330 int r;
1331
1332 assert(m);
1333 assert(domains);
1334
1335 r = ordered_set_ensure_allocated(domains, &dns_name_hash_ops);
1336 if (r < 0)
1337 return r;
1338
1339 LIST_FOREACH(domains, d, m->search_domains) {
6f7da49d
LP
1340
1341 if (filter_route >= 0 &&
1342 d->route_only != !!filter_route)
1343 continue;
1344
9176a57c
LP
1345 r = ordered_set_put(*domains, d->name);
1346 if (r == -EEXIST)
1347 continue;
1348 if (r < 0)
1349 return r;
1350 }
1351
1352 HASHMAP_FOREACH(l, m->links, i) {
1353
1354 LIST_FOREACH(domains, d, l->search_domains) {
6f7da49d
LP
1355
1356 if (filter_route >= 0 &&
1357 d->route_only != !!filter_route)
1358 continue;
1359
9176a57c
LP
1360 r = ordered_set_put(*domains, d->name);
1361 if (r == -EEXIST)
1362 continue;
1363 if (r < 0)
1364 return r;
1365 }
1366 }
1367
1368 return 0;
1369}
c69fa7e3
LP
1370
1371DnssecMode manager_get_dnssec_mode(Manager *m) {
1372 assert(m);
1373
1374 if (m->dnssec_mode != _DNSSEC_MODE_INVALID)
1375 return m->dnssec_mode;
1376
1377 return DNSSEC_NO;
1378}
1379
1380bool manager_dnssec_supported(Manager *m) {
1381 DnsServer *server;
1382 Iterator i;
1383 Link *l;
1384
1385 assert(m);
1386
1387 if (manager_get_dnssec_mode(m) == DNSSEC_NO)
1388 return false;
1389
1390 server = manager_get_dns_server(m);
1391 if (server && !dns_server_dnssec_supported(server))
1392 return false;
1393
1394 HASHMAP_FOREACH(l, m->links, i)
1395 if (!link_dnssec_supported(l))
1396 return false;
1397
1398 return true;
1399}
59c5b597
LP
1400
1401void manager_dnssec_verdict(Manager *m, DnssecVerdict verdict, const DnsResourceKey *key) {
1402
1403 assert(verdict >= 0);
1404 assert(verdict < _DNSSEC_VERDICT_MAX);
1405
f1d34068 1406 if (DEBUG_LOGGING) {
202b76ae 1407 char s[DNS_RESOURCE_KEY_STRING_MAX];
59c5b597 1408
202b76ae
ZJS
1409 log_debug("Found verdict for lookup %s: %s",
1410 dns_resource_key_to_string(key, s, sizeof s),
1411 dnssec_verdict_to_string(verdict));
59c5b597
LP
1412 }
1413
1414 m->n_dnssec_verdict[verdict]++;
1415}
011696f7
LP
1416
1417bool manager_routable(Manager *m, int family) {
1418 Iterator i;
1419 Link *l;
1420
1421 assert(m);
1422
1423 /* Returns true if the host has at least one interface with a routable address of the specified type */
1424
1425 HASHMAP_FOREACH(l, m->links, i)
1426 if (link_relevant(l, family, false))
1427 return true;
1428
1429 return false;
1430}
ba35662f
LP
1431
1432void manager_flush_caches(Manager *m) {
1433 DnsScope *scope;
1434
1435 assert(m);
1436
1437 LIST_FOREACH(scopes, scope, m->dns_scopes)
1438 dns_cache_flush(&scope->cache);
aac57b35
ZJS
1439
1440 log_info("Flushed all caches.");
ba35662f 1441}
943ef07c 1442
59c0fd0e
LP
1443void manager_reset_server_features(Manager *m) {
1444 Iterator i;
1445 Link *l;
1446
1447 dns_server_reset_features_all(m->dns_servers);
1448 dns_server_reset_features_all(m->fallback_dns_servers);
1449
1450 HASHMAP_FOREACH(l, m->links, i)
1451 dns_server_reset_features_all(l->dns_servers);
1452
1453 log_info("Resetting learnt feature levels on all servers.");
1454}
1455
943ef07c
LP
1456void manager_cleanup_saved_user(Manager *m) {
1457 _cleanup_closedir_ DIR *d = NULL;
1458 struct dirent *de;
1459 int r;
1460
1461 assert(m);
1462
1463 /* Clean up all saved per-link files in /run/systemd/resolve/netif/ that don't have a matching interface
1464 * anymore. These files are created to persist settings pushed in by the user via the bus, so that resolved can
1465 * be restarted without losing this data. */
1466
1467 d = opendir("/run/systemd/resolve/netif/");
1468 if (!d) {
1469 if (errno == ENOENT)
1470 return;
1471
1472 log_warning_errno(errno, "Failed to open interface directory: %m");
1473 return;
1474 }
1475
1476 FOREACH_DIRENT_ALL(de, d, log_error_errno(errno, "Failed to read interface directory: %m")) {
1477 _cleanup_free_ char *p = NULL;
1478 int ifindex;
1479 Link *l;
1480
1481 if (!IN_SET(de->d_type, DT_UNKNOWN, DT_REG))
1482 continue;
1483
49bfc877 1484 if (dot_or_dot_dot(de->d_name))
943ef07c
LP
1485 continue;
1486
1487 r = parse_ifindex(de->d_name, &ifindex);
1488 if (r < 0) /* Probably some temporary file from a previous run. Delete it */
1489 goto rm;
1490
1491 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
1492 if (!l) /* link vanished */
1493 goto rm;
1494
1495 if (l->is_managed) /* now managed by networkd, hence the bus settings are useless */
1496 goto rm;
1497
1498 continue;
1499
1500 rm:
1501 p = strappend("/run/systemd/resolve/netif/", de->d_name);
1502 if (!p) {
1503 log_oom();
1504 return;
1505 }
1506
1507 (void) unlink(p);
1508 }
1509}
e7c1b0e4
DR
1510
1511bool manager_next_dnssd_names(Manager *m) {
1512 Iterator i;
1513 DnssdService *s;
1514 bool tried = false;
1515 int r;
1516
1517 assert(m);
1518
1519 HASHMAP_FOREACH(s, m->dnssd_services, i) {
1520 _cleanup_free_ char * new_name = NULL;
1521
1522 if (!s->withdrawn)
1523 continue;
1524
1525 r = manager_next_random_name(s->name_template, &new_name);
1526 if (r < 0) {
1527 log_warning_errno(r, "Failed to get new name for service '%s': %m", s->name);
1528 continue;
1529 }
1530
1531 free_and_replace(s->name_template, new_name);
1532
1533 s->withdrawn = false;
1534
1535 tried = true;
1536 }
1537
1538 if (tried)
1539 manager_refresh_rrs(m);
1540
1541 return tried;
1542}