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-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"
49 #define SEND_TIMEOUT_USEC (200 * USEC_PER_MSEC)
51 static int manager_process_link(sd_netlink
*rtnl
, sd_netlink_message
*mm
, void *userdata
) {
52 Manager
*m
= userdata
;
61 r
= sd_netlink_message_get_type(mm
, &type
);
65 r
= sd_rtnl_message_link_get_ifindex(mm
, &ifindex
);
69 l
= hashmap_get(m
->links
, INT_TO_PTR(ifindex
));
77 r
= link_new(m
, &l
, ifindex
);
82 r
= link_update_rtnl(l
, mm
);
86 r
= link_update_monitor(l
);
91 log_debug("Found new link %i/%s", ifindex
, l
->name
);
98 log_debug("Removing link %i/%s", l
->ifindex
, l
->name
);
108 log_warning_errno(r
, "Failed to process RTNL link message: %m");
112 static int manager_process_address(sd_netlink
*rtnl
, sd_netlink_message
*mm
, void *userdata
) {
113 Manager
*m
= userdata
;
114 union in_addr_union address
;
116 int r
, ifindex
, family
;
124 r
= sd_netlink_message_get_type(mm
, &type
);
128 r
= sd_rtnl_message_addr_get_ifindex(mm
, &ifindex
);
132 l
= hashmap_get(m
->links
, INT_TO_PTR(ifindex
));
136 r
= sd_rtnl_message_addr_get_family(mm
, &family
);
143 r
= sd_netlink_message_read_in_addr(mm
, IFA_LOCAL
, &address
.in
);
145 r
= sd_netlink_message_read_in_addr(mm
, IFA_ADDRESS
, &address
.in
);
153 r
= sd_netlink_message_read_in6_addr(mm
, IFA_LOCAL
, &address
.in6
);
155 r
= sd_netlink_message_read_in6_addr(mm
, IFA_ADDRESS
, &address
.in6
);
166 a
= link_find_address(l
, family
, &address
);
173 r
= link_address_new(l
, &a
, family
, &address
);
178 r
= link_address_update_rtnl(a
, mm
);
185 link_address_free(a
);
192 log_warning_errno(r
, "Failed to process RTNL address message: %m");
196 static int manager_rtnl_listen(Manager
*m
) {
197 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*req
= NULL
, *reply
= NULL
;
198 sd_netlink_message
*i
;
203 /* First, subscribe to interfaces coming and going */
204 r
= sd_netlink_open(&m
->rtnl
);
208 r
= sd_netlink_attach_event(m
->rtnl
, m
->event
, 0);
212 r
= sd_netlink_add_match(m
->rtnl
, RTM_NEWLINK
, manager_process_link
, m
);
216 r
= sd_netlink_add_match(m
->rtnl
, RTM_DELLINK
, manager_process_link
, m
);
220 r
= sd_netlink_add_match(m
->rtnl
, RTM_NEWADDR
, manager_process_address
, m
);
224 r
= sd_netlink_add_match(m
->rtnl
, RTM_DELADDR
, manager_process_address
, m
);
228 /* Then, enumerate all links */
229 r
= sd_rtnl_message_new_link(m
->rtnl
, &req
, RTM_GETLINK
, 0);
233 r
= sd_netlink_message_request_dump(req
, true);
237 r
= sd_netlink_call(m
->rtnl
, req
, 0, &reply
);
241 for (i
= reply
; i
; i
= sd_netlink_message_next(i
)) {
242 r
= manager_process_link(m
->rtnl
, i
, m
);
247 req
= sd_netlink_message_unref(req
);
248 reply
= sd_netlink_message_unref(reply
);
250 /* Finally, enumerate all addresses, too */
251 r
= sd_rtnl_message_new_addr(m
->rtnl
, &req
, RTM_GETADDR
, 0, AF_UNSPEC
);
255 r
= sd_netlink_message_request_dump(req
, true);
259 r
= sd_netlink_call(m
->rtnl
, req
, 0, &reply
);
263 for (i
= reply
; i
; i
= sd_netlink_message_next(i
)) {
264 r
= manager_process_address(m
->rtnl
, i
, m
);
272 static int on_network_event(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
273 Manager
*m
= userdata
;
280 sd_network_monitor_flush(m
->network_monitor
);
282 HASHMAP_FOREACH(l
, m
->links
, i
) {
283 r
= link_update_monitor(l
);
285 log_warning_errno(r
, "Failed to update monitor information for %i: %m", l
->ifindex
);
288 r
= manager_write_resolv_conf(m
);
290 log_warning_errno(r
, "Could not update resolv.conf: %m");
295 static int manager_network_monitor_listen(Manager
*m
) {
300 r
= sd_network_monitor_new(&m
->network_monitor
, NULL
);
304 fd
= sd_network_monitor_get_fd(m
->network_monitor
);
308 events
= sd_network_monitor_get_events(m
->network_monitor
);
312 r
= sd_event_add_io(m
->event
, &m
->network_event_source
, fd
, events
, &on_network_event
, m
);
319 static int determine_hostname(char **llmnr_hostname
, char **mdns_hostname
) {
320 _cleanup_free_
char *h
= NULL
, *n
= NULL
;
321 char label
[DNS_LABEL_MAX
];
325 assert(llmnr_hostname
);
326 assert(mdns_hostname
);
328 /* Extract and normalize the first label of the locally
329 * configured hostname, and check it's not "localhost". */
331 h
= gethostname_malloc();
336 r
= dns_label_unescape(&p
, label
, sizeof(label
));
338 return log_error_errno(r
, "Failed to unescape host name: %m");
340 log_error("Couldn't find a single label in hosntame.");
344 k
= dns_label_undo_idna(label
, r
, label
, sizeof(label
));
346 return log_error_errno(k
, "Failed to undo IDNA: %m");
350 if (!utf8_is_valid(label
)) {
351 log_error("System hostname is not UTF-8 clean.");
355 r
= dns_label_escape_new(label
, r
, &n
);
357 return log_error_errno(r
, "Failed to escape host name: %m");
359 if (is_localhost(n
)) {
360 log_debug("System hostname is 'localhost', ignoring.");
364 r
= dns_name_concat(n
, "local", mdns_hostname
);
366 return log_error_errno(r
, "Failed to determine mDNS hostname: %m");
374 static int on_hostname_change(sd_event_source
*es
, int fd
, uint32_t revents
, void *userdata
) {
375 _cleanup_free_
char *llmnr_hostname
= NULL
, *mdns_hostname
= NULL
;
376 Manager
*m
= userdata
;
381 r
= determine_hostname(&llmnr_hostname
, &mdns_hostname
);
383 return 0; /* ignore invalid hostnames */
385 if (streq(llmnr_hostname
, m
->llmnr_hostname
) && streq(mdns_hostname
, m
->mdns_hostname
))
388 log_info("System hostname changed to '%s'.", llmnr_hostname
);
390 free(m
->llmnr_hostname
);
391 free(m
->mdns_hostname
);
393 m
->llmnr_hostname
= llmnr_hostname
;
394 m
->mdns_hostname
= mdns_hostname
;
396 llmnr_hostname
= mdns_hostname
= NULL
;
398 manager_refresh_rrs(m
);
403 static int manager_watch_hostname(Manager
*m
) {
408 m
->hostname_fd
= open("/proc/sys/kernel/hostname", O_RDONLY
|O_CLOEXEC
|O_NDELAY
|O_NOCTTY
);
409 if (m
->hostname_fd
< 0) {
410 log_warning_errno(errno
, "Failed to watch hostname: %m");
414 r
= sd_event_add_io(m
->event
, &m
->hostname_event_source
, m
->hostname_fd
, 0, on_hostname_change
, m
);
417 /* kernels prior to 3.2 don't support polling this file. Ignore the failure. */
418 m
->hostname_fd
= safe_close(m
->hostname_fd
);
420 return log_error_errno(r
, "Failed to add hostname event source: %m");
423 r
= determine_hostname(&m
->llmnr_hostname
, &m
->mdns_hostname
);
425 log_info("Defaulting to hostname 'linux'.");
426 m
->llmnr_hostname
= strdup("linux");
427 if (!m
->llmnr_hostname
)
430 m
->mdns_hostname
= strdup("linux.local");
431 if (!m
->mdns_hostname
)
434 log_info("Using system hostname '%s'.", m
->llmnr_hostname
);
439 static int manager_sigusr1(sd_event_source
*s
, const struct signalfd_siginfo
*si
, void *userdata
) {
440 _cleanup_free_
char *buffer
= NULL
;
441 _cleanup_fclose_
FILE *f
= NULL
;
442 Manager
*m
= userdata
;
450 f
= open_memstream(&buffer
, &size
);
454 LIST_FOREACH(scopes
, scope
, m
->dns_scopes
)
455 dns_scope_dump(scope
, f
);
457 if (fflush_and_check(f
) < 0)
460 log_dump(LOG_INFO
, buffer
);
464 int manager_new(Manager
**ret
) {
465 _cleanup_(manager_freep
) Manager
*m
= NULL
;
470 m
= new0(Manager
, 1);
474 m
->llmnr_ipv4_udp_fd
= m
->llmnr_ipv6_udp_fd
= -1;
475 m
->llmnr_ipv4_tcp_fd
= m
->llmnr_ipv6_tcp_fd
= -1;
476 m
->mdns_ipv4_fd
= m
->mdns_ipv6_fd
= -1;
479 m
->llmnr_support
= RESOLVE_SUPPORT_YES
;
480 m
->mdns_support
= RESOLVE_SUPPORT_NO
;
481 m
->dnssec_mode
= DNSSEC_NO
;
482 m
->read_resolv_conf
= true;
483 m
->need_builtin_fallbacks
= true;
485 r
= dns_trust_anchor_load(&m
->trust_anchor
);
489 r
= manager_parse_config_file(m
);
493 r
= sd_event_default(&m
->event
);
497 sd_event_add_signal(m
->event
, NULL
, SIGTERM
, NULL
, NULL
);
498 sd_event_add_signal(m
->event
, NULL
, SIGINT
, NULL
, NULL
);
500 sd_event_set_watchdog(m
->event
, true);
502 r
= manager_watch_hostname(m
);
506 r
= dns_scope_new(m
, &m
->unicast_scope
, NULL
, DNS_PROTOCOL_DNS
, AF_UNSPEC
);
510 r
= manager_network_monitor_listen(m
);
514 r
= manager_rtnl_listen(m
);
518 r
= manager_connect_bus(m
);
522 (void) sd_event_add_signal(m
->event
, &m
->sigusr1_event_source
, SIGUSR1
, manager_sigusr1
, m
);
530 int manager_start(Manager
*m
) {
535 r
= manager_llmnr_start(m
);
539 r
= manager_mdns_start(m
);
546 Manager
*manager_free(Manager
*m
) {
552 dns_server_unlink_all(m
->dns_servers
);
553 dns_server_unlink_all(m
->fallback_dns_servers
);
554 dns_search_domain_unlink_all(m
->search_domains
);
556 while ((l
= hashmap_first(m
->links
)))
559 while (m
->dns_queries
)
560 dns_query_free(m
->dns_queries
);
562 dns_scope_free(m
->unicast_scope
);
564 hashmap_free(m
->links
);
565 hashmap_free(m
->dns_transactions
);
567 sd_event_source_unref(m
->network_event_source
);
568 sd_network_monitor_unref(m
->network_monitor
);
570 sd_netlink_unref(m
->rtnl
);
571 sd_event_source_unref(m
->rtnl_event_source
);
573 manager_llmnr_stop(m
);
574 manager_mdns_stop(m
);
576 sd_bus_slot_unref(m
->prepare_for_sleep_slot
);
577 sd_event_source_unref(m
->bus_retry_event_source
);
578 sd_bus_unref(m
->bus
);
580 sd_event_source_unref(m
->sigusr1_event_source
);
582 sd_event_unref(m
->event
);
584 dns_resource_key_unref(m
->llmnr_host_ipv4_key
);
585 dns_resource_key_unref(m
->llmnr_host_ipv6_key
);
587 sd_event_source_unref(m
->hostname_event_source
);
588 safe_close(m
->hostname_fd
);
589 free(m
->llmnr_hostname
);
590 free(m
->mdns_hostname
);
592 dns_trust_anchor_flush(&m
->trust_anchor
);
599 int manager_recv(Manager
*m
, int fd
, DnsProtocol protocol
, DnsPacket
**ret
) {
600 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
602 struct cmsghdr header
; /* For alignment */
603 uint8_t buffer
[CMSG_SPACE(MAXSIZE(struct in_pktinfo
, struct in6_pktinfo
))
604 + CMSG_SPACE(int) /* ttl/hoplimit */
605 + EXTRA_CMSG_SPACE
/* kernel appears to require extra buffer space */];
607 union sockaddr_union sa
;
608 struct msghdr mh
= {};
609 struct cmsghdr
*cmsg
;
618 r
= ioctl(fd
, FIONREAD
, &ms
);
624 r
= dns_packet_new(&p
, protocol
, ms
);
628 iov
.iov_base
= DNS_PACKET_DATA(p
);
629 iov
.iov_len
= p
->allocated
;
631 mh
.msg_name
= &sa
.sa
;
632 mh
.msg_namelen
= sizeof(sa
);
635 mh
.msg_control
= &control
;
636 mh
.msg_controllen
= sizeof(control
);
638 l
= recvmsg(fd
, &mh
, 0);
640 if (errno
== EAGAIN
|| errno
== EINTR
)
649 assert(!(mh
.msg_flags
& MSG_CTRUNC
));
650 assert(!(mh
.msg_flags
& MSG_TRUNC
));
652 p
->size
= (size_t) l
;
654 p
->family
= sa
.sa
.sa_family
;
655 p
->ipproto
= IPPROTO_UDP
;
656 if (p
->family
== AF_INET
) {
657 p
->sender
.in
= sa
.in
.sin_addr
;
658 p
->sender_port
= be16toh(sa
.in
.sin_port
);
659 } else if (p
->family
== AF_INET6
) {
660 p
->sender
.in6
= sa
.in6
.sin6_addr
;
661 p
->sender_port
= be16toh(sa
.in6
.sin6_port
);
662 p
->ifindex
= sa
.in6
.sin6_scope_id
;
664 return -EAFNOSUPPORT
;
666 CMSG_FOREACH(cmsg
, &mh
) {
668 if (cmsg
->cmsg_level
== IPPROTO_IPV6
) {
669 assert(p
->family
== AF_INET6
);
671 switch (cmsg
->cmsg_type
) {
674 struct in6_pktinfo
*i
= (struct in6_pktinfo
*) CMSG_DATA(cmsg
);
677 p
->ifindex
= i
->ipi6_ifindex
;
679 p
->destination
.in6
= i
->ipi6_addr
;
684 p
->ttl
= *(int *) CMSG_DATA(cmsg
);
688 } else if (cmsg
->cmsg_level
== IPPROTO_IP
) {
689 assert(p
->family
== AF_INET
);
691 switch (cmsg
->cmsg_type
) {
694 struct in_pktinfo
*i
= (struct in_pktinfo
*) CMSG_DATA(cmsg
);
697 p
->ifindex
= i
->ipi_ifindex
;
699 p
->destination
.in
= i
->ipi_addr
;
704 p
->ttl
= *(int *) CMSG_DATA(cmsg
);
710 /* The Linux kernel sets the interface index to the loopback
711 * device if the packet came from the local host since it
712 * avoids the routing table in such a case. Let's unset the
713 * interface index in such a case. */
714 if (p
->ifindex
== LOOPBACK_IFINDEX
)
717 if (protocol
!= DNS_PROTOCOL_DNS
) {
718 /* If we don't know the interface index still, we look for the
719 * first local interface with a matching address. Yuck! */
721 p
->ifindex
= manager_find_ifindex(m
, p
->family
, &p
->destination
);
730 static int sendmsg_loop(int fd
, struct msghdr
*mh
, int flags
) {
737 if (sendmsg(fd
, mh
, flags
) >= 0)
746 r
= fd_wait_for_event(fd
, POLLOUT
, SEND_TIMEOUT_USEC
);
754 static int write_loop(int fd
, void *message
, size_t length
) {
761 if (write(fd
, message
, length
) >= 0)
770 r
= fd_wait_for_event(fd
, POLLOUT
, SEND_TIMEOUT_USEC
);
778 int manager_write(Manager
*m
, int fd
, DnsPacket
*p
) {
781 log_debug("Sending %s packet with id %" PRIu16
".", DNS_PACKET_QR(p
) ? "response" : "query", DNS_PACKET_ID(p
));
783 r
= write_loop(fd
, DNS_PACKET_DATA(p
), p
->size
);
790 static int manager_ipv4_send(Manager
*m
, int fd
, int ifindex
, const struct in_addr
*addr
, uint16_t port
, DnsPacket
*p
) {
791 union sockaddr_union sa
= {
792 .in
.sin_family
= AF_INET
,
795 struct cmsghdr header
; /* For alignment */
796 uint8_t buffer
[CMSG_SPACE(sizeof(struct in_pktinfo
))];
798 struct msghdr mh
= {};
807 iov
.iov_base
= DNS_PACKET_DATA(p
);
808 iov
.iov_len
= p
->size
;
810 sa
.in
.sin_addr
= *addr
;
811 sa
.in
.sin_port
= htobe16(port
),
815 mh
.msg_name
= &sa
.sa
;
816 mh
.msg_namelen
= sizeof(sa
.in
);
819 struct cmsghdr
*cmsg
;
820 struct in_pktinfo
*pi
;
824 mh
.msg_control
= &control
;
825 mh
.msg_controllen
= CMSG_LEN(sizeof(struct in_pktinfo
));
827 cmsg
= CMSG_FIRSTHDR(&mh
);
828 cmsg
->cmsg_len
= mh
.msg_controllen
;
829 cmsg
->cmsg_level
= IPPROTO_IP
;
830 cmsg
->cmsg_type
= IP_PKTINFO
;
832 pi
= (struct in_pktinfo
*) CMSG_DATA(cmsg
);
833 pi
->ipi_ifindex
= ifindex
;
836 return sendmsg_loop(fd
, &mh
, 0);
839 static int manager_ipv6_send(Manager
*m
, int fd
, int ifindex
, const struct in6_addr
*addr
, uint16_t port
, DnsPacket
*p
) {
840 union sockaddr_union sa
= {
841 .in6
.sin6_family
= AF_INET6
,
844 struct cmsghdr header
; /* For alignment */
845 uint8_t buffer
[CMSG_SPACE(sizeof(struct in6_pktinfo
))];
847 struct msghdr mh
= {};
856 iov
.iov_base
= DNS_PACKET_DATA(p
);
857 iov
.iov_len
= p
->size
;
859 sa
.in6
.sin6_addr
= *addr
;
860 sa
.in6
.sin6_port
= htobe16(port
),
861 sa
.in6
.sin6_scope_id
= ifindex
;
865 mh
.msg_name
= &sa
.sa
;
866 mh
.msg_namelen
= sizeof(sa
.in6
);
869 struct cmsghdr
*cmsg
;
870 struct in6_pktinfo
*pi
;
874 mh
.msg_control
= &control
;
875 mh
.msg_controllen
= CMSG_LEN(sizeof(struct in6_pktinfo
));
877 cmsg
= CMSG_FIRSTHDR(&mh
);
878 cmsg
->cmsg_len
= mh
.msg_controllen
;
879 cmsg
->cmsg_level
= IPPROTO_IPV6
;
880 cmsg
->cmsg_type
= IPV6_PKTINFO
;
882 pi
= (struct in6_pktinfo
*) CMSG_DATA(cmsg
);
883 pi
->ipi6_ifindex
= ifindex
;
886 return sendmsg_loop(fd
, &mh
, 0);
889 int manager_send(Manager
*m
, int fd
, int ifindex
, int family
, const union in_addr_union
*addr
, uint16_t port
, DnsPacket
*p
) {
896 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
));
898 if (family
== AF_INET
)
899 return manager_ipv4_send(m
, fd
, ifindex
, &addr
->in
, port
, p
);
900 else if (family
== AF_INET6
)
901 return manager_ipv6_send(m
, fd
, ifindex
, &addr
->in6
, port
, p
);
903 return -EAFNOSUPPORT
;
906 uint32_t manager_find_mtu(Manager
*m
) {
911 /* If we don't know on which link a DNS packet would be
912 * delivered, let's find the largest MTU that works on all
913 * interfaces we know of */
915 HASHMAP_FOREACH(l
, m
->links
, i
) {
919 if (mtu
<= 0 || l
->mtu
< mtu
)
926 int manager_find_ifindex(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
931 a
= manager_find_link_address(m
, family
, in_addr
);
933 return a
->link
->ifindex
;
938 void manager_refresh_rrs(Manager
*m
) {
944 m
->llmnr_host_ipv4_key
= dns_resource_key_unref(m
->llmnr_host_ipv4_key
);
945 m
->llmnr_host_ipv6_key
= dns_resource_key_unref(m
->llmnr_host_ipv6_key
);
947 HASHMAP_FOREACH(l
, m
->links
, i
) {
948 link_add_rrs(l
, true);
949 link_add_rrs(l
, false);
953 int manager_next_hostname(Manager
*m
) {
961 p
= strchr(m
->llmnr_hostname
, 0);
964 while (p
> m
->llmnr_hostname
) {
965 if (!strchr("0123456789", p
[-1]))
971 if (*p
== 0 || safe_atou64(p
, &u
) < 0 || u
<= 0)
974 /* Add a random number to the old value. This way we can avoid
975 * that two hosts pick the same hostname, win on IPv4 and lose
976 * on IPv6 (or vice versa), and pick the same hostname
977 * replacement hostname, ad infinitum. We still want the
978 * numbers to go up monotonically, hence we just add a random
981 random_bytes(&a
, sizeof(a
));
984 if (asprintf(&h
, "%.*s%" PRIu64
, (int) (p
- m
->llmnr_hostname
), m
->llmnr_hostname
, u
) < 0)
987 r
= dns_name_concat(h
, "local", &k
);
993 log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m
->llmnr_hostname
, h
);
995 free(m
->llmnr_hostname
);
996 m
->llmnr_hostname
= h
;
998 free(m
->mdns_hostname
);
999 m
->mdns_hostname
= k
;
1001 manager_refresh_rrs(m
);
1006 LinkAddress
* manager_find_link_address(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
1012 HASHMAP_FOREACH(l
, m
->links
, i
) {
1015 a
= link_find_address(l
, family
, in_addr
);
1023 bool manager_our_packet(Manager
*m
, DnsPacket
*p
) {
1027 return !!manager_find_link_address(m
, p
->family
, &p
->sender
);
1030 DnsScope
* manager_find_scope(Manager
*m
, DnsPacket
*p
) {
1036 l
= hashmap_get(m
->links
, INT_TO_PTR(p
->ifindex
));
1040 switch (p
->protocol
) {
1041 case DNS_PROTOCOL_LLMNR
:
1042 if (p
->family
== AF_INET
)
1043 return l
->llmnr_ipv4_scope
;
1044 else if (p
->family
== AF_INET6
)
1045 return l
->llmnr_ipv6_scope
;
1049 case DNS_PROTOCOL_MDNS
:
1050 if (p
->family
== AF_INET
)
1051 return l
->mdns_ipv4_scope
;
1052 else if (p
->family
== AF_INET6
)
1053 return l
->mdns_ipv6_scope
;
1064 void manager_verify_all(Manager
*m
) {
1069 LIST_FOREACH(scopes
, s
, m
->dns_scopes
)
1070 dns_zone_verify_all(&s
->zone
);
1073 int manager_is_own_hostname(Manager
*m
, const char *name
) {
1079 if (m
->llmnr_hostname
) {
1080 r
= dns_name_equal(name
, m
->llmnr_hostname
);
1085 if (m
->mdns_hostname
)
1086 return dns_name_equal(name
, m
->mdns_hostname
);
1091 int manager_compile_dns_servers(Manager
*m
, OrderedSet
**dns
) {
1100 r
= ordered_set_ensure_allocated(dns
, &dns_server_hash_ops
);
1104 /* First add the system-wide servers and domains */
1105 LIST_FOREACH(servers
, s
, m
->dns_servers
) {
1106 r
= ordered_set_put(*dns
, s
);
1113 /* Then, add the per-link servers */
1114 HASHMAP_FOREACH(l
, m
->links
, i
) {
1115 LIST_FOREACH(servers
, s
, l
->dns_servers
) {
1116 r
= ordered_set_put(*dns
, s
);
1124 /* If we found nothing, add the fallback servers */
1125 if (ordered_set_isempty(*dns
)) {
1126 LIST_FOREACH(servers
, s
, m
->fallback_dns_servers
) {
1127 r
= ordered_set_put(*dns
, s
);
1138 int manager_compile_search_domains(Manager
*m
, OrderedSet
**domains
) {
1147 r
= ordered_set_ensure_allocated(domains
, &dns_name_hash_ops
);
1151 LIST_FOREACH(domains
, d
, m
->search_domains
) {
1152 r
= ordered_set_put(*domains
, d
->name
);
1159 HASHMAP_FOREACH(l
, m
->links
, i
) {
1161 LIST_FOREACH(domains
, d
, l
->search_domains
) {
1162 r
= ordered_set_put(*domains
, d
->name
);