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
, 0);
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 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 (void) sd_event_source_set_description(m
->network_event_source
, "network-monitor");
322 static int determine_hostname(char **llmnr_hostname
, char **mdns_hostname
) {
323 _cleanup_free_
char *h
= NULL
, *n
= NULL
;
324 char label
[DNS_LABEL_MAX
];
328 assert(llmnr_hostname
);
329 assert(mdns_hostname
);
331 /* Extract and normalize the first label of the locally
332 * configured hostname, and check it's not "localhost". */
334 h
= gethostname_malloc();
339 r
= dns_label_unescape(&p
, label
, sizeof(label
));
341 return log_error_errno(r
, "Failed to unescape host name: %m");
343 log_error("Couldn't find a single label in hosntame.");
347 k
= dns_label_undo_idna(label
, r
, label
, sizeof(label
));
349 return log_error_errno(k
, "Failed to undo IDNA: %m");
353 if (!utf8_is_valid(label
)) {
354 log_error("System hostname is not UTF-8 clean.");
358 r
= dns_label_escape_new(label
, r
, &n
);
360 return log_error_errno(r
, "Failed to escape host name: %m");
362 if (is_localhost(n
)) {
363 log_debug("System hostname is 'localhost', ignoring.");
367 r
= dns_name_concat(n
, "local", mdns_hostname
);
369 return log_error_errno(r
, "Failed to determine mDNS hostname: %m");
377 static int on_hostname_change(sd_event_source
*es
, int fd
, uint32_t revents
, void *userdata
) {
378 _cleanup_free_
char *llmnr_hostname
= NULL
, *mdns_hostname
= NULL
;
379 Manager
*m
= userdata
;
384 r
= determine_hostname(&llmnr_hostname
, &mdns_hostname
);
386 return 0; /* ignore invalid hostnames */
388 if (streq(llmnr_hostname
, m
->llmnr_hostname
) && streq(mdns_hostname
, m
->mdns_hostname
))
391 log_info("System hostname changed to '%s'.", llmnr_hostname
);
393 free(m
->llmnr_hostname
);
394 free(m
->mdns_hostname
);
396 m
->llmnr_hostname
= llmnr_hostname
;
397 m
->mdns_hostname
= mdns_hostname
;
399 llmnr_hostname
= mdns_hostname
= NULL
;
401 manager_refresh_rrs(m
);
406 static int manager_watch_hostname(Manager
*m
) {
411 m
->hostname_fd
= open("/proc/sys/kernel/hostname", O_RDONLY
|O_CLOEXEC
|O_NDELAY
|O_NOCTTY
);
412 if (m
->hostname_fd
< 0) {
413 log_warning_errno(errno
, "Failed to watch hostname: %m");
417 r
= sd_event_add_io(m
->event
, &m
->hostname_event_source
, m
->hostname_fd
, 0, on_hostname_change
, m
);
420 /* kernels prior to 3.2 don't support polling this file. Ignore the failure. */
421 m
->hostname_fd
= safe_close(m
->hostname_fd
);
423 return log_error_errno(r
, "Failed to add hostname event source: %m");
426 (void) sd_event_source_set_description(m
->hostname_event_source
, "hostname");
428 r
= determine_hostname(&m
->llmnr_hostname
, &m
->mdns_hostname
);
430 log_info("Defaulting to hostname 'linux'.");
431 m
->llmnr_hostname
= strdup("linux");
432 if (!m
->llmnr_hostname
)
435 m
->mdns_hostname
= strdup("linux.local");
436 if (!m
->mdns_hostname
)
439 log_info("Using system hostname '%s'.", m
->llmnr_hostname
);
444 static int manager_sigusr1(sd_event_source
*s
, const struct signalfd_siginfo
*si
, void *userdata
) {
445 _cleanup_free_
char *buffer
= NULL
;
446 _cleanup_fclose_
FILE *f
= NULL
;
447 Manager
*m
= userdata
;
455 f
= open_memstream(&buffer
, &size
);
459 LIST_FOREACH(scopes
, scope
, m
->dns_scopes
)
460 dns_scope_dump(scope
, f
);
462 if (fflush_and_check(f
) < 0)
465 log_dump(LOG_INFO
, buffer
);
469 int manager_new(Manager
**ret
) {
470 _cleanup_(manager_freep
) Manager
*m
= NULL
;
475 m
= new0(Manager
, 1);
479 m
->llmnr_ipv4_udp_fd
= m
->llmnr_ipv6_udp_fd
= -1;
480 m
->llmnr_ipv4_tcp_fd
= m
->llmnr_ipv6_tcp_fd
= -1;
481 m
->mdns_ipv4_fd
= m
->mdns_ipv6_fd
= -1;
484 m
->llmnr_support
= RESOLVE_SUPPORT_YES
;
485 m
->mdns_support
= RESOLVE_SUPPORT_NO
;
486 m
->dnssec_mode
= DNSSEC_NO
;
487 m
->read_resolv_conf
= true;
488 m
->need_builtin_fallbacks
= true;
489 m
->etc_hosts_last
= m
->etc_hosts_mtime
= USEC_INFINITY
;
491 r
= dns_trust_anchor_load(&m
->trust_anchor
);
495 r
= manager_parse_config_file(m
);
499 r
= sd_event_default(&m
->event
);
503 sd_event_add_signal(m
->event
, NULL
, SIGTERM
, NULL
, NULL
);
504 sd_event_add_signal(m
->event
, NULL
, SIGINT
, NULL
, NULL
);
506 sd_event_set_watchdog(m
->event
, true);
508 r
= manager_watch_hostname(m
);
512 r
= dns_scope_new(m
, &m
->unicast_scope
, NULL
, DNS_PROTOCOL_DNS
, AF_UNSPEC
);
516 r
= manager_network_monitor_listen(m
);
520 r
= manager_rtnl_listen(m
);
524 r
= manager_connect_bus(m
);
528 (void) sd_event_add_signal(m
->event
, &m
->sigusr1_event_source
, SIGUSR1
, manager_sigusr1
, m
);
536 int manager_start(Manager
*m
) {
541 r
= manager_llmnr_start(m
);
545 r
= manager_mdns_start(m
);
552 Manager
*manager_free(Manager
*m
) {
558 dns_server_unlink_all(m
->dns_servers
);
559 dns_server_unlink_all(m
->fallback_dns_servers
);
560 dns_search_domain_unlink_all(m
->search_domains
);
562 while ((l
= hashmap_first(m
->links
)))
565 while (m
->dns_queries
)
566 dns_query_free(m
->dns_queries
);
568 dns_scope_free(m
->unicast_scope
);
570 hashmap_free(m
->links
);
571 hashmap_free(m
->dns_transactions
);
573 sd_event_source_unref(m
->network_event_source
);
574 sd_network_monitor_unref(m
->network_monitor
);
576 sd_netlink_unref(m
->rtnl
);
577 sd_event_source_unref(m
->rtnl_event_source
);
579 manager_llmnr_stop(m
);
580 manager_mdns_stop(m
);
582 sd_bus_slot_unref(m
->prepare_for_sleep_slot
);
583 sd_event_source_unref(m
->bus_retry_event_source
);
584 sd_bus_unref(m
->bus
);
586 sd_event_source_unref(m
->sigusr1_event_source
);
588 sd_event_unref(m
->event
);
590 dns_resource_key_unref(m
->llmnr_host_ipv4_key
);
591 dns_resource_key_unref(m
->llmnr_host_ipv6_key
);
593 sd_event_source_unref(m
->hostname_event_source
);
594 safe_close(m
->hostname_fd
);
595 free(m
->llmnr_hostname
);
596 free(m
->mdns_hostname
);
598 dns_trust_anchor_flush(&m
->trust_anchor
);
599 manager_etc_hosts_flush(m
);
606 int manager_recv(Manager
*m
, int fd
, DnsProtocol protocol
, DnsPacket
**ret
) {
607 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
609 struct cmsghdr header
; /* For alignment */
610 uint8_t buffer
[CMSG_SPACE(MAXSIZE(struct in_pktinfo
, struct in6_pktinfo
))
611 + CMSG_SPACE(int) /* ttl/hoplimit */
612 + EXTRA_CMSG_SPACE
/* kernel appears to require extra buffer space */];
614 union sockaddr_union sa
;
615 struct msghdr mh
= {};
616 struct cmsghdr
*cmsg
;
625 r
= ioctl(fd
, FIONREAD
, &ms
);
631 r
= dns_packet_new(&p
, protocol
, ms
);
635 iov
.iov_base
= DNS_PACKET_DATA(p
);
636 iov
.iov_len
= p
->allocated
;
638 mh
.msg_name
= &sa
.sa
;
639 mh
.msg_namelen
= sizeof(sa
);
642 mh
.msg_control
= &control
;
643 mh
.msg_controllen
= sizeof(control
);
645 l
= recvmsg(fd
, &mh
, 0);
647 if (errno
== EAGAIN
|| errno
== EINTR
)
656 assert(!(mh
.msg_flags
& MSG_CTRUNC
));
657 assert(!(mh
.msg_flags
& MSG_TRUNC
));
659 p
->size
= (size_t) l
;
661 p
->family
= sa
.sa
.sa_family
;
662 p
->ipproto
= IPPROTO_UDP
;
663 if (p
->family
== AF_INET
) {
664 p
->sender
.in
= sa
.in
.sin_addr
;
665 p
->sender_port
= be16toh(sa
.in
.sin_port
);
666 } else if (p
->family
== AF_INET6
) {
667 p
->sender
.in6
= sa
.in6
.sin6_addr
;
668 p
->sender_port
= be16toh(sa
.in6
.sin6_port
);
669 p
->ifindex
= sa
.in6
.sin6_scope_id
;
671 return -EAFNOSUPPORT
;
673 CMSG_FOREACH(cmsg
, &mh
) {
675 if (cmsg
->cmsg_level
== IPPROTO_IPV6
) {
676 assert(p
->family
== AF_INET6
);
678 switch (cmsg
->cmsg_type
) {
681 struct in6_pktinfo
*i
= (struct in6_pktinfo
*) CMSG_DATA(cmsg
);
684 p
->ifindex
= i
->ipi6_ifindex
;
686 p
->destination
.in6
= i
->ipi6_addr
;
691 p
->ttl
= *(int *) CMSG_DATA(cmsg
);
695 } else if (cmsg
->cmsg_level
== IPPROTO_IP
) {
696 assert(p
->family
== AF_INET
);
698 switch (cmsg
->cmsg_type
) {
701 struct in_pktinfo
*i
= (struct in_pktinfo
*) CMSG_DATA(cmsg
);
704 p
->ifindex
= i
->ipi_ifindex
;
706 p
->destination
.in
= i
->ipi_addr
;
711 p
->ttl
= *(int *) CMSG_DATA(cmsg
);
717 /* The Linux kernel sets the interface index to the loopback
718 * device if the packet came from the local host since it
719 * avoids the routing table in such a case. Let's unset the
720 * interface index in such a case. */
721 if (p
->ifindex
== LOOPBACK_IFINDEX
)
724 if (protocol
!= DNS_PROTOCOL_DNS
) {
725 /* If we don't know the interface index still, we look for the
726 * first local interface with a matching address. Yuck! */
728 p
->ifindex
= manager_find_ifindex(m
, p
->family
, &p
->destination
);
737 static int sendmsg_loop(int fd
, struct msghdr
*mh
, int flags
) {
744 if (sendmsg(fd
, mh
, flags
) >= 0)
753 r
= fd_wait_for_event(fd
, POLLOUT
, SEND_TIMEOUT_USEC
);
761 static int write_loop(int fd
, void *message
, size_t length
) {
768 if (write(fd
, message
, length
) >= 0)
777 r
= fd_wait_for_event(fd
, POLLOUT
, SEND_TIMEOUT_USEC
);
785 int manager_write(Manager
*m
, int fd
, DnsPacket
*p
) {
788 log_debug("Sending %s packet with id %" PRIu16
".", DNS_PACKET_QR(p
) ? "response" : "query", DNS_PACKET_ID(p
));
790 r
= write_loop(fd
, DNS_PACKET_DATA(p
), p
->size
);
797 static int manager_ipv4_send(Manager
*m
, int fd
, int ifindex
, const struct in_addr
*addr
, uint16_t port
, DnsPacket
*p
) {
798 union sockaddr_union sa
= {
799 .in
.sin_family
= AF_INET
,
802 struct cmsghdr header
; /* For alignment */
803 uint8_t buffer
[CMSG_SPACE(sizeof(struct in_pktinfo
))];
805 struct msghdr mh
= {};
814 iov
.iov_base
= DNS_PACKET_DATA(p
);
815 iov
.iov_len
= p
->size
;
817 sa
.in
.sin_addr
= *addr
;
818 sa
.in
.sin_port
= htobe16(port
),
822 mh
.msg_name
= &sa
.sa
;
823 mh
.msg_namelen
= sizeof(sa
.in
);
826 struct cmsghdr
*cmsg
;
827 struct in_pktinfo
*pi
;
831 mh
.msg_control
= &control
;
832 mh
.msg_controllen
= CMSG_LEN(sizeof(struct in_pktinfo
));
834 cmsg
= CMSG_FIRSTHDR(&mh
);
835 cmsg
->cmsg_len
= mh
.msg_controllen
;
836 cmsg
->cmsg_level
= IPPROTO_IP
;
837 cmsg
->cmsg_type
= IP_PKTINFO
;
839 pi
= (struct in_pktinfo
*) CMSG_DATA(cmsg
);
840 pi
->ipi_ifindex
= ifindex
;
843 return sendmsg_loop(fd
, &mh
, 0);
846 static int manager_ipv6_send(Manager
*m
, int fd
, int ifindex
, const struct in6_addr
*addr
, uint16_t port
, DnsPacket
*p
) {
847 union sockaddr_union sa
= {
848 .in6
.sin6_family
= AF_INET6
,
851 struct cmsghdr header
; /* For alignment */
852 uint8_t buffer
[CMSG_SPACE(sizeof(struct in6_pktinfo
))];
854 struct msghdr mh
= {};
863 iov
.iov_base
= DNS_PACKET_DATA(p
);
864 iov
.iov_len
= p
->size
;
866 sa
.in6
.sin6_addr
= *addr
;
867 sa
.in6
.sin6_port
= htobe16(port
),
868 sa
.in6
.sin6_scope_id
= ifindex
;
872 mh
.msg_name
= &sa
.sa
;
873 mh
.msg_namelen
= sizeof(sa
.in6
);
876 struct cmsghdr
*cmsg
;
877 struct in6_pktinfo
*pi
;
881 mh
.msg_control
= &control
;
882 mh
.msg_controllen
= CMSG_LEN(sizeof(struct in6_pktinfo
));
884 cmsg
= CMSG_FIRSTHDR(&mh
);
885 cmsg
->cmsg_len
= mh
.msg_controllen
;
886 cmsg
->cmsg_level
= IPPROTO_IPV6
;
887 cmsg
->cmsg_type
= IPV6_PKTINFO
;
889 pi
= (struct in6_pktinfo
*) CMSG_DATA(cmsg
);
890 pi
->ipi6_ifindex
= ifindex
;
893 return sendmsg_loop(fd
, &mh
, 0);
896 int manager_send(Manager
*m
, int fd
, int ifindex
, int family
, const union in_addr_union
*addr
, uint16_t port
, DnsPacket
*p
) {
903 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
));
905 if (family
== AF_INET
)
906 return manager_ipv4_send(m
, fd
, ifindex
, &addr
->in
, port
, p
);
907 else if (family
== AF_INET6
)
908 return manager_ipv6_send(m
, fd
, ifindex
, &addr
->in6
, port
, p
);
910 return -EAFNOSUPPORT
;
913 uint32_t manager_find_mtu(Manager
*m
) {
918 /* If we don't know on which link a DNS packet would be
919 * delivered, let's find the largest MTU that works on all
920 * interfaces we know of */
922 HASHMAP_FOREACH(l
, m
->links
, i
) {
926 if (mtu
<= 0 || l
->mtu
< mtu
)
933 int manager_find_ifindex(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
938 a
= manager_find_link_address(m
, family
, in_addr
);
940 return a
->link
->ifindex
;
945 void manager_refresh_rrs(Manager
*m
) {
951 m
->llmnr_host_ipv4_key
= dns_resource_key_unref(m
->llmnr_host_ipv4_key
);
952 m
->llmnr_host_ipv6_key
= dns_resource_key_unref(m
->llmnr_host_ipv6_key
);
954 HASHMAP_FOREACH(l
, m
->links
, i
) {
955 link_add_rrs(l
, true);
956 link_add_rrs(l
, false);
960 int manager_next_hostname(Manager
*m
) {
968 p
= strchr(m
->llmnr_hostname
, 0);
971 while (p
> m
->llmnr_hostname
) {
972 if (!strchr("0123456789", p
[-1]))
978 if (*p
== 0 || safe_atou64(p
, &u
) < 0 || u
<= 0)
981 /* Add a random number to the old value. This way we can avoid
982 * that two hosts pick the same hostname, win on IPv4 and lose
983 * on IPv6 (or vice versa), and pick the same hostname
984 * replacement hostname, ad infinitum. We still want the
985 * numbers to go up monotonically, hence we just add a random
988 random_bytes(&a
, sizeof(a
));
991 if (asprintf(&h
, "%.*s%" PRIu64
, (int) (p
- m
->llmnr_hostname
), m
->llmnr_hostname
, u
) < 0)
994 r
= dns_name_concat(h
, "local", &k
);
1000 log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m
->llmnr_hostname
, h
);
1002 free(m
->llmnr_hostname
);
1003 m
->llmnr_hostname
= h
;
1005 free(m
->mdns_hostname
);
1006 m
->mdns_hostname
= k
;
1008 manager_refresh_rrs(m
);
1013 LinkAddress
* manager_find_link_address(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
1019 HASHMAP_FOREACH(l
, m
->links
, i
) {
1022 a
= link_find_address(l
, family
, in_addr
);
1030 bool manager_our_packet(Manager
*m
, DnsPacket
*p
) {
1034 return !!manager_find_link_address(m
, p
->family
, &p
->sender
);
1037 DnsScope
* manager_find_scope(Manager
*m
, DnsPacket
*p
) {
1043 l
= hashmap_get(m
->links
, INT_TO_PTR(p
->ifindex
));
1047 switch (p
->protocol
) {
1048 case DNS_PROTOCOL_LLMNR
:
1049 if (p
->family
== AF_INET
)
1050 return l
->llmnr_ipv4_scope
;
1051 else if (p
->family
== AF_INET6
)
1052 return l
->llmnr_ipv6_scope
;
1056 case DNS_PROTOCOL_MDNS
:
1057 if (p
->family
== AF_INET
)
1058 return l
->mdns_ipv4_scope
;
1059 else if (p
->family
== AF_INET6
)
1060 return l
->mdns_ipv6_scope
;
1071 void manager_verify_all(Manager
*m
) {
1076 LIST_FOREACH(scopes
, s
, m
->dns_scopes
)
1077 dns_zone_verify_all(&s
->zone
);
1080 int manager_is_own_hostname(Manager
*m
, const char *name
) {
1086 if (m
->llmnr_hostname
) {
1087 r
= dns_name_equal(name
, m
->llmnr_hostname
);
1092 if (m
->mdns_hostname
)
1093 return dns_name_equal(name
, m
->mdns_hostname
);
1098 int manager_compile_dns_servers(Manager
*m
, OrderedSet
**dns
) {
1107 r
= ordered_set_ensure_allocated(dns
, &dns_server_hash_ops
);
1111 /* First add the system-wide servers and domains */
1112 LIST_FOREACH(servers
, s
, m
->dns_servers
) {
1113 r
= ordered_set_put(*dns
, s
);
1120 /* Then, add the per-link servers */
1121 HASHMAP_FOREACH(l
, m
->links
, i
) {
1122 LIST_FOREACH(servers
, s
, l
->dns_servers
) {
1123 r
= ordered_set_put(*dns
, s
);
1131 /* If we found nothing, add the fallback servers */
1132 if (ordered_set_isempty(*dns
)) {
1133 LIST_FOREACH(servers
, s
, m
->fallback_dns_servers
) {
1134 r
= ordered_set_put(*dns
, s
);
1145 int manager_compile_search_domains(Manager
*m
, OrderedSet
**domains
) {
1154 r
= ordered_set_ensure_allocated(domains
, &dns_name_hash_ops
);
1158 LIST_FOREACH(domains
, d
, m
->search_domains
) {
1159 r
= ordered_set_put(*domains
, d
->name
);
1166 HASHMAP_FOREACH(l
, m
->links
, i
) {
1168 LIST_FOREACH(domains
, d
, l
->search_domains
) {
1169 r
= ordered_set_put(*domains
, d
->name
);
1180 DnssecMode
manager_get_dnssec_mode(Manager
*m
) {
1183 if (m
->dnssec_mode
!= _DNSSEC_MODE_INVALID
)
1184 return m
->dnssec_mode
;
1189 bool manager_dnssec_supported(Manager
*m
) {
1196 if (manager_get_dnssec_mode(m
) == DNSSEC_NO
)
1199 server
= manager_get_dns_server(m
);
1200 if (server
&& !dns_server_dnssec_supported(server
))
1203 HASHMAP_FOREACH(l
, m
->links
, i
)
1204 if (!link_dnssec_supported(l
))
1210 void manager_dnssec_verdict(Manager
*m
, DnssecVerdict verdict
, const DnsResourceKey
*key
) {
1212 assert(verdict
>= 0);
1213 assert(verdict
< _DNSSEC_VERDICT_MAX
);
1215 if (log_get_max_level() >= LOG_DEBUG
) {
1216 _cleanup_free_
char *s
= NULL
;
1218 (void) dns_resource_key_to_string(key
, &s
);
1220 log_debug("Found verdict for lookup %s: %s", s
? strstrip(s
) : "n/a", dnssec_verdict_to_string(verdict
));
1223 m
->n_dnssec_verdict
[verdict
]++;