1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2014 Tom Gundersen <teg@jklm.no>
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.
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.
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/>.
22 #include <netinet/in.h>
24 #include <sys/ioctl.h>
27 #include "alloc-util.h"
28 #include "dns-domain.h"
30 #include "fileio-label.h"
31 #include "hostname-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"
50 #define SEND_TIMEOUT_USEC (200 * USEC_PER_MSEC)
52 static int manager_process_link(sd_netlink
*rtnl
, sd_netlink_message
*mm
, void *userdata
) {
53 Manager
*m
= userdata
;
62 r
= sd_netlink_message_get_type(mm
, &type
);
66 r
= sd_rtnl_message_link_get_ifindex(mm
, &ifindex
);
70 l
= hashmap_get(m
->links
, INT_TO_PTR(ifindex
));
78 r
= link_new(m
, &l
, ifindex
);
83 r
= link_update_rtnl(l
, mm
);
87 r
= link_update_monitor(l
);
92 log_debug("Found new link %i/%s", ifindex
, l
->name
);
99 log_debug("Removing link %i/%s", l
->ifindex
, l
->name
);
109 log_warning_errno(r
, "Failed to process RTNL link message: %m");
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
;
117 int r
, ifindex
, family
;
125 r
= sd_netlink_message_get_type(mm
, &type
);
129 r
= sd_rtnl_message_addr_get_ifindex(mm
, &ifindex
);
133 l
= hashmap_get(m
->links
, INT_TO_PTR(ifindex
));
137 r
= sd_rtnl_message_addr_get_family(mm
, &family
);
144 r
= sd_netlink_message_read_in_addr(mm
, IFA_LOCAL
, &address
.in
);
146 r
= sd_netlink_message_read_in_addr(mm
, IFA_ADDRESS
, &address
.in
);
154 r
= sd_netlink_message_read_in6_addr(mm
, IFA_LOCAL
, &address
.in6
);
156 r
= sd_netlink_message_read_in6_addr(mm
, IFA_ADDRESS
, &address
.in6
);
167 a
= link_find_address(l
, family
, &address
);
174 r
= link_address_new(l
, &a
, family
, &address
);
179 r
= link_address_update_rtnl(a
, mm
);
186 link_address_free(a
);
193 log_warning_errno(r
, "Failed to process RTNL address message: %m");
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
;
204 /* First, subscribe to interfaces coming and going */
205 r
= sd_netlink_open(&m
->rtnl
);
209 r
= sd_netlink_attach_event(m
->rtnl
, m
->event
, SD_EVENT_PRIORITY_IMPORTANT
);
213 r
= sd_netlink_add_match(m
->rtnl
, RTM_NEWLINK
, manager_process_link
, m
);
217 r
= sd_netlink_add_match(m
->rtnl
, RTM_DELLINK
, manager_process_link
, m
);
221 r
= sd_netlink_add_match(m
->rtnl
, RTM_NEWADDR
, manager_process_address
, m
);
225 r
= sd_netlink_add_match(m
->rtnl
, RTM_DELADDR
, manager_process_address
, m
);
229 /* Then, enumerate all links */
230 r
= sd_rtnl_message_new_link(m
->rtnl
, &req
, RTM_GETLINK
, 0);
234 r
= sd_netlink_message_request_dump(req
, true);
238 r
= sd_netlink_call(m
->rtnl
, req
, 0, &reply
);
242 for (i
= reply
; i
; i
= sd_netlink_message_next(i
)) {
243 r
= manager_process_link(m
->rtnl
, i
, m
);
248 req
= sd_netlink_message_unref(req
);
249 reply
= sd_netlink_message_unref(reply
);
251 /* Finally, enumerate all addresses, too */
252 r
= sd_rtnl_message_new_addr(m
->rtnl
, &req
, RTM_GETADDR
, 0, AF_UNSPEC
);
256 r
= sd_netlink_message_request_dump(req
, true);
260 r
= sd_netlink_call(m
->rtnl
, req
, 0, &reply
);
264 for (i
= reply
; i
; i
= sd_netlink_message_next(i
)) {
265 r
= manager_process_address(m
->rtnl
, i
, m
);
273 static int on_network_event(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
274 Manager
*m
= userdata
;
281 sd_network_monitor_flush(m
->network_monitor
);
283 HASHMAP_FOREACH(l
, m
->links
, i
) {
284 r
= link_update_monitor(l
);
286 log_warning_errno(r
, "Failed to update monitor information for %i: %m", l
->ifindex
);
289 r
= manager_write_resolv_conf(m
);
291 log_warning_errno(r
, "Could not update "PRIVATE_RESOLV_CONF
": %m");
296 static int manager_network_monitor_listen(Manager
*m
) {
301 r
= sd_network_monitor_new(&m
->network_monitor
, NULL
);
305 fd
= sd_network_monitor_get_fd(m
->network_monitor
);
309 events
= sd_network_monitor_get_events(m
->network_monitor
);
313 r
= sd_event_add_io(m
->event
, &m
->network_event_source
, fd
, events
, &on_network_event
, m
);
317 r
= sd_event_source_set_priority(m
->network_event_source
, SD_EVENT_PRIORITY_IMPORTANT
+5);
321 (void) sd_event_source_set_description(m
->network_event_source
, "network-monitor");
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
];
332 assert(llmnr_hostname
);
333 assert(mdns_hostname
);
335 /* Extract and normalize the first label of the locally
336 * configured hostname, and check it's not "localhost". */
338 h
= gethostname_malloc();
343 r
= dns_label_unescape(&p
, label
, sizeof(label
));
345 return log_error_errno(r
, "Failed to unescape host name: %m");
347 log_error("Couldn't find a single label in hosntame.");
351 k
= dns_label_undo_idna(label
, r
, label
, sizeof(label
));
353 return log_error_errno(k
, "Failed to undo IDNA: %m");
357 if (!utf8_is_valid(label
)) {
358 log_error("System hostname is not UTF-8 clean.");
362 r
= dns_label_escape_new(label
, r
, &n
);
364 return log_error_errno(r
, "Failed to escape host name: %m");
366 if (is_localhost(n
)) {
367 log_debug("System hostname is 'localhost', ignoring.");
371 r
= dns_name_concat(n
, "local", mdns_hostname
);
373 return log_error_errno(r
, "Failed to determine mDNS hostname: %m");
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
;
388 r
= determine_hostname(&llmnr_hostname
, &mdns_hostname
);
390 return 0; /* ignore invalid hostnames */
392 if (streq(llmnr_hostname
, m
->llmnr_hostname
) && streq(mdns_hostname
, m
->mdns_hostname
))
395 log_info("System hostname changed to '%s'.", llmnr_hostname
);
397 free(m
->llmnr_hostname
);
398 free(m
->mdns_hostname
);
400 m
->llmnr_hostname
= llmnr_hostname
;
401 m
->mdns_hostname
= mdns_hostname
;
403 llmnr_hostname
= mdns_hostname
= NULL
;
405 manager_refresh_rrs(m
);
410 static int manager_watch_hostname(Manager
*m
) {
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");
421 r
= sd_event_add_io(m
->event
, &m
->hostname_event_source
, m
->hostname_fd
, 0, on_hostname_change
, m
);
424 /* kernels prior to 3.2 don't support polling this file. Ignore the failure. */
425 m
->hostname_fd
= safe_close(m
->hostname_fd
);
427 return log_error_errno(r
, "Failed to add hostname event source: %m");
430 (void) sd_event_source_set_description(m
->hostname_event_source
, "hostname");
432 r
= determine_hostname(&m
->llmnr_hostname
, &m
->mdns_hostname
);
434 log_info("Defaulting to hostname 'linux'.");
435 m
->llmnr_hostname
= strdup("linux");
436 if (!m
->llmnr_hostname
)
439 m
->mdns_hostname
= strdup("linux.local");
440 if (!m
->mdns_hostname
)
443 log_info("Using system hostname '%s'.", m
->llmnr_hostname
);
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
;
459 f
= open_memstream(&buffer
, &size
);
463 LIST_FOREACH(scopes
, scope
, m
->dns_scopes
)
464 dns_scope_dump(scope
, f
);
466 if (fflush_and_check(f
) < 0)
469 log_dump(LOG_INFO
, buffer
);
473 int manager_new(Manager
**ret
) {
474 _cleanup_(manager_freep
) Manager
*m
= NULL
;
479 m
= new0(Manager
, 1);
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;
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
;
495 r
= dns_trust_anchor_load(&m
->trust_anchor
);
499 r
= manager_parse_config_file(m
);
503 r
= sd_event_default(&m
->event
);
507 sd_event_add_signal(m
->event
, NULL
, SIGTERM
, NULL
, NULL
);
508 sd_event_add_signal(m
->event
, NULL
, SIGINT
, NULL
, NULL
);
510 sd_event_set_watchdog(m
->event
, true);
512 r
= manager_watch_hostname(m
);
516 r
= dns_scope_new(m
, &m
->unicast_scope
, NULL
, DNS_PROTOCOL_DNS
, AF_UNSPEC
);
520 r
= manager_network_monitor_listen(m
);
524 r
= manager_rtnl_listen(m
);
528 r
= manager_connect_bus(m
);
532 (void) sd_event_add_signal(m
->event
, &m
->sigusr1_event_source
, SIGUSR1
, manager_sigusr1
, m
);
540 int manager_start(Manager
*m
) {
545 r
= manager_llmnr_start(m
);
549 r
= manager_mdns_start(m
);
556 Manager
*manager_free(Manager
*m
) {
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
);
566 while ((l
= hashmap_first(m
->links
)))
569 while (m
->dns_queries
)
570 dns_query_free(m
->dns_queries
);
572 dns_scope_free(m
->unicast_scope
);
574 hashmap_free(m
->links
);
575 hashmap_free(m
->dns_transactions
);
577 sd_event_source_unref(m
->network_event_source
);
578 sd_network_monitor_unref(m
->network_monitor
);
580 sd_netlink_unref(m
->rtnl
);
581 sd_event_source_unref(m
->rtnl_event_source
);
583 manager_llmnr_stop(m
);
584 manager_mdns_stop(m
);
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
);
590 sd_event_source_unref(m
->sigusr1_event_source
);
592 sd_event_unref(m
->event
);
594 dns_resource_key_unref(m
->llmnr_host_ipv4_key
);
595 dns_resource_key_unref(m
->llmnr_host_ipv6_key
);
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
);
602 dns_trust_anchor_flush(&m
->trust_anchor
);
603 manager_etc_hosts_flush(m
);
610 int manager_recv(Manager
*m
, int fd
, DnsProtocol protocol
, DnsPacket
**ret
) {
611 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
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 */];
618 union sockaddr_union sa
;
619 struct msghdr mh
= {};
620 struct cmsghdr
*cmsg
;
629 r
= ioctl(fd
, FIONREAD
, &ms
);
635 r
= dns_packet_new(&p
, protocol
, ms
);
639 iov
.iov_base
= DNS_PACKET_DATA(p
);
640 iov
.iov_len
= p
->allocated
;
642 mh
.msg_name
= &sa
.sa
;
643 mh
.msg_namelen
= sizeof(sa
);
646 mh
.msg_control
= &control
;
647 mh
.msg_controllen
= sizeof(control
);
649 l
= recvmsg(fd
, &mh
, 0);
651 if (errno
== EAGAIN
|| errno
== EINTR
)
660 assert(!(mh
.msg_flags
& MSG_CTRUNC
));
661 assert(!(mh
.msg_flags
& MSG_TRUNC
));
663 p
->size
= (size_t) l
;
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
;
675 return -EAFNOSUPPORT
;
677 CMSG_FOREACH(cmsg
, &mh
) {
679 if (cmsg
->cmsg_level
== IPPROTO_IPV6
) {
680 assert(p
->family
== AF_INET6
);
682 switch (cmsg
->cmsg_type
) {
685 struct in6_pktinfo
*i
= (struct in6_pktinfo
*) CMSG_DATA(cmsg
);
688 p
->ifindex
= i
->ipi6_ifindex
;
690 p
->destination
.in6
= i
->ipi6_addr
;
695 p
->ttl
= *(int *) CMSG_DATA(cmsg
);
699 } else if (cmsg
->cmsg_level
== IPPROTO_IP
) {
700 assert(p
->family
== AF_INET
);
702 switch (cmsg
->cmsg_type
) {
705 struct in_pktinfo
*i
= (struct in_pktinfo
*) CMSG_DATA(cmsg
);
708 p
->ifindex
= i
->ipi_ifindex
;
710 p
->destination
.in
= i
->ipi_addr
;
715 p
->ttl
= *(int *) CMSG_DATA(cmsg
);
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
)
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! */
732 p
->ifindex
= manager_find_ifindex(m
, p
->family
, &p
->destination
);
741 static int sendmsg_loop(int fd
, struct msghdr
*mh
, int flags
) {
748 if (sendmsg(fd
, mh
, flags
) >= 0)
757 r
= fd_wait_for_event(fd
, POLLOUT
, SEND_TIMEOUT_USEC
);
765 static int write_loop(int fd
, void *message
, size_t length
) {
772 if (write(fd
, message
, length
) >= 0)
781 r
= fd_wait_for_event(fd
, POLLOUT
, SEND_TIMEOUT_USEC
);
789 int manager_write(Manager
*m
, int fd
, DnsPacket
*p
) {
792 log_debug("Sending %s packet with id %" PRIu16
".", DNS_PACKET_QR(p
) ? "response" : "query", DNS_PACKET_ID(p
));
794 r
= write_loop(fd
, DNS_PACKET_DATA(p
), p
->size
);
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
,
806 struct cmsghdr header
; /* For alignment */
807 uint8_t buffer
[CMSG_SPACE(sizeof(struct in_pktinfo
))];
809 struct msghdr mh
= {};
818 iov
.iov_base
= DNS_PACKET_DATA(p
);
819 iov
.iov_len
= p
->size
;
821 sa
.in
.sin_addr
= *addr
;
822 sa
.in
.sin_port
= htobe16(port
),
826 mh
.msg_name
= &sa
.sa
;
827 mh
.msg_namelen
= sizeof(sa
.in
);
830 struct cmsghdr
*cmsg
;
831 struct in_pktinfo
*pi
;
835 mh
.msg_control
= &control
;
836 mh
.msg_controllen
= CMSG_LEN(sizeof(struct in_pktinfo
));
838 cmsg
= CMSG_FIRSTHDR(&mh
);
839 cmsg
->cmsg_len
= mh
.msg_controllen
;
840 cmsg
->cmsg_level
= IPPROTO_IP
;
841 cmsg
->cmsg_type
= IP_PKTINFO
;
843 pi
= (struct in_pktinfo
*) CMSG_DATA(cmsg
);
844 pi
->ipi_ifindex
= ifindex
;
847 return sendmsg_loop(fd
, &mh
, 0);
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
,
855 struct cmsghdr header
; /* For alignment */
856 uint8_t buffer
[CMSG_SPACE(sizeof(struct in6_pktinfo
))];
858 struct msghdr mh
= {};
867 iov
.iov_base
= DNS_PACKET_DATA(p
);
868 iov
.iov_len
= p
->size
;
870 sa
.in6
.sin6_addr
= *addr
;
871 sa
.in6
.sin6_port
= htobe16(port
),
872 sa
.in6
.sin6_scope_id
= ifindex
;
876 mh
.msg_name
= &sa
.sa
;
877 mh
.msg_namelen
= sizeof(sa
.in6
);
880 struct cmsghdr
*cmsg
;
881 struct in6_pktinfo
*pi
;
885 mh
.msg_control
= &control
;
886 mh
.msg_controllen
= CMSG_LEN(sizeof(struct in6_pktinfo
));
888 cmsg
= CMSG_FIRSTHDR(&mh
);
889 cmsg
->cmsg_len
= mh
.msg_controllen
;
890 cmsg
->cmsg_level
= IPPROTO_IPV6
;
891 cmsg
->cmsg_type
= IPV6_PKTINFO
;
893 pi
= (struct in6_pktinfo
*) CMSG_DATA(cmsg
);
894 pi
->ipi6_ifindex
= ifindex
;
897 return sendmsg_loop(fd
, &mh
, 0);
900 int manager_send(Manager
*m
, int fd
, int ifindex
, int family
, const union in_addr_union
*addr
, uint16_t port
, DnsPacket
*p
) {
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
));
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
);
914 return -EAFNOSUPPORT
;
917 uint32_t manager_find_mtu(Manager
*m
) {
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 */
926 HASHMAP_FOREACH(l
, m
->links
, i
) {
930 if (mtu
<= 0 || l
->mtu
< mtu
)
937 int manager_find_ifindex(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
942 a
= manager_find_link_address(m
, family
, in_addr
);
944 return a
->link
->ifindex
;
949 void manager_refresh_rrs(Manager
*m
) {
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
);
958 HASHMAP_FOREACH(l
, m
->links
, i
) {
959 link_add_rrs(l
, true);
960 link_add_rrs(l
, false);
964 int manager_next_hostname(Manager
*m
) {
972 p
= strchr(m
->llmnr_hostname
, 0);
975 while (p
> m
->llmnr_hostname
) {
976 if (!strchr("0123456789", p
[-1]))
982 if (*p
== 0 || safe_atou64(p
, &u
) < 0 || u
<= 0)
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
992 random_bytes(&a
, sizeof(a
));
995 if (asprintf(&h
, "%.*s%" PRIu64
, (int) (p
- m
->llmnr_hostname
), m
->llmnr_hostname
, u
) < 0)
998 r
= dns_name_concat(h
, "local", &k
);
1004 log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m
->llmnr_hostname
, h
);
1006 free(m
->llmnr_hostname
);
1007 m
->llmnr_hostname
= h
;
1009 free(m
->mdns_hostname
);
1010 m
->mdns_hostname
= k
;
1012 manager_refresh_rrs(m
);
1017 LinkAddress
* manager_find_link_address(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
1023 HASHMAP_FOREACH(l
, m
->links
, i
) {
1026 a
= link_find_address(l
, family
, in_addr
);
1034 bool manager_our_packet(Manager
*m
, DnsPacket
*p
) {
1038 return !!manager_find_link_address(m
, p
->family
, &p
->sender
);
1041 DnsScope
* manager_find_scope(Manager
*m
, DnsPacket
*p
) {
1047 l
= hashmap_get(m
->links
, INT_TO_PTR(p
->ifindex
));
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
;
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
;
1075 void manager_verify_all(Manager
*m
) {
1080 LIST_FOREACH(scopes
, s
, m
->dns_scopes
)
1081 dns_zone_verify_all(&s
->zone
);
1084 int manager_is_own_hostname(Manager
*m
, const char *name
) {
1090 if (m
->llmnr_hostname
) {
1091 r
= dns_name_equal(name
, m
->llmnr_hostname
);
1096 if (m
->mdns_hostname
)
1097 return dns_name_equal(name
, m
->mdns_hostname
);
1102 int manager_compile_dns_servers(Manager
*m
, OrderedSet
**dns
) {
1111 r
= ordered_set_ensure_allocated(dns
, &dns_server_hash_ops
);
1115 /* First add the system-wide servers and domains */
1116 LIST_FOREACH(servers
, s
, m
->dns_servers
) {
1117 r
= ordered_set_put(*dns
, s
);
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
);
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
);
1149 int manager_compile_search_domains(Manager
*m
, OrderedSet
**domains
) {
1158 r
= ordered_set_ensure_allocated(domains
, &dns_name_hash_ops
);
1162 LIST_FOREACH(domains
, d
, m
->search_domains
) {
1163 r
= ordered_set_put(*domains
, d
->name
);
1170 HASHMAP_FOREACH(l
, m
->links
, i
) {
1172 LIST_FOREACH(domains
, d
, l
->search_domains
) {
1173 r
= ordered_set_put(*domains
, d
->name
);
1184 DnssecMode
manager_get_dnssec_mode(Manager
*m
) {
1187 if (m
->dnssec_mode
!= _DNSSEC_MODE_INVALID
)
1188 return m
->dnssec_mode
;
1193 bool manager_dnssec_supported(Manager
*m
) {
1200 if (manager_get_dnssec_mode(m
) == DNSSEC_NO
)
1203 server
= manager_get_dns_server(m
);
1204 if (server
&& !dns_server_dnssec_supported(server
))
1207 HASHMAP_FOREACH(l
, m
->links
, i
)
1208 if (!link_dnssec_supported(l
))
1214 void manager_dnssec_verdict(Manager
*m
, DnssecVerdict verdict
, const DnsResourceKey
*key
) {
1216 assert(verdict
>= 0);
1217 assert(verdict
< _DNSSEC_VERDICT_MAX
);
1219 if (log_get_max_level() >= LOG_DEBUG
) {
1220 _cleanup_free_
char *s
= NULL
;
1222 (void) dns_resource_key_to_string(key
, &s
);
1224 log_debug("Found verdict for lookup %s: %s", s
? strstrip(s
) : "n/a", dnssec_verdict_to_string(verdict
));
1227 m
->n_dnssec_verdict
[verdict
]++;