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 <arpa/inet.h>
25 #include <sys/ioctl.h>
27 #include <netinet/in.h>
29 #include "rtnl-util.h"
30 #include "event-util.h"
31 #include "network-util.h"
32 #include "network-internal.h"
33 #include "conf-parser.h"
34 #include "socket-util.h"
38 #define SEND_TIMEOUT_USEC (200 * USEC_PER_MSEC)
40 static int manager_process_link(sd_rtnl
*rtnl
, sd_rtnl_message
*mm
, void *userdata
) {
41 Manager
*m
= userdata
;
50 r
= sd_rtnl_message_get_type(mm
, &type
);
54 r
= sd_rtnl_message_link_get_ifindex(mm
, &ifindex
);
58 l
= hashmap_get(m
->links
, INT_TO_PTR(ifindex
));
66 r
= link_new(m
, &l
, ifindex
);
71 r
= link_update_rtnl(l
, mm
);
76 log_debug("Found new link %i/%s", ifindex
, l
->name
);
83 log_debug("Removing link %i/%s", l
->ifindex
, l
->name
);
93 log_warning("Failed to process RTNL link message: %s", strerror(-r
));
97 static int manager_process_address(sd_rtnl
*rtnl
, sd_rtnl_message
*mm
, void *userdata
) {
98 Manager
*m
= userdata
;
99 union in_addr_union address
;
101 int r
, ifindex
, family
;
109 r
= sd_rtnl_message_get_type(mm
, &type
);
113 r
= sd_rtnl_message_addr_get_ifindex(mm
, &ifindex
);
117 l
= hashmap_get(m
->links
, INT_TO_PTR(ifindex
));
121 r
= sd_rtnl_message_addr_get_family(mm
, &family
);
128 r
= sd_rtnl_message_read_in_addr(mm
, IFA_LOCAL
, &address
.in
);
130 r
= sd_rtnl_message_read_in_addr(mm
, IFA_ADDRESS
, &address
.in
);
138 r
= sd_rtnl_message_read_in6_addr(mm
, IFA_LOCAL
, &address
.in6
);
140 r
= sd_rtnl_message_read_in6_addr(mm
, IFA_ADDRESS
, &address
.in6
);
151 a
= link_find_address(l
, family
, &address
);
158 r
= link_address_new(l
, &a
, family
, &address
);
163 r
= link_address_update_rtnl(a
, mm
);
171 link_address_free(a
);
178 log_warning("Failed to process RTNL address message: %s", strerror(-r
));
183 static int manager_rtnl_listen(Manager
*m
) {
184 _cleanup_rtnl_message_unref_ sd_rtnl_message
*req
= NULL
, *reply
= NULL
;
190 /* First, subscibe to interfaces coming and going */
191 r
= sd_rtnl_open(&m
->rtnl
, 3, RTNLGRP_LINK
, RTNLGRP_IPV4_IFADDR
, RTNLGRP_IPV6_IFADDR
);
195 r
= sd_rtnl_attach_event(m
->rtnl
, m
->event
, 0);
199 r
= sd_rtnl_add_match(m
->rtnl
, RTM_NEWLINK
, manager_process_link
, m
);
203 r
= sd_rtnl_add_match(m
->rtnl
, RTM_DELLINK
, manager_process_link
, m
);
207 r
= sd_rtnl_add_match(m
->rtnl
, RTM_NEWADDR
, manager_process_address
, m
);
211 r
= sd_rtnl_add_match(m
->rtnl
, RTM_DELADDR
, manager_process_address
, m
);
215 /* Then, enumerate all links */
216 r
= sd_rtnl_message_new_link(m
->rtnl
, &req
, RTM_GETLINK
, 0);
220 r
= sd_rtnl_message_request_dump(req
, true);
224 r
= sd_rtnl_call(m
->rtnl
, req
, 0, &reply
);
228 for (i
= reply
; i
; i
= sd_rtnl_message_next(i
)) {
229 r
= manager_process_link(m
->rtnl
, i
, m
);
234 req
= sd_rtnl_message_unref(req
);
235 reply
= sd_rtnl_message_unref(reply
);
237 /* Finally, enumerate all addresses, too */
238 r
= sd_rtnl_message_new_addr(m
->rtnl
, &req
, RTM_GETADDR
, 0, AF_UNSPEC
);
242 r
= sd_rtnl_message_request_dump(req
, true);
246 r
= sd_rtnl_call(m
->rtnl
, req
, 0, &reply
);
250 for (i
= reply
; i
; i
= sd_rtnl_message_next(i
)) {
251 r
= manager_process_address(m
->rtnl
, i
, m
);
259 static int on_network_event(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
260 Manager
*m
= userdata
;
267 sd_network_monitor_flush(m
->network_monitor
);
269 HASHMAP_FOREACH(l
, m
->links
, i
) {
270 r
= link_update_monitor(l
);
272 log_warning("Failed to update monitor information for %i: %s", l
->ifindex
, strerror(-r
));
275 r
= manager_write_resolv_conf(m
);
277 log_warning("Could not update resolv.conf: %s", strerror(-r
));
282 static int manager_network_monitor_listen(Manager
*m
) {
287 r
= sd_network_monitor_new(&m
->network_monitor
, NULL
);
291 fd
= sd_network_monitor_get_fd(m
->network_monitor
);
295 events
= sd_network_monitor_get_events(m
->network_monitor
);
299 r
= sd_event_add_io(m
->event
, &m
->network_event_source
, fd
, events
, &on_network_event
, m
);
306 static int parse_dns_server_string(Manager
*m
, const char *string
) {
314 FOREACH_WORD_QUOTED(word
, length
, string
, state
) {
315 char buffer
[length
+1];
317 union in_addr_union addr
;
319 memcpy(buffer
, word
, length
);
322 r
= in_addr_from_string_auto(buffer
, &family
, &addr
);
324 log_warning("Ignoring invalid DNS address '%s'", buffer
);
328 /* filter out duplicates */
329 if (manager_find_dns_server(m
, family
, &addr
))
332 r
= dns_server_new(m
, NULL
, NULL
, family
, &addr
);
340 int config_parse_dnsv(
342 const char *filename
,
345 unsigned section_line
,
352 Manager
*m
= userdata
;
360 /* Empty assignment means clear the list */
361 if (isempty(rvalue
)) {
362 while (m
->dns_servers
)
363 dns_server_free(m
->dns_servers
);
368 r
= parse_dns_server_string(m
, rvalue
);
370 log_error("Failed to parse DNS server string");
377 int manager_parse_config_file(Manager
*m
) {
380 return config_parse(NULL
, "/etc/systemd/resolved.conf", NULL
,
382 config_item_perf_lookup
, resolved_gperf_lookup
,
383 false, false, true, m
);
386 int manager_new(Manager
**ret
) {
387 _cleanup_(manager_freep
) Manager
*m
= NULL
;
392 m
= new0(Manager
, 1);
396 m
->dns_ipv4_fd
= m
->dns_ipv6_fd
= -1;
397 m
->llmnr_ipv4_udp_fd
= m
->llmnr_ipv6_udp_fd
= -1;
398 m
->llmnr_ipv4_tcp_fd
= m
->llmnr_ipv6_tcp_fd
= -1;
402 r
= parse_dns_server_string(m
, DNS_SERVERS
);
406 m
->hostname
= gethostname_malloc();
410 r
= sd_event_default(&m
->event
);
414 sd_event_add_signal(m
->event
, NULL
, SIGTERM
, NULL
, NULL
);
415 sd_event_add_signal(m
->event
, NULL
, SIGINT
, NULL
, NULL
);
417 sd_event_set_watchdog(m
->event
, true);
419 r
= dns_scope_new(m
, &m
->unicast_scope
, NULL
, DNS_PROTOCOL_DNS
, AF_UNSPEC
);
423 r
= manager_network_monitor_listen(m
);
427 r
= manager_rtnl_listen(m
);
431 r
= manager_connect_bus(m
);
435 r
= manager_llmnr_ipv4_udp_fd(m
);
438 r
= manager_llmnr_ipv6_udp_fd(m
);
441 r
= manager_llmnr_ipv4_tcp_fd(m
);
444 r
= manager_llmnr_ipv6_tcp_fd(m
);
454 Manager
*manager_free(Manager
*m
) {
460 while (m
->dns_queries
)
461 dns_query_free(m
->dns_queries
);
463 hashmap_free(m
->dns_query_transactions
);
465 while ((l
= hashmap_first(m
->links
)))
467 hashmap_free(m
->links
);
469 dns_scope_free(m
->unicast_scope
);
471 while (m
->dns_servers
)
472 dns_server_free(m
->dns_servers
);
474 sd_event_source_unref(m
->network_event_source
);
475 sd_network_monitor_unref(m
->network_monitor
);
477 sd_event_source_unref(m
->dns_ipv4_event_source
);
478 sd_event_source_unref(m
->dns_ipv6_event_source
);
479 safe_close(m
->dns_ipv4_fd
);
480 safe_close(m
->dns_ipv6_fd
);
482 sd_event_source_unref(m
->llmnr_ipv4_udp_event_source
);
483 sd_event_source_unref(m
->llmnr_ipv6_udp_event_source
);
484 safe_close(m
->llmnr_ipv4_udp_fd
);
485 safe_close(m
->llmnr_ipv6_udp_fd
);
487 sd_event_source_unref(m
->llmnr_ipv4_tcp_event_source
);
488 sd_event_source_unref(m
->llmnr_ipv6_tcp_event_source
);
489 safe_close(m
->llmnr_ipv4_tcp_fd
);
490 safe_close(m
->llmnr_ipv6_tcp_fd
);
492 sd_event_source_unref(m
->bus_retry_event_source
);
493 sd_bus_unref(m
->bus
);
495 sd_event_unref(m
->event
);
497 dns_resource_key_unref(m
->host_ipv4_key
);
498 dns_resource_key_unref(m
->host_ipv6_key
);
505 static void write_resolve_conf_server(DnsServer
*s
, FILE *f
, unsigned *count
) {
506 _cleanup_free_
char *t
= NULL
;
513 r
= in_addr_to_string(s
->family
, &s
->address
, &t
);
515 log_warning("Invalid DNS address. Ignoring.");
520 fputs("# Too many DNS servers configured, the following entries may be ignored\n", f
);
522 fprintf(f
, "nameserver %s\n", t
);
526 int manager_write_resolv_conf(Manager
*m
) {
527 const char *path
= "/run/systemd/resolve/resolv.conf";
528 _cleanup_free_
char *temp_path
= NULL
;
529 _cleanup_fclose_
FILE *f
= NULL
;
538 r
= fopen_temporary(path
, &f
, &temp_path
);
542 fchmod(fileno(f
), 0644);
544 fputs("# This file is managed by systemd-resolved(8). Do not edit.\n#\n"
545 "# Third party programs must not access this file directly, but\n"
546 "# only through the symlink at /etc/resolv.conf. To manage\n"
547 "# resolv.conf(5) in a different way, replace the symlink by a\n"
548 "# static file or a different symlink.\n\n", f
);
550 HASHMAP_FOREACH(l
, m
->links
, i
)
551 LIST_FOREACH(servers
, s
, l
->dns_servers
)
552 write_resolve_conf_server(s
, f
, &count
);
554 LIST_FOREACH(servers
, s
, m
->dns_servers
)
555 write_resolve_conf_server(s
, f
, &count
);
557 r
= fflush_and_check(f
);
561 if (rename(temp_path
, path
) < 0) {
574 int manager_recv(Manager
*m
, int fd
, DnsProtocol protocol
, DnsPacket
**ret
) {
575 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
577 struct cmsghdr header
; /* For alignment */
578 uint8_t buffer
[CMSG_SPACE(MAX(sizeof(struct in_pktinfo
), sizeof(struct in6_pktinfo
)))
579 + CMSG_SPACE(int) /* ttl/hoplimit */
580 + EXTRA_CMSG_SPACE
/* kernel appears to require extra buffer space */];
582 union sockaddr_union sa
;
583 struct msghdr mh
= {};
584 struct cmsghdr
*cmsg
;
593 r
= ioctl(fd
, FIONREAD
, &ms
);
599 r
= dns_packet_new(&p
, protocol
, ms
);
603 iov
.iov_base
= DNS_PACKET_DATA(p
);
604 iov
.iov_len
= p
->allocated
;
606 mh
.msg_name
= &sa
.sa
;
607 mh
.msg_namelen
= sizeof(sa
);
610 mh
.msg_control
= &control
;
611 mh
.msg_controllen
= sizeof(control
);
613 l
= recvmsg(fd
, &mh
, 0);
615 if (errno
== EAGAIN
|| errno
== EINTR
)
624 assert(!(mh
.msg_flags
& MSG_CTRUNC
));
625 assert(!(mh
.msg_flags
& MSG_TRUNC
));
627 p
->size
= (size_t) l
;
629 p
->family
= sa
.sa
.sa_family
;
630 p
->ipproto
= IPPROTO_UDP
;
631 if (p
->family
== AF_INET
) {
632 p
->sender
.in
= sa
.in
.sin_addr
;
633 p
->sender_port
= be16toh(sa
.in
.sin_port
);
634 } else if (p
->family
== AF_INET6
) {
635 p
->sender
.in6
= sa
.in6
.sin6_addr
;
636 p
->sender_port
= be16toh(sa
.in6
.sin6_port
);
637 p
->ifindex
= sa
.in6
.sin6_scope_id
;
639 return -EAFNOSUPPORT
;
641 for (cmsg
= CMSG_FIRSTHDR(&mh
); cmsg
; cmsg
= CMSG_NXTHDR(&mh
, cmsg
)) {
643 if (cmsg
->cmsg_level
== IPPROTO_IPV6
) {
644 assert(p
->family
== AF_INET6
);
646 switch (cmsg
->cmsg_type
) {
649 struct in6_pktinfo
*i
= (struct in6_pktinfo
*) CMSG_DATA(cmsg
);
652 p
->ifindex
= i
->ipi6_ifindex
;
654 p
->destination
.in6
= i
->ipi6_addr
;
659 p
->ttl
= *(int *) CMSG_DATA(cmsg
);
663 } else if (cmsg
->cmsg_level
== IPPROTO_IP
) {
664 assert(p
->family
== AF_INET
);
666 switch (cmsg
->cmsg_type
) {
669 struct in_pktinfo
*i
= (struct in_pktinfo
*) CMSG_DATA(cmsg
);
672 p
->ifindex
= i
->ipi_ifindex
;
674 p
->destination
.in
= i
->ipi_addr
;
679 p
->ttl
= *(int *) CMSG_DATA(cmsg
);
685 /* The Linux kernel sets the interface index to the loopback
686 * device if the packet came from the local host since it
687 * avoids the routing table in such a case. Let's unset the
688 * interface index in such a case. */
689 if (p
->ifindex
> 0 && manager_ifindex_is_loopback(m
, p
->ifindex
) != 0)
692 /* If we don't know the interface index still, we look for the
693 * first local interface with a matching address. Yuck! */
695 p
->ifindex
= manager_find_ifindex(m
, p
->family
, &p
->destination
);
703 static int on_dns_packet(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
704 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
705 DnsQueryTransaction
*t
= NULL
;
706 Manager
*m
= userdata
;
709 r
= manager_recv(m
, fd
, DNS_PROTOCOL_DNS
, &p
);
713 if (dns_packet_validate_reply(p
) > 0) {
714 t
= hashmap_get(m
->dns_query_transactions
, UINT_TO_PTR(DNS_PACKET_ID(p
)));
718 dns_query_transaction_process_reply(t
, p
);
721 log_debug("Invalid DNS packet.");
726 int manager_dns_ipv4_fd(Manager
*m
) {
732 if (m
->dns_ipv4_fd
>= 0)
733 return m
->dns_ipv4_fd
;
735 m
->dns_ipv4_fd
= socket(AF_INET
, SOCK_DGRAM
|SOCK_CLOEXEC
|SOCK_NONBLOCK
, 0);
736 if (m
->dns_ipv4_fd
< 0)
739 r
= setsockopt(m
->dns_ipv4_fd
, IPPROTO_IP
, IP_PKTINFO
, &one
, sizeof(one
));
745 r
= sd_event_add_io(m
->event
, &m
->dns_ipv4_event_source
, m
->dns_ipv4_fd
, EPOLLIN
, on_dns_packet
, m
);
749 return m
->dns_ipv4_fd
;
752 m
->dns_ipv4_fd
= safe_close(m
->dns_ipv4_fd
);
756 int manager_dns_ipv6_fd(Manager
*m
) {
762 if (m
->dns_ipv6_fd
>= 0)
763 return m
->dns_ipv6_fd
;
765 m
->dns_ipv6_fd
= socket(AF_INET6
, SOCK_DGRAM
|SOCK_CLOEXEC
|SOCK_NONBLOCK
, 0);
766 if (m
->dns_ipv6_fd
< 0)
769 r
= setsockopt(m
->dns_ipv6_fd
, IPPROTO_IPV6
, IPV6_RECVPKTINFO
, &one
, sizeof(one
));
775 r
= sd_event_add_io(m
->event
, &m
->dns_ipv6_event_source
, m
->dns_ipv6_fd
, EPOLLIN
, on_dns_packet
, m
);
779 return m
->dns_ipv6_fd
;
782 m
->dns_ipv6_fd
= safe_close(m
->dns_ipv6_fd
);
786 static int sendmsg_loop(int fd
, struct msghdr
*mh
, int flags
) {
793 if (sendmsg(fd
, mh
, flags
) >= 0)
802 r
= fd_wait_for_event(fd
, POLLOUT
, SEND_TIMEOUT_USEC
);
810 static int manager_ipv4_send(Manager
*m
, int fd
, int ifindex
, const struct in_addr
*addr
, uint16_t port
, DnsPacket
*p
) {
811 union sockaddr_union sa
= {
812 .in
.sin_family
= AF_INET
,
815 struct cmsghdr header
; /* For alignment */
816 uint8_t buffer
[CMSG_SPACE(sizeof(struct in_pktinfo
))];
818 struct msghdr mh
= {};
827 iov
.iov_base
= DNS_PACKET_DATA(p
);
828 iov
.iov_len
= p
->size
;
830 sa
.in
.sin_addr
= *addr
;
831 sa
.in
.sin_port
= htobe16(port
),
835 mh
.msg_name
= &sa
.sa
;
836 mh
.msg_namelen
= sizeof(sa
.in
);
839 struct cmsghdr
*cmsg
;
840 struct in_pktinfo
*pi
;
844 mh
.msg_control
= &control
;
845 mh
.msg_controllen
= CMSG_LEN(sizeof(struct in_pktinfo
));
847 cmsg
= CMSG_FIRSTHDR(&mh
);
848 cmsg
->cmsg_len
= mh
.msg_controllen
;
849 cmsg
->cmsg_level
= IPPROTO_IP
;
850 cmsg
->cmsg_type
= IP_PKTINFO
;
852 pi
= (struct in_pktinfo
*) CMSG_DATA(cmsg
);
853 pi
->ipi_ifindex
= ifindex
;
856 return sendmsg_loop(fd
, &mh
, 0);
859 static int manager_ipv6_send(Manager
*m
, int fd
, int ifindex
, const struct in6_addr
*addr
, uint16_t port
, DnsPacket
*p
) {
860 union sockaddr_union sa
= {
861 .in6
.sin6_family
= AF_INET6
,
864 struct cmsghdr header
; /* For alignment */
865 uint8_t buffer
[CMSG_SPACE(sizeof(struct in6_pktinfo
))];
867 struct msghdr mh
= {};
876 iov
.iov_base
= DNS_PACKET_DATA(p
);
877 iov
.iov_len
= p
->size
;
879 sa
.in6
.sin6_addr
= *addr
;
880 sa
.in6
.sin6_port
= htobe16(port
),
881 sa
.in6
.sin6_scope_id
= ifindex
;
885 mh
.msg_name
= &sa
.sa
;
886 mh
.msg_namelen
= sizeof(sa
.in6
);
889 struct cmsghdr
*cmsg
;
890 struct in6_pktinfo
*pi
;
894 mh
.msg_control
= &control
;
895 mh
.msg_controllen
= CMSG_LEN(sizeof(struct in6_pktinfo
));
897 cmsg
= CMSG_FIRSTHDR(&mh
);
898 cmsg
->cmsg_len
= mh
.msg_controllen
;
899 cmsg
->cmsg_level
= IPPROTO_IPV6
;
900 cmsg
->cmsg_type
= IPV6_PKTINFO
;
902 pi
= (struct in6_pktinfo
*) CMSG_DATA(cmsg
);
903 pi
->ipi6_ifindex
= ifindex
;
906 return sendmsg_loop(fd
, &mh
, 0);
909 int manager_send(Manager
*m
, int fd
, int ifindex
, int family
, const union in_addr_union
*addr
, uint16_t port
, DnsPacket
*p
) {
916 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
));
918 if (family
== AF_INET
)
919 return manager_ipv4_send(m
, fd
, ifindex
, &addr
->in
, port
, p
);
920 else if (family
== AF_INET6
)
921 return manager_ipv6_send(m
, fd
, ifindex
, &addr
->in6
, port
, p
);
923 return -EAFNOSUPPORT
;
926 DnsServer
* manager_find_dns_server(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
932 LIST_FOREACH(servers
, s
, m
->dns_servers
) {
934 if (s
->family
== family
&&
935 in_addr_equal(family
, &s
->address
, in_addr
))
942 DnsServer
*manager_get_dns_server(Manager
*m
) {
945 if (!m
->current_dns_server
)
946 m
->current_dns_server
= m
->dns_servers
;
948 return m
->current_dns_server
;
951 void manager_next_dns_server(Manager
*m
) {
954 if (!m
->current_dns_server
) {
955 m
->current_dns_server
= m
->dns_servers
;
959 if (!m
->current_dns_server
)
962 if (m
->current_dns_server
->servers_next
) {
963 m
->current_dns_server
= m
->current_dns_server
->servers_next
;
967 m
->current_dns_server
= m
->dns_servers
;
970 uint32_t manager_find_mtu(Manager
*m
) {
975 /* If we don't know on which link a DNS packet would be
976 * delivered, let's find the largest MTU that works on all
977 * interfaces we know of */
979 HASHMAP_FOREACH(l
, m
->links
, i
) {
983 if (mtu
<= 0 || l
->mtu
< mtu
)
990 static int on_llmnr_packet(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
991 _cleanup_(dns_packet_unrefp
) DnsPacket
*p
= NULL
;
992 DnsQueryTransaction
*t
= NULL
;
993 Manager
*m
= userdata
;
996 r
= manager_recv(m
, fd
, DNS_PROTOCOL_LLMNR
, &p
);
1000 if (dns_packet_validate_reply(p
) > 0) {
1001 log_debug("Got reply packet for id %u", DNS_PACKET_ID(p
));
1003 t
= hashmap_get(m
->dns_query_transactions
, UINT_TO_PTR(DNS_PACKET_ID(p
)));
1007 dns_query_transaction_process_reply(t
, p
);
1009 } else if (dns_packet_validate_query(p
) > 0) {
1012 l
= hashmap_get(m
->links
, INT_TO_PTR(p
->ifindex
));
1014 DnsScope
*scope
= NULL
;
1016 if (p
->family
== AF_INET
)
1017 scope
= l
->llmnr_ipv4_scope
;
1018 else if (p
->family
== AF_INET6
)
1019 scope
= l
->llmnr_ipv6_scope
;
1022 dns_scope_process_query(scope
, NULL
, p
);
1025 log_debug("Invalid LLMNR packet.");
1030 int manager_llmnr_ipv4_udp_fd(Manager
*m
) {
1031 union sockaddr_union sa
= {
1032 .in
.sin_family
= AF_INET
,
1033 .in
.sin_port
= htobe16(5355),
1035 static const int one
= 1, pmtu
= IP_PMTUDISC_DONT
, ttl
= 255;
1040 if (m
->llmnr_ipv4_udp_fd
>= 0)
1041 return m
->llmnr_ipv4_udp_fd
;
1043 m
->llmnr_ipv4_udp_fd
= socket(AF_INET
, SOCK_DGRAM
|SOCK_CLOEXEC
|SOCK_NONBLOCK
, 0);
1044 if (m
->llmnr_ipv4_udp_fd
< 0)
1047 /* RFC 4795, section 2.5 recommends setting the TTL of UDP packets to 255. */
1048 r
= setsockopt(m
->llmnr_ipv4_udp_fd
, IPPROTO_IP
, IP_TTL
, &ttl
, sizeof(ttl
));
1054 r
= setsockopt(m
->llmnr_ipv4_udp_fd
, IPPROTO_IP
, IP_MULTICAST_TTL
, &ttl
, sizeof(ttl
));
1060 r
= setsockopt(m
->llmnr_ipv4_udp_fd
, IPPROTO_IP
, IP_MULTICAST_LOOP
, &one
, sizeof(one
));
1066 r
= setsockopt(m
->llmnr_ipv4_udp_fd
, SOL_SOCKET
, SO_REUSEADDR
, &one
, sizeof(one
));
1072 r
= setsockopt(m
->llmnr_ipv4_udp_fd
, IPPROTO_IP
, IP_PKTINFO
, &one
, sizeof(one
));
1078 r
= setsockopt(m
->llmnr_ipv4_udp_fd
, IPPROTO_IP
, IP_RECVTTL
, &one
, sizeof(one
));
1084 /* Disable Don't-Fragment bit in the IP header */
1085 r
= setsockopt(m
->llmnr_ipv4_udp_fd
, IPPROTO_IP
, IP_MTU_DISCOVER
, &pmtu
, sizeof(pmtu
));
1091 r
= bind(m
->llmnr_ipv4_udp_fd
, &sa
.sa
, sizeof(sa
.in
));
1097 r
= sd_event_add_io(m
->event
, &m
->llmnr_ipv4_udp_event_source
, m
->llmnr_ipv4_udp_fd
, EPOLLIN
, on_llmnr_packet
, m
);
1101 return m
->llmnr_ipv4_udp_fd
;
1104 m
->llmnr_ipv4_udp_fd
= safe_close(m
->llmnr_ipv4_udp_fd
);
1108 int manager_llmnr_ipv6_udp_fd(Manager
*m
) {
1109 union sockaddr_union sa
= {
1110 .in6
.sin6_family
= AF_INET6
,
1111 .in6
.sin6_port
= htobe16(5355),
1113 static const int one
= 1, ttl
= 255;
1118 if (m
->llmnr_ipv6_udp_fd
>= 0)
1119 return m
->llmnr_ipv6_udp_fd
;
1121 m
->llmnr_ipv6_udp_fd
= socket(AF_INET6
, SOCK_DGRAM
|SOCK_CLOEXEC
|SOCK_NONBLOCK
, 0);
1122 if (m
->llmnr_ipv6_udp_fd
< 0)
1125 r
= setsockopt(m
->llmnr_ipv6_udp_fd
, IPPROTO_IPV6
, IPV6_UNICAST_HOPS
, &ttl
, sizeof(ttl
));
1131 /* RFC 4795, section 2.5 recommends setting the TTL of UDP packets to 255. */
1132 r
= setsockopt(m
->llmnr_ipv6_udp_fd
, IPPROTO_IPV6
, IPV6_MULTICAST_HOPS
, &ttl
, sizeof(ttl
));
1138 r
= setsockopt(m
->llmnr_ipv6_udp_fd
, IPPROTO_IPV6
, IPV6_MULTICAST_LOOP
, &one
, sizeof(one
));
1144 r
= setsockopt(m
->llmnr_ipv6_udp_fd
, IPPROTO_IPV6
, IPV6_V6ONLY
, &one
, sizeof(one
));
1150 r
= setsockopt(m
->llmnr_ipv6_udp_fd
, SOL_SOCKET
, SO_REUSEADDR
, &one
, sizeof(one
));
1156 r
= setsockopt(m
->llmnr_ipv6_udp_fd
, IPPROTO_IPV6
, IPV6_RECVPKTINFO
, &one
, sizeof(one
));
1162 r
= setsockopt(m
->llmnr_ipv6_udp_fd
, IPPROTO_IPV6
, IPV6_RECVHOPLIMIT
, &one
, sizeof(one
));
1168 r
= bind(m
->llmnr_ipv6_udp_fd
, &sa
.sa
, sizeof(sa
.in6
));
1174 r
= sd_event_add_io(m
->event
, &m
->llmnr_ipv6_udp_event_source
, m
->llmnr_ipv6_udp_fd
, EPOLLIN
, on_llmnr_packet
, m
);
1180 return m
->llmnr_ipv6_udp_fd
;
1183 m
->llmnr_ipv6_udp_fd
= safe_close(m
->llmnr_ipv6_udp_fd
);
1187 static int on_llmnr_stream_packet(DnsStream
*s
) {
1190 if (dns_packet_validate_query(s
->read_packet
) > 0) {
1193 l
= hashmap_get(s
->manager
->links
, INT_TO_PTR(s
->read_packet
->ifindex
));
1195 DnsScope
*scope
= NULL
;
1197 if (s
->read_packet
->family
== AF_INET
)
1198 scope
= l
->llmnr_ipv4_scope
;
1199 else if (s
->read_packet
->family
== AF_INET6
)
1200 scope
= l
->llmnr_ipv6_scope
;
1203 dns_scope_process_query(scope
, s
, s
->read_packet
);
1205 /* If no reply packet was set, we free the stream */
1206 if (s
->write_packet
)
1216 static int on_llmnr_stream(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
1218 Manager
*m
= userdata
;
1221 cfd
= accept4(fd
, NULL
, NULL
, SOCK_NONBLOCK
|SOCK_CLOEXEC
);
1223 if (errno
== EAGAIN
|| errno
== EINTR
)
1229 r
= dns_stream_new(m
, &stream
, DNS_PROTOCOL_LLMNR
, cfd
);
1235 stream
->on_packet
= on_llmnr_stream_packet
;
1239 int manager_llmnr_ipv4_tcp_fd(Manager
*m
) {
1240 union sockaddr_union sa
= {
1241 .in
.sin_family
= AF_INET
,
1242 .in
.sin_port
= htobe16(5355),
1244 static const int one
= 1, pmtu
= IP_PMTUDISC_DONT
;
1249 if (m
->llmnr_ipv4_tcp_fd
>= 0)
1250 return m
->llmnr_ipv4_tcp_fd
;
1252 m
->llmnr_ipv4_tcp_fd
= socket(AF_INET
, SOCK_STREAM
|SOCK_CLOEXEC
|SOCK_NONBLOCK
, 0);
1253 if (m
->llmnr_ipv4_tcp_fd
< 0)
1256 /* RFC 4795, section 2.5. requires setting the TTL of TCP streams to 1 */
1257 r
= setsockopt(m
->llmnr_ipv4_tcp_fd
, IPPROTO_IP
, IP_TTL
, &one
, sizeof(one
));
1263 r
= setsockopt(m
->llmnr_ipv4_tcp_fd
, SOL_SOCKET
, SO_REUSEADDR
, &one
, sizeof(one
));
1269 r
= setsockopt(m
->llmnr_ipv4_tcp_fd
, IPPROTO_IP
, IP_PKTINFO
, &one
, sizeof(one
));
1275 r
= setsockopt(m
->llmnr_ipv4_tcp_fd
, IPPROTO_IP
, IP_RECVTTL
, &one
, sizeof(one
));
1281 /* Disable Don't-Fragment bit in the IP header */
1282 r
= setsockopt(m
->llmnr_ipv4_tcp_fd
, IPPROTO_IP
, IP_MTU_DISCOVER
, &pmtu
, sizeof(pmtu
));
1288 r
= bind(m
->llmnr_ipv4_tcp_fd
, &sa
.sa
, sizeof(sa
.in
));
1294 r
= listen(m
->llmnr_ipv4_tcp_fd
, SOMAXCONN
);
1300 r
= sd_event_add_io(m
->event
, &m
->llmnr_ipv4_tcp_event_source
, m
->llmnr_ipv4_tcp_fd
, EPOLLIN
, on_llmnr_stream
, m
);
1304 return m
->llmnr_ipv4_tcp_fd
;
1307 m
->llmnr_ipv4_tcp_fd
= safe_close(m
->llmnr_ipv4_tcp_fd
);
1311 int manager_llmnr_ipv6_tcp_fd(Manager
*m
) {
1312 union sockaddr_union sa
= {
1313 .in6
.sin6_family
= AF_INET6
,
1314 .in6
.sin6_port
= htobe16(5355),
1316 static const int one
= 1;
1321 if (m
->llmnr_ipv6_tcp_fd
>= 0)
1322 return m
->llmnr_ipv6_tcp_fd
;
1324 m
->llmnr_ipv6_tcp_fd
= socket(AF_INET6
, SOCK_STREAM
|SOCK_CLOEXEC
|SOCK_NONBLOCK
, 0);
1325 if (m
->llmnr_ipv6_tcp_fd
< 0)
1328 /* RFC 4795, section 2.5. requires setting the TTL of TCP streams to 1 */
1329 r
= setsockopt(m
->llmnr_ipv6_tcp_fd
, IPPROTO_IPV6
, IPV6_UNICAST_HOPS
, &one
, sizeof(one
));
1335 r
= setsockopt(m
->llmnr_ipv6_tcp_fd
, IPPROTO_IPV6
, IPV6_V6ONLY
, &one
, sizeof(one
));
1341 r
= setsockopt(m
->llmnr_ipv6_tcp_fd
, SOL_SOCKET
, SO_REUSEADDR
, &one
, sizeof(one
));
1347 r
= setsockopt(m
->llmnr_ipv6_tcp_fd
, IPPROTO_IPV6
, IPV6_RECVPKTINFO
, &one
, sizeof(one
));
1353 r
= setsockopt(m
->llmnr_ipv6_tcp_fd
, IPPROTO_IPV6
, IPV6_RECVHOPLIMIT
, &one
, sizeof(one
));
1359 r
= bind(m
->llmnr_ipv6_tcp_fd
, &sa
.sa
, sizeof(sa
.in6
));
1365 r
= listen(m
->llmnr_ipv6_tcp_fd
, SOMAXCONN
);
1371 r
= sd_event_add_io(m
->event
, &m
->llmnr_ipv6_tcp_event_source
, m
->llmnr_ipv6_tcp_fd
, EPOLLIN
, on_llmnr_stream
, m
);
1377 return m
->llmnr_ipv6_tcp_fd
;
1380 m
->llmnr_ipv6_tcp_fd
= safe_close(m
->llmnr_ipv6_tcp_fd
);
1384 int manager_ifindex_is_loopback(Manager
*m
, int ifindex
) {
1391 l
= hashmap_get(m
->links
, INT_TO_PTR(ifindex
));
1392 if (l
->flags
& IFF_LOOPBACK
)
1398 int manager_find_ifindex(Manager
*m
, int family
, const union in_addr_union
*in_addr
) {
1404 HASHMAP_FOREACH(l
, m
->links
, i
)
1405 if (link_find_address(l
, family
, in_addr
))