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 "socket-util.h"
44 #include "string-table.h"
45 #include "string-util.h"
48 #define SEND_TIMEOUT_USEC (200 * USEC_PER_MSEC)
50 static int manager_process_link(sd_netlink
*rtnl
, sd_netlink_message
*mm
, void *userdata
) {
51 Manager
*m
= userdata
;
60 r
= sd_netlink_message_get_type(mm
, &type
);
64 r
= sd_rtnl_message_link_get_ifindex(mm
, &ifindex
);
68 l
= hashmap_get(m
->links
, INT_TO_PTR(ifindex
));
76 r
= link_new(m
, &l
, ifindex
);
81 r
= link_update_rtnl(l
, mm
);
85 r
= link_update_monitor(l
);
90 log_debug("Found new link %i/%s", ifindex
, l
->name
);
97 log_debug("Removing link %i/%s", l
->ifindex
, l
->name
);
107 log_warning_errno(r
, "Failed to process RTNL link message: %m");
111 static int manager_process_address(sd_netlink
*rtnl
, sd_netlink_message
*mm
, void *userdata
) {
112 Manager
*m
= userdata
;
113 union in_addr_union address
;
115 int r
, ifindex
, family
;
123 r
= sd_netlink_message_get_type(mm
, &type
);
127 r
= sd_rtnl_message_addr_get_ifindex(mm
, &ifindex
);
131 l
= hashmap_get(m
->links
, INT_TO_PTR(ifindex
));
135 r
= sd_rtnl_message_addr_get_family(mm
, &family
);
142 r
= sd_netlink_message_read_in_addr(mm
, IFA_LOCAL
, &address
.in
);
144 r
= sd_netlink_message_read_in_addr(mm
, IFA_ADDRESS
, &address
.in
);
152 r
= sd_netlink_message_read_in6_addr(mm
, IFA_LOCAL
, &address
.in6
);
154 r
= sd_netlink_message_read_in6_addr(mm
, IFA_ADDRESS
, &address
.in6
);
165 a
= link_find_address(l
, family
, &address
);
172 r
= link_address_new(l
, &a
, family
, &address
);
177 r
= link_address_update_rtnl(a
, mm
);
184 link_address_free(a
);
191 log_warning_errno(r
, "Failed to process RTNL address message: %m");
195 static int manager_rtnl_listen(Manager
*m
) {
196 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*req
= NULL
, *reply
= NULL
;
197 sd_netlink_message
*i
;
202 /* First, subscribe to interfaces coming and going */
203 r
= sd_netlink_open(&m
->rtnl
);
207 r
= sd_netlink_attach_event(m
->rtnl
, m
->event
, 0);
211 r
= sd_netlink_add_match(m
->rtnl
, RTM_NEWLINK
, manager_process_link
, m
);
215 r
= sd_netlink_add_match(m
->rtnl
, RTM_DELLINK
, manager_process_link
, m
);
219 r
= sd_netlink_add_match(m
->rtnl
, RTM_NEWADDR
, manager_process_address
, m
);
223 r
= sd_netlink_add_match(m
->rtnl
, RTM_DELADDR
, manager_process_address
, m
);
227 /* Then, enumerate all links */
228 r
= sd_rtnl_message_new_link(m
->rtnl
, &req
, RTM_GETLINK
, 0);
232 r
= sd_netlink_message_request_dump(req
, true);
236 r
= sd_netlink_call(m
->rtnl
, req
, 0, &reply
);
240 for (i
= reply
; i
; i
= sd_netlink_message_next(i
)) {
241 r
= manager_process_link(m
->rtnl
, i
, m
);
246 req
= sd_netlink_message_unref(req
);
247 reply
= sd_netlink_message_unref(reply
);
249 /* Finally, enumerate all addresses, too */
250 r
= sd_rtnl_message_new_addr(m
->rtnl
, &req
, RTM_GETADDR
, 0, AF_UNSPEC
);
254 r
= sd_netlink_message_request_dump(req
, true);
258 r
= sd_netlink_call(m
->rtnl
, req
, 0, &reply
);
262 for (i
= reply
; i
; i
= sd_netlink_message_next(i
)) {
263 r
= manager_process_address(m
->rtnl
, i
, m
);
271 static int on_network_event(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
272 Manager
*m
= userdata
;
279 sd_network_monitor_flush(m
->network_monitor
);
281 HASHMAP_FOREACH(l
, m
->links
, i
) {
282 r
= link_update_monitor(l
);
284 log_warning_errno(r
, "Failed to update monitor information for %i: %m", l
->ifindex
);
287 r
= manager_write_resolv_conf(m
);
289 log_warning_errno(r
, "Could not update resolv.conf: %m");
294 static int manager_network_monitor_listen(Manager
*m
) {
299 r
= sd_network_monitor_new(&m
->network_monitor
, NULL
);
303 fd
= sd_network_monitor_get_fd(m
->network_monitor
);
307 events
= sd_network_monitor_get_events(m
->network_monitor
);
311 r
= sd_event_add_io(m
->event
, &m
->network_event_source
, fd
, events
, &on_network_event
, m
);
318 static int determine_hostname(char **llmnr_hostname
, char **mdns_hostname
) {
319 _cleanup_free_
char *h
= NULL
, *n
= NULL
;
320 char label
[DNS_LABEL_MAX
];
324 assert(llmnr_hostname
);
325 assert(mdns_hostname
);
327 /* Extract and normalize the first label of the locally
328 * configured hostname, and check it's not "localhost". */
330 h
= gethostname_malloc();
335 r
= dns_label_unescape(&p
, label
, sizeof(label
));
337 return log_error_errno(r
, "Failed to unescape host name: %m");
339 log_error("Couldn't find a single label in hosntame.");
343 k
= dns_label_undo_idna(label
, r
, label
, sizeof(label
));
345 return log_error_errno(k
, "Failed to undo IDNA: %m");
349 if (!utf8_is_valid(label
)) {
350 log_error("System hostname is not UTF-8 clean.");
354 r
= dns_label_escape_new(label
, r
, &n
);
356 return log_error_errno(r
, "Failed to escape host name: %m");
358 if (is_localhost(n
)) {
359 log_debug("System hostname is 'localhost', ignoring.");
363 r
= dns_name_concat(n
, "local", mdns_hostname
);
365 return log_error_errno(r
, "Failed to determine mDNS hostname: %m");
373 static int on_hostname_change(sd_event_source
*es
, int fd
, uint32_t revents
, void *userdata
) {
374 _cleanup_free_
char *llmnr_hostname
= NULL
, *mdns_hostname
= NULL
;
375 Manager
*m
= userdata
;
380 r
= determine_hostname(&llmnr_hostname
, &mdns_hostname
);
382 return 0; /* ignore invalid hostnames */
384 if (streq(llmnr_hostname
, m
->llmnr_hostname
) && streq(mdns_hostname
, m
->mdns_hostname
))
387 log_info("System hostname changed to '%s'.", llmnr_hostname
);
389 free(m
->llmnr_hostname
);
390 free(m
->mdns_hostname
);
392 m
->llmnr_hostname
= llmnr_hostname
;
393 m
->mdns_hostname
= mdns_hostname
;
395 llmnr_hostname
= mdns_hostname
= NULL
;
397 manager_refresh_rrs(m
);
402 static int manager_watch_hostname(Manager
*m
) {
407 m
->hostname_fd
= open("/proc/sys/kernel/hostname", O_RDONLY
|O_CLOEXEC
|O_NDELAY
|O_NOCTTY
);
408 if (m
->hostname_fd
< 0) {
409 log_warning_errno(errno
, "Failed to watch hostname: %m");
413 r
= sd_event_add_io(m
->event
, &m
->hostname_event_source
, m
->hostname_fd
, 0, on_hostname_change
, m
);
416 /* kernels prior to 3.2 don't support polling this file. Ignore the failure. */
417 m
->hostname_fd
= safe_close(m
->hostname_fd
);
419 return log_error_errno(r
, "Failed to add hostname event source: %m");
422 r
= determine_hostname(&m
->llmnr_hostname
, &m
->mdns_hostname
);
424 log_info("Defaulting to hostname 'linux'.");
425 m
->llmnr_hostname
= strdup("linux");
426 if (!m
->llmnr_hostname
)
429 m
->mdns_hostname
= strdup("linux.local");
430 if (!m
->mdns_hostname
)
433 log_info("Using system hostname '%s'.", m
->llmnr_hostname
);
438 static int manager_sigusr1(sd_event_source
*s
, const struct signalfd_siginfo
*si
, void *userdata
) {
439 _cleanup_free_
char *buffer
= NULL
;
440 _cleanup_fclose_
FILE *f
= NULL
;
441 Manager
*m
= userdata
;
449 f
= open_memstream(&buffer
, &size
);
453 LIST_FOREACH(scopes
, scope
, m
->dns_scopes
)
454 dns_scope_dump(scope
, f
);
456 if (fflush_and_check(f
) < 0)
459 log_dump(LOG_INFO
, buffer
);
463 int manager_new(Manager
**ret
) {
464 _cleanup_(manager_freep
) Manager
*m
= NULL
;
469 m
= new0(Manager
, 1);
473 m
->llmnr_ipv4_udp_fd
= m
->llmnr_ipv6_udp_fd
= -1;
474 m
->llmnr_ipv4_tcp_fd
= m
->llmnr_ipv6_tcp_fd
= -1;
477 m
->llmnr_support
= SUPPORT_YES
;
478 m
->read_resolv_conf
= true;
479 m
->need_builtin_fallbacks
= true;
481 r
= dns_trust_anchor_load(&m
->trust_anchor
);
485 r
= sd_event_default(&m
->event
);
489 sd_event_add_signal(m
->event
, NULL
, SIGTERM
, NULL
, NULL
);
490 sd_event_add_signal(m
->event
, NULL
, SIGINT
, NULL
, NULL
);
492 sd_event_set_watchdog(m
->event
, true);
494 r
= manager_watch_hostname(m
);
498 r
= dns_scope_new(m
, &m
->unicast_scope
, NULL
, DNS_PROTOCOL_DNS
, AF_UNSPEC
);
502 r
= manager_network_monitor_listen(m
);
506 r
= manager_rtnl_listen(m
);
510 r
= manager_connect_bus(m
);
514 (void) sd_event_add_signal(m
->event
, &m
->sigusr1_event_source
, SIGUSR1
, manager_sigusr1
, m
);
522 int manager_start(Manager
*m
) {
527 r
= manager_llmnr_start(m
);
534 Manager
*manager_free(Manager
*m
) {
540 dns_server_unlink_all(m
->dns_servers
);
541 dns_server_unlink_all(m
->fallback_dns_servers
);
542 dns_search_domain_unlink_all(m
->search_domains
);
544 while ((l
= hashmap_first(m
->links
)))
547 while (m
->dns_queries
)
548 dns_query_free(m
->dns_queries
);
550 dns_scope_free(m
->unicast_scope
);
552 hashmap_free(m
->links
);
553 hashmap_free(m
->dns_transactions
);
555 sd_event_source_unref(m
->network_event_source
);
556 sd_network_monitor_unref(m
->network_monitor
);
558 sd_netlink_unref(m
->rtnl
);
559 sd_event_source_unref(m
->rtnl_event_source
);
561 manager_llmnr_stop(m
);
563 sd_bus_slot_unref(m
->prepare_for_sleep_slot
);
564 sd_event_source_unref(m
->bus_retry_event_source
);
565 sd_bus_unref(m
->bus
);
567 sd_event_source_unref(m
->sigusr1_event_source
);
569 sd_event_unref(m
->event
);
571 dns_resource_key_unref(m
->llmnr_host_ipv4_key
);
572 dns_resource_key_unref(m
->llmnr_host_ipv6_key
);
574 sd_event_source_unref(m
->hostname_event_source
);
575 safe_close(m
->hostname_fd
);
576 free(m
->llmnr_hostname
);
577 free(m
->mdns_hostname
);
579 dns_trust_anchor_flush(&m
->trust_anchor
);
586 int manager_recv(Manager
*m
, int fd
, DnsProtocol protocol
, DnsPacket
**ret
) {
587 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
589 struct cmsghdr header
; /* For alignment */
590 uint8_t buffer
[CMSG_SPACE(MAXSIZE(struct in_pktinfo
, struct in6_pktinfo
))
591 + CMSG_SPACE(int) /* ttl/hoplimit */
592 + EXTRA_CMSG_SPACE
/* kernel appears to require extra buffer space */];
594 union sockaddr_union sa
;
595 struct msghdr mh
= {};
596 struct cmsghdr
*cmsg
;
605 r
= ioctl(fd
, FIONREAD
, &ms
);
611 r
= dns_packet_new(&p
, protocol
, ms
);
615 iov
.iov_base
= DNS_PACKET_DATA(p
);
616 iov
.iov_len
= p
->allocated
;
618 mh
.msg_name
= &sa
.sa
;
619 mh
.msg_namelen
= sizeof(sa
);
622 mh
.msg_control
= &control
;
623 mh
.msg_controllen
= sizeof(control
);
625 l
= recvmsg(fd
, &mh
, 0);
627 if (errno
== EAGAIN
|| errno
== EINTR
)
636 assert(!(mh
.msg_flags
& MSG_CTRUNC
));
637 assert(!(mh
.msg_flags
& MSG_TRUNC
));
639 p
->size
= (size_t) l
;
641 p
->family
= sa
.sa
.sa_family
;
642 p
->ipproto
= IPPROTO_UDP
;
643 if (p
->family
== AF_INET
) {
644 p
->sender
.in
= sa
.in
.sin_addr
;
645 p
->sender_port
= be16toh(sa
.in
.sin_port
);
646 } else if (p
->family
== AF_INET6
) {
647 p
->sender
.in6
= sa
.in6
.sin6_addr
;
648 p
->sender_port
= be16toh(sa
.in6
.sin6_port
);
649 p
->ifindex
= sa
.in6
.sin6_scope_id
;
651 return -EAFNOSUPPORT
;
653 CMSG_FOREACH(cmsg
, &mh
) {
655 if (cmsg
->cmsg_level
== IPPROTO_IPV6
) {
656 assert(p
->family
== AF_INET6
);
658 switch (cmsg
->cmsg_type
) {
661 struct in6_pktinfo
*i
= (struct in6_pktinfo
*) CMSG_DATA(cmsg
);
664 p
->ifindex
= i
->ipi6_ifindex
;
666 p
->destination
.in6
= i
->ipi6_addr
;
671 p
->ttl
= *(int *) CMSG_DATA(cmsg
);
675 } else if (cmsg
->cmsg_level
== IPPROTO_IP
) {
676 assert(p
->family
== AF_INET
);
678 switch (cmsg
->cmsg_type
) {
681 struct in_pktinfo
*i
= (struct in_pktinfo
*) CMSG_DATA(cmsg
);
684 p
->ifindex
= i
->ipi_ifindex
;
686 p
->destination
.in
= i
->ipi_addr
;
691 p
->ttl
= *(int *) CMSG_DATA(cmsg
);
697 /* The Linux kernel sets the interface index to the loopback
698 * device if the packet came from the local host since it
699 * avoids the routing table in such a case. Let's unset the
700 * interface index in such a case. */
701 if (p
->ifindex
== LOOPBACK_IFINDEX
)
704 if (protocol
!= DNS_PROTOCOL_DNS
) {
705 /* If we don't know the interface index still, we look for the
706 * first local interface with a matching address. Yuck! */
708 p
->ifindex
= manager_find_ifindex(m
, p
->family
, &p
->destination
);
717 static int sendmsg_loop(int fd
, struct msghdr
*mh
, int flags
) {
724 if (sendmsg(fd
, mh
, flags
) >= 0)
733 r
= fd_wait_for_event(fd
, POLLOUT
, SEND_TIMEOUT_USEC
);
741 static int write_loop(int fd
, void *message
, size_t length
) {
748 if (write(fd
, message
, length
) >= 0)
757 r
= fd_wait_for_event(fd
, POLLOUT
, SEND_TIMEOUT_USEC
);
765 int manager_write(Manager
*m
, int fd
, DnsPacket
*p
) {
768 log_debug("Sending %s packet with id %u", DNS_PACKET_QR(p
) ? "response" : "query", DNS_PACKET_ID(p
));
770 r
= write_loop(fd
, DNS_PACKET_DATA(p
), p
->size
);
777 static int manager_ipv4_send(Manager
*m
, int fd
, int ifindex
, const struct in_addr
*addr
, uint16_t port
, DnsPacket
*p
) {
778 union sockaddr_union sa
= {
779 .in
.sin_family
= AF_INET
,
782 struct cmsghdr header
; /* For alignment */
783 uint8_t buffer
[CMSG_SPACE(sizeof(struct in_pktinfo
))];
785 struct msghdr mh
= {};
794 iov
.iov_base
= DNS_PACKET_DATA(p
);
795 iov
.iov_len
= p
->size
;
797 sa
.in
.sin_addr
= *addr
;
798 sa
.in
.sin_port
= htobe16(port
),
802 mh
.msg_name
= &sa
.sa
;
803 mh
.msg_namelen
= sizeof(sa
.in
);
806 struct cmsghdr
*cmsg
;
807 struct in_pktinfo
*pi
;
811 mh
.msg_control
= &control
;
812 mh
.msg_controllen
= CMSG_LEN(sizeof(struct in_pktinfo
));
814 cmsg
= CMSG_FIRSTHDR(&mh
);
815 cmsg
->cmsg_len
= mh
.msg_controllen
;
816 cmsg
->cmsg_level
= IPPROTO_IP
;
817 cmsg
->cmsg_type
= IP_PKTINFO
;
819 pi
= (struct in_pktinfo
*) CMSG_DATA(cmsg
);
820 pi
->ipi_ifindex
= ifindex
;
823 return sendmsg_loop(fd
, &mh
, 0);
826 static int manager_ipv6_send(Manager
*m
, int fd
, int ifindex
, const struct in6_addr
*addr
, uint16_t port
, DnsPacket
*p
) {
827 union sockaddr_union sa
= {
828 .in6
.sin6_family
= AF_INET6
,
831 struct cmsghdr header
; /* For alignment */
832 uint8_t buffer
[CMSG_SPACE(sizeof(struct in6_pktinfo
))];
834 struct msghdr mh
= {};
843 iov
.iov_base
= DNS_PACKET_DATA(p
);
844 iov
.iov_len
= p
->size
;
846 sa
.in6
.sin6_addr
= *addr
;
847 sa
.in6
.sin6_port
= htobe16(port
),
848 sa
.in6
.sin6_scope_id
= ifindex
;
852 mh
.msg_name
= &sa
.sa
;
853 mh
.msg_namelen
= sizeof(sa
.in6
);
856 struct cmsghdr
*cmsg
;
857 struct in6_pktinfo
*pi
;
861 mh
.msg_control
= &control
;
862 mh
.msg_controllen
= CMSG_LEN(sizeof(struct in6_pktinfo
));
864 cmsg
= CMSG_FIRSTHDR(&mh
);
865 cmsg
->cmsg_len
= mh
.msg_controllen
;
866 cmsg
->cmsg_level
= IPPROTO_IPV6
;
867 cmsg
->cmsg_type
= IPV6_PKTINFO
;
869 pi
= (struct in6_pktinfo
*) CMSG_DATA(cmsg
);
870 pi
->ipi6_ifindex
= ifindex
;
873 return sendmsg_loop(fd
, &mh
, 0);
876 int manager_send(Manager
*m
, int fd
, int ifindex
, int family
, const union in_addr_union
*addr
, uint16_t port
, DnsPacket
*p
) {
883 log_debug("Sending %s packet with id %u on interface %i/%s", DNS_PACKET_QR(p
) ? "response" : "query", DNS_PACKET_ID(p
), ifindex
, af_to_name(family
));
885 if (family
== AF_INET
)
886 return manager_ipv4_send(m
, fd
, ifindex
, &addr
->in
, port
, p
);
887 else if (family
== AF_INET6
)
888 return manager_ipv6_send(m
, fd
, ifindex
, &addr
->in6
, port
, p
);
890 return -EAFNOSUPPORT
;
893 uint32_t manager_find_mtu(Manager
*m
) {
898 /* If we don't know on which link a DNS packet would be
899 * delivered, let's find the largest MTU that works on all
900 * interfaces we know of */
902 HASHMAP_FOREACH(l
, m
->links
, i
) {
906 if (mtu
<= 0 || l
->mtu
< mtu
)
913 int manager_find_ifindex(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
918 a
= manager_find_link_address(m
, family
, in_addr
);
920 return a
->link
->ifindex
;
925 void manager_refresh_rrs(Manager
*m
) {
931 m
->llmnr_host_ipv4_key
= dns_resource_key_unref(m
->llmnr_host_ipv4_key
);
932 m
->llmnr_host_ipv6_key
= dns_resource_key_unref(m
->llmnr_host_ipv6_key
);
934 HASHMAP_FOREACH(l
, m
->links
, i
) {
935 link_add_rrs(l
, true);
936 link_add_rrs(l
, false);
940 int manager_next_hostname(Manager
*m
) {
948 p
= strchr(m
->llmnr_hostname
, 0);
951 while (p
> m
->llmnr_hostname
) {
952 if (!strchr("0123456789", p
[-1]))
958 if (*p
== 0 || safe_atou64(p
, &u
) < 0 || u
<= 0)
961 /* Add a random number to the old value. This way we can avoid
962 * that two hosts pick the same hostname, win on IPv4 and lose
963 * on IPv6 (or vice versa), and pick the same hostname
964 * replacement hostname, ad infinitum. We still want the
965 * numbers to go up monotonically, hence we just add a random
968 random_bytes(&a
, sizeof(a
));
971 if (asprintf(&h
, "%.*s%" PRIu64
, (int) (p
- m
->llmnr_hostname
), m
->llmnr_hostname
, u
) < 0)
974 r
= dns_name_concat(h
, "local", &k
);
980 log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m
->llmnr_hostname
, h
);
982 free(m
->llmnr_hostname
);
983 m
->llmnr_hostname
= h
;
985 free(m
->mdns_hostname
);
986 m
->mdns_hostname
= k
;
988 manager_refresh_rrs(m
);
993 LinkAddress
* manager_find_link_address(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
999 HASHMAP_FOREACH(l
, m
->links
, i
) {
1002 a
= link_find_address(l
, family
, in_addr
);
1010 bool manager_our_packet(Manager
*m
, DnsPacket
*p
) {
1014 return !!manager_find_link_address(m
, p
->family
, &p
->sender
);
1017 DnsScope
* manager_find_scope(Manager
*m
, DnsPacket
*p
) {
1023 l
= hashmap_get(m
->links
, INT_TO_PTR(p
->ifindex
));
1027 if (p
->protocol
== DNS_PROTOCOL_LLMNR
) {
1028 if (p
->family
== AF_INET
)
1029 return l
->llmnr_ipv4_scope
;
1030 else if (p
->family
== AF_INET6
)
1031 return l
->llmnr_ipv6_scope
;
1037 void manager_verify_all(Manager
*m
) {
1042 LIST_FOREACH(scopes
, s
, m
->dns_scopes
)
1043 dns_zone_verify_all(&s
->zone
);
1046 int manager_is_own_hostname(Manager
*m
, const char *name
) {
1052 if (m
->llmnr_hostname
) {
1053 r
= dns_name_equal(name
, m
->llmnr_hostname
);
1058 if (m
->mdns_hostname
)
1059 return dns_name_equal(name
, m
->mdns_hostname
);
1064 int manager_compile_dns_servers(Manager
*m
, OrderedSet
**dns
) {
1073 r
= ordered_set_ensure_allocated(dns
, &dns_server_hash_ops
);
1077 /* First add the system-wide servers and domains */
1078 LIST_FOREACH(servers
, s
, m
->dns_servers
) {
1079 r
= ordered_set_put(*dns
, s
);
1086 /* Then, add the per-link servers */
1087 HASHMAP_FOREACH(l
, m
->links
, i
) {
1088 LIST_FOREACH(servers
, s
, l
->dns_servers
) {
1089 r
= ordered_set_put(*dns
, s
);
1097 /* If we found nothing, add the fallback servers */
1098 if (ordered_set_isempty(*dns
)) {
1099 LIST_FOREACH(servers
, s
, m
->fallback_dns_servers
) {
1100 r
= ordered_set_put(*dns
, s
);
1111 int manager_compile_search_domains(Manager
*m
, OrderedSet
**domains
) {
1120 r
= ordered_set_ensure_allocated(domains
, &dns_name_hash_ops
);
1124 LIST_FOREACH(domains
, d
, m
->search_domains
) {
1125 r
= ordered_set_put(*domains
, d
->name
);
1132 HASHMAP_FOREACH(l
, m
->links
, i
) {
1134 LIST_FOREACH(domains
, d
, l
->search_domains
) {
1135 r
= ordered_set_put(*domains
, d
->name
);
1146 static const char* const support_table
[_SUPPORT_MAX
] = {
1147 [SUPPORT_NO
] = "no",
1148 [SUPPORT_YES
] = "yes",
1149 [SUPPORT_RESOLVE
] = "resolve",
1151 DEFINE_STRING_TABLE_LOOKUP(support
, Support
);