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 int manager_new(Manager
**ret
) {
434 _cleanup_(manager_freep
) Manager
*m
= NULL
;
439 m
= new0(Manager
, 1);
443 m
->llmnr_ipv4_udp_fd
= m
->llmnr_ipv6_udp_fd
= -1;
444 m
->llmnr_ipv4_tcp_fd
= m
->llmnr_ipv6_tcp_fd
= -1;
447 m
->llmnr_support
= SUPPORT_YES
;
448 m
->read_resolv_conf
= true;
450 r
= manager_parse_dns_server(m
, DNS_SERVER_FALLBACK
, DNS_SERVERS
);
454 r
= sd_event_default(&m
->event
);
458 sd_event_add_signal(m
->event
, NULL
, SIGTERM
, NULL
, NULL
);
459 sd_event_add_signal(m
->event
, NULL
, SIGINT
, NULL
, NULL
);
461 sd_event_set_watchdog(m
->event
, true);
463 r
= manager_watch_hostname(m
);
467 r
= dns_scope_new(m
, &m
->unicast_scope
, NULL
, DNS_PROTOCOL_DNS
, AF_UNSPEC
);
471 r
= manager_network_monitor_listen(m
);
475 r
= manager_rtnl_listen(m
);
479 r
= manager_connect_bus(m
);
489 int manager_start(Manager
*m
) {
494 r
= manager_llmnr_start(m
);
501 Manager
*manager_free(Manager
*m
) {
507 while ((l
= hashmap_first(m
->links
)))
510 while (m
->dns_queries
)
511 dns_query_free(m
->dns_queries
);
513 manager_flush_dns_servers(m
, DNS_SERVER_SYSTEM
);
514 manager_flush_dns_servers(m
, DNS_SERVER_FALLBACK
);
516 dns_scope_free(m
->unicast_scope
);
518 hashmap_free(m
->links
);
519 hashmap_free(m
->dns_transactions
);
521 sd_event_source_unref(m
->network_event_source
);
522 sd_network_monitor_unref(m
->network_monitor
);
524 manager_llmnr_stop(m
);
526 sd_bus_slot_unref(m
->prepare_for_sleep_slot
);
527 sd_event_source_unref(m
->bus_retry_event_source
);
528 sd_bus_unref(m
->bus
);
530 sd_event_unref(m
->event
);
532 dns_resource_key_unref(m
->llmnr_host_ipv4_key
);
533 dns_resource_key_unref(m
->llmnr_host_ipv6_key
);
535 safe_close(m
->hostname_fd
);
536 sd_event_source_unref(m
->hostname_event_source
);
537 free(m
->llmnr_hostname
);
538 free(m
->mdns_hostname
);
545 int manager_read_resolv_conf(Manager
*m
) {
546 _cleanup_fclose_
FILE *f
= NULL
;
555 /* Reads the system /etc/resolv.conf, if it exists and is not
556 * symlinked to our own resolv.conf instance */
558 if (!m
->read_resolv_conf
)
561 r
= stat("/etc/resolv.conf", &st
);
564 log_warning_errno(errno
, "Failed to open /etc/resolv.conf: %m");
569 /* Have we already seen the file? */
570 t
= timespec_load(&st
.st_mtim
);
571 if (t
== m
->resolv_conf_mtime
)
574 m
->resolv_conf_mtime
= t
;
576 /* Is it symlinked to our own file? */
577 if (stat("/run/systemd/resolve/resolv.conf", &own
) >= 0 &&
578 st
.st_dev
== own
.st_dev
&&
579 st
.st_ino
== own
.st_ino
) {
584 f
= fopen("/etc/resolv.conf", "re");
587 log_warning_errno(errno
, "Failed to open /etc/resolv.conf: %m");
592 if (fstat(fileno(f
), &st
) < 0) {
593 log_error_errno(errno
, "Failed to stat open file: %m");
598 LIST_FOREACH(servers
, s
, m
->dns_servers
)
601 FOREACH_LINE(line
, f
, r
= -errno
; goto clear
) {
602 union in_addr_union address
;
610 if (*l
== '#' || *l
== ';')
613 a
= first_word(l
, "nameserver");
617 r
= in_addr_from_string_auto(a
, &family
, &address
);
619 log_warning("Failed to parse name server %s.", a
);
623 LIST_FOREACH(servers
, s
, m
->dns_servers
)
624 if (s
->family
== family
&& in_addr_equal(family
, &s
->address
, &address
) > 0)
630 r
= dns_server_new(m
, NULL
, DNS_SERVER_SYSTEM
, NULL
, family
, &address
);
636 LIST_FOREACH_SAFE(servers
, s
, nx
, m
->dns_servers
)
638 LIST_REMOVE(servers
, m
->dns_servers
, s
);
642 /* Whenever /etc/resolv.conf changes, start using the first
643 * DNS server of it. This is useful to deal with broken
644 * network managing implementations (like NetworkManager),
645 * that when connecting to a VPN place both the VPN DNS
646 * servers and the local ones in /etc/resolv.conf. Without
647 * resetting the DNS server to use back to the first entry we
648 * will continue to use the local one thus being unable to
649 * resolve VPN domains. */
650 manager_set_dns_server(m
, m
->dns_servers
);
655 while (m
->dns_servers
) {
658 LIST_REMOVE(servers
, m
->dns_servers
, s
);
665 static void write_resolv_conf_server(DnsServer
*s
, FILE *f
, unsigned *count
) {
666 _cleanup_free_
char *t
= NULL
;
673 r
= in_addr_to_string(s
->family
, &s
->address
, &t
);
675 log_warning_errno(r
, "Invalid DNS address. Ignoring: %m");
680 fputs("# Too many DNS servers configured, the following entries may be ignored.\n", f
);
682 fprintf(f
, "nameserver %s\n", t
);
686 static void write_resolv_conf_search(
687 const char *domain
, FILE *f
,
695 if (*count
>= MAXDNSRCH
||
696 *length
+ strlen(domain
) > 256) {
697 if (*count
== MAXDNSRCH
)
698 fputs(" # Too many search domains configured, remaining ones ignored.", f
);
700 fputs(" # Total length of all search domains is too long, remaining ones ignored.", f
);
705 fprintf(f
, " %s", domain
);
707 (*length
) += strlen(domain
);
711 static int write_resolv_conf_contents(FILE *f
, OrderedSet
*dns
, OrderedSet
*domains
) {
714 fputs("# This file is managed by systemd-resolved(8). Do not edit.\n#\n"
715 "# Third party programs must not access this file directly, but\n"
716 "# only through the symlink at /etc/resolv.conf. To manage\n"
717 "# resolv.conf(5) in a different way, replace the symlink by a\n"
718 "# static file or a different symlink.\n\n", f
);
720 if (ordered_set_isempty(dns
))
721 fputs("# No DNS servers known.\n", f
);
726 ORDERED_SET_FOREACH(s
, dns
, i
)
727 write_resolv_conf_server(s
, f
, &count
);
730 if (!ordered_set_isempty(domains
)) {
731 unsigned length
= 0, count
= 0;
735 ORDERED_SET_FOREACH(domain
, domains
, i
)
736 write_resolv_conf_search(domain
, f
, &count
, &length
);
740 return fflush_and_check(f
);
743 int manager_write_resolv_conf(Manager
*m
) {
744 static const char path
[] = "/run/systemd/resolve/resolv.conf";
745 _cleanup_free_
char *temp_path
= NULL
;
746 _cleanup_fclose_
FILE *f
= NULL
;
747 _cleanup_ordered_set_free_ OrderedSet
*dns
= NULL
, *domains
= NULL
;
755 /* Read the system /etc/resolv.conf first */
756 manager_read_resolv_conf(m
);
758 /* Add the full list to a set, to filter out duplicates */
759 dns
= ordered_set_new(&dns_server_hash_ops
);
763 domains
= ordered_set_new(&dns_name_hash_ops
);
767 /* First add the system-wide servers */
768 LIST_FOREACH(servers
, s
, m
->dns_servers
) {
769 r
= ordered_set_put(dns
, s
);
776 /* Then, add the per-link servers and domains */
777 HASHMAP_FOREACH(l
, m
->links
, i
) {
780 LIST_FOREACH(servers
, s
, l
->dns_servers
) {
781 r
= ordered_set_put(dns
, s
);
788 if (!l
->unicast_scope
)
791 STRV_FOREACH(domain
, l
->unicast_scope
->domains
) {
792 r
= ordered_set_put(domains
, *domain
);
800 /* If we found nothing, add the fallback servers */
801 if (ordered_set_isempty(dns
)) {
802 LIST_FOREACH(servers
, s
, m
->fallback_dns_servers
) {
803 r
= ordered_set_put(dns
, s
);
811 r
= fopen_temporary_label(path
, path
, &f
, &temp_path
);
815 fchmod(fileno(f
), 0644);
817 r
= write_resolv_conf_contents(f
, dns
, domains
);
821 if (rename(temp_path
, path
) < 0) {
830 (void) unlink(temp_path
);
834 int manager_recv(Manager
*m
, int fd
, DnsProtocol protocol
, DnsPacket
**ret
) {
835 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
837 struct cmsghdr header
; /* For alignment */
838 uint8_t buffer
[CMSG_SPACE(MAXSIZE(struct in_pktinfo
, struct in6_pktinfo
))
839 + CMSG_SPACE(int) /* ttl/hoplimit */
840 + EXTRA_CMSG_SPACE
/* kernel appears to require extra buffer space */];
842 union sockaddr_union sa
;
843 struct msghdr mh
= {};
844 struct cmsghdr
*cmsg
;
853 r
= ioctl(fd
, FIONREAD
, &ms
);
859 r
= dns_packet_new(&p
, protocol
, ms
);
863 iov
.iov_base
= DNS_PACKET_DATA(p
);
864 iov
.iov_len
= p
->allocated
;
866 mh
.msg_name
= &sa
.sa
;
867 mh
.msg_namelen
= sizeof(sa
);
870 mh
.msg_control
= &control
;
871 mh
.msg_controllen
= sizeof(control
);
873 l
= recvmsg(fd
, &mh
, 0);
875 if (errno
== EAGAIN
|| errno
== EINTR
)
884 assert(!(mh
.msg_flags
& MSG_CTRUNC
));
885 assert(!(mh
.msg_flags
& MSG_TRUNC
));
887 p
->size
= (size_t) l
;
889 p
->family
= sa
.sa
.sa_family
;
890 p
->ipproto
= IPPROTO_UDP
;
891 if (p
->family
== AF_INET
) {
892 p
->sender
.in
= sa
.in
.sin_addr
;
893 p
->sender_port
= be16toh(sa
.in
.sin_port
);
894 } else if (p
->family
== AF_INET6
) {
895 p
->sender
.in6
= sa
.in6
.sin6_addr
;
896 p
->sender_port
= be16toh(sa
.in6
.sin6_port
);
897 p
->ifindex
= sa
.in6
.sin6_scope_id
;
899 return -EAFNOSUPPORT
;
901 CMSG_FOREACH(cmsg
, &mh
) {
903 if (cmsg
->cmsg_level
== IPPROTO_IPV6
) {
904 assert(p
->family
== AF_INET6
);
906 switch (cmsg
->cmsg_type
) {
909 struct in6_pktinfo
*i
= (struct in6_pktinfo
*) CMSG_DATA(cmsg
);
912 p
->ifindex
= i
->ipi6_ifindex
;
914 p
->destination
.in6
= i
->ipi6_addr
;
919 p
->ttl
= *(int *) CMSG_DATA(cmsg
);
923 } else if (cmsg
->cmsg_level
== IPPROTO_IP
) {
924 assert(p
->family
== AF_INET
);
926 switch (cmsg
->cmsg_type
) {
929 struct in_pktinfo
*i
= (struct in_pktinfo
*) CMSG_DATA(cmsg
);
932 p
->ifindex
= i
->ipi_ifindex
;
934 p
->destination
.in
= i
->ipi_addr
;
939 p
->ttl
= *(int *) CMSG_DATA(cmsg
);
945 /* The Linux kernel sets the interface index to the loopback
946 * device if the packet came from the local host since it
947 * avoids the routing table in such a case. Let's unset the
948 * interface index in such a case. */
949 if (p
->ifindex
== LOOPBACK_IFINDEX
)
952 if (protocol
!= DNS_PROTOCOL_DNS
) {
953 /* If we don't know the interface index still, we look for the
954 * first local interface with a matching address. Yuck! */
956 p
->ifindex
= manager_find_ifindex(m
, p
->family
, &p
->destination
);
965 static int sendmsg_loop(int fd
, struct msghdr
*mh
, int flags
) {
972 if (sendmsg(fd
, mh
, flags
) >= 0)
981 r
= fd_wait_for_event(fd
, POLLOUT
, SEND_TIMEOUT_USEC
);
989 static int write_loop(int fd
, void *message
, size_t length
) {
996 if (write(fd
, message
, length
) >= 0)
1002 if (errno
!= EAGAIN
)
1005 r
= fd_wait_for_event(fd
, POLLOUT
, SEND_TIMEOUT_USEC
);
1013 int manager_write(Manager
*m
, int fd
, DnsPacket
*p
) {
1016 log_debug("Sending %s packet with id %u", DNS_PACKET_QR(p
) ? "response" : "query", DNS_PACKET_ID(p
));
1018 r
= write_loop(fd
, DNS_PACKET_DATA(p
), p
->size
);
1025 static int manager_ipv4_send(Manager
*m
, int fd
, int ifindex
, const struct in_addr
*addr
, uint16_t port
, DnsPacket
*p
) {
1026 union sockaddr_union sa
= {
1027 .in
.sin_family
= AF_INET
,
1030 struct cmsghdr header
; /* For alignment */
1031 uint8_t buffer
[CMSG_SPACE(sizeof(struct in_pktinfo
))];
1033 struct msghdr mh
= {};
1042 iov
.iov_base
= DNS_PACKET_DATA(p
);
1043 iov
.iov_len
= p
->size
;
1045 sa
.in
.sin_addr
= *addr
;
1046 sa
.in
.sin_port
= htobe16(port
),
1050 mh
.msg_name
= &sa
.sa
;
1051 mh
.msg_namelen
= sizeof(sa
.in
);
1054 struct cmsghdr
*cmsg
;
1055 struct in_pktinfo
*pi
;
1059 mh
.msg_control
= &control
;
1060 mh
.msg_controllen
= CMSG_LEN(sizeof(struct in_pktinfo
));
1062 cmsg
= CMSG_FIRSTHDR(&mh
);
1063 cmsg
->cmsg_len
= mh
.msg_controllen
;
1064 cmsg
->cmsg_level
= IPPROTO_IP
;
1065 cmsg
->cmsg_type
= IP_PKTINFO
;
1067 pi
= (struct in_pktinfo
*) CMSG_DATA(cmsg
);
1068 pi
->ipi_ifindex
= ifindex
;
1071 return sendmsg_loop(fd
, &mh
, 0);
1074 static int manager_ipv6_send(Manager
*m
, int fd
, int ifindex
, const struct in6_addr
*addr
, uint16_t port
, DnsPacket
*p
) {
1075 union sockaddr_union sa
= {
1076 .in6
.sin6_family
= AF_INET6
,
1079 struct cmsghdr header
; /* For alignment */
1080 uint8_t buffer
[CMSG_SPACE(sizeof(struct in6_pktinfo
))];
1082 struct msghdr mh
= {};
1091 iov
.iov_base
= DNS_PACKET_DATA(p
);
1092 iov
.iov_len
= p
->size
;
1094 sa
.in6
.sin6_addr
= *addr
;
1095 sa
.in6
.sin6_port
= htobe16(port
),
1096 sa
.in6
.sin6_scope_id
= ifindex
;
1100 mh
.msg_name
= &sa
.sa
;
1101 mh
.msg_namelen
= sizeof(sa
.in6
);
1104 struct cmsghdr
*cmsg
;
1105 struct in6_pktinfo
*pi
;
1109 mh
.msg_control
= &control
;
1110 mh
.msg_controllen
= CMSG_LEN(sizeof(struct in6_pktinfo
));
1112 cmsg
= CMSG_FIRSTHDR(&mh
);
1113 cmsg
->cmsg_len
= mh
.msg_controllen
;
1114 cmsg
->cmsg_level
= IPPROTO_IPV6
;
1115 cmsg
->cmsg_type
= IPV6_PKTINFO
;
1117 pi
= (struct in6_pktinfo
*) CMSG_DATA(cmsg
);
1118 pi
->ipi6_ifindex
= ifindex
;
1121 return sendmsg_loop(fd
, &mh
, 0);
1124 int manager_send(Manager
*m
, int fd
, int ifindex
, int family
, const union in_addr_union
*addr
, uint16_t port
, DnsPacket
*p
) {
1131 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
));
1133 if (family
== AF_INET
)
1134 return manager_ipv4_send(m
, fd
, ifindex
, &addr
->in
, port
, p
);
1135 else if (family
== AF_INET6
)
1136 return manager_ipv6_send(m
, fd
, ifindex
, &addr
->in6
, port
, p
);
1138 return -EAFNOSUPPORT
;
1141 DnsServer
* manager_find_dns_server(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
1147 LIST_FOREACH(servers
, s
, m
->dns_servers
)
1148 if (s
->family
== family
&& in_addr_equal(family
, &s
->address
, in_addr
) > 0)
1151 LIST_FOREACH(servers
, s
, m
->fallback_dns_servers
)
1152 if (s
->family
== family
&& in_addr_equal(family
, &s
->address
, in_addr
) > 0)
1158 DnsServer
*manager_set_dns_server(Manager
*m
, DnsServer
*s
) {
1161 if (m
->current_dns_server
== s
)
1165 _cleanup_free_
char *ip
= NULL
;
1167 in_addr_to_string(s
->family
, &s
->address
, &ip
);
1168 log_info("Switching to system DNS server %s.", strna(ip
));
1171 m
->current_dns_server
= s
;
1173 if (m
->unicast_scope
)
1174 dns_cache_flush(&m
->unicast_scope
->cache
);
1179 DnsServer
*manager_get_dns_server(Manager
*m
) {
1183 /* Try to read updates resolv.conf */
1184 manager_read_resolv_conf(m
);
1186 if (!m
->current_dns_server
)
1187 manager_set_dns_server(m
, m
->dns_servers
);
1189 if (!m
->current_dns_server
) {
1193 /* No DNS servers configured, let's see if there are
1194 * any on any links. If not, we use the fallback
1197 HASHMAP_FOREACH(l
, m
->links
, i
)
1198 if (l
->dns_servers
) {
1204 manager_set_dns_server(m
, m
->fallback_dns_servers
);
1207 return m
->current_dns_server
;
1210 void manager_next_dns_server(Manager
*m
) {
1213 /* If there's currently no DNS server set, then the next
1214 * manager_get_dns_server() will find one */
1215 if (!m
->current_dns_server
)
1218 /* Change to the next one */
1219 if (m
->current_dns_server
->servers_next
) {
1220 manager_set_dns_server(m
, m
->current_dns_server
->servers_next
);
1224 /* If there was no next one, then start from the beginning of
1226 if (m
->current_dns_server
->type
== DNS_SERVER_FALLBACK
)
1227 manager_set_dns_server(m
, m
->fallback_dns_servers
);
1229 manager_set_dns_server(m
, m
->dns_servers
);
1232 uint32_t manager_find_mtu(Manager
*m
) {
1237 /* If we don't know on which link a DNS packet would be
1238 * delivered, let's find the largest MTU that works on all
1239 * interfaces we know of */
1241 HASHMAP_FOREACH(l
, m
->links
, i
) {
1245 if (mtu
<= 0 || l
->mtu
< mtu
)
1252 int manager_find_ifindex(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
1257 a
= manager_find_link_address(m
, family
, in_addr
);
1259 return a
->link
->ifindex
;
1264 void manager_refresh_rrs(Manager
*m
) {
1270 m
->llmnr_host_ipv4_key
= dns_resource_key_unref(m
->llmnr_host_ipv4_key
);
1271 m
->llmnr_host_ipv6_key
= dns_resource_key_unref(m
->llmnr_host_ipv6_key
);
1273 HASHMAP_FOREACH(l
, m
->links
, i
) {
1274 link_add_rrs(l
, true);
1275 link_add_rrs(l
, false);
1279 int manager_next_hostname(Manager
*m
) {
1287 p
= strchr(m
->llmnr_hostname
, 0);
1290 while (p
> m
->llmnr_hostname
) {
1291 if (!strchr("0123456789", p
[-1]))
1297 if (*p
== 0 || safe_atou64(p
, &u
) < 0 || u
<= 0)
1300 /* Add a random number to the old value. This way we can avoid
1301 * that two hosts pick the same hostname, win on IPv4 and lose
1302 * on IPv6 (or vice versa), and pick the same hostname
1303 * replacement hostname, ad infinitum. We still want the
1304 * numbers to go up monotonically, hence we just add a random
1307 random_bytes(&a
, sizeof(a
));
1310 if (asprintf(&h
, "%.*s%" PRIu64
, (int) (p
- m
->llmnr_hostname
), m
->llmnr_hostname
, u
) < 0)
1313 r
= dns_name_concat(h
, "local", &k
);
1319 log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m
->llmnr_hostname
, h
);
1321 free(m
->llmnr_hostname
);
1322 m
->llmnr_hostname
= h
;
1324 free(m
->mdns_hostname
);
1325 m
->mdns_hostname
= k
;
1327 manager_refresh_rrs(m
);
1332 LinkAddress
* manager_find_link_address(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
1338 HASHMAP_FOREACH(l
, m
->links
, i
) {
1341 a
= link_find_address(l
, family
, in_addr
);
1349 bool manager_our_packet(Manager
*m
, DnsPacket
*p
) {
1353 return !!manager_find_link_address(m
, p
->family
, &p
->sender
);
1356 DnsScope
* manager_find_scope(Manager
*m
, DnsPacket
*p
) {
1362 l
= hashmap_get(m
->links
, INT_TO_PTR(p
->ifindex
));
1366 if (p
->protocol
== DNS_PROTOCOL_LLMNR
) {
1367 if (p
->family
== AF_INET
)
1368 return l
->llmnr_ipv4_scope
;
1369 else if (p
->family
== AF_INET6
)
1370 return l
->llmnr_ipv6_scope
;
1376 void manager_verify_all(Manager
*m
) {
1381 LIST_FOREACH(scopes
, s
, m
->dns_scopes
)
1382 dns_zone_verify_all(&s
->zone
);
1385 void manager_flush_dns_servers(Manager
*m
, DnsServerType t
) {
1390 if (t
== DNS_SERVER_SYSTEM
)
1391 while (m
->dns_servers
) {
1394 LIST_REMOVE(servers
, m
->dns_servers
, s
);
1395 dns_server_unref(s
);
1398 if (t
== DNS_SERVER_FALLBACK
)
1399 while (m
->fallback_dns_servers
) {
1400 s
= m
->fallback_dns_servers
;
1402 LIST_REMOVE(servers
, m
->fallback_dns_servers
, s
);
1403 dns_server_unref(s
);
1407 int manager_is_own_hostname(Manager
*m
, const char *name
) {
1413 if (m
->llmnr_hostname
) {
1414 r
= dns_name_equal(name
, m
->llmnr_hostname
);
1419 if (m
->mdns_hostname
)
1420 return dns_name_equal(name
, m
->mdns_hostname
);
1425 static const char* const support_table
[_SUPPORT_MAX
] = {
1426 [SUPPORT_NO
] = "no",
1427 [SUPPORT_YES
] = "yes",
1428 [SUPPORT_RESOLVE
] = "resolve",
1430 DEFINE_STRING_TABLE_LOOKUP(support
, Support
);