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