1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2014 Tom Gundersen <teg@jklm.no>
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include <netinet/in.h>
25 #include <sys/ioctl.h>
28 #include "dns-domain.h"
30 #include "fileio-label.h"
31 #include "hostname-util.h"
33 #include "netlink-util.h"
34 #include "network-internal.h"
35 #include "ordered-set.h"
36 #include "random-util.h"
37 #include "resolved-bus.h"
38 #include "resolved-conf.h"
39 #include "resolved-llmnr.h"
40 #include "resolved-manager.h"
41 #include "socket-util.h"
42 #include "string-util.h"
45 #define SEND_TIMEOUT_USEC (200 * USEC_PER_MSEC)
47 static int manager_process_link(sd_netlink
*rtnl
, sd_netlink_message
*mm
, void *userdata
) {
48 Manager
*m
= userdata
;
57 r
= sd_netlink_message_get_type(mm
, &type
);
61 r
= sd_rtnl_message_link_get_ifindex(mm
, &ifindex
);
65 l
= hashmap_get(m
->links
, INT_TO_PTR(ifindex
));
73 r
= link_new(m
, &l
, ifindex
);
78 r
= link_update_rtnl(l
, mm
);
82 r
= link_update_monitor(l
);
87 log_debug("Found new link %i/%s", ifindex
, l
->name
);
94 log_debug("Removing link %i/%s", l
->ifindex
, l
->name
);
104 log_warning_errno(r
, "Failed to process RTNL link message: %m");
108 static int manager_process_address(sd_netlink
*rtnl
, sd_netlink_message
*mm
, void *userdata
) {
109 Manager
*m
= userdata
;
110 union in_addr_union address
;
112 int r
, ifindex
, family
;
120 r
= sd_netlink_message_get_type(mm
, &type
);
124 r
= sd_rtnl_message_addr_get_ifindex(mm
, &ifindex
);
128 l
= hashmap_get(m
->links
, INT_TO_PTR(ifindex
));
132 r
= sd_rtnl_message_addr_get_family(mm
, &family
);
139 r
= sd_netlink_message_read_in_addr(mm
, IFA_LOCAL
, &address
.in
);
141 r
= sd_netlink_message_read_in_addr(mm
, IFA_ADDRESS
, &address
.in
);
149 r
= sd_netlink_message_read_in6_addr(mm
, IFA_LOCAL
, &address
.in6
);
151 r
= sd_netlink_message_read_in6_addr(mm
, IFA_ADDRESS
, &address
.in6
);
162 a
= link_find_address(l
, family
, &address
);
169 r
= link_address_new(l
, &a
, family
, &address
);
174 r
= link_address_update_rtnl(a
, mm
);
181 link_address_free(a
);
188 log_warning_errno(r
, "Failed to process RTNL address message: %m");
192 static int manager_rtnl_listen(Manager
*m
) {
193 _cleanup_netlink_message_unref_ sd_netlink_message
*req
= NULL
, *reply
= NULL
;
194 sd_netlink_message
*i
;
199 /* First, subscribe to interfaces coming and going */
200 r
= sd_netlink_open(&m
->rtnl
);
204 r
= sd_netlink_attach_event(m
->rtnl
, m
->event
, 0);
208 r
= sd_netlink_add_match(m
->rtnl
, RTM_NEWLINK
, manager_process_link
, m
);
212 r
= sd_netlink_add_match(m
->rtnl
, RTM_DELLINK
, manager_process_link
, m
);
216 r
= sd_netlink_add_match(m
->rtnl
, RTM_NEWADDR
, manager_process_address
, m
);
220 r
= sd_netlink_add_match(m
->rtnl
, RTM_DELADDR
, manager_process_address
, m
);
224 /* Then, enumerate all links */
225 r
= sd_rtnl_message_new_link(m
->rtnl
, &req
, RTM_GETLINK
, 0);
229 r
= sd_netlink_message_request_dump(req
, true);
233 r
= sd_netlink_call(m
->rtnl
, req
, 0, &reply
);
237 for (i
= reply
; i
; i
= sd_netlink_message_next(i
)) {
238 r
= manager_process_link(m
->rtnl
, i
, m
);
243 req
= sd_netlink_message_unref(req
);
244 reply
= sd_netlink_message_unref(reply
);
246 /* Finally, enumerate all addresses, too */
247 r
= sd_rtnl_message_new_addr(m
->rtnl
, &req
, RTM_GETADDR
, 0, AF_UNSPEC
);
251 r
= sd_netlink_message_request_dump(req
, true);
255 r
= sd_netlink_call(m
->rtnl
, req
, 0, &reply
);
259 for (i
= reply
; i
; i
= sd_netlink_message_next(i
)) {
260 r
= manager_process_address(m
->rtnl
, i
, m
);
268 static int on_network_event(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
269 Manager
*m
= userdata
;
276 sd_network_monitor_flush(m
->network_monitor
);
278 HASHMAP_FOREACH(l
, m
->links
, i
) {
279 r
= link_update_monitor(l
);
281 log_warning_errno(r
, "Failed to update monitor information for %i: %m", l
->ifindex
);
284 r
= manager_write_resolv_conf(m
);
286 log_warning_errno(r
, "Could not update resolv.conf: %m");
291 static int manager_network_monitor_listen(Manager
*m
) {
296 r
= sd_network_monitor_new(&m
->network_monitor
, NULL
);
300 fd
= sd_network_monitor_get_fd(m
->network_monitor
);
304 events
= sd_network_monitor_get_events(m
->network_monitor
);
308 r
= sd_event_add_io(m
->event
, &m
->network_event_source
, fd
, events
, &on_network_event
, m
);
315 static int determine_hostname(char **llmnr_hostname
, char **mdns_hostname
) {
316 _cleanup_free_
char *h
= NULL
, *n
= NULL
;
317 char label
[DNS_LABEL_MAX
];
321 assert(llmnr_hostname
);
322 assert(mdns_hostname
);
324 /* Extract and normalize the first label of the locally
325 * configured hostname, and check it's not "localhost". */
327 h
= gethostname_malloc();
332 r
= dns_label_unescape(&p
, label
, sizeof(label
));
334 return log_error_errno(r
, "Failed to unescape host name: %m");
336 log_error("Couldn't find a single label in hosntame.");
340 k
= dns_label_undo_idna(label
, r
, label
, sizeof(label
));
342 return log_error_errno(k
, "Failed to undo IDNA: %m");
346 if (!utf8_is_valid(label
)) {
347 log_error("System hostname is not UTF-8 clean.");
351 r
= dns_label_escape(label
, r
, &n
);
353 return log_error_errno(r
, "Failed to escape host name: %m");
355 if (is_localhost(n
)) {
356 log_debug("System hostname is 'localhost', ignoring.");
360 r
= dns_name_concat(n
, "local", mdns_hostname
);
362 return log_error_errno(r
, "Failed to determine mDNS hostname: %m");
370 static int on_hostname_change(sd_event_source
*es
, int fd
, uint32_t revents
, void *userdata
) {
371 _cleanup_free_
char *llmnr_hostname
= NULL
, *mdns_hostname
= NULL
;
372 Manager
*m
= userdata
;
377 r
= determine_hostname(&llmnr_hostname
, &mdns_hostname
);
379 return 0; /* ignore invalid hostnames */
381 if (streq(llmnr_hostname
, m
->llmnr_hostname
) && streq(mdns_hostname
, m
->mdns_hostname
))
384 log_info("System hostname changed to '%s'.", llmnr_hostname
);
386 free(m
->llmnr_hostname
);
387 free(m
->mdns_hostname
);
389 m
->llmnr_hostname
= llmnr_hostname
;
390 m
->mdns_hostname
= mdns_hostname
;
392 llmnr_hostname
= mdns_hostname
= NULL
;
394 manager_refresh_rrs(m
);
399 static int manager_watch_hostname(Manager
*m
) {
404 m
->hostname_fd
= open("/proc/sys/kernel/hostname", O_RDONLY
|O_CLOEXEC
|O_NDELAY
|O_NOCTTY
);
405 if (m
->hostname_fd
< 0) {
406 log_warning_errno(errno
, "Failed to watch hostname: %m");
410 r
= sd_event_add_io(m
->event
, &m
->hostname_event_source
, m
->hostname_fd
, 0, on_hostname_change
, m
);
413 /* kernels prior to 3.2 don't support polling this file. Ignore the failure. */
414 m
->hostname_fd
= safe_close(m
->hostname_fd
);
416 return log_error_errno(r
, "Failed to add hostname event source: %m");
419 r
= determine_hostname(&m
->llmnr_hostname
, &m
->mdns_hostname
);
421 log_info("Defaulting to hostname 'linux'.");
422 m
->llmnr_hostname
= strdup("linux");
423 if (!m
->llmnr_hostname
)
426 m
->mdns_hostname
= strdup("linux.local");
427 if (!m
->mdns_hostname
)
430 log_info("Using system hostname '%s'.", m
->llmnr_hostname
);
435 static int manager_sigusr1(sd_event_source
*s
, const struct signalfd_siginfo
*si
, void *userdata
) {
436 _cleanup_free_
char *buffer
= NULL
;
437 _cleanup_fclose_
FILE *f
= NULL
;
438 Manager
*m
= userdata
;
446 f
= open_memstream(&buffer
, &size
);
450 LIST_FOREACH(scopes
, scope
, m
->dns_scopes
)
451 dns_scope_dump(scope
, f
);
453 if (fflush_and_check(f
) < 0)
456 log_dump(LOG_INFO
, buffer
);
460 int manager_new(Manager
**ret
) {
461 _cleanup_(manager_freep
) Manager
*m
= NULL
;
466 m
= new0(Manager
, 1);
470 m
->llmnr_ipv4_udp_fd
= m
->llmnr_ipv6_udp_fd
= -1;
471 m
->llmnr_ipv4_tcp_fd
= m
->llmnr_ipv6_tcp_fd
= -1;
474 m
->llmnr_support
= SUPPORT_YES
;
475 m
->read_resolv_conf
= true;
477 r
= manager_parse_dns_server(m
, DNS_SERVER_FALLBACK
, DNS_SERVERS
);
481 r
= sd_event_default(&m
->event
);
485 sd_event_add_signal(m
->event
, NULL
, SIGTERM
, NULL
, NULL
);
486 sd_event_add_signal(m
->event
, NULL
, SIGINT
, NULL
, NULL
);
488 sd_event_set_watchdog(m
->event
, true);
490 r
= manager_watch_hostname(m
);
494 r
= dns_scope_new(m
, &m
->unicast_scope
, NULL
, DNS_PROTOCOL_DNS
, AF_UNSPEC
);
498 r
= manager_network_monitor_listen(m
);
502 r
= manager_rtnl_listen(m
);
506 r
= manager_connect_bus(m
);
510 (void) sd_event_add_signal(m
->event
, &m
->sigusr1_event_source
, SIGUSR1
, manager_sigusr1
, m
);
518 int manager_start(Manager
*m
) {
523 r
= manager_llmnr_start(m
);
530 Manager
*manager_free(Manager
*m
) {
536 while ((l
= hashmap_first(m
->links
)))
539 while (m
->dns_queries
)
540 dns_query_free(m
->dns_queries
);
542 manager_flush_dns_servers(m
, DNS_SERVER_SYSTEM
);
543 manager_flush_dns_servers(m
, DNS_SERVER_FALLBACK
);
545 dns_scope_free(m
->unicast_scope
);
547 hashmap_free(m
->links
);
548 hashmap_free(m
->dns_transactions
);
550 sd_event_source_unref(m
->network_event_source
);
551 sd_network_monitor_unref(m
->network_monitor
);
553 manager_llmnr_stop(m
);
555 sd_bus_slot_unref(m
->prepare_for_sleep_slot
);
556 sd_event_source_unref(m
->bus_retry_event_source
);
557 sd_bus_unref(m
->bus
);
559 sd_event_source_unref(m
->sigusr1_event_source
);
561 sd_event_unref(m
->event
);
563 dns_resource_key_unref(m
->llmnr_host_ipv4_key
);
564 dns_resource_key_unref(m
->llmnr_host_ipv6_key
);
566 sd_event_source_unref(m
->hostname_event_source
);
567 safe_close(m
->hostname_fd
);
568 free(m
->llmnr_hostname
);
569 free(m
->mdns_hostname
);
576 int manager_read_resolv_conf(Manager
*m
) {
577 _cleanup_fclose_
FILE *f
= NULL
;
586 /* Reads the system /etc/resolv.conf, if it exists and is not
587 * symlinked to our own resolv.conf instance */
589 if (!m
->read_resolv_conf
)
592 r
= stat("/etc/resolv.conf", &st
);
595 log_warning_errno(errno
, "Failed to open /etc/resolv.conf: %m");
600 /* Have we already seen the file? */
601 t
= timespec_load(&st
.st_mtim
);
602 if (t
== m
->resolv_conf_mtime
)
605 m
->resolv_conf_mtime
= t
;
607 /* Is it symlinked to our own file? */
608 if (stat("/run/systemd/resolve/resolv.conf", &own
) >= 0 &&
609 st
.st_dev
== own
.st_dev
&&
610 st
.st_ino
== own
.st_ino
) {
615 f
= fopen("/etc/resolv.conf", "re");
618 log_warning_errno(errno
, "Failed to open /etc/resolv.conf: %m");
623 if (fstat(fileno(f
), &st
) < 0) {
624 r
= log_error_errno(errno
, "Failed to stat open file: %m");
628 LIST_FOREACH(servers
, s
, m
->dns_servers
)
631 FOREACH_LINE(line
, f
, r
= -errno
; goto clear
) {
632 union in_addr_union address
;
640 if (*l
== '#' || *l
== ';')
643 a
= first_word(l
, "nameserver");
647 r
= in_addr_from_string_auto(a
, &family
, &address
);
649 log_warning("Failed to parse name server %s.", a
);
653 LIST_FOREACH(servers
, s
, m
->dns_servers
)
654 if (s
->family
== family
&& in_addr_equal(family
, &s
->address
, &address
) > 0)
660 r
= dns_server_new(m
, NULL
, DNS_SERVER_SYSTEM
, NULL
, family
, &address
);
666 LIST_FOREACH_SAFE(servers
, s
, nx
, m
->dns_servers
)
668 LIST_REMOVE(servers
, m
->dns_servers
, s
);
672 /* Whenever /etc/resolv.conf changes, start using the first
673 * DNS server of it. This is useful to deal with broken
674 * network managing implementations (like NetworkManager),
675 * that when connecting to a VPN place both the VPN DNS
676 * servers and the local ones in /etc/resolv.conf. Without
677 * resetting the DNS server to use back to the first entry we
678 * will continue to use the local one thus being unable to
679 * resolve VPN domains. */
680 manager_set_dns_server(m
, m
->dns_servers
);
685 while (m
->dns_servers
) {
688 LIST_REMOVE(servers
, m
->dns_servers
, s
);
695 static void write_resolv_conf_server(DnsServer
*s
, FILE *f
, unsigned *count
) {
696 _cleanup_free_
char *t
= NULL
;
703 r
= in_addr_to_string(s
->family
, &s
->address
, &t
);
705 log_warning_errno(r
, "Invalid DNS address. Ignoring: %m");
710 fputs("# Too many DNS servers configured, the following entries may be ignored.\n", f
);
712 fprintf(f
, "nameserver %s\n", t
);
716 static void write_resolv_conf_search(
717 const char *domain
, FILE *f
,
725 if (*count
>= MAXDNSRCH
||
726 *length
+ strlen(domain
) > 256) {
727 if (*count
== MAXDNSRCH
)
728 fputs(" # Too many search domains configured, remaining ones ignored.", f
);
730 fputs(" # Total length of all search domains is too long, remaining ones ignored.", f
);
735 fprintf(f
, " %s", domain
);
737 (*length
) += strlen(domain
);
741 static int write_resolv_conf_contents(FILE *f
, OrderedSet
*dns
, OrderedSet
*domains
) {
744 fputs("# This file is managed by systemd-resolved(8). Do not edit.\n#\n"
745 "# Third party programs must not access this file directly, but\n"
746 "# only through the symlink at /etc/resolv.conf. To manage\n"
747 "# resolv.conf(5) in a different way, replace the symlink by a\n"
748 "# static file or a different symlink.\n\n", f
);
750 if (ordered_set_isempty(dns
))
751 fputs("# No DNS servers known.\n", f
);
756 ORDERED_SET_FOREACH(s
, dns
, i
)
757 write_resolv_conf_server(s
, f
, &count
);
760 if (!ordered_set_isempty(domains
)) {
761 unsigned length
= 0, count
= 0;
765 ORDERED_SET_FOREACH(domain
, domains
, i
)
766 write_resolv_conf_search(domain
, f
, &count
, &length
);
770 return fflush_and_check(f
);
773 int manager_write_resolv_conf(Manager
*m
) {
774 static const char path
[] = "/run/systemd/resolve/resolv.conf";
775 _cleanup_free_
char *temp_path
= NULL
;
776 _cleanup_fclose_
FILE *f
= NULL
;
777 _cleanup_ordered_set_free_ OrderedSet
*dns
= NULL
, *domains
= NULL
;
785 /* Read the system /etc/resolv.conf first */
786 manager_read_resolv_conf(m
);
788 /* Add the full list to a set, to filter out duplicates */
789 dns
= ordered_set_new(&dns_server_hash_ops
);
793 domains
= ordered_set_new(&dns_name_hash_ops
);
797 /* First add the system-wide servers */
798 LIST_FOREACH(servers
, s
, m
->dns_servers
) {
799 r
= ordered_set_put(dns
, s
);
806 /* Then, add the per-link servers and domains */
807 HASHMAP_FOREACH(l
, m
->links
, i
) {
810 LIST_FOREACH(servers
, s
, l
->dns_servers
) {
811 r
= ordered_set_put(dns
, s
);
818 if (!l
->unicast_scope
)
821 STRV_FOREACH(domain
, l
->unicast_scope
->domains
) {
822 r
= ordered_set_put(domains
, *domain
);
830 /* If we found nothing, add the fallback servers */
831 if (ordered_set_isempty(dns
)) {
832 LIST_FOREACH(servers
, s
, m
->fallback_dns_servers
) {
833 r
= ordered_set_put(dns
, s
);
841 r
= fopen_temporary_label(path
, path
, &f
, &temp_path
);
845 fchmod(fileno(f
), 0644);
847 r
= write_resolv_conf_contents(f
, dns
, domains
);
851 if (rename(temp_path
, path
) < 0) {
860 (void) unlink(temp_path
);
864 int manager_recv(Manager
*m
, int fd
, DnsProtocol protocol
, DnsPacket
**ret
) {
865 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
867 struct cmsghdr header
; /* For alignment */
868 uint8_t buffer
[CMSG_SPACE(MAXSIZE(struct in_pktinfo
, struct in6_pktinfo
))
869 + CMSG_SPACE(int) /* ttl/hoplimit */
870 + EXTRA_CMSG_SPACE
/* kernel appears to require extra buffer space */];
872 union sockaddr_union sa
;
873 struct msghdr mh
= {};
874 struct cmsghdr
*cmsg
;
883 r
= ioctl(fd
, FIONREAD
, &ms
);
889 r
= dns_packet_new(&p
, protocol
, ms
);
893 iov
.iov_base
= DNS_PACKET_DATA(p
);
894 iov
.iov_len
= p
->allocated
;
896 mh
.msg_name
= &sa
.sa
;
897 mh
.msg_namelen
= sizeof(sa
);
900 mh
.msg_control
= &control
;
901 mh
.msg_controllen
= sizeof(control
);
903 l
= recvmsg(fd
, &mh
, 0);
905 if (errno
== EAGAIN
|| errno
== EINTR
)
914 assert(!(mh
.msg_flags
& MSG_CTRUNC
));
915 assert(!(mh
.msg_flags
& MSG_TRUNC
));
917 p
->size
= (size_t) l
;
919 p
->family
= sa
.sa
.sa_family
;
920 p
->ipproto
= IPPROTO_UDP
;
921 if (p
->family
== AF_INET
) {
922 p
->sender
.in
= sa
.in
.sin_addr
;
923 p
->sender_port
= be16toh(sa
.in
.sin_port
);
924 } else if (p
->family
== AF_INET6
) {
925 p
->sender
.in6
= sa
.in6
.sin6_addr
;
926 p
->sender_port
= be16toh(sa
.in6
.sin6_port
);
927 p
->ifindex
= sa
.in6
.sin6_scope_id
;
929 return -EAFNOSUPPORT
;
931 CMSG_FOREACH(cmsg
, &mh
) {
933 if (cmsg
->cmsg_level
== IPPROTO_IPV6
) {
934 assert(p
->family
== AF_INET6
);
936 switch (cmsg
->cmsg_type
) {
939 struct in6_pktinfo
*i
= (struct in6_pktinfo
*) CMSG_DATA(cmsg
);
942 p
->ifindex
= i
->ipi6_ifindex
;
944 p
->destination
.in6
= i
->ipi6_addr
;
949 p
->ttl
= *(int *) CMSG_DATA(cmsg
);
953 } else if (cmsg
->cmsg_level
== IPPROTO_IP
) {
954 assert(p
->family
== AF_INET
);
956 switch (cmsg
->cmsg_type
) {
959 struct in_pktinfo
*i
= (struct in_pktinfo
*) CMSG_DATA(cmsg
);
962 p
->ifindex
= i
->ipi_ifindex
;
964 p
->destination
.in
= i
->ipi_addr
;
969 p
->ttl
= *(int *) CMSG_DATA(cmsg
);
975 /* The Linux kernel sets the interface index to the loopback
976 * device if the packet came from the local host since it
977 * avoids the routing table in such a case. Let's unset the
978 * interface index in such a case. */
979 if (p
->ifindex
== LOOPBACK_IFINDEX
)
982 if (protocol
!= DNS_PROTOCOL_DNS
) {
983 /* If we don't know the interface index still, we look for the
984 * first local interface with a matching address. Yuck! */
986 p
->ifindex
= manager_find_ifindex(m
, p
->family
, &p
->destination
);
995 static int sendmsg_loop(int fd
, struct msghdr
*mh
, int flags
) {
1002 if (sendmsg(fd
, mh
, flags
) >= 0)
1008 if (errno
!= EAGAIN
)
1011 r
= fd_wait_for_event(fd
, POLLOUT
, SEND_TIMEOUT_USEC
);
1019 static int write_loop(int fd
, void *message
, size_t length
) {
1026 if (write(fd
, message
, length
) >= 0)
1032 if (errno
!= EAGAIN
)
1035 r
= fd_wait_for_event(fd
, POLLOUT
, SEND_TIMEOUT_USEC
);
1043 int manager_write(Manager
*m
, int fd
, DnsPacket
*p
) {
1046 log_debug("Sending %s packet with id %u", DNS_PACKET_QR(p
) ? "response" : "query", DNS_PACKET_ID(p
));
1048 r
= write_loop(fd
, DNS_PACKET_DATA(p
), p
->size
);
1055 static int manager_ipv4_send(Manager
*m
, int fd
, int ifindex
, const struct in_addr
*addr
, uint16_t port
, DnsPacket
*p
) {
1056 union sockaddr_union sa
= {
1057 .in
.sin_family
= AF_INET
,
1060 struct cmsghdr header
; /* For alignment */
1061 uint8_t buffer
[CMSG_SPACE(sizeof(struct in_pktinfo
))];
1063 struct msghdr mh
= {};
1072 iov
.iov_base
= DNS_PACKET_DATA(p
);
1073 iov
.iov_len
= p
->size
;
1075 sa
.in
.sin_addr
= *addr
;
1076 sa
.in
.sin_port
= htobe16(port
),
1080 mh
.msg_name
= &sa
.sa
;
1081 mh
.msg_namelen
= sizeof(sa
.in
);
1084 struct cmsghdr
*cmsg
;
1085 struct in_pktinfo
*pi
;
1089 mh
.msg_control
= &control
;
1090 mh
.msg_controllen
= CMSG_LEN(sizeof(struct in_pktinfo
));
1092 cmsg
= CMSG_FIRSTHDR(&mh
);
1093 cmsg
->cmsg_len
= mh
.msg_controllen
;
1094 cmsg
->cmsg_level
= IPPROTO_IP
;
1095 cmsg
->cmsg_type
= IP_PKTINFO
;
1097 pi
= (struct in_pktinfo
*) CMSG_DATA(cmsg
);
1098 pi
->ipi_ifindex
= ifindex
;
1101 return sendmsg_loop(fd
, &mh
, 0);
1104 static int manager_ipv6_send(Manager
*m
, int fd
, int ifindex
, const struct in6_addr
*addr
, uint16_t port
, DnsPacket
*p
) {
1105 union sockaddr_union sa
= {
1106 .in6
.sin6_family
= AF_INET6
,
1109 struct cmsghdr header
; /* For alignment */
1110 uint8_t buffer
[CMSG_SPACE(sizeof(struct in6_pktinfo
))];
1112 struct msghdr mh
= {};
1121 iov
.iov_base
= DNS_PACKET_DATA(p
);
1122 iov
.iov_len
= p
->size
;
1124 sa
.in6
.sin6_addr
= *addr
;
1125 sa
.in6
.sin6_port
= htobe16(port
),
1126 sa
.in6
.sin6_scope_id
= ifindex
;
1130 mh
.msg_name
= &sa
.sa
;
1131 mh
.msg_namelen
= sizeof(sa
.in6
);
1134 struct cmsghdr
*cmsg
;
1135 struct in6_pktinfo
*pi
;
1139 mh
.msg_control
= &control
;
1140 mh
.msg_controllen
= CMSG_LEN(sizeof(struct in6_pktinfo
));
1142 cmsg
= CMSG_FIRSTHDR(&mh
);
1143 cmsg
->cmsg_len
= mh
.msg_controllen
;
1144 cmsg
->cmsg_level
= IPPROTO_IPV6
;
1145 cmsg
->cmsg_type
= IPV6_PKTINFO
;
1147 pi
= (struct in6_pktinfo
*) CMSG_DATA(cmsg
);
1148 pi
->ipi6_ifindex
= ifindex
;
1151 return sendmsg_loop(fd
, &mh
, 0);
1154 int manager_send(Manager
*m
, int fd
, int ifindex
, int family
, const union in_addr_union
*addr
, uint16_t port
, DnsPacket
*p
) {
1161 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
));
1163 if (family
== AF_INET
)
1164 return manager_ipv4_send(m
, fd
, ifindex
, &addr
->in
, port
, p
);
1165 else if (family
== AF_INET6
)
1166 return manager_ipv6_send(m
, fd
, ifindex
, &addr
->in6
, port
, p
);
1168 return -EAFNOSUPPORT
;
1171 DnsServer
* manager_find_dns_server(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
1177 LIST_FOREACH(servers
, s
, m
->dns_servers
)
1178 if (s
->family
== family
&& in_addr_equal(family
, &s
->address
, in_addr
) > 0)
1181 LIST_FOREACH(servers
, s
, m
->fallback_dns_servers
)
1182 if (s
->family
== family
&& in_addr_equal(family
, &s
->address
, in_addr
) > 0)
1188 DnsServer
*manager_set_dns_server(Manager
*m
, DnsServer
*s
) {
1191 if (m
->current_dns_server
== s
)
1195 _cleanup_free_
char *ip
= NULL
;
1197 in_addr_to_string(s
->family
, &s
->address
, &ip
);
1198 log_info("Switching to system DNS server %s.", strna(ip
));
1201 m
->current_dns_server
= s
;
1203 if (m
->unicast_scope
)
1204 dns_cache_flush(&m
->unicast_scope
->cache
);
1209 DnsServer
*manager_get_dns_server(Manager
*m
) {
1213 /* Try to read updates resolv.conf */
1214 manager_read_resolv_conf(m
);
1216 if (!m
->current_dns_server
)
1217 manager_set_dns_server(m
, m
->dns_servers
);
1219 if (!m
->current_dns_server
) {
1223 /* No DNS servers configured, let's see if there are
1224 * any on any links. If not, we use the fallback
1227 HASHMAP_FOREACH(l
, m
->links
, i
)
1228 if (l
->dns_servers
) {
1234 manager_set_dns_server(m
, m
->fallback_dns_servers
);
1237 return m
->current_dns_server
;
1240 void manager_next_dns_server(Manager
*m
) {
1243 /* If there's currently no DNS server set, then the next
1244 * manager_get_dns_server() will find one */
1245 if (!m
->current_dns_server
)
1248 /* Change to the next one */
1249 if (m
->current_dns_server
->servers_next
) {
1250 manager_set_dns_server(m
, m
->current_dns_server
->servers_next
);
1254 /* If there was no next one, then start from the beginning of
1256 if (m
->current_dns_server
->type
== DNS_SERVER_FALLBACK
)
1257 manager_set_dns_server(m
, m
->fallback_dns_servers
);
1259 manager_set_dns_server(m
, m
->dns_servers
);
1262 uint32_t manager_find_mtu(Manager
*m
) {
1267 /* If we don't know on which link a DNS packet would be
1268 * delivered, let's find the largest MTU that works on all
1269 * interfaces we know of */
1271 HASHMAP_FOREACH(l
, m
->links
, i
) {
1275 if (mtu
<= 0 || l
->mtu
< mtu
)
1282 int manager_find_ifindex(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
1287 a
= manager_find_link_address(m
, family
, in_addr
);
1289 return a
->link
->ifindex
;
1294 void manager_refresh_rrs(Manager
*m
) {
1300 m
->llmnr_host_ipv4_key
= dns_resource_key_unref(m
->llmnr_host_ipv4_key
);
1301 m
->llmnr_host_ipv6_key
= dns_resource_key_unref(m
->llmnr_host_ipv6_key
);
1303 HASHMAP_FOREACH(l
, m
->links
, i
) {
1304 link_add_rrs(l
, true);
1305 link_add_rrs(l
, false);
1309 int manager_next_hostname(Manager
*m
) {
1317 p
= strchr(m
->llmnr_hostname
, 0);
1320 while (p
> m
->llmnr_hostname
) {
1321 if (!strchr("0123456789", p
[-1]))
1327 if (*p
== 0 || safe_atou64(p
, &u
) < 0 || u
<= 0)
1330 /* Add a random number to the old value. This way we can avoid
1331 * that two hosts pick the same hostname, win on IPv4 and lose
1332 * on IPv6 (or vice versa), and pick the same hostname
1333 * replacement hostname, ad infinitum. We still want the
1334 * numbers to go up monotonically, hence we just add a random
1337 random_bytes(&a
, sizeof(a
));
1340 if (asprintf(&h
, "%.*s%" PRIu64
, (int) (p
- m
->llmnr_hostname
), m
->llmnr_hostname
, u
) < 0)
1343 r
= dns_name_concat(h
, "local", &k
);
1349 log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m
->llmnr_hostname
, h
);
1351 free(m
->llmnr_hostname
);
1352 m
->llmnr_hostname
= h
;
1354 free(m
->mdns_hostname
);
1355 m
->mdns_hostname
= k
;
1357 manager_refresh_rrs(m
);
1362 LinkAddress
* manager_find_link_address(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
1368 HASHMAP_FOREACH(l
, m
->links
, i
) {
1371 a
= link_find_address(l
, family
, in_addr
);
1379 bool manager_our_packet(Manager
*m
, DnsPacket
*p
) {
1383 return !!manager_find_link_address(m
, p
->family
, &p
->sender
);
1386 DnsScope
* manager_find_scope(Manager
*m
, DnsPacket
*p
) {
1392 l
= hashmap_get(m
->links
, INT_TO_PTR(p
->ifindex
));
1396 if (p
->protocol
== DNS_PROTOCOL_LLMNR
) {
1397 if (p
->family
== AF_INET
)
1398 return l
->llmnr_ipv4_scope
;
1399 else if (p
->family
== AF_INET6
)
1400 return l
->llmnr_ipv6_scope
;
1406 void manager_verify_all(Manager
*m
) {
1411 LIST_FOREACH(scopes
, s
, m
->dns_scopes
)
1412 dns_zone_verify_all(&s
->zone
);
1415 void manager_flush_dns_servers(Manager
*m
, DnsServerType t
) {
1420 if (t
== DNS_SERVER_SYSTEM
)
1421 while (m
->dns_servers
) {
1424 LIST_REMOVE(servers
, m
->dns_servers
, s
);
1425 dns_server_unref(s
);
1428 if (t
== DNS_SERVER_FALLBACK
)
1429 while (m
->fallback_dns_servers
) {
1430 s
= m
->fallback_dns_servers
;
1432 LIST_REMOVE(servers
, m
->fallback_dns_servers
, s
);
1433 dns_server_unref(s
);
1437 int manager_is_own_hostname(Manager
*m
, const char *name
) {
1443 if (m
->llmnr_hostname
) {
1444 r
= dns_name_equal(name
, m
->llmnr_hostname
);
1449 if (m
->mdns_hostname
)
1450 return dns_name_equal(name
, m
->mdns_hostname
);
1455 static const char* const support_table
[_SUPPORT_MAX
] = {
1456 [SUPPORT_NO
] = "no",
1457 [SUPPORT_YES
] = "yes",
1458 [SUPPORT_RESOLVE
] = "resolve",
1460 DEFINE_STRING_TABLE_LOOKUP(support
, Support
);