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 r
= log_error_errno(errno
, "Failed to stat open file: %m");
626 LIST_FOREACH(servers
, s
, m
->dns_servers
)
629 FOREACH_LINE(line
, f
, r
= -errno
; goto clear
) {
630 union in_addr_union address
;
638 if (*l
== '#' || *l
== ';')
641 a
= first_word(l
, "nameserver");
645 r
= in_addr_from_string_auto(a
, &family
, &address
);
647 log_warning("Failed to parse name server %s.", a
);
651 LIST_FOREACH(servers
, s
, m
->dns_servers
)
652 if (s
->family
== family
&& in_addr_equal(family
, &s
->address
, &address
) > 0)
658 r
= dns_server_new(m
, NULL
, DNS_SERVER_SYSTEM
, NULL
, family
, &address
);
664 LIST_FOREACH_SAFE(servers
, s
, nx
, m
->dns_servers
)
666 LIST_REMOVE(servers
, m
->dns_servers
, s
);
670 /* Whenever /etc/resolv.conf changes, start using the first
671 * DNS server of it. This is useful to deal with broken
672 * network managing implementations (like NetworkManager),
673 * that when connecting to a VPN place both the VPN DNS
674 * servers and the local ones in /etc/resolv.conf. Without
675 * resetting the DNS server to use back to the first entry we
676 * will continue to use the local one thus being unable to
677 * resolve VPN domains. */
678 manager_set_dns_server(m
, m
->dns_servers
);
683 while (m
->dns_servers
) {
686 LIST_REMOVE(servers
, m
->dns_servers
, s
);
693 static void write_resolv_conf_server(DnsServer
*s
, FILE *f
, unsigned *count
) {
694 _cleanup_free_
char *t
= NULL
;
701 r
= in_addr_to_string(s
->family
, &s
->address
, &t
);
703 log_warning_errno(r
, "Invalid DNS address. Ignoring: %m");
708 fputs("# Too many DNS servers configured, the following entries may be ignored.\n", f
);
710 fprintf(f
, "nameserver %s\n", t
);
714 static void write_resolv_conf_search(
715 const char *domain
, FILE *f
,
723 if (*count
>= MAXDNSRCH
||
724 *length
+ strlen(domain
) > 256) {
725 if (*count
== MAXDNSRCH
)
726 fputs(" # Too many search domains configured, remaining ones ignored.", f
);
728 fputs(" # Total length of all search domains is too long, remaining ones ignored.", f
);
733 fprintf(f
, " %s", domain
);
735 (*length
) += strlen(domain
);
739 static int write_resolv_conf_contents(FILE *f
, OrderedSet
*dns
, OrderedSet
*domains
) {
742 fputs("# This file is managed by systemd-resolved(8). Do not edit.\n#\n"
743 "# Third party programs must not access this file directly, but\n"
744 "# only through the symlink at /etc/resolv.conf. To manage\n"
745 "# resolv.conf(5) in a different way, replace the symlink by a\n"
746 "# static file or a different symlink.\n\n", f
);
748 if (ordered_set_isempty(dns
))
749 fputs("# No DNS servers known.\n", f
);
754 ORDERED_SET_FOREACH(s
, dns
, i
)
755 write_resolv_conf_server(s
, f
, &count
);
758 if (!ordered_set_isempty(domains
)) {
759 unsigned length
= 0, count
= 0;
763 ORDERED_SET_FOREACH(domain
, domains
, i
)
764 write_resolv_conf_search(domain
, f
, &count
, &length
);
768 return fflush_and_check(f
);
771 int manager_write_resolv_conf(Manager
*m
) {
772 static const char path
[] = "/run/systemd/resolve/resolv.conf";
773 _cleanup_free_
char *temp_path
= NULL
;
774 _cleanup_fclose_
FILE *f
= NULL
;
775 _cleanup_ordered_set_free_ OrderedSet
*dns
= NULL
, *domains
= NULL
;
783 /* Read the system /etc/resolv.conf first */
784 manager_read_resolv_conf(m
);
786 /* Add the full list to a set, to filter out duplicates */
787 dns
= ordered_set_new(&dns_server_hash_ops
);
791 domains
= ordered_set_new(&dns_name_hash_ops
);
795 /* First add the system-wide servers */
796 LIST_FOREACH(servers
, s
, m
->dns_servers
) {
797 r
= ordered_set_put(dns
, s
);
804 /* Then, add the per-link servers and domains */
805 HASHMAP_FOREACH(l
, m
->links
, i
) {
808 LIST_FOREACH(servers
, s
, l
->dns_servers
) {
809 r
= ordered_set_put(dns
, s
);
816 if (!l
->unicast_scope
)
819 STRV_FOREACH(domain
, l
->unicast_scope
->domains
) {
820 r
= ordered_set_put(domains
, *domain
);
828 /* If we found nothing, add the fallback servers */
829 if (ordered_set_isempty(dns
)) {
830 LIST_FOREACH(servers
, s
, m
->fallback_dns_servers
) {
831 r
= ordered_set_put(dns
, s
);
839 r
= fopen_temporary_label(path
, path
, &f
, &temp_path
);
843 fchmod(fileno(f
), 0644);
845 r
= write_resolv_conf_contents(f
, dns
, domains
);
849 if (rename(temp_path
, path
) < 0) {
858 (void) unlink(temp_path
);
862 int manager_recv(Manager
*m
, int fd
, DnsProtocol protocol
, DnsPacket
**ret
) {
863 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
865 struct cmsghdr header
; /* For alignment */
866 uint8_t buffer
[CMSG_SPACE(MAXSIZE(struct in_pktinfo
, struct in6_pktinfo
))
867 + CMSG_SPACE(int) /* ttl/hoplimit */
868 + EXTRA_CMSG_SPACE
/* kernel appears to require extra buffer space */];
870 union sockaddr_union sa
;
871 struct msghdr mh
= {};
872 struct cmsghdr
*cmsg
;
881 r
= ioctl(fd
, FIONREAD
, &ms
);
887 r
= dns_packet_new(&p
, protocol
, ms
);
891 iov
.iov_base
= DNS_PACKET_DATA(p
);
892 iov
.iov_len
= p
->allocated
;
894 mh
.msg_name
= &sa
.sa
;
895 mh
.msg_namelen
= sizeof(sa
);
898 mh
.msg_control
= &control
;
899 mh
.msg_controllen
= sizeof(control
);
901 l
= recvmsg(fd
, &mh
, 0);
903 if (errno
== EAGAIN
|| errno
== EINTR
)
912 assert(!(mh
.msg_flags
& MSG_CTRUNC
));
913 assert(!(mh
.msg_flags
& MSG_TRUNC
));
915 p
->size
= (size_t) l
;
917 p
->family
= sa
.sa
.sa_family
;
918 p
->ipproto
= IPPROTO_UDP
;
919 if (p
->family
== AF_INET
) {
920 p
->sender
.in
= sa
.in
.sin_addr
;
921 p
->sender_port
= be16toh(sa
.in
.sin_port
);
922 } else if (p
->family
== AF_INET6
) {
923 p
->sender
.in6
= sa
.in6
.sin6_addr
;
924 p
->sender_port
= be16toh(sa
.in6
.sin6_port
);
925 p
->ifindex
= sa
.in6
.sin6_scope_id
;
927 return -EAFNOSUPPORT
;
929 CMSG_FOREACH(cmsg
, &mh
) {
931 if (cmsg
->cmsg_level
== IPPROTO_IPV6
) {
932 assert(p
->family
== AF_INET6
);
934 switch (cmsg
->cmsg_type
) {
937 struct in6_pktinfo
*i
= (struct in6_pktinfo
*) CMSG_DATA(cmsg
);
940 p
->ifindex
= i
->ipi6_ifindex
;
942 p
->destination
.in6
= i
->ipi6_addr
;
947 p
->ttl
= *(int *) CMSG_DATA(cmsg
);
951 } else if (cmsg
->cmsg_level
== IPPROTO_IP
) {
952 assert(p
->family
== AF_INET
);
954 switch (cmsg
->cmsg_type
) {
957 struct in_pktinfo
*i
= (struct in_pktinfo
*) CMSG_DATA(cmsg
);
960 p
->ifindex
= i
->ipi_ifindex
;
962 p
->destination
.in
= i
->ipi_addr
;
967 p
->ttl
= *(int *) CMSG_DATA(cmsg
);
973 /* The Linux kernel sets the interface index to the loopback
974 * device if the packet came from the local host since it
975 * avoids the routing table in such a case. Let's unset the
976 * interface index in such a case. */
977 if (p
->ifindex
== LOOPBACK_IFINDEX
)
980 if (protocol
!= DNS_PROTOCOL_DNS
) {
981 /* If we don't know the interface index still, we look for the
982 * first local interface with a matching address. Yuck! */
984 p
->ifindex
= manager_find_ifindex(m
, p
->family
, &p
->destination
);
993 static int sendmsg_loop(int fd
, struct msghdr
*mh
, int flags
) {
1000 if (sendmsg(fd
, mh
, flags
) >= 0)
1006 if (errno
!= EAGAIN
)
1009 r
= fd_wait_for_event(fd
, POLLOUT
, SEND_TIMEOUT_USEC
);
1017 static int write_loop(int fd
, void *message
, size_t length
) {
1024 if (write(fd
, message
, length
) >= 0)
1030 if (errno
!= EAGAIN
)
1033 r
= fd_wait_for_event(fd
, POLLOUT
, SEND_TIMEOUT_USEC
);
1041 int manager_write(Manager
*m
, int fd
, DnsPacket
*p
) {
1044 log_debug("Sending %s packet with id %u", DNS_PACKET_QR(p
) ? "response" : "query", DNS_PACKET_ID(p
));
1046 r
= write_loop(fd
, DNS_PACKET_DATA(p
), p
->size
);
1053 static int manager_ipv4_send(Manager
*m
, int fd
, int ifindex
, const struct in_addr
*addr
, uint16_t port
, DnsPacket
*p
) {
1054 union sockaddr_union sa
= {
1055 .in
.sin_family
= AF_INET
,
1058 struct cmsghdr header
; /* For alignment */
1059 uint8_t buffer
[CMSG_SPACE(sizeof(struct in_pktinfo
))];
1061 struct msghdr mh
= {};
1070 iov
.iov_base
= DNS_PACKET_DATA(p
);
1071 iov
.iov_len
= p
->size
;
1073 sa
.in
.sin_addr
= *addr
;
1074 sa
.in
.sin_port
= htobe16(port
),
1078 mh
.msg_name
= &sa
.sa
;
1079 mh
.msg_namelen
= sizeof(sa
.in
);
1082 struct cmsghdr
*cmsg
;
1083 struct in_pktinfo
*pi
;
1087 mh
.msg_control
= &control
;
1088 mh
.msg_controllen
= CMSG_LEN(sizeof(struct in_pktinfo
));
1090 cmsg
= CMSG_FIRSTHDR(&mh
);
1091 cmsg
->cmsg_len
= mh
.msg_controllen
;
1092 cmsg
->cmsg_level
= IPPROTO_IP
;
1093 cmsg
->cmsg_type
= IP_PKTINFO
;
1095 pi
= (struct in_pktinfo
*) CMSG_DATA(cmsg
);
1096 pi
->ipi_ifindex
= ifindex
;
1099 return sendmsg_loop(fd
, &mh
, 0);
1102 static int manager_ipv6_send(Manager
*m
, int fd
, int ifindex
, const struct in6_addr
*addr
, uint16_t port
, DnsPacket
*p
) {
1103 union sockaddr_union sa
= {
1104 .in6
.sin6_family
= AF_INET6
,
1107 struct cmsghdr header
; /* For alignment */
1108 uint8_t buffer
[CMSG_SPACE(sizeof(struct in6_pktinfo
))];
1110 struct msghdr mh
= {};
1119 iov
.iov_base
= DNS_PACKET_DATA(p
);
1120 iov
.iov_len
= p
->size
;
1122 sa
.in6
.sin6_addr
= *addr
;
1123 sa
.in6
.sin6_port
= htobe16(port
),
1124 sa
.in6
.sin6_scope_id
= ifindex
;
1128 mh
.msg_name
= &sa
.sa
;
1129 mh
.msg_namelen
= sizeof(sa
.in6
);
1132 struct cmsghdr
*cmsg
;
1133 struct in6_pktinfo
*pi
;
1137 mh
.msg_control
= &control
;
1138 mh
.msg_controllen
= CMSG_LEN(sizeof(struct in6_pktinfo
));
1140 cmsg
= CMSG_FIRSTHDR(&mh
);
1141 cmsg
->cmsg_len
= mh
.msg_controllen
;
1142 cmsg
->cmsg_level
= IPPROTO_IPV6
;
1143 cmsg
->cmsg_type
= IPV6_PKTINFO
;
1145 pi
= (struct in6_pktinfo
*) CMSG_DATA(cmsg
);
1146 pi
->ipi6_ifindex
= ifindex
;
1149 return sendmsg_loop(fd
, &mh
, 0);
1152 int manager_send(Manager
*m
, int fd
, int ifindex
, int family
, const union in_addr_union
*addr
, uint16_t port
, DnsPacket
*p
) {
1159 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
));
1161 if (family
== AF_INET
)
1162 return manager_ipv4_send(m
, fd
, ifindex
, &addr
->in
, port
, p
);
1163 else if (family
== AF_INET6
)
1164 return manager_ipv6_send(m
, fd
, ifindex
, &addr
->in6
, port
, p
);
1166 return -EAFNOSUPPORT
;
1169 DnsServer
* manager_find_dns_server(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
1175 LIST_FOREACH(servers
, s
, m
->dns_servers
)
1176 if (s
->family
== family
&& in_addr_equal(family
, &s
->address
, in_addr
) > 0)
1179 LIST_FOREACH(servers
, s
, m
->fallback_dns_servers
)
1180 if (s
->family
== family
&& in_addr_equal(family
, &s
->address
, in_addr
) > 0)
1186 DnsServer
*manager_set_dns_server(Manager
*m
, DnsServer
*s
) {
1189 if (m
->current_dns_server
== s
)
1193 _cleanup_free_
char *ip
= NULL
;
1195 in_addr_to_string(s
->family
, &s
->address
, &ip
);
1196 log_info("Switching to system DNS server %s.", strna(ip
));
1199 m
->current_dns_server
= s
;
1201 if (m
->unicast_scope
)
1202 dns_cache_flush(&m
->unicast_scope
->cache
);
1207 DnsServer
*manager_get_dns_server(Manager
*m
) {
1211 /* Try to read updates resolv.conf */
1212 manager_read_resolv_conf(m
);
1214 if (!m
->current_dns_server
)
1215 manager_set_dns_server(m
, m
->dns_servers
);
1217 if (!m
->current_dns_server
) {
1221 /* No DNS servers configured, let's see if there are
1222 * any on any links. If not, we use the fallback
1225 HASHMAP_FOREACH(l
, m
->links
, i
)
1226 if (l
->dns_servers
) {
1232 manager_set_dns_server(m
, m
->fallback_dns_servers
);
1235 return m
->current_dns_server
;
1238 void manager_next_dns_server(Manager
*m
) {
1241 /* If there's currently no DNS server set, then the next
1242 * manager_get_dns_server() will find one */
1243 if (!m
->current_dns_server
)
1246 /* Change to the next one */
1247 if (m
->current_dns_server
->servers_next
) {
1248 manager_set_dns_server(m
, m
->current_dns_server
->servers_next
);
1252 /* If there was no next one, then start from the beginning of
1254 if (m
->current_dns_server
->type
== DNS_SERVER_FALLBACK
)
1255 manager_set_dns_server(m
, m
->fallback_dns_servers
);
1257 manager_set_dns_server(m
, m
->dns_servers
);
1260 uint32_t manager_find_mtu(Manager
*m
) {
1265 /* If we don't know on which link a DNS packet would be
1266 * delivered, let's find the largest MTU that works on all
1267 * interfaces we know of */
1269 HASHMAP_FOREACH(l
, m
->links
, i
) {
1273 if (mtu
<= 0 || l
->mtu
< mtu
)
1280 int manager_find_ifindex(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
1285 a
= manager_find_link_address(m
, family
, in_addr
);
1287 return a
->link
->ifindex
;
1292 void manager_refresh_rrs(Manager
*m
) {
1298 m
->llmnr_host_ipv4_key
= dns_resource_key_unref(m
->llmnr_host_ipv4_key
);
1299 m
->llmnr_host_ipv6_key
= dns_resource_key_unref(m
->llmnr_host_ipv6_key
);
1301 HASHMAP_FOREACH(l
, m
->links
, i
) {
1302 link_add_rrs(l
, true);
1303 link_add_rrs(l
, false);
1307 int manager_next_hostname(Manager
*m
) {
1315 p
= strchr(m
->llmnr_hostname
, 0);
1318 while (p
> m
->llmnr_hostname
) {
1319 if (!strchr("0123456789", p
[-1]))
1325 if (*p
== 0 || safe_atou64(p
, &u
) < 0 || u
<= 0)
1328 /* Add a random number to the old value. This way we can avoid
1329 * that two hosts pick the same hostname, win on IPv4 and lose
1330 * on IPv6 (or vice versa), and pick the same hostname
1331 * replacement hostname, ad infinitum. We still want the
1332 * numbers to go up monotonically, hence we just add a random
1335 random_bytes(&a
, sizeof(a
));
1338 if (asprintf(&h
, "%.*s%" PRIu64
, (int) (p
- m
->llmnr_hostname
), m
->llmnr_hostname
, u
) < 0)
1341 r
= dns_name_concat(h
, "local", &k
);
1347 log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m
->llmnr_hostname
, h
);
1349 free(m
->llmnr_hostname
);
1350 m
->llmnr_hostname
= h
;
1352 free(m
->mdns_hostname
);
1353 m
->mdns_hostname
= k
;
1355 manager_refresh_rrs(m
);
1360 LinkAddress
* manager_find_link_address(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
1366 HASHMAP_FOREACH(l
, m
->links
, i
) {
1369 a
= link_find_address(l
, family
, in_addr
);
1377 bool manager_our_packet(Manager
*m
, DnsPacket
*p
) {
1381 return !!manager_find_link_address(m
, p
->family
, &p
->sender
);
1384 DnsScope
* manager_find_scope(Manager
*m
, DnsPacket
*p
) {
1390 l
= hashmap_get(m
->links
, INT_TO_PTR(p
->ifindex
));
1394 if (p
->protocol
== DNS_PROTOCOL_LLMNR
) {
1395 if (p
->family
== AF_INET
)
1396 return l
->llmnr_ipv4_scope
;
1397 else if (p
->family
== AF_INET6
)
1398 return l
->llmnr_ipv6_scope
;
1404 void manager_verify_all(Manager
*m
) {
1409 LIST_FOREACH(scopes
, s
, m
->dns_scopes
)
1410 dns_zone_verify_all(&s
->zone
);
1413 void manager_flush_dns_servers(Manager
*m
, DnsServerType t
) {
1418 if (t
== DNS_SERVER_SYSTEM
)
1419 while (m
->dns_servers
) {
1422 LIST_REMOVE(servers
, m
->dns_servers
, s
);
1423 dns_server_unref(s
);
1426 if (t
== DNS_SERVER_FALLBACK
)
1427 while (m
->fallback_dns_servers
) {
1428 s
= m
->fallback_dns_servers
;
1430 LIST_REMOVE(servers
, m
->fallback_dns_servers
, s
);
1431 dns_server_unref(s
);
1435 int manager_is_own_hostname(Manager
*m
, const char *name
) {
1441 if (m
->llmnr_hostname
) {
1442 r
= dns_name_equal(name
, m
->llmnr_hostname
);
1447 if (m
->mdns_hostname
)
1448 return dns_name_equal(name
, m
->mdns_hostname
);
1453 static const char* const support_table
[_SUPPORT_MAX
] = {
1454 [SUPPORT_NO
] = "no",
1455 [SUPPORT_YES
] = "yes",
1456 [SUPPORT_RESOLVE
] = "resolve",
1458 DEFINE_STRING_TABLE_LOOKUP(support
, Support
);