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
= sd_event_default(&m
->event
);
485 sd_event_add_signal(m
->event
, NULL
, SIGTERM
, NULL
, NULL
);
486 sd_event_add_signal(m
->event
, NULL
, SIGINT
, NULL
, NULL
);
488 sd_event_set_watchdog(m
->event
, true);
490 r
= manager_watch_hostname(m
);
494 r
= dns_scope_new(m
, &m
->unicast_scope
, NULL
, DNS_PROTOCOL_DNS
, AF_UNSPEC
);
498 r
= manager_network_monitor_listen(m
);
502 r
= manager_rtnl_listen(m
);
506 r
= manager_connect_bus(m
);
510 (void) sd_event_add_signal(m
->event
, &m
->sigusr1_event_source
, SIGUSR1
, manager_sigusr1
, m
);
518 int manager_start(Manager
*m
) {
523 r
= manager_llmnr_start(m
);
530 Manager
*manager_free(Manager
*m
) {
536 dns_server_unlink_all(m
->dns_servers
);
537 dns_server_unlink_all(m
->fallback_dns_servers
);
538 dns_search_domain_unlink_all(m
->search_domains
);
540 while ((l
= hashmap_first(m
->links
)))
543 while (m
->dns_queries
)
544 dns_query_free(m
->dns_queries
);
546 dns_scope_free(m
->unicast_scope
);
548 hashmap_free(m
->links
);
549 hashmap_free(m
->dns_transactions
);
551 sd_event_source_unref(m
->network_event_source
);
552 sd_network_monitor_unref(m
->network_monitor
);
554 sd_netlink_unref(m
->rtnl
);
555 sd_event_source_unref(m
->rtnl_event_source
);
557 manager_llmnr_stop(m
);
559 sd_bus_slot_unref(m
->prepare_for_sleep_slot
);
560 sd_event_source_unref(m
->bus_retry_event_source
);
561 sd_bus_unref(m
->bus
);
563 sd_event_source_unref(m
->sigusr1_event_source
);
565 sd_event_unref(m
->event
);
567 dns_resource_key_unref(m
->llmnr_host_ipv4_key
);
568 dns_resource_key_unref(m
->llmnr_host_ipv6_key
);
570 sd_event_source_unref(m
->hostname_event_source
);
571 safe_close(m
->hostname_fd
);
572 free(m
->llmnr_hostname
);
573 free(m
->mdns_hostname
);
580 int manager_recv(Manager
*m
, int fd
, DnsProtocol protocol
, DnsPacket
**ret
) {
581 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
583 struct cmsghdr header
; /* For alignment */
584 uint8_t buffer
[CMSG_SPACE(MAXSIZE(struct in_pktinfo
, struct in6_pktinfo
))
585 + CMSG_SPACE(int) /* ttl/hoplimit */
586 + EXTRA_CMSG_SPACE
/* kernel appears to require extra buffer space */];
588 union sockaddr_union sa
;
589 struct msghdr mh
= {};
590 struct cmsghdr
*cmsg
;
599 r
= ioctl(fd
, FIONREAD
, &ms
);
605 r
= dns_packet_new(&p
, protocol
, ms
);
609 iov
.iov_base
= DNS_PACKET_DATA(p
);
610 iov
.iov_len
= p
->allocated
;
612 mh
.msg_name
= &sa
.sa
;
613 mh
.msg_namelen
= sizeof(sa
);
616 mh
.msg_control
= &control
;
617 mh
.msg_controllen
= sizeof(control
);
619 l
= recvmsg(fd
, &mh
, 0);
621 if (errno
== EAGAIN
|| errno
== EINTR
)
630 assert(!(mh
.msg_flags
& MSG_CTRUNC
));
631 assert(!(mh
.msg_flags
& MSG_TRUNC
));
633 p
->size
= (size_t) l
;
635 p
->family
= sa
.sa
.sa_family
;
636 p
->ipproto
= IPPROTO_UDP
;
637 if (p
->family
== AF_INET
) {
638 p
->sender
.in
= sa
.in
.sin_addr
;
639 p
->sender_port
= be16toh(sa
.in
.sin_port
);
640 } else if (p
->family
== AF_INET6
) {
641 p
->sender
.in6
= sa
.in6
.sin6_addr
;
642 p
->sender_port
= be16toh(sa
.in6
.sin6_port
);
643 p
->ifindex
= sa
.in6
.sin6_scope_id
;
645 return -EAFNOSUPPORT
;
647 CMSG_FOREACH(cmsg
, &mh
) {
649 if (cmsg
->cmsg_level
== IPPROTO_IPV6
) {
650 assert(p
->family
== AF_INET6
);
652 switch (cmsg
->cmsg_type
) {
655 struct in6_pktinfo
*i
= (struct in6_pktinfo
*) CMSG_DATA(cmsg
);
658 p
->ifindex
= i
->ipi6_ifindex
;
660 p
->destination
.in6
= i
->ipi6_addr
;
665 p
->ttl
= *(int *) CMSG_DATA(cmsg
);
669 } else if (cmsg
->cmsg_level
== IPPROTO_IP
) {
670 assert(p
->family
== AF_INET
);
672 switch (cmsg
->cmsg_type
) {
675 struct in_pktinfo
*i
= (struct in_pktinfo
*) CMSG_DATA(cmsg
);
678 p
->ifindex
= i
->ipi_ifindex
;
680 p
->destination
.in
= i
->ipi_addr
;
685 p
->ttl
= *(int *) CMSG_DATA(cmsg
);
691 /* The Linux kernel sets the interface index to the loopback
692 * device if the packet came from the local host since it
693 * avoids the routing table in such a case. Let's unset the
694 * interface index in such a case. */
695 if (p
->ifindex
== LOOPBACK_IFINDEX
)
698 if (protocol
!= DNS_PROTOCOL_DNS
) {
699 /* If we don't know the interface index still, we look for the
700 * first local interface with a matching address. Yuck! */
702 p
->ifindex
= manager_find_ifindex(m
, p
->family
, &p
->destination
);
711 static int sendmsg_loop(int fd
, struct msghdr
*mh
, int flags
) {
718 if (sendmsg(fd
, mh
, flags
) >= 0)
727 r
= fd_wait_for_event(fd
, POLLOUT
, SEND_TIMEOUT_USEC
);
735 static int write_loop(int fd
, void *message
, size_t length
) {
742 if (write(fd
, message
, length
) >= 0)
751 r
= fd_wait_for_event(fd
, POLLOUT
, SEND_TIMEOUT_USEC
);
759 int manager_write(Manager
*m
, int fd
, DnsPacket
*p
) {
762 log_debug("Sending %s packet with id %u", DNS_PACKET_QR(p
) ? "response" : "query", DNS_PACKET_ID(p
));
764 r
= write_loop(fd
, DNS_PACKET_DATA(p
), p
->size
);
771 static int manager_ipv4_send(Manager
*m
, int fd
, int ifindex
, const struct in_addr
*addr
, uint16_t port
, DnsPacket
*p
) {
772 union sockaddr_union sa
= {
773 .in
.sin_family
= AF_INET
,
776 struct cmsghdr header
; /* For alignment */
777 uint8_t buffer
[CMSG_SPACE(sizeof(struct in_pktinfo
))];
779 struct msghdr mh
= {};
788 iov
.iov_base
= DNS_PACKET_DATA(p
);
789 iov
.iov_len
= p
->size
;
791 sa
.in
.sin_addr
= *addr
;
792 sa
.in
.sin_port
= htobe16(port
),
796 mh
.msg_name
= &sa
.sa
;
797 mh
.msg_namelen
= sizeof(sa
.in
);
800 struct cmsghdr
*cmsg
;
801 struct in_pktinfo
*pi
;
805 mh
.msg_control
= &control
;
806 mh
.msg_controllen
= CMSG_LEN(sizeof(struct in_pktinfo
));
808 cmsg
= CMSG_FIRSTHDR(&mh
);
809 cmsg
->cmsg_len
= mh
.msg_controllen
;
810 cmsg
->cmsg_level
= IPPROTO_IP
;
811 cmsg
->cmsg_type
= IP_PKTINFO
;
813 pi
= (struct in_pktinfo
*) CMSG_DATA(cmsg
);
814 pi
->ipi_ifindex
= ifindex
;
817 return sendmsg_loop(fd
, &mh
, 0);
820 static int manager_ipv6_send(Manager
*m
, int fd
, int ifindex
, const struct in6_addr
*addr
, uint16_t port
, DnsPacket
*p
) {
821 union sockaddr_union sa
= {
822 .in6
.sin6_family
= AF_INET6
,
825 struct cmsghdr header
; /* For alignment */
826 uint8_t buffer
[CMSG_SPACE(sizeof(struct in6_pktinfo
))];
828 struct msghdr mh
= {};
837 iov
.iov_base
= DNS_PACKET_DATA(p
);
838 iov
.iov_len
= p
->size
;
840 sa
.in6
.sin6_addr
= *addr
;
841 sa
.in6
.sin6_port
= htobe16(port
),
842 sa
.in6
.sin6_scope_id
= ifindex
;
846 mh
.msg_name
= &sa
.sa
;
847 mh
.msg_namelen
= sizeof(sa
.in6
);
850 struct cmsghdr
*cmsg
;
851 struct in6_pktinfo
*pi
;
855 mh
.msg_control
= &control
;
856 mh
.msg_controllen
= CMSG_LEN(sizeof(struct in6_pktinfo
));
858 cmsg
= CMSG_FIRSTHDR(&mh
);
859 cmsg
->cmsg_len
= mh
.msg_controllen
;
860 cmsg
->cmsg_level
= IPPROTO_IPV6
;
861 cmsg
->cmsg_type
= IPV6_PKTINFO
;
863 pi
= (struct in6_pktinfo
*) CMSG_DATA(cmsg
);
864 pi
->ipi6_ifindex
= ifindex
;
867 return sendmsg_loop(fd
, &mh
, 0);
870 int manager_send(Manager
*m
, int fd
, int ifindex
, int family
, const union in_addr_union
*addr
, uint16_t port
, DnsPacket
*p
) {
877 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
));
879 if (family
== AF_INET
)
880 return manager_ipv4_send(m
, fd
, ifindex
, &addr
->in
, port
, p
);
881 else if (family
== AF_INET6
)
882 return manager_ipv6_send(m
, fd
, ifindex
, &addr
->in6
, port
, p
);
884 return -EAFNOSUPPORT
;
887 uint32_t manager_find_mtu(Manager
*m
) {
892 /* If we don't know on which link a DNS packet would be
893 * delivered, let's find the largest MTU that works on all
894 * interfaces we know of */
896 HASHMAP_FOREACH(l
, m
->links
, i
) {
900 if (mtu
<= 0 || l
->mtu
< mtu
)
907 int manager_find_ifindex(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
912 a
= manager_find_link_address(m
, family
, in_addr
);
914 return a
->link
->ifindex
;
919 void manager_refresh_rrs(Manager
*m
) {
925 m
->llmnr_host_ipv4_key
= dns_resource_key_unref(m
->llmnr_host_ipv4_key
);
926 m
->llmnr_host_ipv6_key
= dns_resource_key_unref(m
->llmnr_host_ipv6_key
);
928 HASHMAP_FOREACH(l
, m
->links
, i
) {
929 link_add_rrs(l
, true);
930 link_add_rrs(l
, false);
934 int manager_next_hostname(Manager
*m
) {
942 p
= strchr(m
->llmnr_hostname
, 0);
945 while (p
> m
->llmnr_hostname
) {
946 if (!strchr("0123456789", p
[-1]))
952 if (*p
== 0 || safe_atou64(p
, &u
) < 0 || u
<= 0)
955 /* Add a random number to the old value. This way we can avoid
956 * that two hosts pick the same hostname, win on IPv4 and lose
957 * on IPv6 (or vice versa), and pick the same hostname
958 * replacement hostname, ad infinitum. We still want the
959 * numbers to go up monotonically, hence we just add a random
962 random_bytes(&a
, sizeof(a
));
965 if (asprintf(&h
, "%.*s%" PRIu64
, (int) (p
- m
->llmnr_hostname
), m
->llmnr_hostname
, u
) < 0)
968 r
= dns_name_concat(h
, "local", &k
);
974 log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m
->llmnr_hostname
, h
);
976 free(m
->llmnr_hostname
);
977 m
->llmnr_hostname
= h
;
979 free(m
->mdns_hostname
);
980 m
->mdns_hostname
= k
;
982 manager_refresh_rrs(m
);
987 LinkAddress
* manager_find_link_address(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
993 HASHMAP_FOREACH(l
, m
->links
, i
) {
996 a
= link_find_address(l
, family
, in_addr
);
1004 bool manager_our_packet(Manager
*m
, DnsPacket
*p
) {
1008 return !!manager_find_link_address(m
, p
->family
, &p
->sender
);
1011 DnsScope
* manager_find_scope(Manager
*m
, DnsPacket
*p
) {
1017 l
= hashmap_get(m
->links
, INT_TO_PTR(p
->ifindex
));
1021 if (p
->protocol
== DNS_PROTOCOL_LLMNR
) {
1022 if (p
->family
== AF_INET
)
1023 return l
->llmnr_ipv4_scope
;
1024 else if (p
->family
== AF_INET6
)
1025 return l
->llmnr_ipv6_scope
;
1031 void manager_verify_all(Manager
*m
) {
1036 LIST_FOREACH(scopes
, s
, m
->dns_scopes
)
1037 dns_zone_verify_all(&s
->zone
);
1040 int manager_is_own_hostname(Manager
*m
, const char *name
) {
1046 if (m
->llmnr_hostname
) {
1047 r
= dns_name_equal(name
, m
->llmnr_hostname
);
1052 if (m
->mdns_hostname
)
1053 return dns_name_equal(name
, m
->mdns_hostname
);
1058 int manager_compile_dns_servers(Manager
*m
, OrderedSet
**dns
) {
1067 r
= ordered_set_ensure_allocated(dns
, &dns_server_hash_ops
);
1071 /* First add the system-wide servers and domains */
1072 LIST_FOREACH(servers
, s
, m
->dns_servers
) {
1073 r
= ordered_set_put(*dns
, s
);
1080 /* Then, add the per-link servers */
1081 HASHMAP_FOREACH(l
, m
->links
, i
) {
1082 LIST_FOREACH(servers
, s
, l
->dns_servers
) {
1083 r
= ordered_set_put(*dns
, s
);
1091 /* If we found nothing, add the fallback servers */
1092 if (ordered_set_isempty(*dns
)) {
1093 LIST_FOREACH(servers
, s
, m
->fallback_dns_servers
) {
1094 r
= ordered_set_put(*dns
, s
);
1105 int manager_compile_search_domains(Manager
*m
, OrderedSet
**domains
) {
1114 r
= ordered_set_ensure_allocated(domains
, &dns_name_hash_ops
);
1118 LIST_FOREACH(domains
, d
, m
->search_domains
) {
1119 r
= ordered_set_put(*domains
, d
->name
);
1126 HASHMAP_FOREACH(l
, m
->links
, i
) {
1128 LIST_FOREACH(domains
, d
, l
->search_domains
) {
1129 r
= ordered_set_put(*domains
, d
->name
);
1140 static const char* const support_table
[_SUPPORT_MAX
] = {
1141 [SUPPORT_NO
] = "no",
1142 [SUPPORT_YES
] = "yes",
1143 [SUPPORT_RESOLVE
] = "resolve",
1145 DEFINE_STRING_TABLE_LOOKUP(support
, Support
);