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