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 "alloc-util.h"
29 #include "dns-domain.h"
31 #include "fileio-label.h"
32 #include "hostname-util.h"
34 #include "netlink-util.h"
35 #include "network-internal.h"
36 #include "ordered-set.h"
37 #include "parse-util.h"
38 #include "random-util.h"
39 #include "resolved-bus.h"
40 #include "resolved-conf.h"
41 #include "resolved-llmnr.h"
42 #include "resolved-manager.h"
43 #include "socket-util.h"
44 #include "string-table.h"
45 #include "string-util.h"
48 #define SEND_TIMEOUT_USEC (200 * USEC_PER_MSEC)
50 static int manager_process_link(sd_netlink
*rtnl
, sd_netlink_message
*mm
, void *userdata
) {
51 Manager
*m
= userdata
;
60 r
= sd_netlink_message_get_type(mm
, &type
);
64 r
= sd_rtnl_message_link_get_ifindex(mm
, &ifindex
);
68 l
= hashmap_get(m
->links
, INT_TO_PTR(ifindex
));
76 r
= link_new(m
, &l
, ifindex
);
81 r
= link_update_rtnl(l
, mm
);
85 r
= link_update_monitor(l
);
90 log_debug("Found new link %i/%s", ifindex
, l
->name
);
97 log_debug("Removing link %i/%s", l
->ifindex
, l
->name
);
107 log_warning_errno(r
, "Failed to process RTNL link message: %m");
111 static int manager_process_address(sd_netlink
*rtnl
, sd_netlink_message
*mm
, void *userdata
) {
112 Manager
*m
= userdata
;
113 union in_addr_union address
;
115 int r
, ifindex
, family
;
123 r
= sd_netlink_message_get_type(mm
, &type
);
127 r
= sd_rtnl_message_addr_get_ifindex(mm
, &ifindex
);
131 l
= hashmap_get(m
->links
, INT_TO_PTR(ifindex
));
135 r
= sd_rtnl_message_addr_get_family(mm
, &family
);
142 r
= sd_netlink_message_read_in_addr(mm
, IFA_LOCAL
, &address
.in
);
144 r
= sd_netlink_message_read_in_addr(mm
, IFA_ADDRESS
, &address
.in
);
152 r
= sd_netlink_message_read_in6_addr(mm
, IFA_LOCAL
, &address
.in6
);
154 r
= sd_netlink_message_read_in6_addr(mm
, IFA_ADDRESS
, &address
.in6
);
165 a
= link_find_address(l
, family
, &address
);
172 r
= link_address_new(l
, &a
, family
, &address
);
177 r
= link_address_update_rtnl(a
, mm
);
184 link_address_free(a
);
191 log_warning_errno(r
, "Failed to process RTNL address message: %m");
195 static int manager_rtnl_listen(Manager
*m
) {
196 _cleanup_netlink_message_unref_ sd_netlink_message
*req
= NULL
, *reply
= NULL
;
197 sd_netlink_message
*i
;
202 /* First, subscribe to interfaces coming and going */
203 r
= sd_netlink_open(&m
->rtnl
);
207 r
= sd_netlink_attach_event(m
->rtnl
, m
->event
, 0);
211 r
= sd_netlink_add_match(m
->rtnl
, RTM_NEWLINK
, manager_process_link
, m
);
215 r
= sd_netlink_add_match(m
->rtnl
, RTM_DELLINK
, manager_process_link
, m
);
219 r
= sd_netlink_add_match(m
->rtnl
, RTM_NEWADDR
, manager_process_address
, m
);
223 r
= sd_netlink_add_match(m
->rtnl
, RTM_DELADDR
, manager_process_address
, m
);
227 /* Then, enumerate all links */
228 r
= sd_rtnl_message_new_link(m
->rtnl
, &req
, RTM_GETLINK
, 0);
232 r
= sd_netlink_message_request_dump(req
, true);
236 r
= sd_netlink_call(m
->rtnl
, req
, 0, &reply
);
240 for (i
= reply
; i
; i
= sd_netlink_message_next(i
)) {
241 r
= manager_process_link(m
->rtnl
, i
, m
);
246 req
= sd_netlink_message_unref(req
);
247 reply
= sd_netlink_message_unref(reply
);
249 /* Finally, enumerate all addresses, too */
250 r
= sd_rtnl_message_new_addr(m
->rtnl
, &req
, RTM_GETADDR
, 0, AF_UNSPEC
);
254 r
= sd_netlink_message_request_dump(req
, true);
258 r
= sd_netlink_call(m
->rtnl
, req
, 0, &reply
);
262 for (i
= reply
; i
; i
= sd_netlink_message_next(i
)) {
263 r
= manager_process_address(m
->rtnl
, i
, m
);
271 static int on_network_event(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
272 Manager
*m
= userdata
;
279 sd_network_monitor_flush(m
->network_monitor
);
281 HASHMAP_FOREACH(l
, m
->links
, i
) {
282 r
= link_update_monitor(l
);
284 log_warning_errno(r
, "Failed to update monitor information for %i: %m", l
->ifindex
);
287 r
= manager_write_resolv_conf(m
);
289 log_warning_errno(r
, "Could not update resolv.conf: %m");
294 static int manager_network_monitor_listen(Manager
*m
) {
299 r
= sd_network_monitor_new(&m
->network_monitor
, NULL
);
303 fd
= sd_network_monitor_get_fd(m
->network_monitor
);
307 events
= sd_network_monitor_get_events(m
->network_monitor
);
311 r
= sd_event_add_io(m
->event
, &m
->network_event_source
, fd
, events
, &on_network_event
, m
);
318 static int determine_hostname(char **llmnr_hostname
, char **mdns_hostname
) {
319 _cleanup_free_
char *h
= NULL
, *n
= NULL
;
320 char label
[DNS_LABEL_MAX
];
324 assert(llmnr_hostname
);
325 assert(mdns_hostname
);
327 /* Extract and normalize the first label of the locally
328 * configured hostname, and check it's not "localhost". */
330 h
= gethostname_malloc();
335 r
= dns_label_unescape(&p
, label
, sizeof(label
));
337 return log_error_errno(r
, "Failed to unescape host name: %m");
339 log_error("Couldn't find a single label in hosntame.");
343 k
= dns_label_undo_idna(label
, r
, label
, sizeof(label
));
345 return log_error_errno(k
, "Failed to undo IDNA: %m");
349 if (!utf8_is_valid(label
)) {
350 log_error("System hostname is not UTF-8 clean.");
354 r
= dns_label_escape(label
, r
, &n
);
356 return log_error_errno(r
, "Failed to escape host name: %m");
358 if (is_localhost(n
)) {
359 log_debug("System hostname is 'localhost', ignoring.");
363 r
= dns_name_concat(n
, "local", mdns_hostname
);
365 return log_error_errno(r
, "Failed to determine mDNS hostname: %m");
373 static int on_hostname_change(sd_event_source
*es
, int fd
, uint32_t revents
, void *userdata
) {
374 _cleanup_free_
char *llmnr_hostname
= NULL
, *mdns_hostname
= NULL
;
375 Manager
*m
= userdata
;
380 r
= determine_hostname(&llmnr_hostname
, &mdns_hostname
);
382 return 0; /* ignore invalid hostnames */
384 if (streq(llmnr_hostname
, m
->llmnr_hostname
) && streq(mdns_hostname
, m
->mdns_hostname
))
387 log_info("System hostname changed to '%s'.", llmnr_hostname
);
389 free(m
->llmnr_hostname
);
390 free(m
->mdns_hostname
);
392 m
->llmnr_hostname
= llmnr_hostname
;
393 m
->mdns_hostname
= mdns_hostname
;
395 llmnr_hostname
= mdns_hostname
= NULL
;
397 manager_refresh_rrs(m
);
402 static int manager_watch_hostname(Manager
*m
) {
407 m
->hostname_fd
= open("/proc/sys/kernel/hostname", O_RDONLY
|O_CLOEXEC
|O_NDELAY
|O_NOCTTY
);
408 if (m
->hostname_fd
< 0) {
409 log_warning_errno(errno
, "Failed to watch hostname: %m");
413 r
= sd_event_add_io(m
->event
, &m
->hostname_event_source
, m
->hostname_fd
, 0, on_hostname_change
, m
);
416 /* kernels prior to 3.2 don't support polling this file. Ignore the failure. */
417 m
->hostname_fd
= safe_close(m
->hostname_fd
);
419 return log_error_errno(r
, "Failed to add hostname event source: %m");
422 r
= determine_hostname(&m
->llmnr_hostname
, &m
->mdns_hostname
);
424 log_info("Defaulting to hostname 'linux'.");
425 m
->llmnr_hostname
= strdup("linux");
426 if (!m
->llmnr_hostname
)
429 m
->mdns_hostname
= strdup("linux.local");
430 if (!m
->mdns_hostname
)
433 log_info("Using system hostname '%s'.", m
->llmnr_hostname
);
438 static int manager_sigusr1(sd_event_source
*s
, const struct signalfd_siginfo
*si
, void *userdata
) {
439 _cleanup_free_
char *buffer
= NULL
;
440 _cleanup_fclose_
FILE *f
= NULL
;
441 Manager
*m
= userdata
;
449 f
= open_memstream(&buffer
, &size
);
453 LIST_FOREACH(scopes
, scope
, m
->dns_scopes
)
454 dns_scope_dump(scope
, f
);
456 if (fflush_and_check(f
) < 0)
459 log_dump(LOG_INFO
, buffer
);
463 int manager_new(Manager
**ret
) {
464 _cleanup_(manager_freep
) Manager
*m
= NULL
;
469 m
= new0(Manager
, 1);
473 m
->llmnr_ipv4_udp_fd
= m
->llmnr_ipv6_udp_fd
= -1;
474 m
->llmnr_ipv4_tcp_fd
= m
->llmnr_ipv6_tcp_fd
= -1;
477 m
->llmnr_support
= SUPPORT_YES
;
478 m
->read_resolv_conf
= true;
480 r
= manager_parse_dns_server_string_and_warn(m
, DNS_SERVER_FALLBACK
, DNS_SERVERS
);
484 r
= sd_event_default(&m
->event
);
488 sd_event_add_signal(m
->event
, NULL
, SIGTERM
, NULL
, NULL
);
489 sd_event_add_signal(m
->event
, NULL
, SIGINT
, NULL
, NULL
);
491 sd_event_set_watchdog(m
->event
, true);
493 r
= manager_watch_hostname(m
);
497 r
= dns_scope_new(m
, &m
->unicast_scope
, NULL
, DNS_PROTOCOL_DNS
, AF_UNSPEC
);
501 r
= manager_network_monitor_listen(m
);
505 r
= manager_rtnl_listen(m
);
509 r
= manager_connect_bus(m
);
513 (void) sd_event_add_signal(m
->event
, &m
->sigusr1_event_source
, SIGUSR1
, manager_sigusr1
, m
);
521 int manager_start(Manager
*m
) {
526 r
= manager_llmnr_start(m
);
533 Manager
*manager_free(Manager
*m
) {
539 while ((l
= hashmap_first(m
->links
)))
542 while (m
->dns_queries
)
543 dns_query_free(m
->dns_queries
);
545 manager_flush_dns_servers(m
, DNS_SERVER_SYSTEM
);
546 manager_flush_dns_servers(m
, DNS_SERVER_FALLBACK
);
548 dns_scope_free(m
->unicast_scope
);
550 hashmap_free(m
->links
);
551 hashmap_free(m
->dns_transactions
);
553 sd_event_source_unref(m
->network_event_source
);
554 sd_network_monitor_unref(m
->network_monitor
);
556 sd_netlink_unref(m
->rtnl
);
557 sd_event_source_unref(m
->rtnl_event_source
);
559 manager_llmnr_stop(m
);
561 sd_bus_slot_unref(m
->prepare_for_sleep_slot
);
562 sd_event_source_unref(m
->bus_retry_event_source
);
563 sd_bus_unref(m
->bus
);
565 sd_event_source_unref(m
->sigusr1_event_source
);
567 sd_event_unref(m
->event
);
569 dns_resource_key_unref(m
->llmnr_host_ipv4_key
);
570 dns_resource_key_unref(m
->llmnr_host_ipv6_key
);
572 sd_event_source_unref(m
->hostname_event_source
);
573 safe_close(m
->hostname_fd
);
574 free(m
->llmnr_hostname
);
575 free(m
->mdns_hostname
);
582 int manager_read_resolv_conf(Manager
*m
) {
583 _cleanup_fclose_
FILE *f
= NULL
;
592 /* Reads the system /etc/resolv.conf, if it exists and is not
593 * symlinked to our own resolv.conf instance */
595 if (!m
->read_resolv_conf
)
598 r
= stat("/etc/resolv.conf", &st
);
603 r
= log_warning_errno(errno
, "Failed to open /etc/resolv.conf: %m");
607 /* Have we already seen the file? */
608 t
= timespec_load(&st
.st_mtim
);
609 if (t
== m
->resolv_conf_mtime
)
612 m
->resolv_conf_mtime
= t
;
614 /* Is it symlinked to our own file? */
615 if (stat("/run/systemd/resolve/resolv.conf", &own
) >= 0 &&
616 st
.st_dev
== own
.st_dev
&&
617 st
.st_ino
== own
.st_ino
) {
622 f
= fopen("/etc/resolv.conf", "re");
627 r
= log_warning_errno(errno
, "Failed to open /etc/resolv.conf: %m");
631 if (fstat(fileno(f
), &st
) < 0) {
632 r
= log_error_errno(errno
, "Failed to stat open file: %m");
636 manager_mark_dns_servers(m
, DNS_SERVER_SYSTEM
);
638 FOREACH_LINE(line
, f
, r
= -errno
; goto clear
) {
639 _cleanup_strv_free_
char **d
= NULL
;
646 if (*l
== '#' || *l
== ';')
649 a
= first_word(l
, "nameserver");
651 r
= manager_add_dns_server_by_string(m
, DNS_SERVER_SYSTEM
, a
);
653 log_warning_errno(r
, "Failed to parse DNS server address '%s', ignoring.", a
);
659 manager_flush_marked_dns_servers(m
, DNS_SERVER_SYSTEM
);
661 /* Whenever /etc/resolv.conf changes, start using the first
662 * DNS server of it. This is useful to deal with broken
663 * network managing implementations (like NetworkManager),
664 * that when connecting to a VPN place both the VPN DNS
665 * servers and the local ones in /etc/resolv.conf. Without
666 * resetting the DNS server to use back to the first entry we
667 * will continue to use the local one thus being unable to
668 * resolve VPN domains. */
669 manager_set_dns_server(m
, m
->dns_servers
);
674 while (m
->dns_servers
) {
677 LIST_REMOVE(servers
, m
->dns_servers
, s
);
684 static void write_resolv_conf_server(DnsServer
*s
, FILE *f
, unsigned *count
) {
685 _cleanup_free_
char *t
= NULL
;
692 r
= in_addr_to_string(s
->family
, &s
->address
, &t
);
694 log_warning_errno(r
, "Invalid DNS address. Ignoring: %m");
699 fputs("# Too many DNS servers configured, the following entries may be ignored.\n", f
);
702 fprintf(f
, "nameserver %s\n", t
);
705 static void write_resolv_conf_search(
715 if (*count
>= MAXDNSRCH
||
716 *length
+ strlen(domain
) > 256) {
717 if (*count
== MAXDNSRCH
)
718 fputs(" # Too many search domains configured, remaining ones ignored.", f
);
720 fputs(" # Total length of all search domains is too long, remaining ones ignored.", f
);
725 (*length
) += strlen(domain
);
732 static int write_resolv_conf_contents(FILE *f
, OrderedSet
*dns
, OrderedSet
*domains
) {
735 fputs("# This file is managed by systemd-resolved(8). Do not edit.\n#\n"
736 "# Third party programs must not access this file directly, but\n"
737 "# only through the symlink at /etc/resolv.conf. To manage\n"
738 "# resolv.conf(5) in a different way, replace the symlink by a\n"
739 "# static file or a different symlink.\n\n", f
);
741 if (ordered_set_isempty(dns
))
742 fputs("# No DNS servers known.\n", f
);
747 ORDERED_SET_FOREACH(s
, dns
, i
)
748 write_resolv_conf_server(s
, f
, &count
);
751 if (!ordered_set_isempty(domains
)) {
752 unsigned length
= 0, count
= 0;
756 ORDERED_SET_FOREACH(domain
, domains
, i
)
757 write_resolv_conf_search(domain
, f
, &count
, &length
);
761 return fflush_and_check(f
);
764 int manager_write_resolv_conf(Manager
*m
) {
765 static const char path
[] = "/run/systemd/resolve/resolv.conf";
766 _cleanup_free_
char *temp_path
= NULL
;
767 _cleanup_fclose_
FILE *f
= NULL
;
768 _cleanup_ordered_set_free_ OrderedSet
*dns
= NULL
, *domains
= NULL
;
776 /* Read the system /etc/resolv.conf first */
777 manager_read_resolv_conf(m
);
779 /* Add the full list to a set, to filter out duplicates */
780 dns
= ordered_set_new(&dns_server_hash_ops
);
784 domains
= ordered_set_new(&dns_name_hash_ops
);
788 /* First add the system-wide servers and domains */
789 LIST_FOREACH(servers
, s
, m
->dns_servers
) {
790 r
= ordered_set_put(dns
, s
);
797 /* Then, add the per-link servers and domains */
798 HASHMAP_FOREACH(l
, m
->links
, i
) {
801 LIST_FOREACH(servers
, s
, l
->dns_servers
) {
802 r
= ordered_set_put(dns
, s
);
809 if (!l
->unicast_scope
)
812 STRV_FOREACH(domain
, l
->unicast_scope
->domains
) {
813 r
= ordered_set_put(domains
, *domain
);
821 /* If we found nothing, add the fallback servers */
822 if (ordered_set_isempty(dns
)) {
823 LIST_FOREACH(servers
, s
, m
->fallback_dns_servers
) {
824 r
= ordered_set_put(dns
, s
);
832 r
= fopen_temporary_label(path
, path
, &f
, &temp_path
);
836 fchmod(fileno(f
), 0644);
838 r
= write_resolv_conf_contents(f
, dns
, domains
);
842 if (rename(temp_path
, path
) < 0) {
851 (void) unlink(temp_path
);
855 int manager_recv(Manager
*m
, int fd
, DnsProtocol protocol
, DnsPacket
**ret
) {
856 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
858 struct cmsghdr header
; /* For alignment */
859 uint8_t buffer
[CMSG_SPACE(MAXSIZE(struct in_pktinfo
, struct in6_pktinfo
))
860 + CMSG_SPACE(int) /* ttl/hoplimit */
861 + EXTRA_CMSG_SPACE
/* kernel appears to require extra buffer space */];
863 union sockaddr_union sa
;
864 struct msghdr mh
= {};
865 struct cmsghdr
*cmsg
;
874 r
= ioctl(fd
, FIONREAD
, &ms
);
880 r
= dns_packet_new(&p
, protocol
, ms
);
884 iov
.iov_base
= DNS_PACKET_DATA(p
);
885 iov
.iov_len
= p
->allocated
;
887 mh
.msg_name
= &sa
.sa
;
888 mh
.msg_namelen
= sizeof(sa
);
891 mh
.msg_control
= &control
;
892 mh
.msg_controllen
= sizeof(control
);
894 l
= recvmsg(fd
, &mh
, 0);
896 if (errno
== EAGAIN
|| errno
== EINTR
)
905 assert(!(mh
.msg_flags
& MSG_CTRUNC
));
906 assert(!(mh
.msg_flags
& MSG_TRUNC
));
908 p
->size
= (size_t) l
;
910 p
->family
= sa
.sa
.sa_family
;
911 p
->ipproto
= IPPROTO_UDP
;
912 if (p
->family
== AF_INET
) {
913 p
->sender
.in
= sa
.in
.sin_addr
;
914 p
->sender_port
= be16toh(sa
.in
.sin_port
);
915 } else if (p
->family
== AF_INET6
) {
916 p
->sender
.in6
= sa
.in6
.sin6_addr
;
917 p
->sender_port
= be16toh(sa
.in6
.sin6_port
);
918 p
->ifindex
= sa
.in6
.sin6_scope_id
;
920 return -EAFNOSUPPORT
;
922 CMSG_FOREACH(cmsg
, &mh
) {
924 if (cmsg
->cmsg_level
== IPPROTO_IPV6
) {
925 assert(p
->family
== AF_INET6
);
927 switch (cmsg
->cmsg_type
) {
930 struct in6_pktinfo
*i
= (struct in6_pktinfo
*) CMSG_DATA(cmsg
);
933 p
->ifindex
= i
->ipi6_ifindex
;
935 p
->destination
.in6
= i
->ipi6_addr
;
940 p
->ttl
= *(int *) CMSG_DATA(cmsg
);
944 } else if (cmsg
->cmsg_level
== IPPROTO_IP
) {
945 assert(p
->family
== AF_INET
);
947 switch (cmsg
->cmsg_type
) {
950 struct in_pktinfo
*i
= (struct in_pktinfo
*) CMSG_DATA(cmsg
);
953 p
->ifindex
= i
->ipi_ifindex
;
955 p
->destination
.in
= i
->ipi_addr
;
960 p
->ttl
= *(int *) CMSG_DATA(cmsg
);
966 /* The Linux kernel sets the interface index to the loopback
967 * device if the packet came from the local host since it
968 * avoids the routing table in such a case. Let's unset the
969 * interface index in such a case. */
970 if (p
->ifindex
== LOOPBACK_IFINDEX
)
973 if (protocol
!= DNS_PROTOCOL_DNS
) {
974 /* If we don't know the interface index still, we look for the
975 * first local interface with a matching address. Yuck! */
977 p
->ifindex
= manager_find_ifindex(m
, p
->family
, &p
->destination
);
986 static int sendmsg_loop(int fd
, struct msghdr
*mh
, int flags
) {
993 if (sendmsg(fd
, mh
, flags
) >= 0)
1002 r
= fd_wait_for_event(fd
, POLLOUT
, SEND_TIMEOUT_USEC
);
1010 static int write_loop(int fd
, void *message
, size_t length
) {
1017 if (write(fd
, message
, length
) >= 0)
1023 if (errno
!= EAGAIN
)
1026 r
= fd_wait_for_event(fd
, POLLOUT
, SEND_TIMEOUT_USEC
);
1034 int manager_write(Manager
*m
, int fd
, DnsPacket
*p
) {
1037 log_debug("Sending %s packet with id %u", DNS_PACKET_QR(p
) ? "response" : "query", DNS_PACKET_ID(p
));
1039 r
= write_loop(fd
, DNS_PACKET_DATA(p
), p
->size
);
1046 static int manager_ipv4_send(Manager
*m
, int fd
, int ifindex
, const struct in_addr
*addr
, uint16_t port
, DnsPacket
*p
) {
1047 union sockaddr_union sa
= {
1048 .in
.sin_family
= AF_INET
,
1051 struct cmsghdr header
; /* For alignment */
1052 uint8_t buffer
[CMSG_SPACE(sizeof(struct in_pktinfo
))];
1054 struct msghdr mh
= {};
1063 iov
.iov_base
= DNS_PACKET_DATA(p
);
1064 iov
.iov_len
= p
->size
;
1066 sa
.in
.sin_addr
= *addr
;
1067 sa
.in
.sin_port
= htobe16(port
),
1071 mh
.msg_name
= &sa
.sa
;
1072 mh
.msg_namelen
= sizeof(sa
.in
);
1075 struct cmsghdr
*cmsg
;
1076 struct in_pktinfo
*pi
;
1080 mh
.msg_control
= &control
;
1081 mh
.msg_controllen
= CMSG_LEN(sizeof(struct in_pktinfo
));
1083 cmsg
= CMSG_FIRSTHDR(&mh
);
1084 cmsg
->cmsg_len
= mh
.msg_controllen
;
1085 cmsg
->cmsg_level
= IPPROTO_IP
;
1086 cmsg
->cmsg_type
= IP_PKTINFO
;
1088 pi
= (struct in_pktinfo
*) CMSG_DATA(cmsg
);
1089 pi
->ipi_ifindex
= ifindex
;
1092 return sendmsg_loop(fd
, &mh
, 0);
1095 static int manager_ipv6_send(Manager
*m
, int fd
, int ifindex
, const struct in6_addr
*addr
, uint16_t port
, DnsPacket
*p
) {
1096 union sockaddr_union sa
= {
1097 .in6
.sin6_family
= AF_INET6
,
1100 struct cmsghdr header
; /* For alignment */
1101 uint8_t buffer
[CMSG_SPACE(sizeof(struct in6_pktinfo
))];
1103 struct msghdr mh
= {};
1112 iov
.iov_base
= DNS_PACKET_DATA(p
);
1113 iov
.iov_len
= p
->size
;
1115 sa
.in6
.sin6_addr
= *addr
;
1116 sa
.in6
.sin6_port
= htobe16(port
),
1117 sa
.in6
.sin6_scope_id
= ifindex
;
1121 mh
.msg_name
= &sa
.sa
;
1122 mh
.msg_namelen
= sizeof(sa
.in6
);
1125 struct cmsghdr
*cmsg
;
1126 struct in6_pktinfo
*pi
;
1130 mh
.msg_control
= &control
;
1131 mh
.msg_controllen
= CMSG_LEN(sizeof(struct in6_pktinfo
));
1133 cmsg
= CMSG_FIRSTHDR(&mh
);
1134 cmsg
->cmsg_len
= mh
.msg_controllen
;
1135 cmsg
->cmsg_level
= IPPROTO_IPV6
;
1136 cmsg
->cmsg_type
= IPV6_PKTINFO
;
1138 pi
= (struct in6_pktinfo
*) CMSG_DATA(cmsg
);
1139 pi
->ipi6_ifindex
= ifindex
;
1142 return sendmsg_loop(fd
, &mh
, 0);
1145 int manager_send(Manager
*m
, int fd
, int ifindex
, int family
, const union in_addr_union
*addr
, uint16_t port
, DnsPacket
*p
) {
1152 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
));
1154 if (family
== AF_INET
)
1155 return manager_ipv4_send(m
, fd
, ifindex
, &addr
->in
, port
, p
);
1156 else if (family
== AF_INET6
)
1157 return manager_ipv6_send(m
, fd
, ifindex
, &addr
->in6
, port
, p
);
1159 return -EAFNOSUPPORT
;
1162 DnsServer
* manager_find_dns_server(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
1168 LIST_FOREACH(servers
, s
, m
->dns_servers
)
1169 if (s
->family
== family
&& in_addr_equal(family
, &s
->address
, in_addr
) > 0)
1172 LIST_FOREACH(servers
, s
, m
->fallback_dns_servers
)
1173 if (s
->family
== family
&& in_addr_equal(family
, &s
->address
, in_addr
) > 0)
1179 DnsServer
*manager_set_dns_server(Manager
*m
, DnsServer
*s
) {
1182 if (m
->current_dns_server
== s
)
1186 _cleanup_free_
char *ip
= NULL
;
1188 in_addr_to_string(s
->family
, &s
->address
, &ip
);
1189 log_info("Switching to system DNS server %s.", strna(ip
));
1192 m
->current_dns_server
= s
;
1194 if (m
->unicast_scope
)
1195 dns_cache_flush(&m
->unicast_scope
->cache
);
1200 DnsServer
*manager_get_dns_server(Manager
*m
) {
1204 /* Try to read updates resolv.conf */
1205 manager_read_resolv_conf(m
);
1207 if (!m
->current_dns_server
)
1208 manager_set_dns_server(m
, m
->dns_servers
);
1210 if (!m
->current_dns_server
) {
1214 /* No DNS servers configured, let's see if there are
1215 * any on any links. If not, we use the fallback
1218 HASHMAP_FOREACH(l
, m
->links
, i
)
1219 if (l
->dns_servers
) {
1225 manager_set_dns_server(m
, m
->fallback_dns_servers
);
1228 return m
->current_dns_server
;
1231 void manager_next_dns_server(Manager
*m
) {
1234 /* If there's currently no DNS server set, then the next
1235 * manager_get_dns_server() will find one */
1236 if (!m
->current_dns_server
)
1239 /* Change to the next one */
1240 if (m
->current_dns_server
->servers_next
) {
1241 manager_set_dns_server(m
, m
->current_dns_server
->servers_next
);
1245 /* If there was no next one, then start from the beginning of
1247 if (m
->current_dns_server
->type
== DNS_SERVER_FALLBACK
)
1248 manager_set_dns_server(m
, m
->fallback_dns_servers
);
1250 manager_set_dns_server(m
, m
->dns_servers
);
1253 uint32_t manager_find_mtu(Manager
*m
) {
1258 /* If we don't know on which link a DNS packet would be
1259 * delivered, let's find the largest MTU that works on all
1260 * interfaces we know of */
1262 HASHMAP_FOREACH(l
, m
->links
, i
) {
1266 if (mtu
<= 0 || l
->mtu
< mtu
)
1273 int manager_find_ifindex(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
1278 a
= manager_find_link_address(m
, family
, in_addr
);
1280 return a
->link
->ifindex
;
1285 void manager_refresh_rrs(Manager
*m
) {
1291 m
->llmnr_host_ipv4_key
= dns_resource_key_unref(m
->llmnr_host_ipv4_key
);
1292 m
->llmnr_host_ipv6_key
= dns_resource_key_unref(m
->llmnr_host_ipv6_key
);
1294 HASHMAP_FOREACH(l
, m
->links
, i
) {
1295 link_add_rrs(l
, true);
1296 link_add_rrs(l
, false);
1300 int manager_next_hostname(Manager
*m
) {
1308 p
= strchr(m
->llmnr_hostname
, 0);
1311 while (p
> m
->llmnr_hostname
) {
1312 if (!strchr("0123456789", p
[-1]))
1318 if (*p
== 0 || safe_atou64(p
, &u
) < 0 || u
<= 0)
1321 /* Add a random number to the old value. This way we can avoid
1322 * that two hosts pick the same hostname, win on IPv4 and lose
1323 * on IPv6 (or vice versa), and pick the same hostname
1324 * replacement hostname, ad infinitum. We still want the
1325 * numbers to go up monotonically, hence we just add a random
1328 random_bytes(&a
, sizeof(a
));
1331 if (asprintf(&h
, "%.*s%" PRIu64
, (int) (p
- m
->llmnr_hostname
), m
->llmnr_hostname
, u
) < 0)
1334 r
= dns_name_concat(h
, "local", &k
);
1340 log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m
->llmnr_hostname
, h
);
1342 free(m
->llmnr_hostname
);
1343 m
->llmnr_hostname
= h
;
1345 free(m
->mdns_hostname
);
1346 m
->mdns_hostname
= k
;
1348 manager_refresh_rrs(m
);
1353 LinkAddress
* manager_find_link_address(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
1359 HASHMAP_FOREACH(l
, m
->links
, i
) {
1362 a
= link_find_address(l
, family
, in_addr
);
1370 bool manager_our_packet(Manager
*m
, DnsPacket
*p
) {
1374 return !!manager_find_link_address(m
, p
->family
, &p
->sender
);
1377 DnsScope
* manager_find_scope(Manager
*m
, DnsPacket
*p
) {
1383 l
= hashmap_get(m
->links
, INT_TO_PTR(p
->ifindex
));
1387 if (p
->protocol
== DNS_PROTOCOL_LLMNR
) {
1388 if (p
->family
== AF_INET
)
1389 return l
->llmnr_ipv4_scope
;
1390 else if (p
->family
== AF_INET6
)
1391 return l
->llmnr_ipv6_scope
;
1397 void manager_verify_all(Manager
*m
) {
1402 LIST_FOREACH(scopes
, s
, m
->dns_scopes
)
1403 dns_zone_verify_all(&s
->zone
);
1406 int manager_is_own_hostname(Manager
*m
, const char *name
) {
1412 if (m
->llmnr_hostname
) {
1413 r
= dns_name_equal(name
, m
->llmnr_hostname
);
1418 if (m
->mdns_hostname
)
1419 return dns_name_equal(name
, m
->mdns_hostname
);
1424 static const char* const support_table
[_SUPPORT_MAX
] = {
1425 [SUPPORT_NO
] = "no",
1426 [SUPPORT_YES
] = "yes",
1427 [SUPPORT_RESOLVE
] = "resolve",
1429 DEFINE_STRING_TABLE_LOOKUP(support
, Support
);