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>
25 #include <sys/ioctl.h>
28 #include "dns-domain.h"
30 #include "fileio-label.h"
31 #include "hostname-util.h"
32 #include "netlink-util.h"
33 #include "network-internal.h"
34 #include "ordered-set.h"
35 #include "random-util.h"
36 #include "resolved-bus.h"
37 #include "resolved-conf.h"
38 #include "resolved-llmnr.h"
39 #include "resolved-manager.h"
40 #include "socket-util.h"
41 #include "string-util.h"
44 #define SEND_TIMEOUT_USEC (200 * USEC_PER_MSEC)
46 static int manager_process_link(sd_netlink
*rtnl
, sd_netlink_message
*mm
, void *userdata
) {
47 Manager
*m
= userdata
;
56 r
= sd_netlink_message_get_type(mm
, &type
);
60 r
= sd_rtnl_message_link_get_ifindex(mm
, &ifindex
);
64 l
= hashmap_get(m
->links
, INT_TO_PTR(ifindex
));
72 r
= link_new(m
, &l
, ifindex
);
77 r
= link_update_rtnl(l
, mm
);
81 r
= link_update_monitor(l
);
86 log_debug("Found new link %i/%s", ifindex
, l
->name
);
93 log_debug("Removing link %i/%s", l
->ifindex
, l
->name
);
103 log_warning_errno(r
, "Failed to process RTNL link message: %m");
107 static int manager_process_address(sd_netlink
*rtnl
, sd_netlink_message
*mm
, void *userdata
) {
108 Manager
*m
= userdata
;
109 union in_addr_union address
;
111 int r
, ifindex
, family
;
119 r
= sd_netlink_message_get_type(mm
, &type
);
123 r
= sd_rtnl_message_addr_get_ifindex(mm
, &ifindex
);
127 l
= hashmap_get(m
->links
, INT_TO_PTR(ifindex
));
131 r
= sd_rtnl_message_addr_get_family(mm
, &family
);
138 r
= sd_netlink_message_read_in_addr(mm
, IFA_LOCAL
, &address
.in
);
140 r
= sd_netlink_message_read_in_addr(mm
, IFA_ADDRESS
, &address
.in
);
148 r
= sd_netlink_message_read_in6_addr(mm
, IFA_LOCAL
, &address
.in6
);
150 r
= sd_netlink_message_read_in6_addr(mm
, IFA_ADDRESS
, &address
.in6
);
161 a
= link_find_address(l
, family
, &address
);
168 r
= link_address_new(l
, &a
, family
, &address
);
173 r
= link_address_update_rtnl(a
, mm
);
180 link_address_free(a
);
187 log_warning_errno(r
, "Failed to process RTNL address message: %m");
191 static int manager_rtnl_listen(Manager
*m
) {
192 _cleanup_netlink_message_unref_ sd_netlink_message
*req
= NULL
, *reply
= NULL
;
193 sd_netlink_message
*i
;
198 /* First, subscribe to interfaces coming and going */
199 r
= sd_netlink_open(&m
->rtnl
);
203 r
= sd_netlink_attach_event(m
->rtnl
, m
->event
, 0);
207 r
= sd_netlink_add_match(m
->rtnl
, RTM_NEWLINK
, manager_process_link
, m
);
211 r
= sd_netlink_add_match(m
->rtnl
, RTM_DELLINK
, manager_process_link
, m
);
215 r
= sd_netlink_add_match(m
->rtnl
, RTM_NEWADDR
, manager_process_address
, m
);
219 r
= sd_netlink_add_match(m
->rtnl
, RTM_DELADDR
, manager_process_address
, m
);
223 /* Then, enumerate all links */
224 r
= sd_rtnl_message_new_link(m
->rtnl
, &req
, RTM_GETLINK
, 0);
228 r
= sd_netlink_message_request_dump(req
, true);
232 r
= sd_netlink_call(m
->rtnl
, req
, 0, &reply
);
236 for (i
= reply
; i
; i
= sd_netlink_message_next(i
)) {
237 r
= manager_process_link(m
->rtnl
, i
, m
);
242 req
= sd_netlink_message_unref(req
);
243 reply
= sd_netlink_message_unref(reply
);
245 /* Finally, enumerate all addresses, too */
246 r
= sd_rtnl_message_new_addr(m
->rtnl
, &req
, RTM_GETADDR
, 0, AF_UNSPEC
);
250 r
= sd_netlink_message_request_dump(req
, true);
254 r
= sd_netlink_call(m
->rtnl
, req
, 0, &reply
);
258 for (i
= reply
; i
; i
= sd_netlink_message_next(i
)) {
259 r
= manager_process_address(m
->rtnl
, i
, m
);
267 static int on_network_event(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
268 Manager
*m
= userdata
;
275 sd_network_monitor_flush(m
->network_monitor
);
277 HASHMAP_FOREACH(l
, m
->links
, i
) {
278 r
= link_update_monitor(l
);
280 log_warning_errno(r
, "Failed to update monitor information for %i: %m", l
->ifindex
);
283 r
= manager_write_resolv_conf(m
);
285 log_warning_errno(r
, "Could not update resolv.conf: %m");
290 static int manager_network_monitor_listen(Manager
*m
) {
295 r
= sd_network_monitor_new(&m
->network_monitor
, NULL
);
299 fd
= sd_network_monitor_get_fd(m
->network_monitor
);
303 events
= sd_network_monitor_get_events(m
->network_monitor
);
307 r
= sd_event_add_io(m
->event
, &m
->network_event_source
, fd
, events
, &on_network_event
, m
);
314 static int determine_hostname(char **llmnr_hostname
, char **mdns_hostname
) {
315 _cleanup_free_
char *h
= NULL
, *n
= NULL
;
316 char label
[DNS_LABEL_MAX
];
320 assert(llmnr_hostname
);
321 assert(mdns_hostname
);
323 /* Extract and normalize the first label of the locally
324 * configured hostname, and check it's not "localhost". */
326 h
= gethostname_malloc();
331 r
= dns_label_unescape(&p
, label
, sizeof(label
));
333 return log_error_errno(r
, "Failed to unescape host name: %m");
335 log_error("Couldn't find a single label in hosntame.");
339 k
= dns_label_undo_idna(label
, r
, label
, sizeof(label
));
341 return log_error_errno(k
, "Failed to undo IDNA: %m");
345 if (!utf8_is_valid(label
)) {
346 log_error("System hostname is not UTF-8 clean.");
350 r
= dns_label_escape(label
, r
, &n
);
352 return log_error_errno(r
, "Failed to escape host name: %m");
354 if (is_localhost(n
)) {
355 log_debug("System hostname is 'localhost', ignoring.");
359 r
= dns_name_concat(n
, "local", mdns_hostname
);
361 return log_error_errno(r
, "Failed to determine mDNS hostname: %m");
369 static int on_hostname_change(sd_event_source
*es
, int fd
, uint32_t revents
, void *userdata
) {
370 _cleanup_free_
char *llmnr_hostname
= NULL
, *mdns_hostname
= NULL
;
371 Manager
*m
= userdata
;
376 r
= determine_hostname(&llmnr_hostname
, &mdns_hostname
);
378 return 0; /* ignore invalid hostnames */
380 if (streq(llmnr_hostname
, m
->llmnr_hostname
) && streq(mdns_hostname
, m
->mdns_hostname
))
383 log_info("System hostname changed to '%s'.", llmnr_hostname
);
385 free(m
->llmnr_hostname
);
386 free(m
->mdns_hostname
);
388 m
->llmnr_hostname
= llmnr_hostname
;
389 m
->mdns_hostname
= mdns_hostname
;
391 llmnr_hostname
= mdns_hostname
= NULL
;
393 manager_refresh_rrs(m
);
398 static int manager_watch_hostname(Manager
*m
) {
403 m
->hostname_fd
= open("/proc/sys/kernel/hostname", O_RDONLY
|O_CLOEXEC
|O_NDELAY
|O_NOCTTY
);
404 if (m
->hostname_fd
< 0) {
405 log_warning_errno(errno
, "Failed to watch hostname: %m");
409 r
= sd_event_add_io(m
->event
, &m
->hostname_event_source
, m
->hostname_fd
, 0, on_hostname_change
, m
);
412 /* kernels prior to 3.2 don't support polling this file. Ignore the failure. */
413 m
->hostname_fd
= safe_close(m
->hostname_fd
);
415 return log_error_errno(r
, "Failed to add hostname event source: %m");
418 r
= determine_hostname(&m
->llmnr_hostname
, &m
->mdns_hostname
);
420 log_info("Defaulting to hostname 'linux'.");
421 m
->llmnr_hostname
= strdup("linux");
422 if (!m
->llmnr_hostname
)
425 m
->mdns_hostname
= strdup("linux.local");
426 if (!m
->mdns_hostname
)
429 log_info("Using system hostname '%s'.", m
->llmnr_hostname
);
434 static int manager_sigusr1(sd_event_source
*s
, const struct signalfd_siginfo
*si
, void *userdata
) {
435 _cleanup_free_
char *buffer
= NULL
;
436 _cleanup_fclose_
FILE *f
= NULL
;
437 Manager
*m
= userdata
;
445 f
= open_memstream(&buffer
, &size
);
449 LIST_FOREACH(scopes
, scope
, m
->dns_scopes
)
450 dns_scope_dump(scope
, f
);
452 if (fflush_and_check(f
) < 0)
455 log_dump(LOG_INFO
, buffer
);
459 int manager_new(Manager
**ret
) {
460 _cleanup_(manager_freep
) Manager
*m
= NULL
;
465 m
= new0(Manager
, 1);
469 m
->llmnr_ipv4_udp_fd
= m
->llmnr_ipv6_udp_fd
= -1;
470 m
->llmnr_ipv4_tcp_fd
= m
->llmnr_ipv6_tcp_fd
= -1;
473 m
->llmnr_support
= SUPPORT_YES
;
474 m
->read_resolv_conf
= true;
476 r
= manager_parse_dns_server(m
, DNS_SERVER_FALLBACK
, DNS_SERVERS
);
480 r
= sd_event_default(&m
->event
);
484 sd_event_add_signal(m
->event
, NULL
, SIGTERM
, NULL
, NULL
);
485 sd_event_add_signal(m
->event
, NULL
, SIGINT
, NULL
, NULL
);
487 sd_event_set_watchdog(m
->event
, true);
489 r
= manager_watch_hostname(m
);
493 r
= dns_scope_new(m
, &m
->unicast_scope
, NULL
, DNS_PROTOCOL_DNS
, AF_UNSPEC
);
497 r
= manager_network_monitor_listen(m
);
501 r
= manager_rtnl_listen(m
);
505 r
= manager_connect_bus(m
);
509 (void) sd_event_add_signal(m
->event
, &m
->sigusr1_event_source
, SIGUSR1
, manager_sigusr1
, m
);
517 int manager_start(Manager
*m
) {
522 r
= manager_llmnr_start(m
);
529 Manager
*manager_free(Manager
*m
) {
535 while ((l
= hashmap_first(m
->links
)))
538 while (m
->dns_queries
)
539 dns_query_free(m
->dns_queries
);
541 manager_flush_dns_servers(m
, DNS_SERVER_SYSTEM
);
542 manager_flush_dns_servers(m
, DNS_SERVER_FALLBACK
);
544 dns_scope_free(m
->unicast_scope
);
546 hashmap_free(m
->links
);
547 hashmap_free(m
->dns_transactions
);
549 sd_event_source_unref(m
->network_event_source
);
550 sd_network_monitor_unref(m
->network_monitor
);
552 manager_llmnr_stop(m
);
554 sd_bus_slot_unref(m
->prepare_for_sleep_slot
);
555 sd_event_source_unref(m
->bus_retry_event_source
);
556 sd_bus_unref(m
->bus
);
558 sd_event_source_unref(m
->sigusr1_event_source
);
560 sd_event_unref(m
->event
);
562 dns_resource_key_unref(m
->llmnr_host_ipv4_key
);
563 dns_resource_key_unref(m
->llmnr_host_ipv6_key
);
565 sd_event_source_unref(m
->hostname_event_source
);
566 safe_close(m
->hostname_fd
);
567 free(m
->llmnr_hostname
);
568 free(m
->mdns_hostname
);
575 int manager_read_resolv_conf(Manager
*m
) {
576 _cleanup_fclose_
FILE *f
= NULL
;
585 /* Reads the system /etc/resolv.conf, if it exists and is not
586 * symlinked to our own resolv.conf instance */
588 if (!m
->read_resolv_conf
)
591 r
= stat("/etc/resolv.conf", &st
);
594 log_warning_errno(errno
, "Failed to open /etc/resolv.conf: %m");
599 /* Have we already seen the file? */
600 t
= timespec_load(&st
.st_mtim
);
601 if (t
== m
->resolv_conf_mtime
)
604 m
->resolv_conf_mtime
= t
;
606 /* Is it symlinked to our own file? */
607 if (stat("/run/systemd/resolve/resolv.conf", &own
) >= 0 &&
608 st
.st_dev
== own
.st_dev
&&
609 st
.st_ino
== own
.st_ino
) {
614 f
= fopen("/etc/resolv.conf", "re");
617 log_warning_errno(errno
, "Failed to open /etc/resolv.conf: %m");
622 if (fstat(fileno(f
), &st
) < 0) {
623 r
= log_error_errno(errno
, "Failed to stat open file: %m");
627 LIST_FOREACH(servers
, s
, m
->dns_servers
)
630 FOREACH_LINE(line
, f
, r
= -errno
; goto clear
) {
631 union in_addr_union address
;
639 if (*l
== '#' || *l
== ';')
642 a
= first_word(l
, "nameserver");
646 r
= in_addr_from_string_auto(a
, &family
, &address
);
648 log_warning("Failed to parse name server %s.", a
);
652 LIST_FOREACH(servers
, s
, m
->dns_servers
)
653 if (s
->family
== family
&& in_addr_equal(family
, &s
->address
, &address
) > 0)
659 r
= dns_server_new(m
, NULL
, DNS_SERVER_SYSTEM
, NULL
, family
, &address
);
665 LIST_FOREACH_SAFE(servers
, s
, nx
, m
->dns_servers
)
667 LIST_REMOVE(servers
, m
->dns_servers
, s
);
671 /* Whenever /etc/resolv.conf changes, start using the first
672 * DNS server of it. This is useful to deal with broken
673 * network managing implementations (like NetworkManager),
674 * that when connecting to a VPN place both the VPN DNS
675 * servers and the local ones in /etc/resolv.conf. Without
676 * resetting the DNS server to use back to the first entry we
677 * will continue to use the local one thus being unable to
678 * resolve VPN domains. */
679 manager_set_dns_server(m
, m
->dns_servers
);
684 while (m
->dns_servers
) {
687 LIST_REMOVE(servers
, m
->dns_servers
, s
);
694 static void write_resolv_conf_server(DnsServer
*s
, FILE *f
, unsigned *count
) {
695 _cleanup_free_
char *t
= NULL
;
702 r
= in_addr_to_string(s
->family
, &s
->address
, &t
);
704 log_warning_errno(r
, "Invalid DNS address. Ignoring: %m");
709 fputs("# Too many DNS servers configured, the following entries may be ignored.\n", f
);
711 fprintf(f
, "nameserver %s\n", t
);
715 static void write_resolv_conf_search(
716 const char *domain
, FILE *f
,
724 if (*count
>= MAXDNSRCH
||
725 *length
+ strlen(domain
) > 256) {
726 if (*count
== MAXDNSRCH
)
727 fputs(" # Too many search domains configured, remaining ones ignored.", f
);
729 fputs(" # Total length of all search domains is too long, remaining ones ignored.", f
);
734 fprintf(f
, " %s", domain
);
736 (*length
) += strlen(domain
);
740 static int write_resolv_conf_contents(FILE *f
, OrderedSet
*dns
, OrderedSet
*domains
) {
743 fputs("# This file is managed by systemd-resolved(8). Do not edit.\n#\n"
744 "# Third party programs must not access this file directly, but\n"
745 "# only through the symlink at /etc/resolv.conf. To manage\n"
746 "# resolv.conf(5) in a different way, replace the symlink by a\n"
747 "# static file or a different symlink.\n\n", f
);
749 if (ordered_set_isempty(dns
))
750 fputs("# No DNS servers known.\n", f
);
755 ORDERED_SET_FOREACH(s
, dns
, i
)
756 write_resolv_conf_server(s
, f
, &count
);
759 if (!ordered_set_isempty(domains
)) {
760 unsigned length
= 0, count
= 0;
764 ORDERED_SET_FOREACH(domain
, domains
, i
)
765 write_resolv_conf_search(domain
, f
, &count
, &length
);
769 return fflush_and_check(f
);
772 int manager_write_resolv_conf(Manager
*m
) {
773 static const char path
[] = "/run/systemd/resolve/resolv.conf";
774 _cleanup_free_
char *temp_path
= NULL
;
775 _cleanup_fclose_
FILE *f
= NULL
;
776 _cleanup_ordered_set_free_ OrderedSet
*dns
= NULL
, *domains
= NULL
;
784 /* Read the system /etc/resolv.conf first */
785 manager_read_resolv_conf(m
);
787 /* Add the full list to a set, to filter out duplicates */
788 dns
= ordered_set_new(&dns_server_hash_ops
);
792 domains
= ordered_set_new(&dns_name_hash_ops
);
796 /* First add the system-wide servers */
797 LIST_FOREACH(servers
, s
, m
->dns_servers
) {
798 r
= ordered_set_put(dns
, s
);
805 /* Then, add the per-link servers and domains */
806 HASHMAP_FOREACH(l
, m
->links
, i
) {
809 LIST_FOREACH(servers
, s
, l
->dns_servers
) {
810 r
= ordered_set_put(dns
, s
);
817 if (!l
->unicast_scope
)
820 STRV_FOREACH(domain
, l
->unicast_scope
->domains
) {
821 r
= ordered_set_put(domains
, *domain
);
829 /* If we found nothing, add the fallback servers */
830 if (ordered_set_isempty(dns
)) {
831 LIST_FOREACH(servers
, s
, m
->fallback_dns_servers
) {
832 r
= ordered_set_put(dns
, s
);
840 r
= fopen_temporary_label(path
, path
, &f
, &temp_path
);
844 fchmod(fileno(f
), 0644);
846 r
= write_resolv_conf_contents(f
, dns
, domains
);
850 if (rename(temp_path
, path
) < 0) {
859 (void) unlink(temp_path
);
863 int manager_recv(Manager
*m
, int fd
, DnsProtocol protocol
, DnsPacket
**ret
) {
864 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
866 struct cmsghdr header
; /* For alignment */
867 uint8_t buffer
[CMSG_SPACE(MAXSIZE(struct in_pktinfo
, struct in6_pktinfo
))
868 + CMSG_SPACE(int) /* ttl/hoplimit */
869 + EXTRA_CMSG_SPACE
/* kernel appears to require extra buffer space */];
871 union sockaddr_union sa
;
872 struct msghdr mh
= {};
873 struct cmsghdr
*cmsg
;
882 r
= ioctl(fd
, FIONREAD
, &ms
);
888 r
= dns_packet_new(&p
, protocol
, ms
);
892 iov
.iov_base
= DNS_PACKET_DATA(p
);
893 iov
.iov_len
= p
->allocated
;
895 mh
.msg_name
= &sa
.sa
;
896 mh
.msg_namelen
= sizeof(sa
);
899 mh
.msg_control
= &control
;
900 mh
.msg_controllen
= sizeof(control
);
902 l
= recvmsg(fd
, &mh
, 0);
904 if (errno
== EAGAIN
|| errno
== EINTR
)
913 assert(!(mh
.msg_flags
& MSG_CTRUNC
));
914 assert(!(mh
.msg_flags
& MSG_TRUNC
));
916 p
->size
= (size_t) l
;
918 p
->family
= sa
.sa
.sa_family
;
919 p
->ipproto
= IPPROTO_UDP
;
920 if (p
->family
== AF_INET
) {
921 p
->sender
.in
= sa
.in
.sin_addr
;
922 p
->sender_port
= be16toh(sa
.in
.sin_port
);
923 } else if (p
->family
== AF_INET6
) {
924 p
->sender
.in6
= sa
.in6
.sin6_addr
;
925 p
->sender_port
= be16toh(sa
.in6
.sin6_port
);
926 p
->ifindex
= sa
.in6
.sin6_scope_id
;
928 return -EAFNOSUPPORT
;
930 CMSG_FOREACH(cmsg
, &mh
) {
932 if (cmsg
->cmsg_level
== IPPROTO_IPV6
) {
933 assert(p
->family
== AF_INET6
);
935 switch (cmsg
->cmsg_type
) {
938 struct in6_pktinfo
*i
= (struct in6_pktinfo
*) CMSG_DATA(cmsg
);
941 p
->ifindex
= i
->ipi6_ifindex
;
943 p
->destination
.in6
= i
->ipi6_addr
;
948 p
->ttl
= *(int *) CMSG_DATA(cmsg
);
952 } else if (cmsg
->cmsg_level
== IPPROTO_IP
) {
953 assert(p
->family
== AF_INET
);
955 switch (cmsg
->cmsg_type
) {
958 struct in_pktinfo
*i
= (struct in_pktinfo
*) CMSG_DATA(cmsg
);
961 p
->ifindex
= i
->ipi_ifindex
;
963 p
->destination
.in
= i
->ipi_addr
;
968 p
->ttl
= *(int *) CMSG_DATA(cmsg
);
974 /* The Linux kernel sets the interface index to the loopback
975 * device if the packet came from the local host since it
976 * avoids the routing table in such a case. Let's unset the
977 * interface index in such a case. */
978 if (p
->ifindex
== LOOPBACK_IFINDEX
)
981 if (protocol
!= DNS_PROTOCOL_DNS
) {
982 /* If we don't know the interface index still, we look for the
983 * first local interface with a matching address. Yuck! */
985 p
->ifindex
= manager_find_ifindex(m
, p
->family
, &p
->destination
);
994 static int sendmsg_loop(int fd
, struct msghdr
*mh
, int flags
) {
1001 if (sendmsg(fd
, mh
, flags
) >= 0)
1007 if (errno
!= EAGAIN
)
1010 r
= fd_wait_for_event(fd
, POLLOUT
, SEND_TIMEOUT_USEC
);
1018 static int write_loop(int fd
, void *message
, size_t length
) {
1025 if (write(fd
, message
, length
) >= 0)
1031 if (errno
!= EAGAIN
)
1034 r
= fd_wait_for_event(fd
, POLLOUT
, SEND_TIMEOUT_USEC
);
1042 int manager_write(Manager
*m
, int fd
, DnsPacket
*p
) {
1045 log_debug("Sending %s packet with id %u", DNS_PACKET_QR(p
) ? "response" : "query", DNS_PACKET_ID(p
));
1047 r
= write_loop(fd
, DNS_PACKET_DATA(p
), p
->size
);
1054 static int manager_ipv4_send(Manager
*m
, int fd
, int ifindex
, const struct in_addr
*addr
, uint16_t port
, DnsPacket
*p
) {
1055 union sockaddr_union sa
= {
1056 .in
.sin_family
= AF_INET
,
1059 struct cmsghdr header
; /* For alignment */
1060 uint8_t buffer
[CMSG_SPACE(sizeof(struct in_pktinfo
))];
1062 struct msghdr mh
= {};
1071 iov
.iov_base
= DNS_PACKET_DATA(p
);
1072 iov
.iov_len
= p
->size
;
1074 sa
.in
.sin_addr
= *addr
;
1075 sa
.in
.sin_port
= htobe16(port
),
1079 mh
.msg_name
= &sa
.sa
;
1080 mh
.msg_namelen
= sizeof(sa
.in
);
1083 struct cmsghdr
*cmsg
;
1084 struct in_pktinfo
*pi
;
1088 mh
.msg_control
= &control
;
1089 mh
.msg_controllen
= CMSG_LEN(sizeof(struct in_pktinfo
));
1091 cmsg
= CMSG_FIRSTHDR(&mh
);
1092 cmsg
->cmsg_len
= mh
.msg_controllen
;
1093 cmsg
->cmsg_level
= IPPROTO_IP
;
1094 cmsg
->cmsg_type
= IP_PKTINFO
;
1096 pi
= (struct in_pktinfo
*) CMSG_DATA(cmsg
);
1097 pi
->ipi_ifindex
= ifindex
;
1100 return sendmsg_loop(fd
, &mh
, 0);
1103 static int manager_ipv6_send(Manager
*m
, int fd
, int ifindex
, const struct in6_addr
*addr
, uint16_t port
, DnsPacket
*p
) {
1104 union sockaddr_union sa
= {
1105 .in6
.sin6_family
= AF_INET6
,
1108 struct cmsghdr header
; /* For alignment */
1109 uint8_t buffer
[CMSG_SPACE(sizeof(struct in6_pktinfo
))];
1111 struct msghdr mh
= {};
1120 iov
.iov_base
= DNS_PACKET_DATA(p
);
1121 iov
.iov_len
= p
->size
;
1123 sa
.in6
.sin6_addr
= *addr
;
1124 sa
.in6
.sin6_port
= htobe16(port
),
1125 sa
.in6
.sin6_scope_id
= ifindex
;
1129 mh
.msg_name
= &sa
.sa
;
1130 mh
.msg_namelen
= sizeof(sa
.in6
);
1133 struct cmsghdr
*cmsg
;
1134 struct in6_pktinfo
*pi
;
1138 mh
.msg_control
= &control
;
1139 mh
.msg_controllen
= CMSG_LEN(sizeof(struct in6_pktinfo
));
1141 cmsg
= CMSG_FIRSTHDR(&mh
);
1142 cmsg
->cmsg_len
= mh
.msg_controllen
;
1143 cmsg
->cmsg_level
= IPPROTO_IPV6
;
1144 cmsg
->cmsg_type
= IPV6_PKTINFO
;
1146 pi
= (struct in6_pktinfo
*) CMSG_DATA(cmsg
);
1147 pi
->ipi6_ifindex
= ifindex
;
1150 return sendmsg_loop(fd
, &mh
, 0);
1153 int manager_send(Manager
*m
, int fd
, int ifindex
, int family
, const union in_addr_union
*addr
, uint16_t port
, DnsPacket
*p
) {
1160 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
));
1162 if (family
== AF_INET
)
1163 return manager_ipv4_send(m
, fd
, ifindex
, &addr
->in
, port
, p
);
1164 else if (family
== AF_INET6
)
1165 return manager_ipv6_send(m
, fd
, ifindex
, &addr
->in6
, port
, p
);
1167 return -EAFNOSUPPORT
;
1170 DnsServer
* manager_find_dns_server(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
1176 LIST_FOREACH(servers
, s
, m
->dns_servers
)
1177 if (s
->family
== family
&& in_addr_equal(family
, &s
->address
, in_addr
) > 0)
1180 LIST_FOREACH(servers
, s
, m
->fallback_dns_servers
)
1181 if (s
->family
== family
&& in_addr_equal(family
, &s
->address
, in_addr
) > 0)
1187 DnsServer
*manager_set_dns_server(Manager
*m
, DnsServer
*s
) {
1190 if (m
->current_dns_server
== s
)
1194 _cleanup_free_
char *ip
= NULL
;
1196 in_addr_to_string(s
->family
, &s
->address
, &ip
);
1197 log_info("Switching to system DNS server %s.", strna(ip
));
1200 m
->current_dns_server
= s
;
1202 if (m
->unicast_scope
)
1203 dns_cache_flush(&m
->unicast_scope
->cache
);
1208 DnsServer
*manager_get_dns_server(Manager
*m
) {
1212 /* Try to read updates resolv.conf */
1213 manager_read_resolv_conf(m
);
1215 if (!m
->current_dns_server
)
1216 manager_set_dns_server(m
, m
->dns_servers
);
1218 if (!m
->current_dns_server
) {
1222 /* No DNS servers configured, let's see if there are
1223 * any on any links. If not, we use the fallback
1226 HASHMAP_FOREACH(l
, m
->links
, i
)
1227 if (l
->dns_servers
) {
1233 manager_set_dns_server(m
, m
->fallback_dns_servers
);
1236 return m
->current_dns_server
;
1239 void manager_next_dns_server(Manager
*m
) {
1242 /* If there's currently no DNS server set, then the next
1243 * manager_get_dns_server() will find one */
1244 if (!m
->current_dns_server
)
1247 /* Change to the next one */
1248 if (m
->current_dns_server
->servers_next
) {
1249 manager_set_dns_server(m
, m
->current_dns_server
->servers_next
);
1253 /* If there was no next one, then start from the beginning of
1255 if (m
->current_dns_server
->type
== DNS_SERVER_FALLBACK
)
1256 manager_set_dns_server(m
, m
->fallback_dns_servers
);
1258 manager_set_dns_server(m
, m
->dns_servers
);
1261 uint32_t manager_find_mtu(Manager
*m
) {
1266 /* If we don't know on which link a DNS packet would be
1267 * delivered, let's find the largest MTU that works on all
1268 * interfaces we know of */
1270 HASHMAP_FOREACH(l
, m
->links
, i
) {
1274 if (mtu
<= 0 || l
->mtu
< mtu
)
1281 int manager_find_ifindex(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
1286 a
= manager_find_link_address(m
, family
, in_addr
);
1288 return a
->link
->ifindex
;
1293 void manager_refresh_rrs(Manager
*m
) {
1299 m
->llmnr_host_ipv4_key
= dns_resource_key_unref(m
->llmnr_host_ipv4_key
);
1300 m
->llmnr_host_ipv6_key
= dns_resource_key_unref(m
->llmnr_host_ipv6_key
);
1302 HASHMAP_FOREACH(l
, m
->links
, i
) {
1303 link_add_rrs(l
, true);
1304 link_add_rrs(l
, false);
1308 int manager_next_hostname(Manager
*m
) {
1316 p
= strchr(m
->llmnr_hostname
, 0);
1319 while (p
> m
->llmnr_hostname
) {
1320 if (!strchr("0123456789", p
[-1]))
1326 if (*p
== 0 || safe_atou64(p
, &u
) < 0 || u
<= 0)
1329 /* Add a random number to the old value. This way we can avoid
1330 * that two hosts pick the same hostname, win on IPv4 and lose
1331 * on IPv6 (or vice versa), and pick the same hostname
1332 * replacement hostname, ad infinitum. We still want the
1333 * numbers to go up monotonically, hence we just add a random
1336 random_bytes(&a
, sizeof(a
));
1339 if (asprintf(&h
, "%.*s%" PRIu64
, (int) (p
- m
->llmnr_hostname
), m
->llmnr_hostname
, u
) < 0)
1342 r
= dns_name_concat(h
, "local", &k
);
1348 log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m
->llmnr_hostname
, h
);
1350 free(m
->llmnr_hostname
);
1351 m
->llmnr_hostname
= h
;
1353 free(m
->mdns_hostname
);
1354 m
->mdns_hostname
= k
;
1356 manager_refresh_rrs(m
);
1361 LinkAddress
* manager_find_link_address(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
1367 HASHMAP_FOREACH(l
, m
->links
, i
) {
1370 a
= link_find_address(l
, family
, in_addr
);
1378 bool manager_our_packet(Manager
*m
, DnsPacket
*p
) {
1382 return !!manager_find_link_address(m
, p
->family
, &p
->sender
);
1385 DnsScope
* manager_find_scope(Manager
*m
, DnsPacket
*p
) {
1391 l
= hashmap_get(m
->links
, INT_TO_PTR(p
->ifindex
));
1395 if (p
->protocol
== DNS_PROTOCOL_LLMNR
) {
1396 if (p
->family
== AF_INET
)
1397 return l
->llmnr_ipv4_scope
;
1398 else if (p
->family
== AF_INET6
)
1399 return l
->llmnr_ipv6_scope
;
1405 void manager_verify_all(Manager
*m
) {
1410 LIST_FOREACH(scopes
, s
, m
->dns_scopes
)
1411 dns_zone_verify_all(&s
->zone
);
1414 void manager_flush_dns_servers(Manager
*m
, DnsServerType t
) {
1419 if (t
== DNS_SERVER_SYSTEM
)
1420 while (m
->dns_servers
) {
1423 LIST_REMOVE(servers
, m
->dns_servers
, s
);
1424 dns_server_unref(s
);
1427 if (t
== DNS_SERVER_FALLBACK
)
1428 while (m
->fallback_dns_servers
) {
1429 s
= m
->fallback_dns_servers
;
1431 LIST_REMOVE(servers
, m
->fallback_dns_servers
, s
);
1432 dns_server_unref(s
);
1436 int manager_is_own_hostname(Manager
*m
, const char *name
) {
1442 if (m
->llmnr_hostname
) {
1443 r
= dns_name_equal(name
, m
->llmnr_hostname
);
1448 if (m
->mdns_hostname
)
1449 return dns_name_equal(name
, m
->mdns_hostname
);
1454 static const char* const support_table
[_SUPPORT_MAX
] = {
1455 [SUPPORT_NO
] = "no",
1456 [SUPPORT_YES
] = "yes",
1457 [SUPPORT_RESOLVE
] = "resolve",
1459 DEFINE_STRING_TABLE_LOOKUP(support
, Support
);