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