]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-manager.c
resolved: add a generic DnsSearchDomain concept
[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_netlink_message_unref_ 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(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 manager_flush_dns_servers(m, DNS_SERVER_SYSTEM);
537 manager_flush_dns_servers(m, DNS_SERVER_FALLBACK);
538
539 dns_search_domain_unlink_all(m->search_domains);
540
541 while ((l = hashmap_first(m->links)))
542 link_free(l);
543
544 while (m->dns_queries)
545 dns_query_free(m->dns_queries);
546
547 dns_scope_free(m->unicast_scope);
548
549 hashmap_free(m->links);
550 hashmap_free(m->dns_transactions);
551
552 sd_event_source_unref(m->network_event_source);
553 sd_network_monitor_unref(m->network_monitor);
554
555 sd_netlink_unref(m->rtnl);
556 sd_event_source_unref(m->rtnl_event_source);
557
558 manager_llmnr_stop(m);
559
560 sd_bus_slot_unref(m->prepare_for_sleep_slot);
561 sd_event_source_unref(m->bus_retry_event_source);
562 sd_bus_unref(m->bus);
563
564 sd_event_source_unref(m->sigusr1_event_source);
565
566 sd_event_unref(m->event);
567
568 dns_resource_key_unref(m->llmnr_host_ipv4_key);
569 dns_resource_key_unref(m->llmnr_host_ipv6_key);
570
571 sd_event_source_unref(m->hostname_event_source);
572 safe_close(m->hostname_fd);
573 free(m->llmnr_hostname);
574 free(m->mdns_hostname);
575
576 free(m);
577
578 return NULL;
579 }
580
581 int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) {
582 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
583 union {
584 struct cmsghdr header; /* For alignment */
585 uint8_t buffer[CMSG_SPACE(MAXSIZE(struct in_pktinfo, struct in6_pktinfo))
586 + CMSG_SPACE(int) /* ttl/hoplimit */
587 + EXTRA_CMSG_SPACE /* kernel appears to require extra buffer space */];
588 } control;
589 union sockaddr_union sa;
590 struct msghdr mh = {};
591 struct cmsghdr *cmsg;
592 struct iovec iov;
593 int ms = 0, r;
594 ssize_t l;
595
596 assert(m);
597 assert(fd >= 0);
598 assert(ret);
599
600 r = ioctl(fd, FIONREAD, &ms);
601 if (r < 0)
602 return -errno;
603 if (ms < 0)
604 return -EIO;
605
606 r = dns_packet_new(&p, protocol, ms);
607 if (r < 0)
608 return r;
609
610 iov.iov_base = DNS_PACKET_DATA(p);
611 iov.iov_len = p->allocated;
612
613 mh.msg_name = &sa.sa;
614 mh.msg_namelen = sizeof(sa);
615 mh.msg_iov = &iov;
616 mh.msg_iovlen = 1;
617 mh.msg_control = &control;
618 mh.msg_controllen = sizeof(control);
619
620 l = recvmsg(fd, &mh, 0);
621 if (l < 0) {
622 if (errno == EAGAIN || errno == EINTR)
623 return 0;
624
625 return -errno;
626 }
627
628 if (l <= 0)
629 return -EIO;
630
631 assert(!(mh.msg_flags & MSG_CTRUNC));
632 assert(!(mh.msg_flags & MSG_TRUNC));
633
634 p->size = (size_t) l;
635
636 p->family = sa.sa.sa_family;
637 p->ipproto = IPPROTO_UDP;
638 if (p->family == AF_INET) {
639 p->sender.in = sa.in.sin_addr;
640 p->sender_port = be16toh(sa.in.sin_port);
641 } else if (p->family == AF_INET6) {
642 p->sender.in6 = sa.in6.sin6_addr;
643 p->sender_port = be16toh(sa.in6.sin6_port);
644 p->ifindex = sa.in6.sin6_scope_id;
645 } else
646 return -EAFNOSUPPORT;
647
648 CMSG_FOREACH(cmsg, &mh) {
649
650 if (cmsg->cmsg_level == IPPROTO_IPV6) {
651 assert(p->family == AF_INET6);
652
653 switch (cmsg->cmsg_type) {
654
655 case IPV6_PKTINFO: {
656 struct in6_pktinfo *i = (struct in6_pktinfo*) CMSG_DATA(cmsg);
657
658 if (p->ifindex <= 0)
659 p->ifindex = i->ipi6_ifindex;
660
661 p->destination.in6 = i->ipi6_addr;
662 break;
663 }
664
665 case IPV6_HOPLIMIT:
666 p->ttl = *(int *) CMSG_DATA(cmsg);
667 break;
668
669 }
670 } else if (cmsg->cmsg_level == IPPROTO_IP) {
671 assert(p->family == AF_INET);
672
673 switch (cmsg->cmsg_type) {
674
675 case IP_PKTINFO: {
676 struct in_pktinfo *i = (struct in_pktinfo*) CMSG_DATA(cmsg);
677
678 if (p->ifindex <= 0)
679 p->ifindex = i->ipi_ifindex;
680
681 p->destination.in = i->ipi_addr;
682 break;
683 }
684
685 case IP_TTL:
686 p->ttl = *(int *) CMSG_DATA(cmsg);
687 break;
688 }
689 }
690 }
691
692 /* The Linux kernel sets the interface index to the loopback
693 * device if the packet came from the local host since it
694 * avoids the routing table in such a case. Let's unset the
695 * interface index in such a case. */
696 if (p->ifindex == LOOPBACK_IFINDEX)
697 p->ifindex = 0;
698
699 if (protocol != DNS_PROTOCOL_DNS) {
700 /* If we don't know the interface index still, we look for the
701 * first local interface with a matching address. Yuck! */
702 if (p->ifindex <= 0)
703 p->ifindex = manager_find_ifindex(m, p->family, &p->destination);
704 }
705
706 *ret = p;
707 p = NULL;
708
709 return 1;
710 }
711
712 static int sendmsg_loop(int fd, struct msghdr *mh, int flags) {
713 int r;
714
715 assert(fd >= 0);
716 assert(mh);
717
718 for (;;) {
719 if (sendmsg(fd, mh, flags) >= 0)
720 return 0;
721
722 if (errno == EINTR)
723 continue;
724
725 if (errno != EAGAIN)
726 return -errno;
727
728 r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
729 if (r < 0)
730 return r;
731 if (r == 0)
732 return -ETIMEDOUT;
733 }
734 }
735
736 static int write_loop(int fd, void *message, size_t length) {
737 int r;
738
739 assert(fd >= 0);
740 assert(message);
741
742 for (;;) {
743 if (write(fd, message, length) >= 0)
744 return 0;
745
746 if (errno == EINTR)
747 continue;
748
749 if (errno != EAGAIN)
750 return -errno;
751
752 r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
753 if (r < 0)
754 return r;
755 if (r == 0)
756 return -ETIMEDOUT;
757 }
758 }
759
760 int manager_write(Manager *m, int fd, DnsPacket *p) {
761 int r;
762
763 log_debug("Sending %s packet with id %u", DNS_PACKET_QR(p) ? "response" : "query", DNS_PACKET_ID(p));
764
765 r = write_loop(fd, DNS_PACKET_DATA(p), p->size);
766 if (r < 0)
767 return r;
768
769 return 0;
770 }
771
772 static int manager_ipv4_send(Manager *m, int fd, int ifindex, const struct in_addr *addr, uint16_t port, DnsPacket *p) {
773 union sockaddr_union sa = {
774 .in.sin_family = AF_INET,
775 };
776 union {
777 struct cmsghdr header; /* For alignment */
778 uint8_t buffer[CMSG_SPACE(sizeof(struct in_pktinfo))];
779 } control;
780 struct msghdr mh = {};
781 struct iovec iov;
782
783 assert(m);
784 assert(fd >= 0);
785 assert(addr);
786 assert(port > 0);
787 assert(p);
788
789 iov.iov_base = DNS_PACKET_DATA(p);
790 iov.iov_len = p->size;
791
792 sa.in.sin_addr = *addr;
793 sa.in.sin_port = htobe16(port),
794
795 mh.msg_iov = &iov;
796 mh.msg_iovlen = 1;
797 mh.msg_name = &sa.sa;
798 mh.msg_namelen = sizeof(sa.in);
799
800 if (ifindex > 0) {
801 struct cmsghdr *cmsg;
802 struct in_pktinfo *pi;
803
804 zero(control);
805
806 mh.msg_control = &control;
807 mh.msg_controllen = CMSG_LEN(sizeof(struct in_pktinfo));
808
809 cmsg = CMSG_FIRSTHDR(&mh);
810 cmsg->cmsg_len = mh.msg_controllen;
811 cmsg->cmsg_level = IPPROTO_IP;
812 cmsg->cmsg_type = IP_PKTINFO;
813
814 pi = (struct in_pktinfo*) CMSG_DATA(cmsg);
815 pi->ipi_ifindex = ifindex;
816 }
817
818 return sendmsg_loop(fd, &mh, 0);
819 }
820
821 static int manager_ipv6_send(Manager *m, int fd, int ifindex, const struct in6_addr *addr, uint16_t port, DnsPacket *p) {
822 union sockaddr_union sa = {
823 .in6.sin6_family = AF_INET6,
824 };
825 union {
826 struct cmsghdr header; /* For alignment */
827 uint8_t buffer[CMSG_SPACE(sizeof(struct in6_pktinfo))];
828 } control;
829 struct msghdr mh = {};
830 struct iovec iov;
831
832 assert(m);
833 assert(fd >= 0);
834 assert(addr);
835 assert(port > 0);
836 assert(p);
837
838 iov.iov_base = DNS_PACKET_DATA(p);
839 iov.iov_len = p->size;
840
841 sa.in6.sin6_addr = *addr;
842 sa.in6.sin6_port = htobe16(port),
843 sa.in6.sin6_scope_id = ifindex;
844
845 mh.msg_iov = &iov;
846 mh.msg_iovlen = 1;
847 mh.msg_name = &sa.sa;
848 mh.msg_namelen = sizeof(sa.in6);
849
850 if (ifindex > 0) {
851 struct cmsghdr *cmsg;
852 struct in6_pktinfo *pi;
853
854 zero(control);
855
856 mh.msg_control = &control;
857 mh.msg_controllen = CMSG_LEN(sizeof(struct in6_pktinfo));
858
859 cmsg = CMSG_FIRSTHDR(&mh);
860 cmsg->cmsg_len = mh.msg_controllen;
861 cmsg->cmsg_level = IPPROTO_IPV6;
862 cmsg->cmsg_type = IPV6_PKTINFO;
863
864 pi = (struct in6_pktinfo*) CMSG_DATA(cmsg);
865 pi->ipi6_ifindex = ifindex;
866 }
867
868 return sendmsg_loop(fd, &mh, 0);
869 }
870
871 int manager_send(Manager *m, int fd, int ifindex, int family, const union in_addr_union *addr, uint16_t port, DnsPacket *p) {
872 assert(m);
873 assert(fd >= 0);
874 assert(addr);
875 assert(port > 0);
876 assert(p);
877
878 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));
879
880 if (family == AF_INET)
881 return manager_ipv4_send(m, fd, ifindex, &addr->in, port, p);
882 else if (family == AF_INET6)
883 return manager_ipv6_send(m, fd, ifindex, &addr->in6, port, p);
884
885 return -EAFNOSUPPORT;
886 }
887
888 uint32_t manager_find_mtu(Manager *m) {
889 uint32_t mtu = 0;
890 Link *l;
891 Iterator i;
892
893 /* If we don't know on which link a DNS packet would be
894 * delivered, let's find the largest MTU that works on all
895 * interfaces we know of */
896
897 HASHMAP_FOREACH(l, m->links, i) {
898 if (l->mtu <= 0)
899 continue;
900
901 if (mtu <= 0 || l->mtu < mtu)
902 mtu = l->mtu;
903 }
904
905 return mtu;
906 }
907
908 int manager_find_ifindex(Manager *m, int family, const union in_addr_union *in_addr) {
909 LinkAddress *a;
910
911 assert(m);
912
913 a = manager_find_link_address(m, family, in_addr);
914 if (a)
915 return a->link->ifindex;
916
917 return 0;
918 }
919
920 void manager_refresh_rrs(Manager *m) {
921 Iterator i;
922 Link *l;
923
924 assert(m);
925
926 m->llmnr_host_ipv4_key = dns_resource_key_unref(m->llmnr_host_ipv4_key);
927 m->llmnr_host_ipv6_key = dns_resource_key_unref(m->llmnr_host_ipv6_key);
928
929 HASHMAP_FOREACH(l, m->links, i) {
930 link_add_rrs(l, true);
931 link_add_rrs(l, false);
932 }
933 }
934
935 int manager_next_hostname(Manager *m) {
936 const char *p;
937 uint64_t u, a;
938 char *h, *k;
939 int r;
940
941 assert(m);
942
943 p = strchr(m->llmnr_hostname, 0);
944 assert(p);
945
946 while (p > m->llmnr_hostname) {
947 if (!strchr("0123456789", p[-1]))
948 break;
949
950 p--;
951 }
952
953 if (*p == 0 || safe_atou64(p, &u) < 0 || u <= 0)
954 u = 1;
955
956 /* Add a random number to the old value. This way we can avoid
957 * that two hosts pick the same hostname, win on IPv4 and lose
958 * on IPv6 (or vice versa), and pick the same hostname
959 * replacement hostname, ad infinitum. We still want the
960 * numbers to go up monotonically, hence we just add a random
961 * value 1..10 */
962
963 random_bytes(&a, sizeof(a));
964 u += 1 + a % 10;
965
966 if (asprintf(&h, "%.*s%" PRIu64, (int) (p - m->llmnr_hostname), m->llmnr_hostname, u) < 0)
967 return -ENOMEM;
968
969 r = dns_name_concat(h, "local", &k);
970 if (r < 0) {
971 free(h);
972 return r;
973 }
974
975 log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m->llmnr_hostname, h);
976
977 free(m->llmnr_hostname);
978 m->llmnr_hostname = h;
979
980 free(m->mdns_hostname);
981 m->mdns_hostname = k;
982
983 manager_refresh_rrs(m);
984
985 return 0;
986 }
987
988 LinkAddress* manager_find_link_address(Manager *m, int family, const union in_addr_union *in_addr) {
989 Iterator i;
990 Link *l;
991
992 assert(m);
993
994 HASHMAP_FOREACH(l, m->links, i) {
995 LinkAddress *a;
996
997 a = link_find_address(l, family, in_addr);
998 if (a)
999 return a;
1000 }
1001
1002 return NULL;
1003 }
1004
1005 bool manager_our_packet(Manager *m, DnsPacket *p) {
1006 assert(m);
1007 assert(p);
1008
1009 return !!manager_find_link_address(m, p->family, &p->sender);
1010 }
1011
1012 DnsScope* manager_find_scope(Manager *m, DnsPacket *p) {
1013 Link *l;
1014
1015 assert(m);
1016 assert(p);
1017
1018 l = hashmap_get(m->links, INT_TO_PTR(p->ifindex));
1019 if (!l)
1020 return NULL;
1021
1022 if (p->protocol == DNS_PROTOCOL_LLMNR) {
1023 if (p->family == AF_INET)
1024 return l->llmnr_ipv4_scope;
1025 else if (p->family == AF_INET6)
1026 return l->llmnr_ipv6_scope;
1027 }
1028
1029 return NULL;
1030 }
1031
1032 void manager_verify_all(Manager *m) {
1033 DnsScope *s;
1034
1035 assert(m);
1036
1037 LIST_FOREACH(scopes, s, m->dns_scopes)
1038 dns_zone_verify_all(&s->zone);
1039 }
1040
1041 int manager_is_own_hostname(Manager *m, const char *name) {
1042 int r;
1043
1044 assert(m);
1045 assert(name);
1046
1047 if (m->llmnr_hostname) {
1048 r = dns_name_equal(name, m->llmnr_hostname);
1049 if (r != 0)
1050 return r;
1051 }
1052
1053 if (m->mdns_hostname)
1054 return dns_name_equal(name, m->mdns_hostname);
1055
1056 return 0;
1057 }
1058
1059 static const char* const support_table[_SUPPORT_MAX] = {
1060 [SUPPORT_NO] = "no",
1061 [SUPPORT_YES] = "yes",
1062 [SUPPORT_RESOLVE] = "resolve",
1063 };
1064 DEFINE_STRING_TABLE_LOOKUP(support, Support);