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
)
609 /* Whenever /etc/resolv.conf changes, start using the first
610 * DNS server of it. This is useful to deal with broken
611 * network managing implementations (like NetworkManager),
612 * that when connecting to a VPN place both the VPN DNS
613 * servers and the local ones in /etc/resolv.conf. Without
614 * resetting the DNS server to use back to the first entry we
615 * will continue to use the local one thus being unable to
616 * resolve VPN domains. */
617 manager_set_dns_server(m
, m
->dns_servers
);
622 while (m
->dns_servers
)
623 dns_server_free(m
->dns_servers
);
628 static void write_resolv_conf_server(DnsServer
*s
, FILE *f
, unsigned *count
) {
629 _cleanup_free_
char *t
= NULL
;
636 r
= in_addr_to_string(s
->family
, &s
->address
, &t
);
638 log_warning_errno(r
, "Invalid DNS address. Ignoring: %m");
643 fputs("# Too many DNS servers configured, the following entries may be ignored.\n", f
);
645 fprintf(f
, "nameserver %s\n", t
);
649 static void write_resolv_conf_search(
650 const char *domain
, FILE *f
,
658 if (*count
>= MAXDNSRCH
||
659 *length
+ strlen(domain
) > 256) {
660 if (*count
== MAXDNSRCH
)
661 fputs(" # Too many search domains configured, remaining ones ignored.", f
);
663 fputs(" # Total length of all search domains is too long, remaining ones ignored.", f
);
668 fprintf(f
, " %s", domain
);
670 (*length
) += strlen(domain
);
674 static int write_resolv_conf_contents(FILE *f
, OrderedSet
*dns
, OrderedSet
*domains
) {
677 fputs("# This file is managed by systemd-resolved(8). Do not edit.\n#\n"
678 "# Third party programs must not access this file directly, but\n"
679 "# only through the symlink at /etc/resolv.conf. To manage\n"
680 "# resolv.conf(5) in a different way, replace the symlink by a\n"
681 "# static file or a different symlink.\n\n", f
);
683 if (ordered_set_isempty(dns
))
684 fputs("# No DNS servers known.\n", f
);
689 ORDERED_SET_FOREACH(s
, dns
, i
)
690 write_resolv_conf_server(s
, f
, &count
);
693 if (!ordered_set_isempty(domains
)) {
694 unsigned length
= 0, count
= 0;
698 ORDERED_SET_FOREACH(domain
, domains
, i
)
699 write_resolv_conf_search(domain
, f
, &count
, &length
);
703 return fflush_and_check(f
);
706 int manager_write_resolv_conf(Manager
*m
) {
707 static const char path
[] = "/run/systemd/resolve/resolv.conf";
708 _cleanup_free_
char *temp_path
= NULL
;
709 _cleanup_fclose_
FILE *f
= NULL
;
710 _cleanup_ordered_set_free_ OrderedSet
*dns
= NULL
, *domains
= NULL
;
718 /* Read the system /etc/resolv.conf first */
719 manager_read_resolv_conf(m
);
721 /* Add the full list to a set, to filter out duplicates */
722 dns
= ordered_set_new(&dns_server_hash_ops
);
726 domains
= ordered_set_new(&dns_name_hash_ops
);
730 /* First add the system-wide servers */
731 LIST_FOREACH(servers
, s
, m
->dns_servers
) {
732 r
= ordered_set_put(dns
, s
);
739 /* Then, add the per-link servers and domains */
740 HASHMAP_FOREACH(l
, m
->links
, i
) {
743 LIST_FOREACH(servers
, s
, l
->dns_servers
) {
744 r
= ordered_set_put(dns
, s
);
751 if (!l
->unicast_scope
)
754 STRV_FOREACH(domain
, l
->unicast_scope
->domains
) {
755 r
= ordered_set_put(domains
, *domain
);
763 /* If we found nothing, add the fallback servers */
764 if (ordered_set_isempty(dns
)) {
765 LIST_FOREACH(servers
, s
, m
->fallback_dns_servers
) {
766 r
= ordered_set_put(dns
, s
);
774 r
= fopen_temporary_label(path
, path
, &f
, &temp_path
);
778 fchmod(fileno(f
), 0644);
780 r
= write_resolv_conf_contents(f
, dns
, domains
);
784 if (rename(temp_path
, path
) < 0) {
793 (void) unlink(temp_path
);
797 int manager_recv(Manager
*m
, int fd
, DnsProtocol protocol
, DnsPacket
**ret
) {
798 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
800 struct cmsghdr header
; /* For alignment */
801 uint8_t buffer
[CMSG_SPACE(MAXSIZE(struct in_pktinfo
, struct in6_pktinfo
))
802 + CMSG_SPACE(int) /* ttl/hoplimit */
803 + EXTRA_CMSG_SPACE
/* kernel appears to require extra buffer space */];
805 union sockaddr_union sa
;
806 struct msghdr mh
= {};
807 struct cmsghdr
*cmsg
;
816 r
= ioctl(fd
, FIONREAD
, &ms
);
822 r
= dns_packet_new(&p
, protocol
, ms
);
826 iov
.iov_base
= DNS_PACKET_DATA(p
);
827 iov
.iov_len
= p
->allocated
;
829 mh
.msg_name
= &sa
.sa
;
830 mh
.msg_namelen
= sizeof(sa
);
833 mh
.msg_control
= &control
;
834 mh
.msg_controllen
= sizeof(control
);
836 l
= recvmsg(fd
, &mh
, 0);
838 if (errno
== EAGAIN
|| errno
== EINTR
)
847 assert(!(mh
.msg_flags
& MSG_CTRUNC
));
848 assert(!(mh
.msg_flags
& MSG_TRUNC
));
850 p
->size
= (size_t) l
;
852 p
->family
= sa
.sa
.sa_family
;
853 p
->ipproto
= IPPROTO_UDP
;
854 if (p
->family
== AF_INET
) {
855 p
->sender
.in
= sa
.in
.sin_addr
;
856 p
->sender_port
= be16toh(sa
.in
.sin_port
);
857 } else if (p
->family
== AF_INET6
) {
858 p
->sender
.in6
= sa
.in6
.sin6_addr
;
859 p
->sender_port
= be16toh(sa
.in6
.sin6_port
);
860 p
->ifindex
= sa
.in6
.sin6_scope_id
;
862 return -EAFNOSUPPORT
;
864 CMSG_FOREACH(cmsg
, &mh
) {
866 if (cmsg
->cmsg_level
== IPPROTO_IPV6
) {
867 assert(p
->family
== AF_INET6
);
869 switch (cmsg
->cmsg_type
) {
872 struct in6_pktinfo
*i
= (struct in6_pktinfo
*) CMSG_DATA(cmsg
);
875 p
->ifindex
= i
->ipi6_ifindex
;
877 p
->destination
.in6
= i
->ipi6_addr
;
882 p
->ttl
= *(int *) CMSG_DATA(cmsg
);
886 } else if (cmsg
->cmsg_level
== IPPROTO_IP
) {
887 assert(p
->family
== AF_INET
);
889 switch (cmsg
->cmsg_type
) {
892 struct in_pktinfo
*i
= (struct in_pktinfo
*) CMSG_DATA(cmsg
);
895 p
->ifindex
= i
->ipi_ifindex
;
897 p
->destination
.in
= i
->ipi_addr
;
902 p
->ttl
= *(int *) CMSG_DATA(cmsg
);
908 /* The Linux kernel sets the interface index to the loopback
909 * device if the packet came from the local host since it
910 * avoids the routing table in such a case. Let's unset the
911 * interface index in such a case. */
912 if (p
->ifindex
== LOOPBACK_IFINDEX
)
915 /* If we don't know the interface index still, we look for the
916 * first local interface with a matching address. Yuck! */
918 p
->ifindex
= manager_find_ifindex(m
, p
->family
, &p
->destination
);
926 static int on_dns_packet(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
927 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
928 DnsTransaction
*t
= NULL
;
929 Manager
*m
= userdata
;
932 r
= manager_recv(m
, fd
, DNS_PROTOCOL_DNS
, &p
);
936 if (dns_packet_validate_reply(p
) > 0) {
937 t
= hashmap_get(m
->dns_transactions
, UINT_TO_PTR(DNS_PACKET_ID(p
)));
941 dns_transaction_process_reply(t
, p
);
944 log_debug("Invalid DNS packet.");
949 int manager_dns_ipv4_fd(Manager
*m
) {
955 if (m
->dns_ipv4_fd
>= 0)
956 return m
->dns_ipv4_fd
;
958 m
->dns_ipv4_fd
= socket(AF_INET
, SOCK_DGRAM
|SOCK_CLOEXEC
|SOCK_NONBLOCK
, 0);
959 if (m
->dns_ipv4_fd
< 0)
962 r
= setsockopt(m
->dns_ipv4_fd
, IPPROTO_IP
, IP_PKTINFO
, &one
, sizeof(one
));
968 r
= sd_event_add_io(m
->event
, &m
->dns_ipv4_event_source
, m
->dns_ipv4_fd
, EPOLLIN
, on_dns_packet
, m
);
972 return m
->dns_ipv4_fd
;
975 m
->dns_ipv4_fd
= safe_close(m
->dns_ipv4_fd
);
979 int manager_dns_ipv6_fd(Manager
*m
) {
985 if (m
->dns_ipv6_fd
>= 0)
986 return m
->dns_ipv6_fd
;
988 m
->dns_ipv6_fd
= socket(AF_INET6
, SOCK_DGRAM
|SOCK_CLOEXEC
|SOCK_NONBLOCK
, 0);
989 if (m
->dns_ipv6_fd
< 0)
992 r
= setsockopt(m
->dns_ipv6_fd
, IPPROTO_IPV6
, IPV6_RECVPKTINFO
, &one
, sizeof(one
));
998 r
= sd_event_add_io(m
->event
, &m
->dns_ipv6_event_source
, m
->dns_ipv6_fd
, EPOLLIN
, on_dns_packet
, m
);
1002 return m
->dns_ipv6_fd
;
1005 m
->dns_ipv6_fd
= safe_close(m
->dns_ipv6_fd
);
1009 static int sendmsg_loop(int fd
, struct msghdr
*mh
, int flags
) {
1016 if (sendmsg(fd
, mh
, flags
) >= 0)
1022 if (errno
!= EAGAIN
)
1025 r
= fd_wait_for_event(fd
, POLLOUT
, SEND_TIMEOUT_USEC
);
1033 static int manager_ipv4_send(Manager
*m
, int fd
, int ifindex
, const struct in_addr
*addr
, uint16_t port
, DnsPacket
*p
) {
1034 union sockaddr_union sa
= {
1035 .in
.sin_family
= AF_INET
,
1038 struct cmsghdr header
; /* For alignment */
1039 uint8_t buffer
[CMSG_SPACE(sizeof(struct in_pktinfo
))];
1041 struct msghdr mh
= {};
1050 iov
.iov_base
= DNS_PACKET_DATA(p
);
1051 iov
.iov_len
= p
->size
;
1053 sa
.in
.sin_addr
= *addr
;
1054 sa
.in
.sin_port
= htobe16(port
),
1058 mh
.msg_name
= &sa
.sa
;
1059 mh
.msg_namelen
= sizeof(sa
.in
);
1062 struct cmsghdr
*cmsg
;
1063 struct in_pktinfo
*pi
;
1067 mh
.msg_control
= &control
;
1068 mh
.msg_controllen
= CMSG_LEN(sizeof(struct in_pktinfo
));
1070 cmsg
= CMSG_FIRSTHDR(&mh
);
1071 cmsg
->cmsg_len
= mh
.msg_controllen
;
1072 cmsg
->cmsg_level
= IPPROTO_IP
;
1073 cmsg
->cmsg_type
= IP_PKTINFO
;
1075 pi
= (struct in_pktinfo
*) CMSG_DATA(cmsg
);
1076 pi
->ipi_ifindex
= ifindex
;
1079 return sendmsg_loop(fd
, &mh
, 0);
1082 static int manager_ipv6_send(Manager
*m
, int fd
, int ifindex
, const struct in6_addr
*addr
, uint16_t port
, DnsPacket
*p
) {
1083 union sockaddr_union sa
= {
1084 .in6
.sin6_family
= AF_INET6
,
1087 struct cmsghdr header
; /* For alignment */
1088 uint8_t buffer
[CMSG_SPACE(sizeof(struct in6_pktinfo
))];
1090 struct msghdr mh
= {};
1099 iov
.iov_base
= DNS_PACKET_DATA(p
);
1100 iov
.iov_len
= p
->size
;
1102 sa
.in6
.sin6_addr
= *addr
;
1103 sa
.in6
.sin6_port
= htobe16(port
),
1104 sa
.in6
.sin6_scope_id
= ifindex
;
1108 mh
.msg_name
= &sa
.sa
;
1109 mh
.msg_namelen
= sizeof(sa
.in6
);
1112 struct cmsghdr
*cmsg
;
1113 struct in6_pktinfo
*pi
;
1117 mh
.msg_control
= &control
;
1118 mh
.msg_controllen
= CMSG_LEN(sizeof(struct in6_pktinfo
));
1120 cmsg
= CMSG_FIRSTHDR(&mh
);
1121 cmsg
->cmsg_len
= mh
.msg_controllen
;
1122 cmsg
->cmsg_level
= IPPROTO_IPV6
;
1123 cmsg
->cmsg_type
= IPV6_PKTINFO
;
1125 pi
= (struct in6_pktinfo
*) CMSG_DATA(cmsg
);
1126 pi
->ipi6_ifindex
= ifindex
;
1129 return sendmsg_loop(fd
, &mh
, 0);
1132 int manager_send(Manager
*m
, int fd
, int ifindex
, int family
, const union in_addr_union
*addr
, uint16_t port
, DnsPacket
*p
) {
1139 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
));
1141 if (family
== AF_INET
)
1142 return manager_ipv4_send(m
, fd
, ifindex
, &addr
->in
, port
, p
);
1143 else if (family
== AF_INET6
)
1144 return manager_ipv6_send(m
, fd
, ifindex
, &addr
->in6
, port
, p
);
1146 return -EAFNOSUPPORT
;
1149 DnsServer
* manager_find_dns_server(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
1155 LIST_FOREACH(servers
, s
, m
->dns_servers
)
1156 if (s
->family
== family
&& in_addr_equal(family
, &s
->address
, in_addr
) > 0)
1159 LIST_FOREACH(servers
, s
, m
->fallback_dns_servers
)
1160 if (s
->family
== family
&& in_addr_equal(family
, &s
->address
, in_addr
) > 0)
1166 DnsServer
*manager_set_dns_server(Manager
*m
, DnsServer
*s
) {
1169 if (m
->current_dns_server
== s
)
1173 _cleanup_free_
char *ip
= NULL
;
1175 in_addr_to_string(s
->family
, &s
->address
, &ip
);
1176 log_info("Switching to system DNS server %s.", strna(ip
));
1179 m
->current_dns_server
= s
;
1181 if (m
->unicast_scope
)
1182 dns_cache_flush(&m
->unicast_scope
->cache
);
1187 DnsServer
*manager_get_dns_server(Manager
*m
) {
1191 /* Try to read updates resolv.conf */
1192 manager_read_resolv_conf(m
);
1194 if (!m
->current_dns_server
)
1195 manager_set_dns_server(m
, m
->dns_servers
);
1197 if (!m
->current_dns_server
) {
1201 /* No DNS servers configured, let's see if there are
1202 * any on any links. If not, we use the fallback
1205 HASHMAP_FOREACH(l
, m
->links
, i
)
1206 if (l
->dns_servers
) {
1212 manager_set_dns_server(m
, m
->fallback_dns_servers
);
1215 return m
->current_dns_server
;
1218 void manager_next_dns_server(Manager
*m
) {
1221 /* If there's currently no DNS server set, then the next
1222 * manager_get_dns_server() will find one */
1223 if (!m
->current_dns_server
)
1226 /* Change to the next one */
1227 if (m
->current_dns_server
->servers_next
) {
1228 manager_set_dns_server(m
, m
->current_dns_server
->servers_next
);
1232 /* If there was no next one, then start from the beginning of
1234 if (m
->current_dns_server
->type
== DNS_SERVER_FALLBACK
)
1235 manager_set_dns_server(m
, m
->fallback_dns_servers
);
1237 manager_set_dns_server(m
, m
->dns_servers
);
1240 uint32_t manager_find_mtu(Manager
*m
) {
1245 /* If we don't know on which link a DNS packet would be
1246 * delivered, let's find the largest MTU that works on all
1247 * interfaces we know of */
1249 HASHMAP_FOREACH(l
, m
->links
, i
) {
1253 if (mtu
<= 0 || l
->mtu
< mtu
)
1260 int manager_find_ifindex(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
1265 a
= manager_find_link_address(m
, family
, in_addr
);
1267 return a
->link
->ifindex
;
1272 void manager_refresh_rrs(Manager
*m
) {
1278 m
->host_ipv4_key
= dns_resource_key_unref(m
->host_ipv4_key
);
1279 m
->host_ipv6_key
= dns_resource_key_unref(m
->host_ipv6_key
);
1281 HASHMAP_FOREACH(l
, m
->links
, i
) {
1282 link_add_rrs(l
, true);
1283 link_add_rrs(l
, false);
1287 int manager_next_hostname(Manager
*m
) {
1294 p
= strchr(m
->hostname
, 0);
1297 while (p
> m
->hostname
) {
1298 if (!strchr("0123456789", p
[-1]))
1304 if (*p
== 0 || safe_atou64(p
, &u
) < 0 || u
<= 0)
1307 /* Add a random number to the old value. This way we can avoid
1308 * that two hosts pick the same hostname, win on IPv4 and lose
1309 * on IPv6 (or vice versa), and pick the same hostname
1310 * replacement hostname, ad infinitum. We still want the
1311 * numbers to go up monotonically, hence we just add a random
1314 random_bytes(&a
, sizeof(a
));
1317 if (asprintf(&h
, "%.*s%" PRIu64
, (int) (p
- m
->hostname
), m
->hostname
, u
) < 0)
1320 log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m
->hostname
, h
);
1325 manager_refresh_rrs(m
);
1330 LinkAddress
* manager_find_link_address(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
1336 HASHMAP_FOREACH(l
, m
->links
, i
) {
1339 a
= link_find_address(l
, family
, in_addr
);
1347 bool manager_our_packet(Manager
*m
, DnsPacket
*p
) {
1351 return !!manager_find_link_address(m
, p
->family
, &p
->sender
);
1354 DnsScope
* manager_find_scope(Manager
*m
, DnsPacket
*p
) {
1360 l
= hashmap_get(m
->links
, INT_TO_PTR(p
->ifindex
));
1364 if (p
->protocol
== DNS_PROTOCOL_LLMNR
) {
1365 if (p
->family
== AF_INET
)
1366 return l
->llmnr_ipv4_scope
;
1367 else if (p
->family
== AF_INET6
)
1368 return l
->llmnr_ipv6_scope
;
1374 void manager_verify_all(Manager
*m
) {
1379 LIST_FOREACH(scopes
, s
, m
->dns_scopes
)
1380 dns_zone_verify_all(&s
->zone
);
1383 void manager_flush_dns_servers(Manager
*m
, DnsServerType t
) {
1386 if (t
== DNS_SERVER_SYSTEM
)
1387 while (m
->dns_servers
)
1388 dns_server_free(m
->dns_servers
);
1390 if (t
== DNS_SERVER_FALLBACK
)
1391 while (m
->fallback_dns_servers
)
1392 dns_server_free(m
->fallback_dns_servers
);
1395 static const char* const support_table
[_SUPPORT_MAX
] = {
1396 [SUPPORT_NO
] = "no",
1397 [SUPPORT_YES
] = "yes",
1398 [SUPPORT_RESOLVE
] = "resolve",
1400 DEFINE_STRING_TABLE_LOOKUP(support
, Support
);