]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-manager.c
Merge pull request #2137 from fbuihuu/fstab-gen-fix-device-timeout
[thirdparty/systemd.git] / src / resolve / resolved-manager.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2014 Tom Gundersen <teg@jklm.no>
7
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.
12
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.
17
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/>.
20 ***/
21
22 #include <netinet/in.h>
23 #include <poll.h>
24 #include <sys/ioctl.h>
25
26 #include "af-list.h"
27 #include "alloc-util.h"
28 #include "dns-domain.h"
29 #include "fd-util.h"
30 #include "fileio-label.h"
31 #include "hostname-util.h"
32 #include "io-util.h"
33 #include "netlink-util.h"
34 #include "network-internal.h"
35 #include "ordered-set.h"
36 #include "parse-util.h"
37 #include "random-util.h"
38 #include "resolved-bus.h"
39 #include "resolved-conf.h"
40 #include "resolved-llmnr.h"
41 #include "resolved-manager.h"
42 #include "resolved-resolv-conf.h"
43 #include "resolved-mdns.h"
44 #include "socket-util.h"
45 #include "string-table.h"
46 #include "string-util.h"
47 #include "utf8.h"
48
49 #define SEND_TIMEOUT_USEC (200 * USEC_PER_MSEC)
50
51 static int manager_process_link(sd_netlink *rtnl, sd_netlink_message *mm, void *userdata) {
52 Manager *m = userdata;
53 uint16_t type;
54 Link *l;
55 int ifindex, r;
56
57 assert(rtnl);
58 assert(m);
59 assert(mm);
60
61 r = sd_netlink_message_get_type(mm, &type);
62 if (r < 0)
63 goto fail;
64
65 r = sd_rtnl_message_link_get_ifindex(mm, &ifindex);
66 if (r < 0)
67 goto fail;
68
69 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
70
71 switch (type) {
72
73 case RTM_NEWLINK:{
74 bool is_new = !l;
75
76 if (!l) {
77 r = link_new(m, &l, ifindex);
78 if (r < 0)
79 goto fail;
80 }
81
82 r = link_update_rtnl(l, mm);
83 if (r < 0)
84 goto fail;
85
86 r = link_update_monitor(l);
87 if (r < 0)
88 goto fail;
89
90 if (is_new)
91 log_debug("Found new link %i/%s", ifindex, l->name);
92
93 break;
94 }
95
96 case RTM_DELLINK:
97 if (l) {
98 log_debug("Removing link %i/%s", l->ifindex, l->name);
99 link_free(l);
100 }
101
102 break;
103 }
104
105 return 0;
106
107 fail:
108 log_warning_errno(r, "Failed to process RTNL link message: %m");
109 return 0;
110 }
111
112 static int manager_process_address(sd_netlink *rtnl, sd_netlink_message *mm, void *userdata) {
113 Manager *m = userdata;
114 union in_addr_union address;
115 uint16_t type;
116 int r, ifindex, family;
117 LinkAddress *a;
118 Link *l;
119
120 assert(rtnl);
121 assert(mm);
122 assert(m);
123
124 r = sd_netlink_message_get_type(mm, &type);
125 if (r < 0)
126 goto fail;
127
128 r = sd_rtnl_message_addr_get_ifindex(mm, &ifindex);
129 if (r < 0)
130 goto fail;
131
132 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
133 if (!l)
134 return 0;
135
136 r = sd_rtnl_message_addr_get_family(mm, &family);
137 if (r < 0)
138 goto fail;
139
140 switch (family) {
141
142 case AF_INET:
143 r = sd_netlink_message_read_in_addr(mm, IFA_LOCAL, &address.in);
144 if (r < 0) {
145 r = sd_netlink_message_read_in_addr(mm, IFA_ADDRESS, &address.in);
146 if (r < 0)
147 goto fail;
148 }
149
150 break;
151
152 case AF_INET6:
153 r = sd_netlink_message_read_in6_addr(mm, IFA_LOCAL, &address.in6);
154 if (r < 0) {
155 r = sd_netlink_message_read_in6_addr(mm, IFA_ADDRESS, &address.in6);
156 if (r < 0)
157 goto fail;
158 }
159
160 break;
161
162 default:
163 return 0;
164 }
165
166 a = link_find_address(l, family, &address);
167
168 switch (type) {
169
170 case RTM_NEWADDR:
171
172 if (!a) {
173 r = link_address_new(l, &a, family, &address);
174 if (r < 0)
175 return r;
176 }
177
178 r = link_address_update_rtnl(a, mm);
179 if (r < 0)
180 return r;
181
182 break;
183
184 case RTM_DELADDR:
185 link_address_free(a);
186 break;
187 }
188
189 return 0;
190
191 fail:
192 log_warning_errno(r, "Failed to process RTNL address message: %m");
193 return 0;
194 }
195
196 static int manager_rtnl_listen(Manager *m) {
197 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
198 sd_netlink_message *i;
199 int r;
200
201 assert(m);
202
203 /* First, subscribe to interfaces coming and going */
204 r = sd_netlink_open(&m->rtnl);
205 if (r < 0)
206 return r;
207
208 r = sd_netlink_attach_event(m->rtnl, m->event, 0);
209 if (r < 0)
210 return r;
211
212 r = sd_netlink_add_match(m->rtnl, RTM_NEWLINK, manager_process_link, m);
213 if (r < 0)
214 return r;
215
216 r = sd_netlink_add_match(m->rtnl, RTM_DELLINK, manager_process_link, m);
217 if (r < 0)
218 return r;
219
220 r = sd_netlink_add_match(m->rtnl, RTM_NEWADDR, manager_process_address, m);
221 if (r < 0)
222 return r;
223
224 r = sd_netlink_add_match(m->rtnl, RTM_DELADDR, manager_process_address, m);
225 if (r < 0)
226 return r;
227
228 /* Then, enumerate all links */
229 r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
230 if (r < 0)
231 return r;
232
233 r = sd_netlink_message_request_dump(req, true);
234 if (r < 0)
235 return r;
236
237 r = sd_netlink_call(m->rtnl, req, 0, &reply);
238 if (r < 0)
239 return r;
240
241 for (i = reply; i; i = sd_netlink_message_next(i)) {
242 r = manager_process_link(m->rtnl, i, m);
243 if (r < 0)
244 return r;
245 }
246
247 req = sd_netlink_message_unref(req);
248 reply = sd_netlink_message_unref(reply);
249
250 /* Finally, enumerate all addresses, too */
251 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, AF_UNSPEC);
252 if (r < 0)
253 return r;
254
255 r = sd_netlink_message_request_dump(req, true);
256 if (r < 0)
257 return r;
258
259 r = sd_netlink_call(m->rtnl, req, 0, &reply);
260 if (r < 0)
261 return r;
262
263 for (i = reply; i; i = sd_netlink_message_next(i)) {
264 r = manager_process_address(m->rtnl, i, m);
265 if (r < 0)
266 return r;
267 }
268
269 return r;
270 }
271
272 static int on_network_event(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
273 Manager *m = userdata;
274 Iterator i;
275 Link *l;
276 int r;
277
278 assert(m);
279
280 sd_network_monitor_flush(m->network_monitor);
281
282 HASHMAP_FOREACH(l, m->links, i) {
283 r = link_update_monitor(l);
284 if (r < 0)
285 log_warning_errno(r, "Failed to update monitor information for %i: %m", l->ifindex);
286 }
287
288 r = manager_write_resolv_conf(m);
289 if (r < 0)
290 log_warning_errno(r, "Could not update resolv.conf: %m");
291
292 return 0;
293 }
294
295 static int manager_network_monitor_listen(Manager *m) {
296 int r, fd, events;
297
298 assert(m);
299
300 r = sd_network_monitor_new(&m->network_monitor, NULL);
301 if (r < 0)
302 return r;
303
304 fd = sd_network_monitor_get_fd(m->network_monitor);
305 if (fd < 0)
306 return fd;
307
308 events = sd_network_monitor_get_events(m->network_monitor);
309 if (events < 0)
310 return events;
311
312 r = sd_event_add_io(m->event, &m->network_event_source, fd, events, &on_network_event, m);
313 if (r < 0)
314 return r;
315
316 return 0;
317 }
318
319 static int determine_hostname(char **llmnr_hostname, char **mdns_hostname) {
320 _cleanup_free_ char *h = NULL, *n = NULL;
321 char label[DNS_LABEL_MAX];
322 const char *p;
323 int r, k;
324
325 assert(llmnr_hostname);
326 assert(mdns_hostname);
327
328 /* Extract and normalize the first label of the locally
329 * configured hostname, and check it's not "localhost". */
330
331 h = gethostname_malloc();
332 if (!h)
333 return log_oom();
334
335 p = h;
336 r = dns_label_unescape(&p, label, sizeof(label));
337 if (r < 0)
338 return log_error_errno(r, "Failed to unescape host name: %m");
339 if (r == 0) {
340 log_error("Couldn't find a single label in hosntame.");
341 return -EINVAL;
342 }
343
344 k = dns_label_undo_idna(label, r, label, sizeof(label));
345 if (k < 0)
346 return log_error_errno(k, "Failed to undo IDNA: %m");
347 if (k > 0)
348 r = k;
349
350 if (!utf8_is_valid(label)) {
351 log_error("System hostname is not UTF-8 clean.");
352 return -EINVAL;
353 }
354
355 r = dns_label_escape_new(label, r, &n);
356 if (r < 0)
357 return log_error_errno(r, "Failed to escape host name: %m");
358
359 if (is_localhost(n)) {
360 log_debug("System hostname is 'localhost', ignoring.");
361 return -EINVAL;
362 }
363
364 r = dns_name_concat(n, "local", mdns_hostname);
365 if (r < 0)
366 return log_error_errno(r, "Failed to determine mDNS hostname: %m");
367
368 *llmnr_hostname = n;
369 n = NULL;
370
371 return 0;
372 }
373
374 static int on_hostname_change(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
375 _cleanup_free_ char *llmnr_hostname = NULL, *mdns_hostname = NULL;
376 Manager *m = userdata;
377 int r;
378
379 assert(m);
380
381 r = determine_hostname(&llmnr_hostname, &mdns_hostname);
382 if (r < 0)
383 return 0; /* ignore invalid hostnames */
384
385 if (streq(llmnr_hostname, m->llmnr_hostname) && streq(mdns_hostname, m->mdns_hostname))
386 return 0;
387
388 log_info("System hostname changed to '%s'.", llmnr_hostname);
389
390 free(m->llmnr_hostname);
391 free(m->mdns_hostname);
392
393 m->llmnr_hostname = llmnr_hostname;
394 m->mdns_hostname = mdns_hostname;
395
396 llmnr_hostname = mdns_hostname = NULL;
397
398 manager_refresh_rrs(m);
399
400 return 0;
401 }
402
403 static int manager_watch_hostname(Manager *m) {
404 int r;
405
406 assert(m);
407
408 m->hostname_fd = open("/proc/sys/kernel/hostname", O_RDONLY|O_CLOEXEC|O_NDELAY|O_NOCTTY);
409 if (m->hostname_fd < 0) {
410 log_warning_errno(errno, "Failed to watch hostname: %m");
411 return 0;
412 }
413
414 r = sd_event_add_io(m->event, &m->hostname_event_source, m->hostname_fd, 0, on_hostname_change, m);
415 if (r < 0) {
416 if (r == -EPERM)
417 /* kernels prior to 3.2 don't support polling this file. Ignore the failure. */
418 m->hostname_fd = safe_close(m->hostname_fd);
419 else
420 return log_error_errno(r, "Failed to add hostname event source: %m");
421 }
422
423 r = determine_hostname(&m->llmnr_hostname, &m->mdns_hostname);
424 if (r < 0) {
425 log_info("Defaulting to hostname 'linux'.");
426 m->llmnr_hostname = strdup("linux");
427 if (!m->llmnr_hostname)
428 return log_oom();
429
430 m->mdns_hostname = strdup("linux.local");
431 if (!m->mdns_hostname)
432 return log_oom();
433 } else
434 log_info("Using system hostname '%s'.", m->llmnr_hostname);
435
436 return 0;
437 }
438
439 static int manager_sigusr1(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
440 _cleanup_free_ char *buffer = NULL;
441 _cleanup_fclose_ FILE *f = NULL;
442 Manager *m = userdata;
443 size_t size = 0;
444 DnsScope *scope;
445
446 assert(s);
447 assert(si);
448 assert(m);
449
450 f = open_memstream(&buffer, &size);
451 if (!f)
452 return log_oom();
453
454 LIST_FOREACH(scopes, scope, m->dns_scopes)
455 dns_scope_dump(scope, f);
456
457 if (fflush_and_check(f) < 0)
458 return log_oom();
459
460 log_dump(LOG_INFO, buffer);
461 return 0;
462 }
463
464 int manager_new(Manager **ret) {
465 _cleanup_(manager_freep) Manager *m = NULL;
466 int r;
467
468 assert(ret);
469
470 m = new0(Manager, 1);
471 if (!m)
472 return -ENOMEM;
473
474 m->llmnr_ipv4_udp_fd = m->llmnr_ipv6_udp_fd = -1;
475 m->llmnr_ipv4_tcp_fd = m->llmnr_ipv6_tcp_fd = -1;
476 m->mdns_ipv4_fd = m->mdns_ipv6_fd = -1;
477 m->hostname_fd = -1;
478
479 m->llmnr_support = SUPPORT_YES;
480 m->read_resolv_conf = true;
481 m->need_builtin_fallbacks = true;
482
483 r = dns_trust_anchor_load(&m->trust_anchor);
484 if (r < 0)
485 return r;
486
487 r = sd_event_default(&m->event);
488 if (r < 0)
489 return r;
490
491 sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
492 sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
493
494 sd_event_set_watchdog(m->event, true);
495
496 r = manager_watch_hostname(m);
497 if (r < 0)
498 return r;
499
500 r = dns_scope_new(m, &m->unicast_scope, NULL, DNS_PROTOCOL_DNS, AF_UNSPEC);
501 if (r < 0)
502 return r;
503
504 r = manager_network_monitor_listen(m);
505 if (r < 0)
506 return r;
507
508 r = manager_rtnl_listen(m);
509 if (r < 0)
510 return r;
511
512 r = manager_connect_bus(m);
513 if (r < 0)
514 return r;
515
516 (void) sd_event_add_signal(m->event, &m->sigusr1_event_source, SIGUSR1, manager_sigusr1, m);
517
518 *ret = m;
519 m = NULL;
520
521 return 0;
522 }
523
524 int manager_start(Manager *m) {
525 int r;
526
527 assert(m);
528
529 r = manager_llmnr_start(m);
530 if (r < 0)
531 return r;
532
533 r = manager_mdns_start(m);
534 if (r < 0)
535 return r;
536
537 return 0;
538 }
539
540 Manager *manager_free(Manager *m) {
541 Link *l;
542
543 if (!m)
544 return NULL;
545
546 dns_server_unlink_all(m->dns_servers);
547 dns_server_unlink_all(m->fallback_dns_servers);
548 dns_search_domain_unlink_all(m->search_domains);
549
550 while ((l = hashmap_first(m->links)))
551 link_free(l);
552
553 while (m->dns_queries)
554 dns_query_free(m->dns_queries);
555
556 dns_scope_free(m->unicast_scope);
557
558 hashmap_free(m->links);
559 hashmap_free(m->dns_transactions);
560
561 sd_event_source_unref(m->network_event_source);
562 sd_network_monitor_unref(m->network_monitor);
563
564 sd_netlink_unref(m->rtnl);
565 sd_event_source_unref(m->rtnl_event_source);
566
567 manager_llmnr_stop(m);
568 manager_mdns_stop(m);
569
570 sd_bus_slot_unref(m->prepare_for_sleep_slot);
571 sd_event_source_unref(m->bus_retry_event_source);
572 sd_bus_unref(m->bus);
573
574 sd_event_source_unref(m->sigusr1_event_source);
575
576 sd_event_unref(m->event);
577
578 dns_resource_key_unref(m->llmnr_host_ipv4_key);
579 dns_resource_key_unref(m->llmnr_host_ipv6_key);
580
581 sd_event_source_unref(m->hostname_event_source);
582 safe_close(m->hostname_fd);
583 free(m->llmnr_hostname);
584 free(m->mdns_hostname);
585
586 dns_trust_anchor_flush(&m->trust_anchor);
587
588 free(m);
589
590 return NULL;
591 }
592
593 int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) {
594 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
595 union {
596 struct cmsghdr header; /* For alignment */
597 uint8_t buffer[CMSG_SPACE(MAXSIZE(struct in_pktinfo, struct in6_pktinfo))
598 + CMSG_SPACE(int) /* ttl/hoplimit */
599 + EXTRA_CMSG_SPACE /* kernel appears to require extra buffer space */];
600 } control;
601 union sockaddr_union sa;
602 struct msghdr mh = {};
603 struct cmsghdr *cmsg;
604 struct iovec iov;
605 int ms = 0, r;
606 ssize_t l;
607
608 assert(m);
609 assert(fd >= 0);
610 assert(ret);
611
612 r = ioctl(fd, FIONREAD, &ms);
613 if (r < 0)
614 return -errno;
615 if (ms < 0)
616 return -EIO;
617
618 r = dns_packet_new(&p, protocol, ms);
619 if (r < 0)
620 return r;
621
622 iov.iov_base = DNS_PACKET_DATA(p);
623 iov.iov_len = p->allocated;
624
625 mh.msg_name = &sa.sa;
626 mh.msg_namelen = sizeof(sa);
627 mh.msg_iov = &iov;
628 mh.msg_iovlen = 1;
629 mh.msg_control = &control;
630 mh.msg_controllen = sizeof(control);
631
632 l = recvmsg(fd, &mh, 0);
633 if (l < 0) {
634 if (errno == EAGAIN || errno == EINTR)
635 return 0;
636
637 return -errno;
638 }
639
640 if (l <= 0)
641 return -EIO;
642
643 assert(!(mh.msg_flags & MSG_CTRUNC));
644 assert(!(mh.msg_flags & MSG_TRUNC));
645
646 p->size = (size_t) l;
647
648 p->family = sa.sa.sa_family;
649 p->ipproto = IPPROTO_UDP;
650 if (p->family == AF_INET) {
651 p->sender.in = sa.in.sin_addr;
652 p->sender_port = be16toh(sa.in.sin_port);
653 } else if (p->family == AF_INET6) {
654 p->sender.in6 = sa.in6.sin6_addr;
655 p->sender_port = be16toh(sa.in6.sin6_port);
656 p->ifindex = sa.in6.sin6_scope_id;
657 } else
658 return -EAFNOSUPPORT;
659
660 CMSG_FOREACH(cmsg, &mh) {
661
662 if (cmsg->cmsg_level == IPPROTO_IPV6) {
663 assert(p->family == AF_INET6);
664
665 switch (cmsg->cmsg_type) {
666
667 case IPV6_PKTINFO: {
668 struct in6_pktinfo *i = (struct in6_pktinfo*) CMSG_DATA(cmsg);
669
670 if (p->ifindex <= 0)
671 p->ifindex = i->ipi6_ifindex;
672
673 p->destination.in6 = i->ipi6_addr;
674 break;
675 }
676
677 case IPV6_HOPLIMIT:
678 p->ttl = *(int *) CMSG_DATA(cmsg);
679 break;
680
681 }
682 } else if (cmsg->cmsg_level == IPPROTO_IP) {
683 assert(p->family == AF_INET);
684
685 switch (cmsg->cmsg_type) {
686
687 case IP_PKTINFO: {
688 struct in_pktinfo *i = (struct in_pktinfo*) CMSG_DATA(cmsg);
689
690 if (p->ifindex <= 0)
691 p->ifindex = i->ipi_ifindex;
692
693 p->destination.in = i->ipi_addr;
694 break;
695 }
696
697 case IP_TTL:
698 p->ttl = *(int *) CMSG_DATA(cmsg);
699 break;
700 }
701 }
702 }
703
704 /* The Linux kernel sets the interface index to the loopback
705 * device if the packet came from the local host since it
706 * avoids the routing table in such a case. Let's unset the
707 * interface index in such a case. */
708 if (p->ifindex == LOOPBACK_IFINDEX)
709 p->ifindex = 0;
710
711 if (protocol != DNS_PROTOCOL_DNS) {
712 /* If we don't know the interface index still, we look for the
713 * first local interface with a matching address. Yuck! */
714 if (p->ifindex <= 0)
715 p->ifindex = manager_find_ifindex(m, p->family, &p->destination);
716 }
717
718 *ret = p;
719 p = NULL;
720
721 return 1;
722 }
723
724 static int sendmsg_loop(int fd, struct msghdr *mh, int flags) {
725 int r;
726
727 assert(fd >= 0);
728 assert(mh);
729
730 for (;;) {
731 if (sendmsg(fd, mh, flags) >= 0)
732 return 0;
733
734 if (errno == EINTR)
735 continue;
736
737 if (errno != EAGAIN)
738 return -errno;
739
740 r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
741 if (r < 0)
742 return r;
743 if (r == 0)
744 return -ETIMEDOUT;
745 }
746 }
747
748 static int write_loop(int fd, void *message, size_t length) {
749 int r;
750
751 assert(fd >= 0);
752 assert(message);
753
754 for (;;) {
755 if (write(fd, message, length) >= 0)
756 return 0;
757
758 if (errno == EINTR)
759 continue;
760
761 if (errno != EAGAIN)
762 return -errno;
763
764 r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
765 if (r < 0)
766 return r;
767 if (r == 0)
768 return -ETIMEDOUT;
769 }
770 }
771
772 int manager_write(Manager *m, int fd, DnsPacket *p) {
773 int r;
774
775 log_debug("Sending %s packet with id %" PRIu16 ".", DNS_PACKET_QR(p) ? "response" : "query", DNS_PACKET_ID(p));
776
777 r = write_loop(fd, DNS_PACKET_DATA(p), p->size);
778 if (r < 0)
779 return r;
780
781 return 0;
782 }
783
784 static int manager_ipv4_send(Manager *m, int fd, int ifindex, const struct in_addr *addr, uint16_t port, DnsPacket *p) {
785 union sockaddr_union sa = {
786 .in.sin_family = AF_INET,
787 };
788 union {
789 struct cmsghdr header; /* For alignment */
790 uint8_t buffer[CMSG_SPACE(sizeof(struct in_pktinfo))];
791 } control;
792 struct msghdr mh = {};
793 struct iovec iov;
794
795 assert(m);
796 assert(fd >= 0);
797 assert(addr);
798 assert(port > 0);
799 assert(p);
800
801 iov.iov_base = DNS_PACKET_DATA(p);
802 iov.iov_len = p->size;
803
804 sa.in.sin_addr = *addr;
805 sa.in.sin_port = htobe16(port),
806
807 mh.msg_iov = &iov;
808 mh.msg_iovlen = 1;
809 mh.msg_name = &sa.sa;
810 mh.msg_namelen = sizeof(sa.in);
811
812 if (ifindex > 0) {
813 struct cmsghdr *cmsg;
814 struct in_pktinfo *pi;
815
816 zero(control);
817
818 mh.msg_control = &control;
819 mh.msg_controllen = CMSG_LEN(sizeof(struct in_pktinfo));
820
821 cmsg = CMSG_FIRSTHDR(&mh);
822 cmsg->cmsg_len = mh.msg_controllen;
823 cmsg->cmsg_level = IPPROTO_IP;
824 cmsg->cmsg_type = IP_PKTINFO;
825
826 pi = (struct in_pktinfo*) CMSG_DATA(cmsg);
827 pi->ipi_ifindex = ifindex;
828 }
829
830 return sendmsg_loop(fd, &mh, 0);
831 }
832
833 static int manager_ipv6_send(Manager *m, int fd, int ifindex, const struct in6_addr *addr, uint16_t port, DnsPacket *p) {
834 union sockaddr_union sa = {
835 .in6.sin6_family = AF_INET6,
836 };
837 union {
838 struct cmsghdr header; /* For alignment */
839 uint8_t buffer[CMSG_SPACE(sizeof(struct in6_pktinfo))];
840 } control;
841 struct msghdr mh = {};
842 struct iovec iov;
843
844 assert(m);
845 assert(fd >= 0);
846 assert(addr);
847 assert(port > 0);
848 assert(p);
849
850 iov.iov_base = DNS_PACKET_DATA(p);
851 iov.iov_len = p->size;
852
853 sa.in6.sin6_addr = *addr;
854 sa.in6.sin6_port = htobe16(port),
855 sa.in6.sin6_scope_id = ifindex;
856
857 mh.msg_iov = &iov;
858 mh.msg_iovlen = 1;
859 mh.msg_name = &sa.sa;
860 mh.msg_namelen = sizeof(sa.in6);
861
862 if (ifindex > 0) {
863 struct cmsghdr *cmsg;
864 struct in6_pktinfo *pi;
865
866 zero(control);
867
868 mh.msg_control = &control;
869 mh.msg_controllen = CMSG_LEN(sizeof(struct in6_pktinfo));
870
871 cmsg = CMSG_FIRSTHDR(&mh);
872 cmsg->cmsg_len = mh.msg_controllen;
873 cmsg->cmsg_level = IPPROTO_IPV6;
874 cmsg->cmsg_type = IPV6_PKTINFO;
875
876 pi = (struct in6_pktinfo*) CMSG_DATA(cmsg);
877 pi->ipi6_ifindex = ifindex;
878 }
879
880 return sendmsg_loop(fd, &mh, 0);
881 }
882
883 int manager_send(Manager *m, int fd, int ifindex, int family, const union in_addr_union *addr, uint16_t port, DnsPacket *p) {
884 assert(m);
885 assert(fd >= 0);
886 assert(addr);
887 assert(port > 0);
888 assert(p);
889
890 log_debug("Sending %s packet with id %" PRIu16 " on interface %i/%s.", DNS_PACKET_QR(p) ? "response" : "query", DNS_PACKET_ID(p), ifindex, af_to_name(family));
891
892 if (family == AF_INET)
893 return manager_ipv4_send(m, fd, ifindex, &addr->in, port, p);
894 else if (family == AF_INET6)
895 return manager_ipv6_send(m, fd, ifindex, &addr->in6, port, p);
896
897 return -EAFNOSUPPORT;
898 }
899
900 uint32_t manager_find_mtu(Manager *m) {
901 uint32_t mtu = 0;
902 Link *l;
903 Iterator i;
904
905 /* If we don't know on which link a DNS packet would be
906 * delivered, let's find the largest MTU that works on all
907 * interfaces we know of */
908
909 HASHMAP_FOREACH(l, m->links, i) {
910 if (l->mtu <= 0)
911 continue;
912
913 if (mtu <= 0 || l->mtu < mtu)
914 mtu = l->mtu;
915 }
916
917 return mtu;
918 }
919
920 int manager_find_ifindex(Manager *m, int family, const union in_addr_union *in_addr) {
921 LinkAddress *a;
922
923 assert(m);
924
925 a = manager_find_link_address(m, family, in_addr);
926 if (a)
927 return a->link->ifindex;
928
929 return 0;
930 }
931
932 void manager_refresh_rrs(Manager *m) {
933 Iterator i;
934 Link *l;
935
936 assert(m);
937
938 m->llmnr_host_ipv4_key = dns_resource_key_unref(m->llmnr_host_ipv4_key);
939 m->llmnr_host_ipv6_key = dns_resource_key_unref(m->llmnr_host_ipv6_key);
940
941 HASHMAP_FOREACH(l, m->links, i) {
942 link_add_rrs(l, true);
943 link_add_rrs(l, false);
944 }
945 }
946
947 int manager_next_hostname(Manager *m) {
948 const char *p;
949 uint64_t u, a;
950 char *h, *k;
951 int r;
952
953 assert(m);
954
955 p = strchr(m->llmnr_hostname, 0);
956 assert(p);
957
958 while (p > m->llmnr_hostname) {
959 if (!strchr("0123456789", p[-1]))
960 break;
961
962 p--;
963 }
964
965 if (*p == 0 || safe_atou64(p, &u) < 0 || u <= 0)
966 u = 1;
967
968 /* Add a random number to the old value. This way we can avoid
969 * that two hosts pick the same hostname, win on IPv4 and lose
970 * on IPv6 (or vice versa), and pick the same hostname
971 * replacement hostname, ad infinitum. We still want the
972 * numbers to go up monotonically, hence we just add a random
973 * value 1..10 */
974
975 random_bytes(&a, sizeof(a));
976 u += 1 + a % 10;
977
978 if (asprintf(&h, "%.*s%" PRIu64, (int) (p - m->llmnr_hostname), m->llmnr_hostname, u) < 0)
979 return -ENOMEM;
980
981 r = dns_name_concat(h, "local", &k);
982 if (r < 0) {
983 free(h);
984 return r;
985 }
986
987 log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m->llmnr_hostname, h);
988
989 free(m->llmnr_hostname);
990 m->llmnr_hostname = h;
991
992 free(m->mdns_hostname);
993 m->mdns_hostname = k;
994
995 manager_refresh_rrs(m);
996
997 return 0;
998 }
999
1000 LinkAddress* manager_find_link_address(Manager *m, int family, const union in_addr_union *in_addr) {
1001 Iterator i;
1002 Link *l;
1003
1004 assert(m);
1005
1006 HASHMAP_FOREACH(l, m->links, i) {
1007 LinkAddress *a;
1008
1009 a = link_find_address(l, family, in_addr);
1010 if (a)
1011 return a;
1012 }
1013
1014 return NULL;
1015 }
1016
1017 bool manager_our_packet(Manager *m, DnsPacket *p) {
1018 assert(m);
1019 assert(p);
1020
1021 return !!manager_find_link_address(m, p->family, &p->sender);
1022 }
1023
1024 DnsScope* manager_find_scope(Manager *m, DnsPacket *p) {
1025 Link *l;
1026
1027 assert(m);
1028 assert(p);
1029
1030 l = hashmap_get(m->links, INT_TO_PTR(p->ifindex));
1031 if (!l)
1032 return NULL;
1033
1034 switch (p->protocol) {
1035 case DNS_PROTOCOL_LLMNR:
1036 if (p->family == AF_INET)
1037 return l->llmnr_ipv4_scope;
1038 else if (p->family == AF_INET6)
1039 return l->llmnr_ipv6_scope;
1040
1041 break;
1042
1043 case DNS_PROTOCOL_MDNS:
1044 if (p->family == AF_INET)
1045 return l->mdns_ipv4_scope;
1046 else if (p->family == AF_INET6)
1047 return l->mdns_ipv6_scope;
1048
1049 break;
1050
1051 default:
1052 break;
1053 }
1054
1055 return NULL;
1056 }
1057
1058 void manager_verify_all(Manager *m) {
1059 DnsScope *s;
1060
1061 assert(m);
1062
1063 LIST_FOREACH(scopes, s, m->dns_scopes)
1064 dns_zone_verify_all(&s->zone);
1065 }
1066
1067 int manager_is_own_hostname(Manager *m, const char *name) {
1068 int r;
1069
1070 assert(m);
1071 assert(name);
1072
1073 if (m->llmnr_hostname) {
1074 r = dns_name_equal(name, m->llmnr_hostname);
1075 if (r != 0)
1076 return r;
1077 }
1078
1079 if (m->mdns_hostname)
1080 return dns_name_equal(name, m->mdns_hostname);
1081
1082 return 0;
1083 }
1084
1085 int manager_compile_dns_servers(Manager *m, OrderedSet **dns) {
1086 DnsServer *s;
1087 Iterator i;
1088 Link *l;
1089 int r;
1090
1091 assert(m);
1092 assert(dns);
1093
1094 r = ordered_set_ensure_allocated(dns, &dns_server_hash_ops);
1095 if (r < 0)
1096 return r;
1097
1098 /* First add the system-wide servers and domains */
1099 LIST_FOREACH(servers, s, m->dns_servers) {
1100 r = ordered_set_put(*dns, s);
1101 if (r == -EEXIST)
1102 continue;
1103 if (r < 0)
1104 return r;
1105 }
1106
1107 /* Then, add the per-link servers */
1108 HASHMAP_FOREACH(l, m->links, i) {
1109 LIST_FOREACH(servers, s, l->dns_servers) {
1110 r = ordered_set_put(*dns, s);
1111 if (r == -EEXIST)
1112 continue;
1113 if (r < 0)
1114 return r;
1115 }
1116 }
1117
1118 /* If we found nothing, add the fallback servers */
1119 if (ordered_set_isempty(*dns)) {
1120 LIST_FOREACH(servers, s, m->fallback_dns_servers) {
1121 r = ordered_set_put(*dns, s);
1122 if (r == -EEXIST)
1123 continue;
1124 if (r < 0)
1125 return r;
1126 }
1127 }
1128
1129 return 0;
1130 }
1131
1132 int manager_compile_search_domains(Manager *m, OrderedSet **domains) {
1133 DnsSearchDomain *d;
1134 Iterator i;
1135 Link *l;
1136 int r;
1137
1138 assert(m);
1139 assert(domains);
1140
1141 r = ordered_set_ensure_allocated(domains, &dns_name_hash_ops);
1142 if (r < 0)
1143 return r;
1144
1145 LIST_FOREACH(domains, d, m->search_domains) {
1146 r = ordered_set_put(*domains, d->name);
1147 if (r == -EEXIST)
1148 continue;
1149 if (r < 0)
1150 return r;
1151 }
1152
1153 HASHMAP_FOREACH(l, m->links, i) {
1154
1155 LIST_FOREACH(domains, d, l->search_domains) {
1156 r = ordered_set_put(*domains, d->name);
1157 if (r == -EEXIST)
1158 continue;
1159 if (r < 0)
1160 return r;
1161 }
1162 }
1163
1164 return 0;
1165 }
1166
1167 static const char* const support_table[_SUPPORT_MAX] = {
1168 [SUPPORT_NO] = "no",
1169 [SUPPORT_YES] = "yes",
1170 [SUPPORT_RESOLVE] = "resolve",
1171 };
1172 DEFINE_STRING_TABLE_LOOKUP(support, Support);