]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/resolved-manager.c
man/udevadm: remove superfluous --version from subcommands (#8549)
[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
399 *llmnr_hostname = n;
eb60f9cd
LP
400 n = NULL;
401
e96de0ce
LP
402 *full_hostname = h;
403 h = NULL;
404
eb60f9cd
LP
405 return 0;
406}
407
a25b0dc8
LP
408static const char *fallback_hostname(void) {
409
410 /* Determine the fall back hostname. For exposing this system to the outside world, we cannot have it to be
411 * "localhost" even if that's the compiled in hostname. In this case, let's revert to "linux" instead. */
412
413 if (is_localhost(FALLBACK_HOSTNAME))
414 return "linux";
415
416 return FALLBACK_HOSTNAME;
417}
418
419static int make_fallback_hostnames(char **full_hostname, char **llmnr_hostname, char **mdns_hostname) {
420 _cleanup_free_ char *n = NULL, *m = NULL;
421 char label[DNS_LABEL_MAX], *h;
422 const char *p;
423 int r;
424
425 assert(full_hostname);
426 assert(llmnr_hostname);
427 assert(mdns_hostname);
428
429 p = fallback_hostname();
430 r = dns_label_unescape(&p, label, sizeof(label));
431 if (r < 0)
432 return log_error_errno(r, "Failed to unescape fallback host name: %m");
433
434 assert(r > 0); /* The fallback hostname must have at least one label */
435
436 r = dns_label_escape_new(label, r, &n);
437 if (r < 0)
438 return log_error_errno(r, "Failed to escape fallback hostname: %m");
439
440 r = dns_name_concat(n, "local", &m);
441 if (r < 0)
442 return log_error_errno(r, "Failed to concatenate mDNS hostname: %m");
443
444 h = strdup(fallback_hostname());
445 if (!h)
446 return log_oom();
447
448 *llmnr_hostname = n;
449 n = NULL;
450
451 *mdns_hostname = m;
452 m = NULL;
453
454 *full_hostname = h;
455
456 return 0;
457}
458
eb60f9cd 459static int on_hostname_change(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
e96de0ce 460 _cleanup_free_ char *full_hostname = NULL, *llmnr_hostname = NULL, *mdns_hostname = NULL;
eb60f9cd
LP
461 Manager *m = userdata;
462 int r;
463
464 assert(m);
465
e96de0ce 466 r = determine_hostname(&full_hostname, &llmnr_hostname, &mdns_hostname);
eb60f9cd
LP
467 if (r < 0)
468 return 0; /* ignore invalid hostnames */
469
e96de0ce
LP
470 if (streq(full_hostname, m->full_hostname) &&
471 streq(llmnr_hostname, m->llmnr_hostname) &&
472 streq(mdns_hostname, m->mdns_hostname))
eb60f9cd
LP
473 return 0;
474
e96de0ce 475 log_info("System hostname changed to '%s'.", full_hostname);
78c6a153 476
e96de0ce
LP
477 free_and_replace(m->full_hostname, full_hostname);
478 free_and_replace(m->llmnr_hostname, llmnr_hostname);
479 free_and_replace(m->mdns_hostname, mdns_hostname);
eb60f9cd
LP
480
481 manager_refresh_rrs(m);
482
483 return 0;
484}
485
486static int manager_watch_hostname(Manager *m) {
eb60f9cd
LP
487 int r;
488
489 assert(m);
490
db4a47e9
LP
491 m->hostname_fd = open("/proc/sys/kernel/hostname",
492 O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
eb60f9cd 493 if (m->hostname_fd < 0) {
56f64d95 494 log_warning_errno(errno, "Failed to watch hostname: %m");
eb60f9cd
LP
495 return 0;
496 }
497
498 r = sd_event_add_io(m->event, &m->hostname_event_source, m->hostname_fd, 0, on_hostname_change, m);
499 if (r < 0) {
500 if (r == -EPERM)
501 /* kernels prior to 3.2 don't support polling this file. Ignore the failure. */
502 m->hostname_fd = safe_close(m->hostname_fd);
8d3d7072
MS
503 else
504 return log_error_errno(r, "Failed to add hostname event source: %m");
eb60f9cd
LP
505 }
506
aa4a9deb
LP
507 (void) sd_event_source_set_description(m->hostname_event_source, "hostname");
508
e96de0ce 509 r = determine_hostname(&m->full_hostname, &m->llmnr_hostname, &m->mdns_hostname);
eb60f9cd 510 if (r < 0) {
a25b0dc8 511 log_info("Defaulting to hostname '%s'.", fallback_hostname());
78c6a153 512
a25b0dc8
LP
513 r = make_fallback_hostnames(&m->full_hostname, &m->llmnr_hostname, &m->mdns_hostname);
514 if (r < 0)
515 return r;
eb60f9cd 516 } else
e96de0ce 517 log_info("Using system hostname '%s'.", m->full_hostname);
eb60f9cd
LP
518
519 return 0;
520}
521
4d506d6b
LP
522static int manager_sigusr1(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
523 _cleanup_free_ char *buffer = NULL;
524 _cleanup_fclose_ FILE *f = NULL;
525 Manager *m = userdata;
cf84484a 526 DnsServer *server;
4d506d6b
LP
527 size_t size = 0;
528 DnsScope *scope;
cf84484a
LP
529 Iterator i;
530 Link *l;
4d506d6b
LP
531
532 assert(s);
533 assert(si);
534 assert(m);
535
536 f = open_memstream(&buffer, &size);
537 if (!f)
538 return log_oom();
539
0d536673
LP
540 (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
541
4d506d6b
LP
542 LIST_FOREACH(scopes, scope, m->dns_scopes)
543 dns_scope_dump(scope, f);
544
cf84484a
LP
545 LIST_FOREACH(servers, server, m->dns_servers)
546 dns_server_dump(server, f);
547 LIST_FOREACH(servers, server, m->fallback_dns_servers)
548 dns_server_dump(server, f);
549 HASHMAP_FOREACH(l, m->links, i)
550 LIST_FOREACH(servers, server, l->dns_servers)
551 dns_server_dump(server, f);
552
4d506d6b
LP
553 if (fflush_and_check(f) < 0)
554 return log_oom();
555
556 log_dump(LOG_INFO, buffer);
557 return 0;
558}
559
bc81447e
LP
560static int manager_sigusr2(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
561 Manager *m = userdata;
bc81447e
LP
562
563 assert(s);
564 assert(si);
565 assert(m);
566
ba35662f 567 manager_flush_caches(m);
ba35662f 568
bc81447e
LP
569 return 0;
570}
571
d55b0463
LP
572static int manager_sigrtmin1(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
573 Manager *m = userdata;
574
575 assert(s);
576 assert(si);
577 assert(m);
578
579 manager_reset_server_features(m);
580 return 0;
581}
582
091a364c 583int manager_new(Manager **ret) {
74b2466e 584 _cleanup_(manager_freep) Manager *m = NULL;
091a364c
TG
585 int r;
586
c92e531c
LP
587 assert(ret);
588
091a364c
TG
589 m = new0(Manager, 1);
590 if (!m)
591 return -ENOMEM;
592
1716f6dc 593 m->llmnr_ipv4_udp_fd = m->llmnr_ipv6_udp_fd = -1;
623a4c97 594 m->llmnr_ipv4_tcp_fd = m->llmnr_ipv6_tcp_fd = -1;
bc7702b0 595 m->mdns_ipv4_fd = m->mdns_ipv6_fd = -1;
b30bf55d 596 m->dns_stub_udp_fd = m->dns_stub_tcp_fd = -1;
eb60f9cd 597 m->hostname_fd = -1;
1716f6dc 598
af49ca27 599 m->llmnr_support = RESOLVE_SUPPORT_YES;
7bef8e8e 600 m->mdns_support = RESOLVE_SUPPORT_YES;
61ecb465 601 m->dnssec_mode = DEFAULT_DNSSEC_MODE;
ceeddf79 602 m->enable_cache = true;
1ae43295 603 m->dns_stub_listener_mode = DNS_STUB_LISTENER_UDP;
5cb36f41 604 m->read_resolv_conf = true;
00fa60ae 605 m->need_builtin_fallbacks = true;
dd0bc0f1 606 m->etc_hosts_last = m->etc_hosts_mtime = USEC_INFINITY;
091a364c 607
0d2cd476
LP
608 r = dns_trust_anchor_load(&m->trust_anchor);
609 if (r < 0)
610 return r;
611
ad6c0475
LP
612 r = manager_parse_config_file(m);
613 if (r < 0)
5ce497b5 614 log_warning_errno(r, "Failed to parse configuration file: %m");
ad6c0475 615
091a364c
TG
616 r = sd_event_default(&m->event);
617 if (r < 0)
618 return r;
619
620 sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
621 sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
622
623 sd_event_set_watchdog(m->event, true);
624
eb60f9cd
LP
625 r = manager_watch_hostname(m);
626 if (r < 0)
627 return r;
628
6501dd31
DR
629 r = dnssd_load(m);
630 if (r < 0)
631 log_warning_errno(r, "Failed to load DNS-SD configuration files: %m");
632
1716f6dc 633 r = dns_scope_new(m, &m->unicast_scope, NULL, DNS_PROTOCOL_DNS, AF_UNSPEC);
74b2466e
LP
634 if (r < 0)
635 return r;
636
637 r = manager_network_monitor_listen(m);
638 if (r < 0)
639 return r;
640
641 r = manager_rtnl_listen(m);
642 if (r < 0)
643 return r;
644
645 r = manager_connect_bus(m);
646 if (r < 0)
647 return r;
648
4d506d6b 649 (void) sd_event_add_signal(m->event, &m->sigusr1_event_source, SIGUSR1, manager_sigusr1, m);
bc81447e 650 (void) sd_event_add_signal(m->event, &m->sigusr2_event_source, SIGUSR2, manager_sigusr2, m);
d55b0463 651 (void) sd_event_add_signal(m->event, &m->sigrtmin1_event_source, SIGRTMIN+1, manager_sigrtmin1, m);
4d506d6b 652
943ef07c
LP
653 manager_cleanup_saved_user(m);
654
091a364c
TG
655 *ret = m;
656 m = NULL;
657
658 return 0;
659}
660
edc501d4
LP
661int manager_start(Manager *m) {
662 int r;
663
664 assert(m);
665
b30bf55d
LP
666 r = manager_dns_stub_start(m);
667 if (r < 0)
668 return r;
669
edc501d4
LP
670 return 0;
671}
672
74b2466e
LP
673Manager *manager_free(Manager *m) {
674 Link *l;
6501dd31 675 DnssdService *s;
091a364c
TG
676
677 if (!m)
74b2466e
LP
678 return NULL;
679
4b95f179
LP
680 dns_server_unlink_all(m->dns_servers);
681 dns_server_unlink_all(m->fallback_dns_servers);
a51c1048
LP
682 dns_search_domain_unlink_all(m->search_domains);
683
74b2466e
LP
684 while ((l = hashmap_first(m->links)))
685 link_free(l);
f0e15467
LP
686
687 while (m->dns_queries)
688 dns_query_free(m->dns_queries);
74b2466e 689
cab5b059
LP
690 dns_scope_free(m->unicast_scope);
691
b30bf55d
LP
692 /* At this point only orphaned streams should remain. All others should have been freed already by their
693 * owners */
694 while (m->dns_streams)
695 dns_stream_unref(m->dns_streams);
696
f0e15467
LP
697 hashmap_free(m->links);
698 hashmap_free(m->dns_transactions);
699
096b6773
LP
700 sd_event_source_unref(m->network_event_source);
701 sd_network_monitor_unref(m->network_monitor);
091a364c 702
a564ca2f
LP
703 sd_netlink_unref(m->rtnl);
704 sd_event_source_unref(m->rtnl_event_source);
705
edc501d4 706 manager_llmnr_stop(m);
bc7702b0 707 manager_mdns_stop(m);
b30bf55d 708 manager_dns_stub_stop(m);
623a4c97 709
902bb5d8 710 sd_bus_slot_unref(m->prepare_for_sleep_slot);
74b2466e
LP
711 sd_event_source_unref(m->bus_retry_event_source);
712 sd_bus_unref(m->bus);
091a364c 713
4d506d6b 714 sd_event_source_unref(m->sigusr1_event_source);
bc81447e 715 sd_event_source_unref(m->sigusr2_event_source);
d55b0463 716 sd_event_source_unref(m->sigrtmin1_event_source);
4d506d6b 717
74b2466e 718 sd_event_unref(m->event);
623a4c97 719
78c6a153
LP
720 dns_resource_key_unref(m->llmnr_host_ipv4_key);
721 dns_resource_key_unref(m->llmnr_host_ipv6_key);
400cb36e
DR
722 dns_resource_key_unref(m->mdns_host_ipv4_key);
723 dns_resource_key_unref(m->mdns_host_ipv6_key);
eb60f9cd 724
eb60f9cd 725 sd_event_source_unref(m->hostname_event_source);
d9fcf2ba 726 safe_close(m->hostname_fd);
e96de0ce
LP
727
728 free(m->full_hostname);
78c6a153
LP
729 free(m->llmnr_hostname);
730 free(m->mdns_hostname);
eb60f9cd 731
6501dd31
DR
732 while ((s = hashmap_first(m->dnssd_services)))
733 dnssd_service_free(s);
734 hashmap_free(m->dnssd_services);
735
0d2cd476 736 dns_trust_anchor_flush(&m->trust_anchor);
dd0bc0f1 737 manager_etc_hosts_flush(m);
0d2cd476 738
6b430fdb 739 return mfree(m);
091a364c
TG
740}
741
1716f6dc 742int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) {
74b2466e 743 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
1716f6dc
LP
744 union {
745 struct cmsghdr header; /* For alignment */
40a1eebd 746 uint8_t buffer[CMSG_SPACE(MAXSIZE(struct in_pktinfo, struct in6_pktinfo))
1716f6dc 747 + CMSG_SPACE(int) /* ttl/hoplimit */
623a4c97 748 + EXTRA_CMSG_SPACE /* kernel appears to require extra buffer space */];
1716f6dc
LP
749 } control;
750 union sockaddr_union sa;
74b2466e 751 struct msghdr mh = {};
1716f6dc 752 struct cmsghdr *cmsg;
74b2466e 753 struct iovec iov;
4edc2c9b
LP
754 ssize_t ms, l;
755 int r;
74b2466e
LP
756
757 assert(m);
1716f6dc 758 assert(fd >= 0);
74b2466e
LP
759 assert(ret);
760
4edc2c9b 761 ms = next_datagram_size_fd(fd);
74b2466e 762 if (ms < 0)
4edc2c9b 763 return ms;
74b2466e 764
51027656 765 r = dns_packet_new(&p, protocol, ms, DNS_PACKET_SIZE_MAX);
74b2466e
LP
766 if (r < 0)
767 return r;
768
769 iov.iov_base = DNS_PACKET_DATA(p);
770 iov.iov_len = p->allocated;
771
1716f6dc
LP
772 mh.msg_name = &sa.sa;
773 mh.msg_namelen = sizeof(sa);
74b2466e
LP
774 mh.msg_iov = &iov;
775 mh.msg_iovlen = 1;
1716f6dc
LP
776 mh.msg_control = &control;
777 mh.msg_controllen = sizeof(control);
74b2466e 778
a38d9945 779 l = recvmsg(fd, &mh, 0);
f134289a
EV
780 if (l == 0)
781 return 0;
74b2466e 782 if (l < 0) {
4c701096 783 if (IN_SET(errno, EAGAIN, EINTR))
74b2466e
LP
784 return 0;
785
786 return -errno;
091a364c
TG
787 }
788
1716f6dc
LP
789 assert(!(mh.msg_flags & MSG_CTRUNC));
790 assert(!(mh.msg_flags & MSG_TRUNC));
791
74b2466e 792 p->size = (size_t) l;
091a364c 793
1716f6dc 794 p->family = sa.sa.sa_family;
623a4c97
LP
795 p->ipproto = IPPROTO_UDP;
796 if (p->family == AF_INET) {
1716f6dc 797 p->sender.in = sa.in.sin_addr;
623a4c97
LP
798 p->sender_port = be16toh(sa.in.sin_port);
799 } else if (p->family == AF_INET6) {
1716f6dc 800 p->sender.in6 = sa.in6.sin6_addr;
623a4c97
LP
801 p->sender_port = be16toh(sa.in6.sin6_port);
802 p->ifindex = sa.in6.sin6_scope_id;
803 } else
1716f6dc 804 return -EAFNOSUPPORT;
74b2466e 805
2a1288ff 806 CMSG_FOREACH(cmsg, &mh) {
74b2466e 807
1716f6dc
LP
808 if (cmsg->cmsg_level == IPPROTO_IPV6) {
809 assert(p->family == AF_INET6);
74b2466e 810
1716f6dc 811 switch (cmsg->cmsg_type) {
74b2466e 812
1716f6dc
LP
813 case IPV6_PKTINFO: {
814 struct in6_pktinfo *i = (struct in6_pktinfo*) CMSG_DATA(cmsg);
74b2466e 815
623a4c97
LP
816 if (p->ifindex <= 0)
817 p->ifindex = i->ipi6_ifindex;
818
1716f6dc
LP
819 p->destination.in6 = i->ipi6_addr;
820 break;
821 }
74b2466e 822
1716f6dc
LP
823 case IPV6_HOPLIMIT:
824 p->ttl = *(int *) CMSG_DATA(cmsg);
825 break;
74b2466e 826
1716f6dc
LP
827 }
828 } else if (cmsg->cmsg_level == IPPROTO_IP) {
829 assert(p->family == AF_INET);
74b2466e 830
1716f6dc 831 switch (cmsg->cmsg_type) {
74b2466e 832
1716f6dc
LP
833 case IP_PKTINFO: {
834 struct in_pktinfo *i = (struct in_pktinfo*) CMSG_DATA(cmsg);
091a364c 835
623a4c97
LP
836 if (p->ifindex <= 0)
837 p->ifindex = i->ipi_ifindex;
838
1716f6dc
LP
839 p->destination.in = i->ipi_addr;
840 break;
841 }
74b2466e 842
623a4c97 843 case IP_TTL:
1716f6dc
LP
844 p->ttl = *(int *) CMSG_DATA(cmsg);
845 break;
846 }
847 }
848 }
74b2466e 849
623a4c97
LP
850 /* The Linux kernel sets the interface index to the loopback
851 * device if the packet came from the local host since it
852 * avoids the routing table in such a case. Let's unset the
853 * interface index in such a case. */
a5f03596 854 if (p->ifindex == LOOPBACK_IFINDEX)
623a4c97
LP
855 p->ifindex = 0;
856
86ad4cd7
TG
857 if (protocol != DNS_PROTOCOL_DNS) {
858 /* If we don't know the interface index still, we look for the
859 * first local interface with a matching address. Yuck! */
860 if (p->ifindex <= 0)
861 p->ifindex = manager_find_ifindex(m, p->family, &p->destination);
862 }
623a4c97 863
74b2466e
LP
864 *ret = p;
865 p = NULL;
866
867 return 1;
868}
869
74b2466e
LP
870static int sendmsg_loop(int fd, struct msghdr *mh, int flags) {
871 int r;
872
873 assert(fd >= 0);
874 assert(mh);
875
876 for (;;) {
877 if (sendmsg(fd, mh, flags) >= 0)
878 return 0;
879
880 if (errno == EINTR)
881 continue;
882
883 if (errno != EAGAIN)
884 return -errno;
885
886 r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
887 if (r < 0)
888 return r;
889 if (r == 0)
890 return -ETIMEDOUT;
891 }
892}
893
72290734
TG
894static int write_loop(int fd, void *message, size_t length) {
895 int r;
896
897 assert(fd >= 0);
898 assert(message);
899
900 for (;;) {
901 if (write(fd, message, length) >= 0)
902 return 0;
903
904 if (errno == EINTR)
905 continue;
906
907 if (errno != EAGAIN)
908 return -errno;
909
910 r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
911 if (r < 0)
912 return r;
913 if (r == 0)
914 return -ETIMEDOUT;
915 }
916}
917
918int manager_write(Manager *m, int fd, DnsPacket *p) {
919 int r;
920
deb3f3d3 921 log_debug("Sending %s packet with id %" PRIu16 ".", DNS_PACKET_QR(p) ? "response" : "query", DNS_PACKET_ID(p));
72290734
TG
922
923 r = write_loop(fd, DNS_PACKET_DATA(p), p->size);
924 if (r < 0)
925 return r;
926
927 return 0;
928}
929
b30bf55d
LP
930static int manager_ipv4_send(
931 Manager *m,
932 int fd,
933 int ifindex,
934 const struct in_addr *destination,
935 uint16_t port,
936 const struct in_addr *source,
937 DnsPacket *p) {
74b2466e
LP
938 union sockaddr_union sa = {
939 .in.sin_family = AF_INET,
74b2466e 940 };
1716f6dc
LP
941 union {
942 struct cmsghdr header; /* For alignment */
943 uint8_t buffer[CMSG_SPACE(sizeof(struct in_pktinfo))];
944 } control;
74b2466e
LP
945 struct msghdr mh = {};
946 struct iovec iov;
74b2466e
LP
947
948 assert(m);
1716f6dc 949 assert(fd >= 0);
b30bf55d 950 assert(destination);
1716f6dc 951 assert(port > 0);
74b2466e
LP
952 assert(p);
953
74b2466e
LP
954 iov.iov_base = DNS_PACKET_DATA(p);
955 iov.iov_len = p->size;
091a364c 956
b30bf55d 957 sa.in.sin_addr = *destination;
1716f6dc 958 sa.in.sin_port = htobe16(port),
091a364c 959
74b2466e
LP
960 mh.msg_iov = &iov;
961 mh.msg_iovlen = 1;
962 mh.msg_name = &sa.sa;
963 mh.msg_namelen = sizeof(sa.in);
091a364c 964
74b2466e
LP
965 if (ifindex > 0) {
966 struct cmsghdr *cmsg;
967 struct in_pktinfo *pi;
968
969 zero(control);
970
1716f6dc 971 mh.msg_control = &control;
74b2466e
LP
972 mh.msg_controllen = CMSG_LEN(sizeof(struct in_pktinfo));
973
974 cmsg = CMSG_FIRSTHDR(&mh);
975 cmsg->cmsg_len = mh.msg_controllen;
976 cmsg->cmsg_level = IPPROTO_IP;
977 cmsg->cmsg_type = IP_PKTINFO;
978
979 pi = (struct in_pktinfo*) CMSG_DATA(cmsg);
980 pi->ipi_ifindex = ifindex;
b30bf55d
LP
981
982 if (source)
983 pi->ipi_spec_dst = *source;
74b2466e
LP
984 }
985
986 return sendmsg_loop(fd, &mh, 0);
987}
988
b30bf55d
LP
989static int manager_ipv6_send(
990 Manager *m,
991 int fd,
992 int ifindex,
993 const struct in6_addr *destination,
994 uint16_t port,
995 const struct in6_addr *source,
996 DnsPacket *p) {
997
74b2466e
LP
998 union sockaddr_union sa = {
999 .in6.sin6_family = AF_INET6,
74b2466e 1000 };
1716f6dc
LP
1001 union {
1002 struct cmsghdr header; /* For alignment */
1003 uint8_t buffer[CMSG_SPACE(sizeof(struct in6_pktinfo))];
1004 } control;
74b2466e
LP
1005 struct msghdr mh = {};
1006 struct iovec iov;
74b2466e
LP
1007
1008 assert(m);
1716f6dc 1009 assert(fd >= 0);
b30bf55d 1010 assert(destination);
1716f6dc 1011 assert(port > 0);
74b2466e
LP
1012 assert(p);
1013
74b2466e
LP
1014 iov.iov_base = DNS_PACKET_DATA(p);
1015 iov.iov_len = p->size;
1016
b30bf55d 1017 sa.in6.sin6_addr = *destination;
1716f6dc 1018 sa.in6.sin6_port = htobe16(port),
74b2466e
LP
1019 sa.in6.sin6_scope_id = ifindex;
1020
1021 mh.msg_iov = &iov;
1022 mh.msg_iovlen = 1;
1023 mh.msg_name = &sa.sa;
1024 mh.msg_namelen = sizeof(sa.in6);
1025
1026 if (ifindex > 0) {
1027 struct cmsghdr *cmsg;
1028 struct in6_pktinfo *pi;
1029
1030 zero(control);
1031
1716f6dc 1032 mh.msg_control = &control;
74b2466e
LP
1033 mh.msg_controllen = CMSG_LEN(sizeof(struct in6_pktinfo));
1034
1035 cmsg = CMSG_FIRSTHDR(&mh);
1036 cmsg->cmsg_len = mh.msg_controllen;
1037 cmsg->cmsg_level = IPPROTO_IPV6;
1038 cmsg->cmsg_type = IPV6_PKTINFO;
1039
1040 pi = (struct in6_pktinfo*) CMSG_DATA(cmsg);
1041 pi->ipi6_ifindex = ifindex;
b30bf55d
LP
1042
1043 if (source)
1044 pi->ipi6_addr = *source;
74b2466e
LP
1045 }
1046
1047 return sendmsg_loop(fd, &mh, 0);
1048}
1049
b30bf55d
LP
1050int manager_send(
1051 Manager *m,
1052 int fd,
1053 int ifindex,
1054 int family,
1055 const union in_addr_union *destination,
1056 uint16_t port,
1057 const union in_addr_union *source,
1058 DnsPacket *p) {
1059
1716f6dc
LP
1060 assert(m);
1061 assert(fd >= 0);
b30bf55d 1062 assert(destination);
1716f6dc
LP
1063 assert(port > 0);
1064 assert(p);
1065
deb3f3d3 1066 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 1067
1716f6dc 1068 if (family == AF_INET)
b30bf55d 1069 return manager_ipv4_send(m, fd, ifindex, &destination->in, port, &source->in, p);
2817157b 1070 if (family == AF_INET6)
b30bf55d 1071 return manager_ipv6_send(m, fd, ifindex, &destination->in6, port, &source->in6, p);
1716f6dc
LP
1072
1073 return -EAFNOSUPPORT;
1074}
1075
e1c95994
LP
1076uint32_t manager_find_mtu(Manager *m) {
1077 uint32_t mtu = 0;
1078 Link *l;
1079 Iterator i;
1080
1081 /* If we don't know on which link a DNS packet would be
1082 * delivered, let's find the largest MTU that works on all
1083 * interfaces we know of */
1084
1085 HASHMAP_FOREACH(l, m->links, i) {
1086 if (l->mtu <= 0)
1087 continue;
1088
1089 if (mtu <= 0 || l->mtu < mtu)
1090 mtu = l->mtu;
1091 }
1092
1093 return mtu;
1094}
1716f6dc 1095
623a4c97 1096int manager_find_ifindex(Manager *m, int family, const union in_addr_union *in_addr) {
ec2c5e43
LP
1097 LinkAddress *a;
1098
1099 assert(m);
1100
4e945a6f 1101 a = manager_find_link_address(m, family, in_addr);
ec2c5e43
LP
1102 if (a)
1103 return a->link->ifindex;
1104
1105 return 0;
1106}
1107
eb60f9cd
LP
1108void manager_refresh_rrs(Manager *m) {
1109 Iterator i;
1110 Link *l;
6db6a464 1111 DnssdService *s;
eb60f9cd
LP
1112
1113 assert(m);
1114
78c6a153
LP
1115 m->llmnr_host_ipv4_key = dns_resource_key_unref(m->llmnr_host_ipv4_key);
1116 m->llmnr_host_ipv6_key = dns_resource_key_unref(m->llmnr_host_ipv6_key);
400cb36e
DR
1117 m->mdns_host_ipv4_key = dns_resource_key_unref(m->mdns_host_ipv4_key);
1118 m->mdns_host_ipv6_key = dns_resource_key_unref(m->mdns_host_ipv6_key);
eb60f9cd 1119
6db6a464
DR
1120 if (m->mdns_support == RESOLVE_SUPPORT_YES)
1121 HASHMAP_FOREACH(s, m->dnssd_services, i)
1122 if (dnssd_update_rrs(s) < 0)
1123 log_warning("Failed to refresh DNS-SD service '%s'", s->name);
1124
eb60f9cd
LP
1125 HASHMAP_FOREACH(l, m->links, i) {
1126 link_add_rrs(l, true);
1127 link_add_rrs(l, false);
1128 }
1129}
1130
e7c1b0e4 1131static int manager_next_random_name(const char *old, char **ret_new) {
ec2c5e43 1132 const char *p;
556a2294 1133 uint64_t u, a;
e7c1b0e4 1134 char *n;
623a4c97 1135
e7c1b0e4 1136 p = strchr(old, 0);
ec2c5e43
LP
1137 assert(p);
1138
e7c1b0e4
DR
1139 while (p > old) {
1140 if (!strchr(DIGITS, p[-1]))
ec2c5e43
LP
1141 break;
1142
1143 p--;
1144 }
1145
1146 if (*p == 0 || safe_atou64(p, &u) < 0 || u <= 0)
1147 u = 1;
1148
556a2294
LP
1149 /* Add a random number to the old value. This way we can avoid
1150 * that two hosts pick the same hostname, win on IPv4 and lose
1151 * on IPv6 (or vice versa), and pick the same hostname
1152 * replacement hostname, ad infinitum. We still want the
1153 * numbers to go up monotonically, hence we just add a random
1154 * value 1..10 */
1155
1156 random_bytes(&a, sizeof(a));
1157 u += 1 + a % 10;
ec2c5e43 1158
e7c1b0e4 1159 if (asprintf(&n, "%.*s%" PRIu64, (int) (p - old), old, u) < 0)
ec2c5e43
LP
1160 return -ENOMEM;
1161
e7c1b0e4
DR
1162 *ret_new = n;
1163
1164 return 0;
1165}
1166
1167int manager_next_hostname(Manager *m) {
1168 _cleanup_free_ char *h = NULL, *k = NULL;
1169 int r;
1170
1171 assert(m);
1172
1173 r = manager_next_random_name(m->llmnr_hostname, &h);
1174 if (r < 0)
1175 return r;
1176
78c6a153 1177 r = dns_name_concat(h, "local", &k);
e7c1b0e4 1178 if (r < 0)
78c6a153 1179 return r;
78c6a153
LP
1180
1181 log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m->llmnr_hostname, h);
1182
e7c1b0e4
DR
1183 free_and_replace(m->llmnr_hostname, h);
1184 free_and_replace(m->mdns_hostname, k);
ec2c5e43 1185
eb60f9cd 1186 manager_refresh_rrs(m);
623a4c97
LP
1187
1188 return 0;
1189}
ec2c5e43 1190
4e945a6f 1191LinkAddress* manager_find_link_address(Manager *m, int family, const union in_addr_union *in_addr) {
ec2c5e43
LP
1192 Iterator i;
1193 Link *l;
1194
1195 assert(m);
1196
1197 HASHMAP_FOREACH(l, m->links, i) {
1198 LinkAddress *a;
1199
1200 a = link_find_address(l, family, in_addr);
1201 if (a)
1202 return a;
1203 }
1204
1205 return NULL;
1206}
1207
a4076574 1208bool manager_our_packet(Manager *m, DnsPacket *p) {
ec2c5e43
LP
1209 assert(m);
1210 assert(p);
1211
4e945a6f 1212 return !!manager_find_link_address(m, p->family, &p->sender);
ec2c5e43 1213}
4e945a6f 1214
a4076574
LP
1215DnsScope* manager_find_scope(Manager *m, DnsPacket *p) {
1216 Link *l;
1217
1218 assert(m);
1219 assert(p);
1220
1221 l = hashmap_get(m->links, INT_TO_PTR(p->ifindex));
1222 if (!l)
1223 return NULL;
1224
b4f1862d
DM
1225 switch (p->protocol) {
1226 case DNS_PROTOCOL_LLMNR:
a4076574
LP
1227 if (p->family == AF_INET)
1228 return l->llmnr_ipv4_scope;
1229 else if (p->family == AF_INET6)
1230 return l->llmnr_ipv6_scope;
b4f1862d
DM
1231
1232 break;
1233
1234 case DNS_PROTOCOL_MDNS:
1235 if (p->family == AF_INET)
1236 return l->mdns_ipv4_scope;
1237 else if (p->family == AF_INET6)
1238 return l->mdns_ipv6_scope;
1239
1240 break;
1241
1242 default:
1243 break;
a4076574
LP
1244 }
1245
1246 return NULL;
1247}
1248
902bb5d8
LP
1249void manager_verify_all(Manager *m) {
1250 DnsScope *s;
1251
1252 assert(m);
1253
1254 LIST_FOREACH(scopes, s, m->dns_scopes)
1255 dns_zone_verify_all(&s->zone);
1256}
1257
78c6a153 1258int manager_is_own_hostname(Manager *m, const char *name) {
78c6a153
LP
1259 int r;
1260
1261 assert(m);
1262 assert(name);
1263
1264 if (m->llmnr_hostname) {
1265 r = dns_name_equal(name, m->llmnr_hostname);
1266 if (r != 0)
1267 return r;
1268 }
1269
e96de0ce
LP
1270 if (m->mdns_hostname) {
1271 r = dns_name_equal(name, m->mdns_hostname);
1272 if (r != 0)
1273 return r;
1274 }
1275
1276 if (m->full_hostname)
1277 return dns_name_equal(name, m->full_hostname);
78c6a153
LP
1278
1279 return 0;
1280}
1281
9176a57c
LP
1282int manager_compile_dns_servers(Manager *m, OrderedSet **dns) {
1283 DnsServer *s;
1284 Iterator i;
1285 Link *l;
1286 int r;
1287
1288 assert(m);
1289 assert(dns);
1290
1291 r = ordered_set_ensure_allocated(dns, &dns_server_hash_ops);
1292 if (r < 0)
1293 return r;
1294
1295 /* First add the system-wide servers and domains */
1296 LIST_FOREACH(servers, s, m->dns_servers) {
1297 r = ordered_set_put(*dns, s);
1298 if (r == -EEXIST)
1299 continue;
1300 if (r < 0)
1301 return r;
1302 }
1303
1304 /* Then, add the per-link servers */
1305 HASHMAP_FOREACH(l, m->links, i) {
1306 LIST_FOREACH(servers, s, l->dns_servers) {
1307 r = ordered_set_put(*dns, s);
1308 if (r == -EEXIST)
1309 continue;
1310 if (r < 0)
1311 return r;
1312 }
1313 }
1314
1315 /* If we found nothing, add the fallback servers */
1316 if (ordered_set_isempty(*dns)) {
1317 LIST_FOREACH(servers, s, m->fallback_dns_servers) {
1318 r = ordered_set_put(*dns, s);
1319 if (r == -EEXIST)
1320 continue;
1321 if (r < 0)
1322 return r;
1323 }
1324 }
1325
1326 return 0;
1327}
1328
94363cbb
MP
1329/* filter_route is a tri-state:
1330 * < 0: no filtering
1331 * = 0 or false: return only domains which should be used for searching
1332 * > 0 or true: return only domains which are for routing only
1333 */
6f7da49d 1334int manager_compile_search_domains(Manager *m, OrderedSet **domains, int filter_route) {
9176a57c
LP
1335 DnsSearchDomain *d;
1336 Iterator i;
1337 Link *l;
1338 int r;
1339
1340 assert(m);
1341 assert(domains);
1342
1343 r = ordered_set_ensure_allocated(domains, &dns_name_hash_ops);
1344 if (r < 0)
1345 return r;
1346
1347 LIST_FOREACH(domains, d, m->search_domains) {
6f7da49d
LP
1348
1349 if (filter_route >= 0 &&
1350 d->route_only != !!filter_route)
1351 continue;
1352
9176a57c
LP
1353 r = ordered_set_put(*domains, d->name);
1354 if (r == -EEXIST)
1355 continue;
1356 if (r < 0)
1357 return r;
1358 }
1359
1360 HASHMAP_FOREACH(l, m->links, i) {
1361
1362 LIST_FOREACH(domains, d, l->search_domains) {
6f7da49d
LP
1363
1364 if (filter_route >= 0 &&
1365 d->route_only != !!filter_route)
1366 continue;
1367
9176a57c
LP
1368 r = ordered_set_put(*domains, d->name);
1369 if (r == -EEXIST)
1370 continue;
1371 if (r < 0)
1372 return r;
1373 }
1374 }
1375
1376 return 0;
1377}
c69fa7e3
LP
1378
1379DnssecMode manager_get_dnssec_mode(Manager *m) {
1380 assert(m);
1381
1382 if (m->dnssec_mode != _DNSSEC_MODE_INVALID)
1383 return m->dnssec_mode;
1384
1385 return DNSSEC_NO;
1386}
1387
1388bool manager_dnssec_supported(Manager *m) {
1389 DnsServer *server;
1390 Iterator i;
1391 Link *l;
1392
1393 assert(m);
1394
1395 if (manager_get_dnssec_mode(m) == DNSSEC_NO)
1396 return false;
1397
1398 server = manager_get_dns_server(m);
1399 if (server && !dns_server_dnssec_supported(server))
1400 return false;
1401
1402 HASHMAP_FOREACH(l, m->links, i)
1403 if (!link_dnssec_supported(l))
1404 return false;
1405
1406 return true;
1407}
59c5b597
LP
1408
1409void manager_dnssec_verdict(Manager *m, DnssecVerdict verdict, const DnsResourceKey *key) {
1410
1411 assert(verdict >= 0);
1412 assert(verdict < _DNSSEC_VERDICT_MAX);
1413
f1d34068 1414 if (DEBUG_LOGGING) {
202b76ae 1415 char s[DNS_RESOURCE_KEY_STRING_MAX];
59c5b597 1416
202b76ae
ZJS
1417 log_debug("Found verdict for lookup %s: %s",
1418 dns_resource_key_to_string(key, s, sizeof s),
1419 dnssec_verdict_to_string(verdict));
59c5b597
LP
1420 }
1421
1422 m->n_dnssec_verdict[verdict]++;
1423}
011696f7
LP
1424
1425bool manager_routable(Manager *m, int family) {
1426 Iterator i;
1427 Link *l;
1428
1429 assert(m);
1430
1431 /* Returns true if the host has at least one interface with a routable address of the specified type */
1432
1433 HASHMAP_FOREACH(l, m->links, i)
1434 if (link_relevant(l, family, false))
1435 return true;
1436
1437 return false;
1438}
ba35662f
LP
1439
1440void manager_flush_caches(Manager *m) {
1441 DnsScope *scope;
1442
1443 assert(m);
1444
1445 LIST_FOREACH(scopes, scope, m->dns_scopes)
1446 dns_cache_flush(&scope->cache);
aac57b35
ZJS
1447
1448 log_info("Flushed all caches.");
ba35662f 1449}
943ef07c 1450
59c0fd0e
LP
1451void manager_reset_server_features(Manager *m) {
1452 Iterator i;
1453 Link *l;
1454
1455 dns_server_reset_features_all(m->dns_servers);
1456 dns_server_reset_features_all(m->fallback_dns_servers);
1457
1458 HASHMAP_FOREACH(l, m->links, i)
1459 dns_server_reset_features_all(l->dns_servers);
1460
1461 log_info("Resetting learnt feature levels on all servers.");
1462}
1463
943ef07c
LP
1464void manager_cleanup_saved_user(Manager *m) {
1465 _cleanup_closedir_ DIR *d = NULL;
1466 struct dirent *de;
1467 int r;
1468
1469 assert(m);
1470
1471 /* Clean up all saved per-link files in /run/systemd/resolve/netif/ that don't have a matching interface
1472 * anymore. These files are created to persist settings pushed in by the user via the bus, so that resolved can
1473 * be restarted without losing this data. */
1474
1475 d = opendir("/run/systemd/resolve/netif/");
1476 if (!d) {
1477 if (errno == ENOENT)
1478 return;
1479
1480 log_warning_errno(errno, "Failed to open interface directory: %m");
1481 return;
1482 }
1483
1484 FOREACH_DIRENT_ALL(de, d, log_error_errno(errno, "Failed to read interface directory: %m")) {
1485 _cleanup_free_ char *p = NULL;
1486 int ifindex;
1487 Link *l;
1488
1489 if (!IN_SET(de->d_type, DT_UNKNOWN, DT_REG))
1490 continue;
1491
49bfc877 1492 if (dot_or_dot_dot(de->d_name))
943ef07c
LP
1493 continue;
1494
1495 r = parse_ifindex(de->d_name, &ifindex);
1496 if (r < 0) /* Probably some temporary file from a previous run. Delete it */
1497 goto rm;
1498
1499 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
1500 if (!l) /* link vanished */
1501 goto rm;
1502
1503 if (l->is_managed) /* now managed by networkd, hence the bus settings are useless */
1504 goto rm;
1505
1506 continue;
1507
1508 rm:
1509 p = strappend("/run/systemd/resolve/netif/", de->d_name);
1510 if (!p) {
1511 log_oom();
1512 return;
1513 }
1514
1515 (void) unlink(p);
1516 }
1517}
e7c1b0e4
DR
1518
1519bool manager_next_dnssd_names(Manager *m) {
1520 Iterator i;
1521 DnssdService *s;
1522 bool tried = false;
1523 int r;
1524
1525 assert(m);
1526
1527 HASHMAP_FOREACH(s, m->dnssd_services, i) {
1528 _cleanup_free_ char * new_name = NULL;
1529
1530 if (!s->withdrawn)
1531 continue;
1532
1533 r = manager_next_random_name(s->name_template, &new_name);
1534 if (r < 0) {
1535 log_warning_errno(r, "Failed to get new name for service '%s': %m", s->name);
1536 continue;
1537 }
1538
1539 free_and_replace(s->name_template, new_name);
1540
1541 s->withdrawn = false;
1542
1543 tried = true;
1544 }
1545
1546 if (tried)
1547 manager_refresh_rrs(m);
1548
1549 return tried;
1550}