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/>.
23 #include <sys/ioctl.h>
25 #include <netinet/in.h>
27 #include "netlink-util.h"
28 #include "network-internal.h"
29 #include "socket-util.h"
32 #include "fileio-label.h"
33 #include "ordered-set.h"
34 #include "random-util.h"
35 #include "hostname-util.h"
37 #include "dns-domain.h"
38 #include "resolved-conf.h"
39 #include "resolved-bus.h"
40 #include "resolved-manager.h"
41 #include "resolved-llmnr.h"
43 #define SEND_TIMEOUT_USEC (200 * USEC_PER_MSEC)
45 static int manager_process_link(sd_netlink
*rtnl
, sd_netlink_message
*mm
, void *userdata
) {
46 Manager
*m
= userdata
;
55 r
= sd_netlink_message_get_type(mm
, &type
);
59 r
= sd_rtnl_message_link_get_ifindex(mm
, &ifindex
);
63 l
= hashmap_get(m
->links
, INT_TO_PTR(ifindex
));
71 r
= link_new(m
, &l
, ifindex
);
76 r
= link_update_rtnl(l
, mm
);
80 r
= link_update_monitor(l
);
85 log_debug("Found new link %i/%s", ifindex
, l
->name
);
92 log_debug("Removing link %i/%s", l
->ifindex
, l
->name
);
102 log_warning_errno(r
, "Failed to process RTNL link message: %m");
106 static int manager_process_address(sd_netlink
*rtnl
, sd_netlink_message
*mm
, void *userdata
) {
107 Manager
*m
= userdata
;
108 union in_addr_union address
;
110 int r
, ifindex
, family
;
118 r
= sd_netlink_message_get_type(mm
, &type
);
122 r
= sd_rtnl_message_addr_get_ifindex(mm
, &ifindex
);
126 l
= hashmap_get(m
->links
, INT_TO_PTR(ifindex
));
130 r
= sd_rtnl_message_addr_get_family(mm
, &family
);
137 r
= sd_netlink_message_read_in_addr(mm
, IFA_LOCAL
, &address
.in
);
139 r
= sd_netlink_message_read_in_addr(mm
, IFA_ADDRESS
, &address
.in
);
147 r
= sd_netlink_message_read_in6_addr(mm
, IFA_LOCAL
, &address
.in6
);
149 r
= sd_netlink_message_read_in6_addr(mm
, IFA_ADDRESS
, &address
.in6
);
160 a
= link_find_address(l
, family
, &address
);
167 r
= link_address_new(l
, &a
, family
, &address
);
172 r
= link_address_update_rtnl(a
, mm
);
179 link_address_free(a
);
186 log_warning_errno(r
, "Failed to process RTNL address message: %m");
190 static int manager_rtnl_listen(Manager
*m
) {
191 _cleanup_netlink_message_unref_ sd_netlink_message
*req
= NULL
, *reply
= NULL
;
192 sd_netlink_message
*i
;
197 /* First, subscribe to interfaces coming and going */
198 r
= sd_netlink_open(&m
->rtnl
);
202 r
= sd_netlink_attach_event(m
->rtnl
, m
->event
, 0);
206 r
= sd_netlink_add_match(m
->rtnl
, RTM_NEWLINK
, manager_process_link
, m
);
210 r
= sd_netlink_add_match(m
->rtnl
, RTM_DELLINK
, manager_process_link
, m
);
214 r
= sd_netlink_add_match(m
->rtnl
, RTM_NEWADDR
, manager_process_address
, m
);
218 r
= sd_netlink_add_match(m
->rtnl
, RTM_DELADDR
, manager_process_address
, m
);
222 /* Then, enumerate all links */
223 r
= sd_rtnl_message_new_link(m
->rtnl
, &req
, RTM_GETLINK
, 0);
227 r
= sd_netlink_message_request_dump(req
, true);
231 r
= sd_netlink_call(m
->rtnl
, req
, 0, &reply
);
235 for (i
= reply
; i
; i
= sd_netlink_message_next(i
)) {
236 r
= manager_process_link(m
->rtnl
, i
, m
);
241 req
= sd_netlink_message_unref(req
);
242 reply
= sd_netlink_message_unref(reply
);
244 /* Finally, enumerate all addresses, too */
245 r
= sd_rtnl_message_new_addr(m
->rtnl
, &req
, RTM_GETADDR
, 0, AF_UNSPEC
);
249 r
= sd_netlink_message_request_dump(req
, true);
253 r
= sd_netlink_call(m
->rtnl
, req
, 0, &reply
);
257 for (i
= reply
; i
; i
= sd_netlink_message_next(i
)) {
258 r
= manager_process_address(m
->rtnl
, i
, m
);
266 static int on_network_event(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
267 Manager
*m
= userdata
;
274 sd_network_monitor_flush(m
->network_monitor
);
276 HASHMAP_FOREACH(l
, m
->links
, i
) {
277 r
= link_update_monitor(l
);
279 log_warning_errno(r
, "Failed to update monitor information for %i: %m", l
->ifindex
);
282 r
= manager_write_resolv_conf(m
);
284 log_warning_errno(r
, "Could not update resolv.conf: %m");
289 static int manager_network_monitor_listen(Manager
*m
) {
294 r
= sd_network_monitor_new(&m
->network_monitor
, NULL
);
298 fd
= sd_network_monitor_get_fd(m
->network_monitor
);
302 events
= sd_network_monitor_get_events(m
->network_monitor
);
306 r
= sd_event_add_io(m
->event
, &m
->network_event_source
, fd
, events
, &on_network_event
, m
);
313 static int determine_hostname(char **llmnr_hostname
, char **mdns_hostname
) {
314 _cleanup_free_
char *h
= NULL
, *n
= NULL
;
315 char label
[DNS_LABEL_MAX
];
319 assert(llmnr_hostname
);
320 assert(mdns_hostname
);
322 /* Extract and normalize the first label of the locally
323 * configured hostname, and check it's not "localhost". */
325 h
= gethostname_malloc();
330 r
= dns_label_unescape(&p
, label
, sizeof(label
));
332 return log_error_errno(r
, "Failed to unescape host name: %m");
334 log_error("Couldn't find a single label in hosntame.");
338 k
= dns_label_undo_idna(label
, r
, label
, sizeof(label
));
340 return log_error_errno(k
, "Failed to undo IDNA: %m");
344 if (!utf8_is_valid(label
)) {
345 log_error("System hostname is not UTF-8 clean.");
349 r
= dns_label_escape(label
, r
, &n
);
351 return log_error_errno(r
, "Failed to escape host name: %m");
353 if (is_localhost(n
)) {
354 log_debug("System hostname is 'localhost', ignoring.");
358 r
= dns_name_concat(n
, "local", mdns_hostname
);
360 return log_error_errno(r
, "Failed to determine mDNS hostname: %m");
368 static int on_hostname_change(sd_event_source
*es
, int fd
, uint32_t revents
, void *userdata
) {
369 _cleanup_free_
char *llmnr_hostname
= NULL
, *mdns_hostname
= NULL
;
370 Manager
*m
= userdata
;
375 r
= determine_hostname(&llmnr_hostname
, &mdns_hostname
);
377 return 0; /* ignore invalid hostnames */
379 if (streq(llmnr_hostname
, m
->llmnr_hostname
) && streq(mdns_hostname
, m
->mdns_hostname
))
382 log_info("System hostname changed to '%s'.", llmnr_hostname
);
384 free(m
->llmnr_hostname
);
385 free(m
->mdns_hostname
);
387 m
->llmnr_hostname
= llmnr_hostname
;
388 m
->mdns_hostname
= mdns_hostname
;
390 llmnr_hostname
= mdns_hostname
= NULL
;
392 manager_refresh_rrs(m
);
397 static int manager_watch_hostname(Manager
*m
) {
402 m
->hostname_fd
= open("/proc/sys/kernel/hostname", O_RDONLY
|O_CLOEXEC
|O_NDELAY
|O_NOCTTY
);
403 if (m
->hostname_fd
< 0) {
404 log_warning_errno(errno
, "Failed to watch hostname: %m");
408 r
= sd_event_add_io(m
->event
, &m
->hostname_event_source
, m
->hostname_fd
, 0, on_hostname_change
, m
);
411 /* kernels prior to 3.2 don't support polling this file. Ignore the failure. */
412 m
->hostname_fd
= safe_close(m
->hostname_fd
);
414 return log_error_errno(r
, "Failed to add hostname event source: %m");
417 r
= determine_hostname(&m
->llmnr_hostname
, &m
->mdns_hostname
);
419 log_info("Defaulting to hostname 'linux'.");
420 m
->llmnr_hostname
= strdup("linux");
421 if (!m
->llmnr_hostname
)
424 m
->mdns_hostname
= strdup("linux.local");
425 if (!m
->mdns_hostname
)
428 log_info("Using system hostname '%s'.", m
->llmnr_hostname
);
433 static int manager_sigusr1(sd_event_source
*s
, const struct signalfd_siginfo
*si
, void *userdata
) {
434 _cleanup_free_
char *buffer
= NULL
;
435 _cleanup_fclose_
FILE *f
= NULL
;
436 Manager
*m
= userdata
;
444 f
= open_memstream(&buffer
, &size
);
448 LIST_FOREACH(scopes
, scope
, m
->dns_scopes
)
449 dns_scope_dump(scope
, f
);
451 if (fflush_and_check(f
) < 0)
454 log_dump(LOG_INFO
, buffer
);
458 int manager_new(Manager
**ret
) {
459 _cleanup_(manager_freep
) Manager
*m
= NULL
;
464 m
= new0(Manager
, 1);
468 m
->llmnr_ipv4_udp_fd
= m
->llmnr_ipv6_udp_fd
= -1;
469 m
->llmnr_ipv4_tcp_fd
= m
->llmnr_ipv6_tcp_fd
= -1;
472 m
->llmnr_support
= SUPPORT_YES
;
473 m
->read_resolv_conf
= true;
475 r
= manager_parse_dns_server(m
, DNS_SERVER_FALLBACK
, DNS_SERVERS
);
479 r
= sd_event_default(&m
->event
);
483 sd_event_add_signal(m
->event
, NULL
, SIGTERM
, NULL
, NULL
);
484 sd_event_add_signal(m
->event
, NULL
, SIGINT
, NULL
, NULL
);
486 sd_event_set_watchdog(m
->event
, true);
488 r
= manager_watch_hostname(m
);
492 r
= dns_scope_new(m
, &m
->unicast_scope
, NULL
, DNS_PROTOCOL_DNS
, AF_UNSPEC
);
496 r
= manager_network_monitor_listen(m
);
500 r
= manager_rtnl_listen(m
);
504 r
= manager_connect_bus(m
);
508 (void) sd_event_add_signal(m
->event
, &m
->sigusr1_event_source
, SIGUSR1
, manager_sigusr1
, m
);
516 int manager_start(Manager
*m
) {
521 r
= manager_llmnr_start(m
);
528 Manager
*manager_free(Manager
*m
) {
534 while ((l
= hashmap_first(m
->links
)))
537 while (m
->dns_queries
)
538 dns_query_free(m
->dns_queries
);
540 manager_flush_dns_servers(m
, DNS_SERVER_SYSTEM
);
541 manager_flush_dns_servers(m
, DNS_SERVER_FALLBACK
);
543 dns_scope_free(m
->unicast_scope
);
545 hashmap_free(m
->links
);
546 hashmap_free(m
->dns_transactions
);
548 sd_event_source_unref(m
->network_event_source
);
549 sd_network_monitor_unref(m
->network_monitor
);
551 manager_llmnr_stop(m
);
553 sd_bus_slot_unref(m
->prepare_for_sleep_slot
);
554 sd_event_source_unref(m
->bus_retry_event_source
);
555 sd_bus_unref(m
->bus
);
557 sd_event_source_unref(m
->sigusr1_event_source
);
559 sd_event_unref(m
->event
);
561 dns_resource_key_unref(m
->llmnr_host_ipv4_key
);
562 dns_resource_key_unref(m
->llmnr_host_ipv6_key
);
564 sd_event_source_unref(m
->hostname_event_source
);
565 safe_close(m
->hostname_fd
);
566 free(m
->llmnr_hostname
);
567 free(m
->mdns_hostname
);
574 int manager_read_resolv_conf(Manager
*m
) {
575 _cleanup_fclose_
FILE *f
= NULL
;
584 /* Reads the system /etc/resolv.conf, if it exists and is not
585 * symlinked to our own resolv.conf instance */
587 if (!m
->read_resolv_conf
)
590 r
= stat("/etc/resolv.conf", &st
);
593 log_warning_errno(errno
, "Failed to open /etc/resolv.conf: %m");
598 /* Have we already seen the file? */
599 t
= timespec_load(&st
.st_mtim
);
600 if (t
== m
->resolv_conf_mtime
)
603 m
->resolv_conf_mtime
= t
;
605 /* Is it symlinked to our own file? */
606 if (stat("/run/systemd/resolve/resolv.conf", &own
) >= 0 &&
607 st
.st_dev
== own
.st_dev
&&
608 st
.st_ino
== own
.st_ino
) {
613 f
= fopen("/etc/resolv.conf", "re");
616 log_warning_errno(errno
, "Failed to open /etc/resolv.conf: %m");
621 if (fstat(fileno(f
), &st
) < 0) {
622 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
);