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