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
);
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 **ret
) {
315 _cleanup_free_
char *h
= NULL
, *n
= NULL
;
320 h
= gethostname_malloc();
324 if (!utf8_is_valid(h
)) {
325 log_error("System hostname is not UTF-8 clean.");
329 r
= dns_name_normalize(h
, &n
);
331 log_error("System hostname '%s' cannot be normalized.", h
);
341 static int on_hostname_change(sd_event_source
*es
, int fd
, uint32_t revents
, void *userdata
) {
342 _cleanup_free_
char *h
= NULL
;
343 Manager
*m
= userdata
;
348 r
= determine_hostname(&h
);
350 return 0; /* ignore invalid hostnames */
352 if (streq(h
, m
->hostname
))
355 log_info("System hostname changed to '%s'.", h
);
360 manager_refresh_rrs(m
);
365 static int manager_watch_hostname(Manager
*m
) {
370 m
->hostname_fd
= open("/proc/sys/kernel/hostname", O_RDONLY
|O_CLOEXEC
|O_NDELAY
|O_NOCTTY
);
371 if (m
->hostname_fd
< 0) {
372 log_warning_errno(errno
, "Failed to watch hostname: %m");
376 r
= sd_event_add_io(m
->event
, &m
->hostname_event_source
, m
->hostname_fd
, 0, on_hostname_change
, m
);
379 /* kernels prior to 3.2 don't support polling this file. Ignore the failure. */
380 m
->hostname_fd
= safe_close(m
->hostname_fd
);
382 return log_error_errno(r
, "Failed to add hostname event source: %m");
385 r
= determine_hostname(&m
->hostname
);
387 log_info("Defaulting to hostname 'linux'.");
388 m
->hostname
= strdup("linux");
392 log_info("Using system hostname '%s'.", m
->hostname
);
397 int manager_new(Manager
**ret
) {
398 _cleanup_(manager_freep
) Manager
*m
= NULL
;
403 m
= new0(Manager
, 1);
407 m
->dns_ipv4_fd
= m
->dns_ipv6_fd
= -1;
408 m
->llmnr_ipv4_udp_fd
= m
->llmnr_ipv6_udp_fd
= -1;
409 m
->llmnr_ipv4_tcp_fd
= m
->llmnr_ipv6_tcp_fd
= -1;
412 m
->llmnr_support
= SUPPORT_YES
;
413 m
->read_resolv_conf
= true;
415 r
= manager_parse_dns_server(m
, DNS_SERVER_FALLBACK
, DNS_SERVERS
);
419 r
= sd_event_default(&m
->event
);
423 sd_event_add_signal(m
->event
, NULL
, SIGTERM
, NULL
, NULL
);
424 sd_event_add_signal(m
->event
, NULL
, SIGINT
, NULL
, NULL
);
426 sd_event_set_watchdog(m
->event
, true);
428 r
= manager_watch_hostname(m
);
432 r
= dns_scope_new(m
, &m
->unicast_scope
, NULL
, DNS_PROTOCOL_DNS
, AF_UNSPEC
);
436 r
= manager_network_monitor_listen(m
);
440 r
= manager_rtnl_listen(m
);
444 r
= manager_connect_bus(m
);
454 int manager_start(Manager
*m
) {
459 r
= manager_llmnr_start(m
);
466 Manager
*manager_free(Manager
*m
) {
472 while ((l
= hashmap_first(m
->links
)))
475 while (m
->dns_queries
)
476 dns_query_free(m
->dns_queries
);
478 manager_flush_dns_servers(m
, DNS_SERVER_SYSTEM
);
479 manager_flush_dns_servers(m
, DNS_SERVER_FALLBACK
);
481 dns_scope_free(m
->unicast_scope
);
483 hashmap_free(m
->links
);
484 hashmap_free(m
->dns_transactions
);
486 sd_event_source_unref(m
->network_event_source
);
487 sd_network_monitor_unref(m
->network_monitor
);
489 sd_event_source_unref(m
->dns_ipv4_event_source
);
490 sd_event_source_unref(m
->dns_ipv6_event_source
);
491 safe_close(m
->dns_ipv4_fd
);
492 safe_close(m
->dns_ipv6_fd
);
494 manager_llmnr_stop(m
);
496 sd_bus_slot_unref(m
->prepare_for_sleep_slot
);
497 sd_event_source_unref(m
->bus_retry_event_source
);
498 sd_bus_unref(m
->bus
);
500 sd_event_unref(m
->event
);
502 dns_resource_key_unref(m
->host_ipv4_key
);
503 dns_resource_key_unref(m
->host_ipv6_key
);
505 safe_close(m
->hostname_fd
);
506 sd_event_source_unref(m
->hostname_event_source
);
514 int manager_read_resolv_conf(Manager
*m
) {
515 _cleanup_fclose_
FILE *f
= NULL
;
524 /* Reads the system /etc/resolv.conf, if it exists and is not
525 * symlinked to our own resolv.conf instance */
527 if (!m
->read_resolv_conf
)
530 r
= stat("/etc/resolv.conf", &st
);
533 log_warning_errno(errno
, "Failed to open /etc/resolv.conf: %m");
538 /* Have we already seen the file? */
539 t
= timespec_load(&st
.st_mtim
);
540 if (t
== m
->resolv_conf_mtime
)
543 m
->resolv_conf_mtime
= t
;
545 /* Is it symlinked to our own file? */
546 if (stat("/run/systemd/resolve/resolv.conf", &own
) >= 0 &&
547 st
.st_dev
== own
.st_dev
&&
548 st
.st_ino
== own
.st_ino
) {
553 f
= fopen("/etc/resolv.conf", "re");
556 log_warning_errno(errno
, "Failed to open /etc/resolv.conf: %m");
561 if (fstat(fileno(f
), &st
) < 0) {
562 log_error_errno(errno
, "Failed to stat open file: %m");
567 LIST_FOREACH(servers
, s
, m
->dns_servers
)
570 FOREACH_LINE(line
, f
, r
= -errno
; goto clear
) {
571 union in_addr_union address
;
579 if (*l
== '#' || *l
== ';')
582 a
= first_word(l
, "nameserver");
586 r
= in_addr_from_string_auto(a
, &family
, &address
);
588 log_warning("Failed to parse name server %s.", a
);
592 LIST_FOREACH(servers
, s
, m
->dns_servers
)
593 if (s
->family
== family
&& in_addr_equal(family
, &s
->address
, &address
) > 0)
599 r
= dns_server_new(m
, NULL
, DNS_SERVER_SYSTEM
, NULL
, family
, &address
);
605 LIST_FOREACH_SAFE(servers
, s
, nx
, m
->dns_servers
)
607 LIST_REMOVE(servers
, m
->dns_servers
, s
);
611 /* Whenever /etc/resolv.conf changes, start using the first
612 * DNS server of it. This is useful to deal with broken
613 * network managing implementations (like NetworkManager),
614 * that when connecting to a VPN place both the VPN DNS
615 * servers and the local ones in /etc/resolv.conf. Without
616 * resetting the DNS server to use back to the first entry we
617 * will continue to use the local one thus being unable to
618 * resolve VPN domains. */
619 manager_set_dns_server(m
, m
->dns_servers
);
624 while (m
->dns_servers
) {
627 LIST_REMOVE(servers
, m
->dns_servers
, s
);
634 static void write_resolv_conf_server(DnsServer
*s
, FILE *f
, unsigned *count
) {
635 _cleanup_free_
char *t
= NULL
;
642 r
= in_addr_to_string(s
->family
, &s
->address
, &t
);
644 log_warning_errno(r
, "Invalid DNS address. Ignoring: %m");
649 fputs("# Too many DNS servers configured, the following entries may be ignored.\n", f
);
651 fprintf(f
, "nameserver %s\n", t
);
655 static void write_resolv_conf_search(
656 const char *domain
, FILE *f
,
664 if (*count
>= MAXDNSRCH
||
665 *length
+ strlen(domain
) > 256) {
666 if (*count
== MAXDNSRCH
)
667 fputs(" # Too many search domains configured, remaining ones ignored.", f
);
669 fputs(" # Total length of all search domains is too long, remaining ones ignored.", f
);
674 fprintf(f
, " %s", domain
);
676 (*length
) += strlen(domain
);
680 static int write_resolv_conf_contents(FILE *f
, OrderedSet
*dns
, OrderedSet
*domains
) {
683 fputs("# This file is managed by systemd-resolved(8). Do not edit.\n#\n"
684 "# Third party programs must not access this file directly, but\n"
685 "# only through the symlink at /etc/resolv.conf. To manage\n"
686 "# resolv.conf(5) in a different way, replace the symlink by a\n"
687 "# static file or a different symlink.\n\n", f
);
689 if (ordered_set_isempty(dns
))
690 fputs("# No DNS servers known.\n", f
);
695 ORDERED_SET_FOREACH(s
, dns
, i
)
696 write_resolv_conf_server(s
, f
, &count
);
699 if (!ordered_set_isempty(domains
)) {
700 unsigned length
= 0, count
= 0;
704 ORDERED_SET_FOREACH(domain
, domains
, i
)
705 write_resolv_conf_search(domain
, f
, &count
, &length
);
709 return fflush_and_check(f
);
712 int manager_write_resolv_conf(Manager
*m
) {
713 static const char path
[] = "/run/systemd/resolve/resolv.conf";
714 _cleanup_free_
char *temp_path
= NULL
;
715 _cleanup_fclose_
FILE *f
= NULL
;
716 _cleanup_ordered_set_free_ OrderedSet
*dns
= NULL
, *domains
= NULL
;
724 /* Read the system /etc/resolv.conf first */
725 manager_read_resolv_conf(m
);
727 /* Add the full list to a set, to filter out duplicates */
728 dns
= ordered_set_new(&dns_server_hash_ops
);
732 domains
= ordered_set_new(&dns_name_hash_ops
);
736 /* First add the system-wide servers */
737 LIST_FOREACH(servers
, s
, m
->dns_servers
) {
738 r
= ordered_set_put(dns
, s
);
745 /* Then, add the per-link servers and domains */
746 HASHMAP_FOREACH(l
, m
->links
, i
) {
749 LIST_FOREACH(servers
, s
, l
->dns_servers
) {
750 r
= ordered_set_put(dns
, s
);
757 if (!l
->unicast_scope
)
760 STRV_FOREACH(domain
, l
->unicast_scope
->domains
) {
761 r
= ordered_set_put(domains
, *domain
);
769 /* If we found nothing, add the fallback servers */
770 if (ordered_set_isempty(dns
)) {
771 LIST_FOREACH(servers
, s
, m
->fallback_dns_servers
) {
772 r
= ordered_set_put(dns
, s
);
780 r
= fopen_temporary_label(path
, path
, &f
, &temp_path
);
784 fchmod(fileno(f
), 0644);
786 r
= write_resolv_conf_contents(f
, dns
, domains
);
790 if (rename(temp_path
, path
) < 0) {
799 (void) unlink(temp_path
);
803 int manager_recv(Manager
*m
, int fd
, DnsProtocol protocol
, DnsPacket
**ret
) {
804 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
806 struct cmsghdr header
; /* For alignment */
807 uint8_t buffer
[CMSG_SPACE(MAXSIZE(struct in_pktinfo
, struct in6_pktinfo
))
808 + CMSG_SPACE(int) /* ttl/hoplimit */
809 + EXTRA_CMSG_SPACE
/* kernel appears to require extra buffer space */];
811 union sockaddr_union sa
;
812 struct msghdr mh
= {};
813 struct cmsghdr
*cmsg
;
822 r
= ioctl(fd
, FIONREAD
, &ms
);
828 r
= dns_packet_new(&p
, protocol
, ms
);
832 iov
.iov_base
= DNS_PACKET_DATA(p
);
833 iov
.iov_len
= p
->allocated
;
835 mh
.msg_name
= &sa
.sa
;
836 mh
.msg_namelen
= sizeof(sa
);
839 mh
.msg_control
= &control
;
840 mh
.msg_controllen
= sizeof(control
);
842 l
= recvmsg(fd
, &mh
, 0);
844 if (errno
== EAGAIN
|| errno
== EINTR
)
853 assert(!(mh
.msg_flags
& MSG_CTRUNC
));
854 assert(!(mh
.msg_flags
& MSG_TRUNC
));
856 p
->size
= (size_t) l
;
858 p
->family
= sa
.sa
.sa_family
;
859 p
->ipproto
= IPPROTO_UDP
;
860 if (p
->family
== AF_INET
) {
861 p
->sender
.in
= sa
.in
.sin_addr
;
862 p
->sender_port
= be16toh(sa
.in
.sin_port
);
863 } else if (p
->family
== AF_INET6
) {
864 p
->sender
.in6
= sa
.in6
.sin6_addr
;
865 p
->sender_port
= be16toh(sa
.in6
.sin6_port
);
866 p
->ifindex
= sa
.in6
.sin6_scope_id
;
868 return -EAFNOSUPPORT
;
870 CMSG_FOREACH(cmsg
, &mh
) {
872 if (cmsg
->cmsg_level
== IPPROTO_IPV6
) {
873 assert(p
->family
== AF_INET6
);
875 switch (cmsg
->cmsg_type
) {
878 struct in6_pktinfo
*i
= (struct in6_pktinfo
*) CMSG_DATA(cmsg
);
881 p
->ifindex
= i
->ipi6_ifindex
;
883 p
->destination
.in6
= i
->ipi6_addr
;
888 p
->ttl
= *(int *) CMSG_DATA(cmsg
);
892 } else if (cmsg
->cmsg_level
== IPPROTO_IP
) {
893 assert(p
->family
== AF_INET
);
895 switch (cmsg
->cmsg_type
) {
898 struct in_pktinfo
*i
= (struct in_pktinfo
*) CMSG_DATA(cmsg
);
901 p
->ifindex
= i
->ipi_ifindex
;
903 p
->destination
.in
= i
->ipi_addr
;
908 p
->ttl
= *(int *) CMSG_DATA(cmsg
);
914 /* The Linux kernel sets the interface index to the loopback
915 * device if the packet came from the local host since it
916 * avoids the routing table in such a case. Let's unset the
917 * interface index in such a case. */
918 if (p
->ifindex
== LOOPBACK_IFINDEX
)
921 /* If we don't know the interface index still, we look for the
922 * first local interface with a matching address. Yuck! */
924 p
->ifindex
= manager_find_ifindex(m
, p
->family
, &p
->destination
);
932 static int on_dns_packet(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
933 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
934 DnsTransaction
*t
= NULL
;
935 Manager
*m
= userdata
;
938 r
= manager_recv(m
, fd
, DNS_PROTOCOL_DNS
, &p
);
942 if (dns_packet_validate_reply(p
) > 0) {
943 t
= hashmap_get(m
->dns_transactions
, UINT_TO_PTR(DNS_PACKET_ID(p
)));
947 dns_transaction_process_reply(t
, p
);
950 log_debug("Invalid DNS packet.");
955 int manager_dns_ipv4_fd(Manager
*m
) {
961 if (m
->dns_ipv4_fd
>= 0)
962 return m
->dns_ipv4_fd
;
964 m
->dns_ipv4_fd
= socket(AF_INET
, SOCK_DGRAM
|SOCK_CLOEXEC
|SOCK_NONBLOCK
, 0);
965 if (m
->dns_ipv4_fd
< 0)
968 r
= setsockopt(m
->dns_ipv4_fd
, IPPROTO_IP
, IP_PKTINFO
, &one
, sizeof(one
));
974 r
= sd_event_add_io(m
->event
, &m
->dns_ipv4_event_source
, m
->dns_ipv4_fd
, EPOLLIN
, on_dns_packet
, m
);
978 return m
->dns_ipv4_fd
;
981 m
->dns_ipv4_fd
= safe_close(m
->dns_ipv4_fd
);
985 int manager_dns_ipv6_fd(Manager
*m
) {
991 if (m
->dns_ipv6_fd
>= 0)
992 return m
->dns_ipv6_fd
;
994 m
->dns_ipv6_fd
= socket(AF_INET6
, SOCK_DGRAM
|SOCK_CLOEXEC
|SOCK_NONBLOCK
, 0);
995 if (m
->dns_ipv6_fd
< 0)
998 r
= setsockopt(m
->dns_ipv6_fd
, IPPROTO_IPV6
, IPV6_RECVPKTINFO
, &one
, sizeof(one
));
1004 r
= sd_event_add_io(m
->event
, &m
->dns_ipv6_event_source
, m
->dns_ipv6_fd
, EPOLLIN
, on_dns_packet
, m
);
1008 return m
->dns_ipv6_fd
;
1011 m
->dns_ipv6_fd
= safe_close(m
->dns_ipv6_fd
);
1015 static int sendmsg_loop(int fd
, struct msghdr
*mh
, int flags
) {
1022 if (sendmsg(fd
, mh
, flags
) >= 0)
1028 if (errno
!= EAGAIN
)
1031 r
= fd_wait_for_event(fd
, POLLOUT
, SEND_TIMEOUT_USEC
);
1039 static int manager_ipv4_send(Manager
*m
, int fd
, int ifindex
, const struct in_addr
*addr
, uint16_t port
, DnsPacket
*p
) {
1040 union sockaddr_union sa
= {
1041 .in
.sin_family
= AF_INET
,
1044 struct cmsghdr header
; /* For alignment */
1045 uint8_t buffer
[CMSG_SPACE(sizeof(struct in_pktinfo
))];
1047 struct msghdr mh
= {};
1056 iov
.iov_base
= DNS_PACKET_DATA(p
);
1057 iov
.iov_len
= p
->size
;
1059 sa
.in
.sin_addr
= *addr
;
1060 sa
.in
.sin_port
= htobe16(port
),
1064 mh
.msg_name
= &sa
.sa
;
1065 mh
.msg_namelen
= sizeof(sa
.in
);
1068 struct cmsghdr
*cmsg
;
1069 struct in_pktinfo
*pi
;
1073 mh
.msg_control
= &control
;
1074 mh
.msg_controllen
= CMSG_LEN(sizeof(struct in_pktinfo
));
1076 cmsg
= CMSG_FIRSTHDR(&mh
);
1077 cmsg
->cmsg_len
= mh
.msg_controllen
;
1078 cmsg
->cmsg_level
= IPPROTO_IP
;
1079 cmsg
->cmsg_type
= IP_PKTINFO
;
1081 pi
= (struct in_pktinfo
*) CMSG_DATA(cmsg
);
1082 pi
->ipi_ifindex
= ifindex
;
1085 return sendmsg_loop(fd
, &mh
, 0);
1088 static int manager_ipv6_send(Manager
*m
, int fd
, int ifindex
, const struct in6_addr
*addr
, uint16_t port
, DnsPacket
*p
) {
1089 union sockaddr_union sa
= {
1090 .in6
.sin6_family
= AF_INET6
,
1093 struct cmsghdr header
; /* For alignment */
1094 uint8_t buffer
[CMSG_SPACE(sizeof(struct in6_pktinfo
))];
1096 struct msghdr mh
= {};
1105 iov
.iov_base
= DNS_PACKET_DATA(p
);
1106 iov
.iov_len
= p
->size
;
1108 sa
.in6
.sin6_addr
= *addr
;
1109 sa
.in6
.sin6_port
= htobe16(port
),
1110 sa
.in6
.sin6_scope_id
= ifindex
;
1114 mh
.msg_name
= &sa
.sa
;
1115 mh
.msg_namelen
= sizeof(sa
.in6
);
1118 struct cmsghdr
*cmsg
;
1119 struct in6_pktinfo
*pi
;
1123 mh
.msg_control
= &control
;
1124 mh
.msg_controllen
= CMSG_LEN(sizeof(struct in6_pktinfo
));
1126 cmsg
= CMSG_FIRSTHDR(&mh
);
1127 cmsg
->cmsg_len
= mh
.msg_controllen
;
1128 cmsg
->cmsg_level
= IPPROTO_IPV6
;
1129 cmsg
->cmsg_type
= IPV6_PKTINFO
;
1131 pi
= (struct in6_pktinfo
*) CMSG_DATA(cmsg
);
1132 pi
->ipi6_ifindex
= ifindex
;
1135 return sendmsg_loop(fd
, &mh
, 0);
1138 int manager_send(Manager
*m
, int fd
, int ifindex
, int family
, const union in_addr_union
*addr
, uint16_t port
, DnsPacket
*p
) {
1145 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
));
1147 if (family
== AF_INET
)
1148 return manager_ipv4_send(m
, fd
, ifindex
, &addr
->in
, port
, p
);
1149 else if (family
== AF_INET6
)
1150 return manager_ipv6_send(m
, fd
, ifindex
, &addr
->in6
, port
, p
);
1152 return -EAFNOSUPPORT
;
1155 DnsServer
* manager_find_dns_server(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
1161 LIST_FOREACH(servers
, s
, m
->dns_servers
)
1162 if (s
->family
== family
&& in_addr_equal(family
, &s
->address
, in_addr
) > 0)
1165 LIST_FOREACH(servers
, s
, m
->fallback_dns_servers
)
1166 if (s
->family
== family
&& in_addr_equal(family
, &s
->address
, in_addr
) > 0)
1172 DnsServer
*manager_set_dns_server(Manager
*m
, DnsServer
*s
) {
1175 if (m
->current_dns_server
== s
)
1179 _cleanup_free_
char *ip
= NULL
;
1181 in_addr_to_string(s
->family
, &s
->address
, &ip
);
1182 log_info("Switching to system DNS server %s.", strna(ip
));
1185 m
->current_dns_server
= s
;
1187 if (m
->unicast_scope
)
1188 dns_cache_flush(&m
->unicast_scope
->cache
);
1193 DnsServer
*manager_get_dns_server(Manager
*m
) {
1197 /* Try to read updates resolv.conf */
1198 manager_read_resolv_conf(m
);
1200 if (!m
->current_dns_server
)
1201 manager_set_dns_server(m
, m
->dns_servers
);
1203 if (!m
->current_dns_server
) {
1207 /* No DNS servers configured, let's see if there are
1208 * any on any links. If not, we use the fallback
1211 HASHMAP_FOREACH(l
, m
->links
, i
)
1212 if (l
->dns_servers
) {
1218 manager_set_dns_server(m
, m
->fallback_dns_servers
);
1221 return m
->current_dns_server
;
1224 void manager_next_dns_server(Manager
*m
) {
1227 /* If there's currently no DNS server set, then the next
1228 * manager_get_dns_server() will find one */
1229 if (!m
->current_dns_server
)
1232 /* Change to the next one */
1233 if (m
->current_dns_server
->servers_next
) {
1234 manager_set_dns_server(m
, m
->current_dns_server
->servers_next
);
1238 /* If there was no next one, then start from the beginning of
1240 if (m
->current_dns_server
->type
== DNS_SERVER_FALLBACK
)
1241 manager_set_dns_server(m
, m
->fallback_dns_servers
);
1243 manager_set_dns_server(m
, m
->dns_servers
);
1246 uint32_t manager_find_mtu(Manager
*m
) {
1251 /* If we don't know on which link a DNS packet would be
1252 * delivered, let's find the largest MTU that works on all
1253 * interfaces we know of */
1255 HASHMAP_FOREACH(l
, m
->links
, i
) {
1259 if (mtu
<= 0 || l
->mtu
< mtu
)
1266 int manager_find_ifindex(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
1271 a
= manager_find_link_address(m
, family
, in_addr
);
1273 return a
->link
->ifindex
;
1278 void manager_refresh_rrs(Manager
*m
) {
1284 m
->host_ipv4_key
= dns_resource_key_unref(m
->host_ipv4_key
);
1285 m
->host_ipv6_key
= dns_resource_key_unref(m
->host_ipv6_key
);
1287 HASHMAP_FOREACH(l
, m
->links
, i
) {
1288 link_add_rrs(l
, true);
1289 link_add_rrs(l
, false);
1293 int manager_next_hostname(Manager
*m
) {
1300 p
= strchr(m
->hostname
, 0);
1303 while (p
> m
->hostname
) {
1304 if (!strchr("0123456789", p
[-1]))
1310 if (*p
== 0 || safe_atou64(p
, &u
) < 0 || u
<= 0)
1313 /* Add a random number to the old value. This way we can avoid
1314 * that two hosts pick the same hostname, win on IPv4 and lose
1315 * on IPv6 (or vice versa), and pick the same hostname
1316 * replacement hostname, ad infinitum. We still want the
1317 * numbers to go up monotonically, hence we just add a random
1320 random_bytes(&a
, sizeof(a
));
1323 if (asprintf(&h
, "%.*s%" PRIu64
, (int) (p
- m
->hostname
), m
->hostname
, u
) < 0)
1326 log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m
->hostname
, h
);
1331 manager_refresh_rrs(m
);
1336 LinkAddress
* manager_find_link_address(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
1342 HASHMAP_FOREACH(l
, m
->links
, i
) {
1345 a
= link_find_address(l
, family
, in_addr
);
1353 bool manager_our_packet(Manager
*m
, DnsPacket
*p
) {
1357 return !!manager_find_link_address(m
, p
->family
, &p
->sender
);
1360 DnsScope
* manager_find_scope(Manager
*m
, DnsPacket
*p
) {
1366 l
= hashmap_get(m
->links
, INT_TO_PTR(p
->ifindex
));
1370 if (p
->protocol
== DNS_PROTOCOL_LLMNR
) {
1371 if (p
->family
== AF_INET
)
1372 return l
->llmnr_ipv4_scope
;
1373 else if (p
->family
== AF_INET6
)
1374 return l
->llmnr_ipv6_scope
;
1380 void manager_verify_all(Manager
*m
) {
1385 LIST_FOREACH(scopes
, s
, m
->dns_scopes
)
1386 dns_zone_verify_all(&s
->zone
);
1389 void manager_flush_dns_servers(Manager
*m
, DnsServerType t
) {
1394 if (t
== DNS_SERVER_SYSTEM
)
1395 while (m
->dns_servers
) {
1398 LIST_REMOVE(servers
, m
->dns_servers
, s
);
1399 dns_server_unref(s
);
1402 if (t
== DNS_SERVER_FALLBACK
)
1403 while (m
->fallback_dns_servers
) {
1404 s
= m
->fallback_dns_servers
;
1406 LIST_REMOVE(servers
, m
->fallback_dns_servers
, s
);
1407 dns_server_unref(s
);
1411 static const char* const support_table
[_SUPPORT_MAX
] = {
1412 [SUPPORT_NO
] = "no",
1413 [SUPPORT_YES
] = "yes",
1414 [SUPPORT_RESOLVE
] = "resolve",
1416 DEFINE_STRING_TABLE_LOOKUP(support
, Support
);