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_netlink_message_unref_ 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(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;
480 r
= manager_parse_dns_server_string_and_warn(m
, DNS_SERVER_FALLBACK
, DNS_SERVERS
);
484 r
= sd_event_default(&m
->event
);
488 sd_event_add_signal(m
->event
, NULL
, SIGTERM
, NULL
, NULL
);
489 sd_event_add_signal(m
->event
, NULL
, SIGINT
, NULL
, NULL
);
491 sd_event_set_watchdog(m
->event
, true);
493 r
= manager_watch_hostname(m
);
497 r
= dns_scope_new(m
, &m
->unicast_scope
, NULL
, DNS_PROTOCOL_DNS
, AF_UNSPEC
);
501 r
= manager_network_monitor_listen(m
);
505 r
= manager_rtnl_listen(m
);
509 r
= manager_connect_bus(m
);
513 (void) sd_event_add_signal(m
->event
, &m
->sigusr1_event_source
, SIGUSR1
, manager_sigusr1
, m
);
521 int manager_start(Manager
*m
) {
526 r
= manager_llmnr_start(m
);
533 Manager
*manager_free(Manager
*m
) {
539 manager_flush_dns_servers(m
, DNS_SERVER_SYSTEM
);
540 manager_flush_dns_servers(m
, DNS_SERVER_FALLBACK
);
542 while ((l
= hashmap_first(m
->links
)))
545 while (m
->dns_queries
)
546 dns_query_free(m
->dns_queries
);
548 dns_scope_free(m
->unicast_scope
);
550 hashmap_free(m
->links
);
551 hashmap_free(m
->dns_transactions
);
553 sd_event_source_unref(m
->network_event_source
);
554 sd_network_monitor_unref(m
->network_monitor
);
556 sd_netlink_unref(m
->rtnl
);
557 sd_event_source_unref(m
->rtnl_event_source
);
559 manager_llmnr_stop(m
);
561 sd_bus_slot_unref(m
->prepare_for_sleep_slot
);
562 sd_event_source_unref(m
->bus_retry_event_source
);
563 sd_bus_unref(m
->bus
);
565 sd_event_source_unref(m
->sigusr1_event_source
);
567 sd_event_unref(m
->event
);
569 dns_resource_key_unref(m
->llmnr_host_ipv4_key
);
570 dns_resource_key_unref(m
->llmnr_host_ipv6_key
);
572 sd_event_source_unref(m
->hostname_event_source
);
573 safe_close(m
->hostname_fd
);
574 free(m
->llmnr_hostname
);
575 free(m
->mdns_hostname
);
582 int manager_recv(Manager
*m
, int fd
, DnsProtocol protocol
, DnsPacket
**ret
) {
583 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
585 struct cmsghdr header
; /* For alignment */
586 uint8_t buffer
[CMSG_SPACE(MAXSIZE(struct in_pktinfo
, struct in6_pktinfo
))
587 + CMSG_SPACE(int) /* ttl/hoplimit */
588 + EXTRA_CMSG_SPACE
/* kernel appears to require extra buffer space */];
590 union sockaddr_union sa
;
591 struct msghdr mh
= {};
592 struct cmsghdr
*cmsg
;
601 r
= ioctl(fd
, FIONREAD
, &ms
);
607 r
= dns_packet_new(&p
, protocol
, ms
);
611 iov
.iov_base
= DNS_PACKET_DATA(p
);
612 iov
.iov_len
= p
->allocated
;
614 mh
.msg_name
= &sa
.sa
;
615 mh
.msg_namelen
= sizeof(sa
);
618 mh
.msg_control
= &control
;
619 mh
.msg_controllen
= sizeof(control
);
621 l
= recvmsg(fd
, &mh
, 0);
623 if (errno
== EAGAIN
|| errno
== EINTR
)
632 assert(!(mh
.msg_flags
& MSG_CTRUNC
));
633 assert(!(mh
.msg_flags
& MSG_TRUNC
));
635 p
->size
= (size_t) l
;
637 p
->family
= sa
.sa
.sa_family
;
638 p
->ipproto
= IPPROTO_UDP
;
639 if (p
->family
== AF_INET
) {
640 p
->sender
.in
= sa
.in
.sin_addr
;
641 p
->sender_port
= be16toh(sa
.in
.sin_port
);
642 } else if (p
->family
== AF_INET6
) {
643 p
->sender
.in6
= sa
.in6
.sin6_addr
;
644 p
->sender_port
= be16toh(sa
.in6
.sin6_port
);
645 p
->ifindex
= sa
.in6
.sin6_scope_id
;
647 return -EAFNOSUPPORT
;
649 CMSG_FOREACH(cmsg
, &mh
) {
651 if (cmsg
->cmsg_level
== IPPROTO_IPV6
) {
652 assert(p
->family
== AF_INET6
);
654 switch (cmsg
->cmsg_type
) {
657 struct in6_pktinfo
*i
= (struct in6_pktinfo
*) CMSG_DATA(cmsg
);
660 p
->ifindex
= i
->ipi6_ifindex
;
662 p
->destination
.in6
= i
->ipi6_addr
;
667 p
->ttl
= *(int *) CMSG_DATA(cmsg
);
671 } else if (cmsg
->cmsg_level
== IPPROTO_IP
) {
672 assert(p
->family
== AF_INET
);
674 switch (cmsg
->cmsg_type
) {
677 struct in_pktinfo
*i
= (struct in_pktinfo
*) CMSG_DATA(cmsg
);
680 p
->ifindex
= i
->ipi_ifindex
;
682 p
->destination
.in
= i
->ipi_addr
;
687 p
->ttl
= *(int *) CMSG_DATA(cmsg
);
693 /* The Linux kernel sets the interface index to the loopback
694 * device if the packet came from the local host since it
695 * avoids the routing table in such a case. Let's unset the
696 * interface index in such a case. */
697 if (p
->ifindex
== LOOPBACK_IFINDEX
)
700 if (protocol
!= DNS_PROTOCOL_DNS
) {
701 /* If we don't know the interface index still, we look for the
702 * first local interface with a matching address. Yuck! */
704 p
->ifindex
= manager_find_ifindex(m
, p
->family
, &p
->destination
);
713 static int sendmsg_loop(int fd
, struct msghdr
*mh
, int flags
) {
720 if (sendmsg(fd
, mh
, flags
) >= 0)
729 r
= fd_wait_for_event(fd
, POLLOUT
, SEND_TIMEOUT_USEC
);
737 static int write_loop(int fd
, void *message
, size_t length
) {
744 if (write(fd
, message
, length
) >= 0)
753 r
= fd_wait_for_event(fd
, POLLOUT
, SEND_TIMEOUT_USEC
);
761 int manager_write(Manager
*m
, int fd
, DnsPacket
*p
) {
764 log_debug("Sending %s packet with id %u", DNS_PACKET_QR(p
) ? "response" : "query", DNS_PACKET_ID(p
));
766 r
= write_loop(fd
, DNS_PACKET_DATA(p
), p
->size
);
773 static int manager_ipv4_send(Manager
*m
, int fd
, int ifindex
, const struct in_addr
*addr
, uint16_t port
, DnsPacket
*p
) {
774 union sockaddr_union sa
= {
775 .in
.sin_family
= AF_INET
,
778 struct cmsghdr header
; /* For alignment */
779 uint8_t buffer
[CMSG_SPACE(sizeof(struct in_pktinfo
))];
781 struct msghdr mh
= {};
790 iov
.iov_base
= DNS_PACKET_DATA(p
);
791 iov
.iov_len
= p
->size
;
793 sa
.in
.sin_addr
= *addr
;
794 sa
.in
.sin_port
= htobe16(port
),
798 mh
.msg_name
= &sa
.sa
;
799 mh
.msg_namelen
= sizeof(sa
.in
);
802 struct cmsghdr
*cmsg
;
803 struct in_pktinfo
*pi
;
807 mh
.msg_control
= &control
;
808 mh
.msg_controllen
= CMSG_LEN(sizeof(struct in_pktinfo
));
810 cmsg
= CMSG_FIRSTHDR(&mh
);
811 cmsg
->cmsg_len
= mh
.msg_controllen
;
812 cmsg
->cmsg_level
= IPPROTO_IP
;
813 cmsg
->cmsg_type
= IP_PKTINFO
;
815 pi
= (struct in_pktinfo
*) CMSG_DATA(cmsg
);
816 pi
->ipi_ifindex
= ifindex
;
819 return sendmsg_loop(fd
, &mh
, 0);
822 static int manager_ipv6_send(Manager
*m
, int fd
, int ifindex
, const struct in6_addr
*addr
, uint16_t port
, DnsPacket
*p
) {
823 union sockaddr_union sa
= {
824 .in6
.sin6_family
= AF_INET6
,
827 struct cmsghdr header
; /* For alignment */
828 uint8_t buffer
[CMSG_SPACE(sizeof(struct in6_pktinfo
))];
830 struct msghdr mh
= {};
839 iov
.iov_base
= DNS_PACKET_DATA(p
);
840 iov
.iov_len
= p
->size
;
842 sa
.in6
.sin6_addr
= *addr
;
843 sa
.in6
.sin6_port
= htobe16(port
),
844 sa
.in6
.sin6_scope_id
= ifindex
;
848 mh
.msg_name
= &sa
.sa
;
849 mh
.msg_namelen
= sizeof(sa
.in6
);
852 struct cmsghdr
*cmsg
;
853 struct in6_pktinfo
*pi
;
857 mh
.msg_control
= &control
;
858 mh
.msg_controllen
= CMSG_LEN(sizeof(struct in6_pktinfo
));
860 cmsg
= CMSG_FIRSTHDR(&mh
);
861 cmsg
->cmsg_len
= mh
.msg_controllen
;
862 cmsg
->cmsg_level
= IPPROTO_IPV6
;
863 cmsg
->cmsg_type
= IPV6_PKTINFO
;
865 pi
= (struct in6_pktinfo
*) CMSG_DATA(cmsg
);
866 pi
->ipi6_ifindex
= ifindex
;
869 return sendmsg_loop(fd
, &mh
, 0);
872 int manager_send(Manager
*m
, int fd
, int ifindex
, int family
, const union in_addr_union
*addr
, uint16_t port
, DnsPacket
*p
) {
879 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
));
881 if (family
== AF_INET
)
882 return manager_ipv4_send(m
, fd
, ifindex
, &addr
->in
, port
, p
);
883 else if (family
== AF_INET6
)
884 return manager_ipv6_send(m
, fd
, ifindex
, &addr
->in6
, port
, p
);
886 return -EAFNOSUPPORT
;
889 uint32_t manager_find_mtu(Manager
*m
) {
894 /* If we don't know on which link a DNS packet would be
895 * delivered, let's find the largest MTU that works on all
896 * interfaces we know of */
898 HASHMAP_FOREACH(l
, m
->links
, i
) {
902 if (mtu
<= 0 || l
->mtu
< mtu
)
909 int manager_find_ifindex(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
914 a
= manager_find_link_address(m
, family
, in_addr
);
916 return a
->link
->ifindex
;
921 void manager_refresh_rrs(Manager
*m
) {
927 m
->llmnr_host_ipv4_key
= dns_resource_key_unref(m
->llmnr_host_ipv4_key
);
928 m
->llmnr_host_ipv6_key
= dns_resource_key_unref(m
->llmnr_host_ipv6_key
);
930 HASHMAP_FOREACH(l
, m
->links
, i
) {
931 link_add_rrs(l
, true);
932 link_add_rrs(l
, false);
936 int manager_next_hostname(Manager
*m
) {
944 p
= strchr(m
->llmnr_hostname
, 0);
947 while (p
> m
->llmnr_hostname
) {
948 if (!strchr("0123456789", p
[-1]))
954 if (*p
== 0 || safe_atou64(p
, &u
) < 0 || u
<= 0)
957 /* Add a random number to the old value. This way we can avoid
958 * that two hosts pick the same hostname, win on IPv4 and lose
959 * on IPv6 (or vice versa), and pick the same hostname
960 * replacement hostname, ad infinitum. We still want the
961 * numbers to go up monotonically, hence we just add a random
964 random_bytes(&a
, sizeof(a
));
967 if (asprintf(&h
, "%.*s%" PRIu64
, (int) (p
- m
->llmnr_hostname
), m
->llmnr_hostname
, u
) < 0)
970 r
= dns_name_concat(h
, "local", &k
);
976 log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m
->llmnr_hostname
, h
);
978 free(m
->llmnr_hostname
);
979 m
->llmnr_hostname
= h
;
981 free(m
->mdns_hostname
);
982 m
->mdns_hostname
= k
;
984 manager_refresh_rrs(m
);
989 LinkAddress
* manager_find_link_address(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
995 HASHMAP_FOREACH(l
, m
->links
, i
) {
998 a
= link_find_address(l
, family
, in_addr
);
1006 bool manager_our_packet(Manager
*m
, DnsPacket
*p
) {
1010 return !!manager_find_link_address(m
, p
->family
, &p
->sender
);
1013 DnsScope
* manager_find_scope(Manager
*m
, DnsPacket
*p
) {
1019 l
= hashmap_get(m
->links
, INT_TO_PTR(p
->ifindex
));
1023 if (p
->protocol
== DNS_PROTOCOL_LLMNR
) {
1024 if (p
->family
== AF_INET
)
1025 return l
->llmnr_ipv4_scope
;
1026 else if (p
->family
== AF_INET6
)
1027 return l
->llmnr_ipv6_scope
;
1033 void manager_verify_all(Manager
*m
) {
1038 LIST_FOREACH(scopes
, s
, m
->dns_scopes
)
1039 dns_zone_verify_all(&s
->zone
);
1042 int manager_is_own_hostname(Manager
*m
, const char *name
) {
1048 if (m
->llmnr_hostname
) {
1049 r
= dns_name_equal(name
, m
->llmnr_hostname
);
1054 if (m
->mdns_hostname
)
1055 return dns_name_equal(name
, m
->mdns_hostname
);
1060 static const char* const support_table
[_SUPPORT_MAX
] = {
1061 [SUPPORT_NO
] = "no",
1062 [SUPPORT_YES
] = "yes",
1063 [SUPPORT_RESOLVE
] = "resolve",
1065 DEFINE_STRING_TABLE_LOOKUP(support
, Support
);