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
= SUPPORT_YES
;
480 m
->read_resolv_conf
= true;
481 m
->need_builtin_fallbacks
= true;
483 r
= dns_trust_anchor_load(&m
->trust_anchor
);
487 r
= sd_event_default(&m
->event
);
491 sd_event_add_signal(m
->event
, NULL
, SIGTERM
, NULL
, NULL
);
492 sd_event_add_signal(m
->event
, NULL
, SIGINT
, NULL
, NULL
);
494 sd_event_set_watchdog(m
->event
, true);
496 r
= manager_watch_hostname(m
);
500 r
= dns_scope_new(m
, &m
->unicast_scope
, NULL
, DNS_PROTOCOL_DNS
, AF_UNSPEC
);
504 r
= manager_network_monitor_listen(m
);
508 r
= manager_rtnl_listen(m
);
512 r
= manager_connect_bus(m
);
516 (void) sd_event_add_signal(m
->event
, &m
->sigusr1_event_source
, SIGUSR1
, manager_sigusr1
, m
);
524 int manager_start(Manager
*m
) {
529 r
= manager_llmnr_start(m
);
533 r
= manager_mdns_start(m
);
540 Manager
*manager_free(Manager
*m
) {
546 dns_server_unlink_all(m
->dns_servers
);
547 dns_server_unlink_all(m
->fallback_dns_servers
);
548 dns_search_domain_unlink_all(m
->search_domains
);
550 while ((l
= hashmap_first(m
->links
)))
553 while (m
->dns_queries
)
554 dns_query_free(m
->dns_queries
);
556 dns_scope_free(m
->unicast_scope
);
558 hashmap_free(m
->links
);
559 hashmap_free(m
->dns_transactions
);
561 sd_event_source_unref(m
->network_event_source
);
562 sd_network_monitor_unref(m
->network_monitor
);
564 sd_netlink_unref(m
->rtnl
);
565 sd_event_source_unref(m
->rtnl_event_source
);
567 manager_llmnr_stop(m
);
568 manager_mdns_stop(m
);
570 sd_bus_slot_unref(m
->prepare_for_sleep_slot
);
571 sd_event_source_unref(m
->bus_retry_event_source
);
572 sd_bus_unref(m
->bus
);
574 sd_event_source_unref(m
->sigusr1_event_source
);
576 sd_event_unref(m
->event
);
578 dns_resource_key_unref(m
->llmnr_host_ipv4_key
);
579 dns_resource_key_unref(m
->llmnr_host_ipv6_key
);
581 sd_event_source_unref(m
->hostname_event_source
);
582 safe_close(m
->hostname_fd
);
583 free(m
->llmnr_hostname
);
584 free(m
->mdns_hostname
);
586 dns_trust_anchor_flush(&m
->trust_anchor
);
593 int manager_recv(Manager
*m
, int fd
, DnsProtocol protocol
, DnsPacket
**ret
) {
594 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
596 struct cmsghdr header
; /* For alignment */
597 uint8_t buffer
[CMSG_SPACE(MAXSIZE(struct in_pktinfo
, struct in6_pktinfo
))
598 + CMSG_SPACE(int) /* ttl/hoplimit */
599 + EXTRA_CMSG_SPACE
/* kernel appears to require extra buffer space */];
601 union sockaddr_union sa
;
602 struct msghdr mh
= {};
603 struct cmsghdr
*cmsg
;
612 r
= ioctl(fd
, FIONREAD
, &ms
);
618 r
= dns_packet_new(&p
, protocol
, ms
);
622 iov
.iov_base
= DNS_PACKET_DATA(p
);
623 iov
.iov_len
= p
->allocated
;
625 mh
.msg_name
= &sa
.sa
;
626 mh
.msg_namelen
= sizeof(sa
);
629 mh
.msg_control
= &control
;
630 mh
.msg_controllen
= sizeof(control
);
632 l
= recvmsg(fd
, &mh
, 0);
634 if (errno
== EAGAIN
|| errno
== EINTR
)
643 assert(!(mh
.msg_flags
& MSG_CTRUNC
));
644 assert(!(mh
.msg_flags
& MSG_TRUNC
));
646 p
->size
= (size_t) l
;
648 p
->family
= sa
.sa
.sa_family
;
649 p
->ipproto
= IPPROTO_UDP
;
650 if (p
->family
== AF_INET
) {
651 p
->sender
.in
= sa
.in
.sin_addr
;
652 p
->sender_port
= be16toh(sa
.in
.sin_port
);
653 } else if (p
->family
== AF_INET6
) {
654 p
->sender
.in6
= sa
.in6
.sin6_addr
;
655 p
->sender_port
= be16toh(sa
.in6
.sin6_port
);
656 p
->ifindex
= sa
.in6
.sin6_scope_id
;
658 return -EAFNOSUPPORT
;
660 CMSG_FOREACH(cmsg
, &mh
) {
662 if (cmsg
->cmsg_level
== IPPROTO_IPV6
) {
663 assert(p
->family
== AF_INET6
);
665 switch (cmsg
->cmsg_type
) {
668 struct in6_pktinfo
*i
= (struct in6_pktinfo
*) CMSG_DATA(cmsg
);
671 p
->ifindex
= i
->ipi6_ifindex
;
673 p
->destination
.in6
= i
->ipi6_addr
;
678 p
->ttl
= *(int *) CMSG_DATA(cmsg
);
682 } else if (cmsg
->cmsg_level
== IPPROTO_IP
) {
683 assert(p
->family
== AF_INET
);
685 switch (cmsg
->cmsg_type
) {
688 struct in_pktinfo
*i
= (struct in_pktinfo
*) CMSG_DATA(cmsg
);
691 p
->ifindex
= i
->ipi_ifindex
;
693 p
->destination
.in
= i
->ipi_addr
;
698 p
->ttl
= *(int *) CMSG_DATA(cmsg
);
704 /* The Linux kernel sets the interface index to the loopback
705 * device if the packet came from the local host since it
706 * avoids the routing table in such a case. Let's unset the
707 * interface index in such a case. */
708 if (p
->ifindex
== LOOPBACK_IFINDEX
)
711 if (protocol
!= DNS_PROTOCOL_DNS
) {
712 /* If we don't know the interface index still, we look for the
713 * first local interface with a matching address. Yuck! */
715 p
->ifindex
= manager_find_ifindex(m
, p
->family
, &p
->destination
);
724 static int sendmsg_loop(int fd
, struct msghdr
*mh
, int flags
) {
731 if (sendmsg(fd
, mh
, flags
) >= 0)
740 r
= fd_wait_for_event(fd
, POLLOUT
, SEND_TIMEOUT_USEC
);
748 static int write_loop(int fd
, void *message
, size_t length
) {
755 if (write(fd
, message
, length
) >= 0)
764 r
= fd_wait_for_event(fd
, POLLOUT
, SEND_TIMEOUT_USEC
);
772 int manager_write(Manager
*m
, int fd
, DnsPacket
*p
) {
775 log_debug("Sending %s packet with id %" PRIu16
".", DNS_PACKET_QR(p
) ? "response" : "query", DNS_PACKET_ID(p
));
777 r
= write_loop(fd
, DNS_PACKET_DATA(p
), p
->size
);
784 static int manager_ipv4_send(Manager
*m
, int fd
, int ifindex
, const struct in_addr
*addr
, uint16_t port
, DnsPacket
*p
) {
785 union sockaddr_union sa
= {
786 .in
.sin_family
= AF_INET
,
789 struct cmsghdr header
; /* For alignment */
790 uint8_t buffer
[CMSG_SPACE(sizeof(struct in_pktinfo
))];
792 struct msghdr mh
= {};
801 iov
.iov_base
= DNS_PACKET_DATA(p
);
802 iov
.iov_len
= p
->size
;
804 sa
.in
.sin_addr
= *addr
;
805 sa
.in
.sin_port
= htobe16(port
),
809 mh
.msg_name
= &sa
.sa
;
810 mh
.msg_namelen
= sizeof(sa
.in
);
813 struct cmsghdr
*cmsg
;
814 struct in_pktinfo
*pi
;
818 mh
.msg_control
= &control
;
819 mh
.msg_controllen
= CMSG_LEN(sizeof(struct in_pktinfo
));
821 cmsg
= CMSG_FIRSTHDR(&mh
);
822 cmsg
->cmsg_len
= mh
.msg_controllen
;
823 cmsg
->cmsg_level
= IPPROTO_IP
;
824 cmsg
->cmsg_type
= IP_PKTINFO
;
826 pi
= (struct in_pktinfo
*) CMSG_DATA(cmsg
);
827 pi
->ipi_ifindex
= ifindex
;
830 return sendmsg_loop(fd
, &mh
, 0);
833 static int manager_ipv6_send(Manager
*m
, int fd
, int ifindex
, const struct in6_addr
*addr
, uint16_t port
, DnsPacket
*p
) {
834 union sockaddr_union sa
= {
835 .in6
.sin6_family
= AF_INET6
,
838 struct cmsghdr header
; /* For alignment */
839 uint8_t buffer
[CMSG_SPACE(sizeof(struct in6_pktinfo
))];
841 struct msghdr mh
= {};
850 iov
.iov_base
= DNS_PACKET_DATA(p
);
851 iov
.iov_len
= p
->size
;
853 sa
.in6
.sin6_addr
= *addr
;
854 sa
.in6
.sin6_port
= htobe16(port
),
855 sa
.in6
.sin6_scope_id
= ifindex
;
859 mh
.msg_name
= &sa
.sa
;
860 mh
.msg_namelen
= sizeof(sa
.in6
);
863 struct cmsghdr
*cmsg
;
864 struct in6_pktinfo
*pi
;
868 mh
.msg_control
= &control
;
869 mh
.msg_controllen
= CMSG_LEN(sizeof(struct in6_pktinfo
));
871 cmsg
= CMSG_FIRSTHDR(&mh
);
872 cmsg
->cmsg_len
= mh
.msg_controllen
;
873 cmsg
->cmsg_level
= IPPROTO_IPV6
;
874 cmsg
->cmsg_type
= IPV6_PKTINFO
;
876 pi
= (struct in6_pktinfo
*) CMSG_DATA(cmsg
);
877 pi
->ipi6_ifindex
= ifindex
;
880 return sendmsg_loop(fd
, &mh
, 0);
883 int manager_send(Manager
*m
, int fd
, int ifindex
, int family
, const union in_addr_union
*addr
, uint16_t port
, DnsPacket
*p
) {
890 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
));
892 if (family
== AF_INET
)
893 return manager_ipv4_send(m
, fd
, ifindex
, &addr
->in
, port
, p
);
894 else if (family
== AF_INET6
)
895 return manager_ipv6_send(m
, fd
, ifindex
, &addr
->in6
, port
, p
);
897 return -EAFNOSUPPORT
;
900 uint32_t manager_find_mtu(Manager
*m
) {
905 /* If we don't know on which link a DNS packet would be
906 * delivered, let's find the largest MTU that works on all
907 * interfaces we know of */
909 HASHMAP_FOREACH(l
, m
->links
, i
) {
913 if (mtu
<= 0 || l
->mtu
< mtu
)
920 int manager_find_ifindex(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
925 a
= manager_find_link_address(m
, family
, in_addr
);
927 return a
->link
->ifindex
;
932 void manager_refresh_rrs(Manager
*m
) {
938 m
->llmnr_host_ipv4_key
= dns_resource_key_unref(m
->llmnr_host_ipv4_key
);
939 m
->llmnr_host_ipv6_key
= dns_resource_key_unref(m
->llmnr_host_ipv6_key
);
941 HASHMAP_FOREACH(l
, m
->links
, i
) {
942 link_add_rrs(l
, true);
943 link_add_rrs(l
, false);
947 int manager_next_hostname(Manager
*m
) {
955 p
= strchr(m
->llmnr_hostname
, 0);
958 while (p
> m
->llmnr_hostname
) {
959 if (!strchr("0123456789", p
[-1]))
965 if (*p
== 0 || safe_atou64(p
, &u
) < 0 || u
<= 0)
968 /* Add a random number to the old value. This way we can avoid
969 * that two hosts pick the same hostname, win on IPv4 and lose
970 * on IPv6 (or vice versa), and pick the same hostname
971 * replacement hostname, ad infinitum. We still want the
972 * numbers to go up monotonically, hence we just add a random
975 random_bytes(&a
, sizeof(a
));
978 if (asprintf(&h
, "%.*s%" PRIu64
, (int) (p
- m
->llmnr_hostname
), m
->llmnr_hostname
, u
) < 0)
981 r
= dns_name_concat(h
, "local", &k
);
987 log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m
->llmnr_hostname
, h
);
989 free(m
->llmnr_hostname
);
990 m
->llmnr_hostname
= h
;
992 free(m
->mdns_hostname
);
993 m
->mdns_hostname
= k
;
995 manager_refresh_rrs(m
);
1000 LinkAddress
* manager_find_link_address(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
1006 HASHMAP_FOREACH(l
, m
->links
, i
) {
1009 a
= link_find_address(l
, family
, in_addr
);
1017 bool manager_our_packet(Manager
*m
, DnsPacket
*p
) {
1021 return !!manager_find_link_address(m
, p
->family
, &p
->sender
);
1024 DnsScope
* manager_find_scope(Manager
*m
, DnsPacket
*p
) {
1030 l
= hashmap_get(m
->links
, INT_TO_PTR(p
->ifindex
));
1034 switch (p
->protocol
) {
1035 case DNS_PROTOCOL_LLMNR
:
1036 if (p
->family
== AF_INET
)
1037 return l
->llmnr_ipv4_scope
;
1038 else if (p
->family
== AF_INET6
)
1039 return l
->llmnr_ipv6_scope
;
1043 case DNS_PROTOCOL_MDNS
:
1044 if (p
->family
== AF_INET
)
1045 return l
->mdns_ipv4_scope
;
1046 else if (p
->family
== AF_INET6
)
1047 return l
->mdns_ipv6_scope
;
1058 void manager_verify_all(Manager
*m
) {
1063 LIST_FOREACH(scopes
, s
, m
->dns_scopes
)
1064 dns_zone_verify_all(&s
->zone
);
1067 int manager_is_own_hostname(Manager
*m
, const char *name
) {
1073 if (m
->llmnr_hostname
) {
1074 r
= dns_name_equal(name
, m
->llmnr_hostname
);
1079 if (m
->mdns_hostname
)
1080 return dns_name_equal(name
, m
->mdns_hostname
);
1085 int manager_compile_dns_servers(Manager
*m
, OrderedSet
**dns
) {
1094 r
= ordered_set_ensure_allocated(dns
, &dns_server_hash_ops
);
1098 /* First add the system-wide servers and domains */
1099 LIST_FOREACH(servers
, s
, m
->dns_servers
) {
1100 r
= ordered_set_put(*dns
, s
);
1107 /* Then, add the per-link servers */
1108 HASHMAP_FOREACH(l
, m
->links
, i
) {
1109 LIST_FOREACH(servers
, s
, l
->dns_servers
) {
1110 r
= ordered_set_put(*dns
, s
);
1118 /* If we found nothing, add the fallback servers */
1119 if (ordered_set_isempty(*dns
)) {
1120 LIST_FOREACH(servers
, s
, m
->fallback_dns_servers
) {
1121 r
= ordered_set_put(*dns
, s
);
1132 int manager_compile_search_domains(Manager
*m
, OrderedSet
**domains
) {
1141 r
= ordered_set_ensure_allocated(domains
, &dns_name_hash_ops
);
1145 LIST_FOREACH(domains
, d
, m
->search_domains
) {
1146 r
= ordered_set_put(*domains
, d
->name
);
1153 HASHMAP_FOREACH(l
, m
->links
, i
) {
1155 LIST_FOREACH(domains
, d
, l
->search_domains
) {
1156 r
= ordered_set_put(*domains
, d
->name
);
1167 static const char* const support_table
[_SUPPORT_MAX
] = {
1168 [SUPPORT_NO
] = "no",
1169 [SUPPORT_YES
] = "yes",
1170 [SUPPORT_RESOLVE
] = "resolve",
1172 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(support
, Support
, SUPPORT_YES
);