]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-manager.c
resolved: rework what ResolveHostname() with family == AF_UNSPEC means
[thirdparty/systemd.git] / src / resolve / resolved-manager.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2014 Tom Gundersen <teg@jklm.no>
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <netinet/in.h>
23 #include <poll.h>
24 #include <sys/ioctl.h>
25
26 #include "af-list.h"
27 #include "alloc-util.h"
28 #include "dns-domain.h"
29 #include "fd-util.h"
30 #include "fileio-label.h"
31 #include "hostname-util.h"
32 #include "io-util.h"
33 #include "netlink-util.h"
34 #include "network-internal.h"
35 #include "ordered-set.h"
36 #include "parse-util.h"
37 #include "random-util.h"
38 #include "resolved-bus.h"
39 #include "resolved-conf.h"
40 #include "resolved-etc-hosts.h"
41 #include "resolved-llmnr.h"
42 #include "resolved-manager.h"
43 #include "resolved-mdns.h"
44 #include "resolved-resolv-conf.h"
45 #include "socket-util.h"
46 #include "string-table.h"
47 #include "string-util.h"
48 #include "utf8.h"
49
50 #define SEND_TIMEOUT_USEC (200 * USEC_PER_MSEC)
51
52 static int manager_process_link(sd_netlink *rtnl, sd_netlink_message *mm, void *userdata) {
53 Manager *m = userdata;
54 uint16_t type;
55 Link *l;
56 int ifindex, r;
57
58 assert(rtnl);
59 assert(m);
60 assert(mm);
61
62 r = sd_netlink_message_get_type(mm, &type);
63 if (r < 0)
64 goto fail;
65
66 r = sd_rtnl_message_link_get_ifindex(mm, &ifindex);
67 if (r < 0)
68 goto fail;
69
70 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
71
72 switch (type) {
73
74 case RTM_NEWLINK:{
75 bool is_new = !l;
76
77 if (!l) {
78 r = link_new(m, &l, ifindex);
79 if (r < 0)
80 goto fail;
81 }
82
83 r = link_update_rtnl(l, mm);
84 if (r < 0)
85 goto fail;
86
87 r = link_update_monitor(l);
88 if (r < 0)
89 goto fail;
90
91 if (is_new)
92 log_debug("Found new link %i/%s", ifindex, l->name);
93
94 break;
95 }
96
97 case RTM_DELLINK:
98 if (l) {
99 log_debug("Removing link %i/%s", l->ifindex, l->name);
100 link_free(l);
101 }
102
103 break;
104 }
105
106 return 0;
107
108 fail:
109 log_warning_errno(r, "Failed to process RTNL link message: %m");
110 return 0;
111 }
112
113 static int manager_process_address(sd_netlink *rtnl, sd_netlink_message *mm, void *userdata) {
114 Manager *m = userdata;
115 union in_addr_union address;
116 uint16_t type;
117 int r, ifindex, family;
118 LinkAddress *a;
119 Link *l;
120
121 assert(rtnl);
122 assert(mm);
123 assert(m);
124
125 r = sd_netlink_message_get_type(mm, &type);
126 if (r < 0)
127 goto fail;
128
129 r = sd_rtnl_message_addr_get_ifindex(mm, &ifindex);
130 if (r < 0)
131 goto fail;
132
133 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
134 if (!l)
135 return 0;
136
137 r = sd_rtnl_message_addr_get_family(mm, &family);
138 if (r < 0)
139 goto fail;
140
141 switch (family) {
142
143 case AF_INET:
144 r = sd_netlink_message_read_in_addr(mm, IFA_LOCAL, &address.in);
145 if (r < 0) {
146 r = sd_netlink_message_read_in_addr(mm, IFA_ADDRESS, &address.in);
147 if (r < 0)
148 goto fail;
149 }
150
151 break;
152
153 case AF_INET6:
154 r = sd_netlink_message_read_in6_addr(mm, IFA_LOCAL, &address.in6);
155 if (r < 0) {
156 r = sd_netlink_message_read_in6_addr(mm, IFA_ADDRESS, &address.in6);
157 if (r < 0)
158 goto fail;
159 }
160
161 break;
162
163 default:
164 return 0;
165 }
166
167 a = link_find_address(l, family, &address);
168
169 switch (type) {
170
171 case RTM_NEWADDR:
172
173 if (!a) {
174 r = link_address_new(l, &a, family, &address);
175 if (r < 0)
176 return r;
177 }
178
179 r = link_address_update_rtnl(a, mm);
180 if (r < 0)
181 return r;
182
183 break;
184
185 case RTM_DELADDR:
186 link_address_free(a);
187 break;
188 }
189
190 return 0;
191
192 fail:
193 log_warning_errno(r, "Failed to process RTNL address message: %m");
194 return 0;
195 }
196
197 static int manager_rtnl_listen(Manager *m) {
198 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
199 sd_netlink_message *i;
200 int r;
201
202 assert(m);
203
204 /* First, subscribe to interfaces coming and going */
205 r = sd_netlink_open(&m->rtnl);
206 if (r < 0)
207 return r;
208
209 r = sd_netlink_attach_event(m->rtnl, m->event, SD_EVENT_PRIORITY_IMPORTANT);
210 if (r < 0)
211 return r;
212
213 r = sd_netlink_add_match(m->rtnl, RTM_NEWLINK, manager_process_link, m);
214 if (r < 0)
215 return r;
216
217 r = sd_netlink_add_match(m->rtnl, RTM_DELLINK, manager_process_link, m);
218 if (r < 0)
219 return r;
220
221 r = sd_netlink_add_match(m->rtnl, RTM_NEWADDR, manager_process_address, m);
222 if (r < 0)
223 return r;
224
225 r = sd_netlink_add_match(m->rtnl, RTM_DELADDR, manager_process_address, m);
226 if (r < 0)
227 return r;
228
229 /* Then, enumerate all links */
230 r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
231 if (r < 0)
232 return r;
233
234 r = sd_netlink_message_request_dump(req, true);
235 if (r < 0)
236 return r;
237
238 r = sd_netlink_call(m->rtnl, req, 0, &reply);
239 if (r < 0)
240 return r;
241
242 for (i = reply; i; i = sd_netlink_message_next(i)) {
243 r = manager_process_link(m->rtnl, i, m);
244 if (r < 0)
245 return r;
246 }
247
248 req = sd_netlink_message_unref(req);
249 reply = sd_netlink_message_unref(reply);
250
251 /* Finally, enumerate all addresses, too */
252 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, AF_UNSPEC);
253 if (r < 0)
254 return r;
255
256 r = sd_netlink_message_request_dump(req, true);
257 if (r < 0)
258 return r;
259
260 r = sd_netlink_call(m->rtnl, req, 0, &reply);
261 if (r < 0)
262 return r;
263
264 for (i = reply; i; i = sd_netlink_message_next(i)) {
265 r = manager_process_address(m->rtnl, i, m);
266 if (r < 0)
267 return r;
268 }
269
270 return r;
271 }
272
273 static int on_network_event(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
274 Manager *m = userdata;
275 Iterator i;
276 Link *l;
277 int r;
278
279 assert(m);
280
281 sd_network_monitor_flush(m->network_monitor);
282
283 HASHMAP_FOREACH(l, m->links, i) {
284 r = link_update_monitor(l);
285 if (r < 0)
286 log_warning_errno(r, "Failed to update monitor information for %i: %m", l->ifindex);
287 }
288
289 r = manager_write_resolv_conf(m);
290 if (r < 0)
291 log_warning_errno(r, "Could not update "PRIVATE_RESOLV_CONF": %m");
292
293 return 0;
294 }
295
296 static int manager_network_monitor_listen(Manager *m) {
297 int r, fd, events;
298
299 assert(m);
300
301 r = sd_network_monitor_new(&m->network_monitor, NULL);
302 if (r < 0)
303 return r;
304
305 fd = sd_network_monitor_get_fd(m->network_monitor);
306 if (fd < 0)
307 return fd;
308
309 events = sd_network_monitor_get_events(m->network_monitor);
310 if (events < 0)
311 return events;
312
313 r = sd_event_add_io(m->event, &m->network_event_source, fd, events, &on_network_event, m);
314 if (r < 0)
315 return r;
316
317 r = sd_event_source_set_priority(m->network_event_source, SD_EVENT_PRIORITY_IMPORTANT+5);
318 if (r < 0)
319 return r;
320
321 (void) sd_event_source_set_description(m->network_event_source, "network-monitor");
322
323 return 0;
324 }
325
326 static int determine_hostname(char **llmnr_hostname, char **mdns_hostname) {
327 _cleanup_free_ char *h = NULL, *n = NULL;
328 char label[DNS_LABEL_MAX];
329 const char *p;
330 int r, k;
331
332 assert(llmnr_hostname);
333 assert(mdns_hostname);
334
335 /* Extract and normalize the first label of the locally
336 * configured hostname, and check it's not "localhost". */
337
338 h = gethostname_malloc();
339 if (!h)
340 return log_oom();
341
342 p = h;
343 r = dns_label_unescape(&p, label, sizeof(label));
344 if (r < 0)
345 return log_error_errno(r, "Failed to unescape host name: %m");
346 if (r == 0) {
347 log_error("Couldn't find a single label in hosntame.");
348 return -EINVAL;
349 }
350
351 k = dns_label_undo_idna(label, r, label, sizeof(label));
352 if (k < 0)
353 return log_error_errno(k, "Failed to undo IDNA: %m");
354 if (k > 0)
355 r = k;
356
357 if (!utf8_is_valid(label)) {
358 log_error("System hostname is not UTF-8 clean.");
359 return -EINVAL;
360 }
361
362 r = dns_label_escape_new(label, r, &n);
363 if (r < 0)
364 return log_error_errno(r, "Failed to escape host name: %m");
365
366 if (is_localhost(n)) {
367 log_debug("System hostname is 'localhost', ignoring.");
368 return -EINVAL;
369 }
370
371 r = dns_name_concat(n, "local", mdns_hostname);
372 if (r < 0)
373 return log_error_errno(r, "Failed to determine mDNS hostname: %m");
374
375 *llmnr_hostname = n;
376 n = NULL;
377
378 return 0;
379 }
380
381 static int on_hostname_change(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
382 _cleanup_free_ char *llmnr_hostname = NULL, *mdns_hostname = NULL;
383 Manager *m = userdata;
384 int r;
385
386 assert(m);
387
388 r = determine_hostname(&llmnr_hostname, &mdns_hostname);
389 if (r < 0)
390 return 0; /* ignore invalid hostnames */
391
392 if (streq(llmnr_hostname, m->llmnr_hostname) && streq(mdns_hostname, m->mdns_hostname))
393 return 0;
394
395 log_info("System hostname changed to '%s'.", llmnr_hostname);
396
397 free(m->llmnr_hostname);
398 free(m->mdns_hostname);
399
400 m->llmnr_hostname = llmnr_hostname;
401 m->mdns_hostname = mdns_hostname;
402
403 llmnr_hostname = mdns_hostname = NULL;
404
405 manager_refresh_rrs(m);
406
407 return 0;
408 }
409
410 static int manager_watch_hostname(Manager *m) {
411 int r;
412
413 assert(m);
414
415 m->hostname_fd = open("/proc/sys/kernel/hostname", O_RDONLY|O_CLOEXEC|O_NDELAY|O_NOCTTY);
416 if (m->hostname_fd < 0) {
417 log_warning_errno(errno, "Failed to watch hostname: %m");
418 return 0;
419 }
420
421 r = sd_event_add_io(m->event, &m->hostname_event_source, m->hostname_fd, 0, on_hostname_change, m);
422 if (r < 0) {
423 if (r == -EPERM)
424 /* kernels prior to 3.2 don't support polling this file. Ignore the failure. */
425 m->hostname_fd = safe_close(m->hostname_fd);
426 else
427 return log_error_errno(r, "Failed to add hostname event source: %m");
428 }
429
430 (void) sd_event_source_set_description(m->hostname_event_source, "hostname");
431
432 r = determine_hostname(&m->llmnr_hostname, &m->mdns_hostname);
433 if (r < 0) {
434 log_info("Defaulting to hostname 'linux'.");
435 m->llmnr_hostname = strdup("linux");
436 if (!m->llmnr_hostname)
437 return log_oom();
438
439 m->mdns_hostname = strdup("linux.local");
440 if (!m->mdns_hostname)
441 return log_oom();
442 } else
443 log_info("Using system hostname '%s'.", m->llmnr_hostname);
444
445 return 0;
446 }
447
448 static int manager_sigusr1(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
449 _cleanup_free_ char *buffer = NULL;
450 _cleanup_fclose_ FILE *f = NULL;
451 Manager *m = userdata;
452 size_t size = 0;
453 DnsScope *scope;
454
455 assert(s);
456 assert(si);
457 assert(m);
458
459 f = open_memstream(&buffer, &size);
460 if (!f)
461 return log_oom();
462
463 LIST_FOREACH(scopes, scope, m->dns_scopes)
464 dns_scope_dump(scope, f);
465
466 if (fflush_and_check(f) < 0)
467 return log_oom();
468
469 log_dump(LOG_INFO, buffer);
470 return 0;
471 }
472
473 int manager_new(Manager **ret) {
474 _cleanup_(manager_freep) Manager *m = NULL;
475 int r;
476
477 assert(ret);
478
479 m = new0(Manager, 1);
480 if (!m)
481 return -ENOMEM;
482
483 m->llmnr_ipv4_udp_fd = m->llmnr_ipv6_udp_fd = -1;
484 m->llmnr_ipv4_tcp_fd = m->llmnr_ipv6_tcp_fd = -1;
485 m->mdns_ipv4_fd = m->mdns_ipv6_fd = -1;
486 m->hostname_fd = -1;
487
488 m->llmnr_support = RESOLVE_SUPPORT_YES;
489 m->mdns_support = RESOLVE_SUPPORT_NO;
490 m->dnssec_mode = DNSSEC_NO;
491 m->read_resolv_conf = true;
492 m->need_builtin_fallbacks = true;
493 m->etc_hosts_last = m->etc_hosts_mtime = USEC_INFINITY;
494
495 r = dns_trust_anchor_load(&m->trust_anchor);
496 if (r < 0)
497 return r;
498
499 r = manager_parse_config_file(m);
500 if (r < 0)
501 return r;
502
503 r = sd_event_default(&m->event);
504 if (r < 0)
505 return r;
506
507 sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
508 sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
509
510 sd_event_set_watchdog(m->event, true);
511
512 r = manager_watch_hostname(m);
513 if (r < 0)
514 return r;
515
516 r = dns_scope_new(m, &m->unicast_scope, NULL, DNS_PROTOCOL_DNS, AF_UNSPEC);
517 if (r < 0)
518 return r;
519
520 r = manager_network_monitor_listen(m);
521 if (r < 0)
522 return r;
523
524 r = manager_rtnl_listen(m);
525 if (r < 0)
526 return r;
527
528 r = manager_connect_bus(m);
529 if (r < 0)
530 return r;
531
532 (void) sd_event_add_signal(m->event, &m->sigusr1_event_source, SIGUSR1, manager_sigusr1, m);
533
534 *ret = m;
535 m = NULL;
536
537 return 0;
538 }
539
540 int manager_start(Manager *m) {
541 int r;
542
543 assert(m);
544
545 r = manager_llmnr_start(m);
546 if (r < 0)
547 return r;
548
549 r = manager_mdns_start(m);
550 if (r < 0)
551 return r;
552
553 return 0;
554 }
555
556 Manager *manager_free(Manager *m) {
557 Link *l;
558
559 if (!m)
560 return NULL;
561
562 dns_server_unlink_all(m->dns_servers);
563 dns_server_unlink_all(m->fallback_dns_servers);
564 dns_search_domain_unlink_all(m->search_domains);
565
566 while ((l = hashmap_first(m->links)))
567 link_free(l);
568
569 while (m->dns_queries)
570 dns_query_free(m->dns_queries);
571
572 dns_scope_free(m->unicast_scope);
573
574 hashmap_free(m->links);
575 hashmap_free(m->dns_transactions);
576
577 sd_event_source_unref(m->network_event_source);
578 sd_network_monitor_unref(m->network_monitor);
579
580 sd_netlink_unref(m->rtnl);
581 sd_event_source_unref(m->rtnl_event_source);
582
583 manager_llmnr_stop(m);
584 manager_mdns_stop(m);
585
586 sd_bus_slot_unref(m->prepare_for_sleep_slot);
587 sd_event_source_unref(m->bus_retry_event_source);
588 sd_bus_unref(m->bus);
589
590 sd_event_source_unref(m->sigusr1_event_source);
591
592 sd_event_unref(m->event);
593
594 dns_resource_key_unref(m->llmnr_host_ipv4_key);
595 dns_resource_key_unref(m->llmnr_host_ipv6_key);
596
597 sd_event_source_unref(m->hostname_event_source);
598 safe_close(m->hostname_fd);
599 free(m->llmnr_hostname);
600 free(m->mdns_hostname);
601
602 dns_trust_anchor_flush(&m->trust_anchor);
603 manager_etc_hosts_flush(m);
604
605 free(m);
606
607 return NULL;
608 }
609
610 int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) {
611 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
612 union {
613 struct cmsghdr header; /* For alignment */
614 uint8_t buffer[CMSG_SPACE(MAXSIZE(struct in_pktinfo, struct in6_pktinfo))
615 + CMSG_SPACE(int) /* ttl/hoplimit */
616 + EXTRA_CMSG_SPACE /* kernel appears to require extra buffer space */];
617 } control;
618 union sockaddr_union sa;
619 struct msghdr mh = {};
620 struct cmsghdr *cmsg;
621 struct iovec iov;
622 int ms = 0, r;
623 ssize_t l;
624
625 assert(m);
626 assert(fd >= 0);
627 assert(ret);
628
629 r = ioctl(fd, FIONREAD, &ms);
630 if (r < 0)
631 return -errno;
632 if (ms < 0)
633 return -EIO;
634
635 r = dns_packet_new(&p, protocol, ms);
636 if (r < 0)
637 return r;
638
639 iov.iov_base = DNS_PACKET_DATA(p);
640 iov.iov_len = p->allocated;
641
642 mh.msg_name = &sa.sa;
643 mh.msg_namelen = sizeof(sa);
644 mh.msg_iov = &iov;
645 mh.msg_iovlen = 1;
646 mh.msg_control = &control;
647 mh.msg_controllen = sizeof(control);
648
649 l = recvmsg(fd, &mh, 0);
650 if (l < 0) {
651 if (errno == EAGAIN || errno == EINTR)
652 return 0;
653
654 return -errno;
655 }
656
657 if (l <= 0)
658 return -EIO;
659
660 assert(!(mh.msg_flags & MSG_CTRUNC));
661 assert(!(mh.msg_flags & MSG_TRUNC));
662
663 p->size = (size_t) l;
664
665 p->family = sa.sa.sa_family;
666 p->ipproto = IPPROTO_UDP;
667 if (p->family == AF_INET) {
668 p->sender.in = sa.in.sin_addr;
669 p->sender_port = be16toh(sa.in.sin_port);
670 } else if (p->family == AF_INET6) {
671 p->sender.in6 = sa.in6.sin6_addr;
672 p->sender_port = be16toh(sa.in6.sin6_port);
673 p->ifindex = sa.in6.sin6_scope_id;
674 } else
675 return -EAFNOSUPPORT;
676
677 CMSG_FOREACH(cmsg, &mh) {
678
679 if (cmsg->cmsg_level == IPPROTO_IPV6) {
680 assert(p->family == AF_INET6);
681
682 switch (cmsg->cmsg_type) {
683
684 case IPV6_PKTINFO: {
685 struct in6_pktinfo *i = (struct in6_pktinfo*) CMSG_DATA(cmsg);
686
687 if (p->ifindex <= 0)
688 p->ifindex = i->ipi6_ifindex;
689
690 p->destination.in6 = i->ipi6_addr;
691 break;
692 }
693
694 case IPV6_HOPLIMIT:
695 p->ttl = *(int *) CMSG_DATA(cmsg);
696 break;
697
698 }
699 } else if (cmsg->cmsg_level == IPPROTO_IP) {
700 assert(p->family == AF_INET);
701
702 switch (cmsg->cmsg_type) {
703
704 case IP_PKTINFO: {
705 struct in_pktinfo *i = (struct in_pktinfo*) CMSG_DATA(cmsg);
706
707 if (p->ifindex <= 0)
708 p->ifindex = i->ipi_ifindex;
709
710 p->destination.in = i->ipi_addr;
711 break;
712 }
713
714 case IP_TTL:
715 p->ttl = *(int *) CMSG_DATA(cmsg);
716 break;
717 }
718 }
719 }
720
721 /* The Linux kernel sets the interface index to the loopback
722 * device if the packet came from the local host since it
723 * avoids the routing table in such a case. Let's unset the
724 * interface index in such a case. */
725 if (p->ifindex == LOOPBACK_IFINDEX)
726 p->ifindex = 0;
727
728 if (protocol != DNS_PROTOCOL_DNS) {
729 /* If we don't know the interface index still, we look for the
730 * first local interface with a matching address. Yuck! */
731 if (p->ifindex <= 0)
732 p->ifindex = manager_find_ifindex(m, p->family, &p->destination);
733 }
734
735 *ret = p;
736 p = NULL;
737
738 return 1;
739 }
740
741 static int sendmsg_loop(int fd, struct msghdr *mh, int flags) {
742 int r;
743
744 assert(fd >= 0);
745 assert(mh);
746
747 for (;;) {
748 if (sendmsg(fd, mh, flags) >= 0)
749 return 0;
750
751 if (errno == EINTR)
752 continue;
753
754 if (errno != EAGAIN)
755 return -errno;
756
757 r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
758 if (r < 0)
759 return r;
760 if (r == 0)
761 return -ETIMEDOUT;
762 }
763 }
764
765 static int write_loop(int fd, void *message, size_t length) {
766 int r;
767
768 assert(fd >= 0);
769 assert(message);
770
771 for (;;) {
772 if (write(fd, message, length) >= 0)
773 return 0;
774
775 if (errno == EINTR)
776 continue;
777
778 if (errno != EAGAIN)
779 return -errno;
780
781 r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
782 if (r < 0)
783 return r;
784 if (r == 0)
785 return -ETIMEDOUT;
786 }
787 }
788
789 int manager_write(Manager *m, int fd, DnsPacket *p) {
790 int r;
791
792 log_debug("Sending %s packet with id %" PRIu16 ".", DNS_PACKET_QR(p) ? "response" : "query", DNS_PACKET_ID(p));
793
794 r = write_loop(fd, DNS_PACKET_DATA(p), p->size);
795 if (r < 0)
796 return r;
797
798 return 0;
799 }
800
801 static int manager_ipv4_send(Manager *m, int fd, int ifindex, const struct in_addr *addr, uint16_t port, DnsPacket *p) {
802 union sockaddr_union sa = {
803 .in.sin_family = AF_INET,
804 };
805 union {
806 struct cmsghdr header; /* For alignment */
807 uint8_t buffer[CMSG_SPACE(sizeof(struct in_pktinfo))];
808 } control;
809 struct msghdr mh = {};
810 struct iovec iov;
811
812 assert(m);
813 assert(fd >= 0);
814 assert(addr);
815 assert(port > 0);
816 assert(p);
817
818 iov.iov_base = DNS_PACKET_DATA(p);
819 iov.iov_len = p->size;
820
821 sa.in.sin_addr = *addr;
822 sa.in.sin_port = htobe16(port),
823
824 mh.msg_iov = &iov;
825 mh.msg_iovlen = 1;
826 mh.msg_name = &sa.sa;
827 mh.msg_namelen = sizeof(sa.in);
828
829 if (ifindex > 0) {
830 struct cmsghdr *cmsg;
831 struct in_pktinfo *pi;
832
833 zero(control);
834
835 mh.msg_control = &control;
836 mh.msg_controllen = CMSG_LEN(sizeof(struct in_pktinfo));
837
838 cmsg = CMSG_FIRSTHDR(&mh);
839 cmsg->cmsg_len = mh.msg_controllen;
840 cmsg->cmsg_level = IPPROTO_IP;
841 cmsg->cmsg_type = IP_PKTINFO;
842
843 pi = (struct in_pktinfo*) CMSG_DATA(cmsg);
844 pi->ipi_ifindex = ifindex;
845 }
846
847 return sendmsg_loop(fd, &mh, 0);
848 }
849
850 static int manager_ipv6_send(Manager *m, int fd, int ifindex, const struct in6_addr *addr, uint16_t port, DnsPacket *p) {
851 union sockaddr_union sa = {
852 .in6.sin6_family = AF_INET6,
853 };
854 union {
855 struct cmsghdr header; /* For alignment */
856 uint8_t buffer[CMSG_SPACE(sizeof(struct in6_pktinfo))];
857 } control;
858 struct msghdr mh = {};
859 struct iovec iov;
860
861 assert(m);
862 assert(fd >= 0);
863 assert(addr);
864 assert(port > 0);
865 assert(p);
866
867 iov.iov_base = DNS_PACKET_DATA(p);
868 iov.iov_len = p->size;
869
870 sa.in6.sin6_addr = *addr;
871 sa.in6.sin6_port = htobe16(port),
872 sa.in6.sin6_scope_id = ifindex;
873
874 mh.msg_iov = &iov;
875 mh.msg_iovlen = 1;
876 mh.msg_name = &sa.sa;
877 mh.msg_namelen = sizeof(sa.in6);
878
879 if (ifindex > 0) {
880 struct cmsghdr *cmsg;
881 struct in6_pktinfo *pi;
882
883 zero(control);
884
885 mh.msg_control = &control;
886 mh.msg_controllen = CMSG_LEN(sizeof(struct in6_pktinfo));
887
888 cmsg = CMSG_FIRSTHDR(&mh);
889 cmsg->cmsg_len = mh.msg_controllen;
890 cmsg->cmsg_level = IPPROTO_IPV6;
891 cmsg->cmsg_type = IPV6_PKTINFO;
892
893 pi = (struct in6_pktinfo*) CMSG_DATA(cmsg);
894 pi->ipi6_ifindex = ifindex;
895 }
896
897 return sendmsg_loop(fd, &mh, 0);
898 }
899
900 int manager_send(Manager *m, int fd, int ifindex, int family, const union in_addr_union *addr, uint16_t port, DnsPacket *p) {
901 assert(m);
902 assert(fd >= 0);
903 assert(addr);
904 assert(port > 0);
905 assert(p);
906
907 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));
908
909 if (family == AF_INET)
910 return manager_ipv4_send(m, fd, ifindex, &addr->in, port, p);
911 else if (family == AF_INET6)
912 return manager_ipv6_send(m, fd, ifindex, &addr->in6, port, p);
913
914 return -EAFNOSUPPORT;
915 }
916
917 uint32_t manager_find_mtu(Manager *m) {
918 uint32_t mtu = 0;
919 Link *l;
920 Iterator i;
921
922 /* If we don't know on which link a DNS packet would be
923 * delivered, let's find the largest MTU that works on all
924 * interfaces we know of */
925
926 HASHMAP_FOREACH(l, m->links, i) {
927 if (l->mtu <= 0)
928 continue;
929
930 if (mtu <= 0 || l->mtu < mtu)
931 mtu = l->mtu;
932 }
933
934 return mtu;
935 }
936
937 int manager_find_ifindex(Manager *m, int family, const union in_addr_union *in_addr) {
938 LinkAddress *a;
939
940 assert(m);
941
942 a = manager_find_link_address(m, family, in_addr);
943 if (a)
944 return a->link->ifindex;
945
946 return 0;
947 }
948
949 void manager_refresh_rrs(Manager *m) {
950 Iterator i;
951 Link *l;
952
953 assert(m);
954
955 m->llmnr_host_ipv4_key = dns_resource_key_unref(m->llmnr_host_ipv4_key);
956 m->llmnr_host_ipv6_key = dns_resource_key_unref(m->llmnr_host_ipv6_key);
957
958 HASHMAP_FOREACH(l, m->links, i) {
959 link_add_rrs(l, true);
960 link_add_rrs(l, false);
961 }
962 }
963
964 int manager_next_hostname(Manager *m) {
965 const char *p;
966 uint64_t u, a;
967 char *h, *k;
968 int r;
969
970 assert(m);
971
972 p = strchr(m->llmnr_hostname, 0);
973 assert(p);
974
975 while (p > m->llmnr_hostname) {
976 if (!strchr("0123456789", p[-1]))
977 break;
978
979 p--;
980 }
981
982 if (*p == 0 || safe_atou64(p, &u) < 0 || u <= 0)
983 u = 1;
984
985 /* Add a random number to the old value. This way we can avoid
986 * that two hosts pick the same hostname, win on IPv4 and lose
987 * on IPv6 (or vice versa), and pick the same hostname
988 * replacement hostname, ad infinitum. We still want the
989 * numbers to go up monotonically, hence we just add a random
990 * value 1..10 */
991
992 random_bytes(&a, sizeof(a));
993 u += 1 + a % 10;
994
995 if (asprintf(&h, "%.*s%" PRIu64, (int) (p - m->llmnr_hostname), m->llmnr_hostname, u) < 0)
996 return -ENOMEM;
997
998 r = dns_name_concat(h, "local", &k);
999 if (r < 0) {
1000 free(h);
1001 return r;
1002 }
1003
1004 log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m->llmnr_hostname, h);
1005
1006 free(m->llmnr_hostname);
1007 m->llmnr_hostname = h;
1008
1009 free(m->mdns_hostname);
1010 m->mdns_hostname = k;
1011
1012 manager_refresh_rrs(m);
1013
1014 return 0;
1015 }
1016
1017 LinkAddress* manager_find_link_address(Manager *m, int family, const union in_addr_union *in_addr) {
1018 Iterator i;
1019 Link *l;
1020
1021 assert(m);
1022
1023 HASHMAP_FOREACH(l, m->links, i) {
1024 LinkAddress *a;
1025
1026 a = link_find_address(l, family, in_addr);
1027 if (a)
1028 return a;
1029 }
1030
1031 return NULL;
1032 }
1033
1034 bool manager_our_packet(Manager *m, DnsPacket *p) {
1035 assert(m);
1036 assert(p);
1037
1038 return !!manager_find_link_address(m, p->family, &p->sender);
1039 }
1040
1041 DnsScope* manager_find_scope(Manager *m, DnsPacket *p) {
1042 Link *l;
1043
1044 assert(m);
1045 assert(p);
1046
1047 l = hashmap_get(m->links, INT_TO_PTR(p->ifindex));
1048 if (!l)
1049 return NULL;
1050
1051 switch (p->protocol) {
1052 case DNS_PROTOCOL_LLMNR:
1053 if (p->family == AF_INET)
1054 return l->llmnr_ipv4_scope;
1055 else if (p->family == AF_INET6)
1056 return l->llmnr_ipv6_scope;
1057
1058 break;
1059
1060 case DNS_PROTOCOL_MDNS:
1061 if (p->family == AF_INET)
1062 return l->mdns_ipv4_scope;
1063 else if (p->family == AF_INET6)
1064 return l->mdns_ipv6_scope;
1065
1066 break;
1067
1068 default:
1069 break;
1070 }
1071
1072 return NULL;
1073 }
1074
1075 void manager_verify_all(Manager *m) {
1076 DnsScope *s;
1077
1078 assert(m);
1079
1080 LIST_FOREACH(scopes, s, m->dns_scopes)
1081 dns_zone_verify_all(&s->zone);
1082 }
1083
1084 int manager_is_own_hostname(Manager *m, const char *name) {
1085 int r;
1086
1087 assert(m);
1088 assert(name);
1089
1090 if (m->llmnr_hostname) {
1091 r = dns_name_equal(name, m->llmnr_hostname);
1092 if (r != 0)
1093 return r;
1094 }
1095
1096 if (m->mdns_hostname)
1097 return dns_name_equal(name, m->mdns_hostname);
1098
1099 return 0;
1100 }
1101
1102 int manager_compile_dns_servers(Manager *m, OrderedSet **dns) {
1103 DnsServer *s;
1104 Iterator i;
1105 Link *l;
1106 int r;
1107
1108 assert(m);
1109 assert(dns);
1110
1111 r = ordered_set_ensure_allocated(dns, &dns_server_hash_ops);
1112 if (r < 0)
1113 return r;
1114
1115 /* First add the system-wide servers and domains */
1116 LIST_FOREACH(servers, s, m->dns_servers) {
1117 r = ordered_set_put(*dns, s);
1118 if (r == -EEXIST)
1119 continue;
1120 if (r < 0)
1121 return r;
1122 }
1123
1124 /* Then, add the per-link servers */
1125 HASHMAP_FOREACH(l, m->links, i) {
1126 LIST_FOREACH(servers, s, l->dns_servers) {
1127 r = ordered_set_put(*dns, s);
1128 if (r == -EEXIST)
1129 continue;
1130 if (r < 0)
1131 return r;
1132 }
1133 }
1134
1135 /* If we found nothing, add the fallback servers */
1136 if (ordered_set_isempty(*dns)) {
1137 LIST_FOREACH(servers, s, m->fallback_dns_servers) {
1138 r = ordered_set_put(*dns, s);
1139 if (r == -EEXIST)
1140 continue;
1141 if (r < 0)
1142 return r;
1143 }
1144 }
1145
1146 return 0;
1147 }
1148
1149 int manager_compile_search_domains(Manager *m, OrderedSet **domains) {
1150 DnsSearchDomain *d;
1151 Iterator i;
1152 Link *l;
1153 int r;
1154
1155 assert(m);
1156 assert(domains);
1157
1158 r = ordered_set_ensure_allocated(domains, &dns_name_hash_ops);
1159 if (r < 0)
1160 return r;
1161
1162 LIST_FOREACH(domains, d, m->search_domains) {
1163 r = ordered_set_put(*domains, d->name);
1164 if (r == -EEXIST)
1165 continue;
1166 if (r < 0)
1167 return r;
1168 }
1169
1170 HASHMAP_FOREACH(l, m->links, i) {
1171
1172 LIST_FOREACH(domains, d, l->search_domains) {
1173 r = ordered_set_put(*domains, d->name);
1174 if (r == -EEXIST)
1175 continue;
1176 if (r < 0)
1177 return r;
1178 }
1179 }
1180
1181 return 0;
1182 }
1183
1184 DnssecMode manager_get_dnssec_mode(Manager *m) {
1185 assert(m);
1186
1187 if (m->dnssec_mode != _DNSSEC_MODE_INVALID)
1188 return m->dnssec_mode;
1189
1190 return DNSSEC_NO;
1191 }
1192
1193 bool manager_dnssec_supported(Manager *m) {
1194 DnsServer *server;
1195 Iterator i;
1196 Link *l;
1197
1198 assert(m);
1199
1200 if (manager_get_dnssec_mode(m) == DNSSEC_NO)
1201 return false;
1202
1203 server = manager_get_dns_server(m);
1204 if (server && !dns_server_dnssec_supported(server))
1205 return false;
1206
1207 HASHMAP_FOREACH(l, m->links, i)
1208 if (!link_dnssec_supported(l))
1209 return false;
1210
1211 return true;
1212 }
1213
1214 void manager_dnssec_verdict(Manager *m, DnssecVerdict verdict, const DnsResourceKey *key) {
1215
1216 assert(verdict >= 0);
1217 assert(verdict < _DNSSEC_VERDICT_MAX);
1218
1219 if (log_get_max_level() >= LOG_DEBUG) {
1220 _cleanup_free_ char *s = NULL;
1221
1222 (void) dns_resource_key_to_string(key, &s);
1223
1224 log_debug("Found verdict for lookup %s: %s", s ? strstrip(s) : "n/a", dnssec_verdict_to_string(verdict));
1225 }
1226
1227 m->n_dnssec_verdict[verdict]++;
1228 }
1229
1230 bool manager_routable(Manager *m, int family) {
1231 Iterator i;
1232 Link *l;
1233
1234 assert(m);
1235
1236 /* Returns true if the host has at least one interface with a routable address of the specified type */
1237
1238 HASHMAP_FOREACH(l, m->links, i)
1239 if (link_relevant(l, family, false))
1240 return true;
1241
1242 return false;
1243 }