]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-manager.c
resolved: beef up DNS server configuration logic
[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 <arpa/inet.h>
23 #include <resolv.h>
24 #include <net/if.h>
25 #include <sys/ioctl.h>
26 #include <sys/poll.h>
27 #include <netinet/in.h>
28
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"
35 #include "af-list.h"
36 #include "utf8.h"
37
38 #include "resolved.h"
39 #include "resolved-conf.h"
40 #include "resolved-dns-domain.h"
41
42 #define SEND_TIMEOUT_USEC (200 * USEC_PER_MSEC)
43
44 static int manager_process_link(sd_rtnl *rtnl, sd_rtnl_message *mm, void *userdata) {
45 Manager *m = userdata;
46 uint16_t type;
47 Link *l;
48 int ifindex, r;
49
50 assert(rtnl);
51 assert(m);
52 assert(mm);
53
54 r = sd_rtnl_message_get_type(mm, &type);
55 if (r < 0)
56 goto fail;
57
58 r = sd_rtnl_message_link_get_ifindex(mm, &ifindex);
59 if (r < 0)
60 goto fail;
61
62 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
63
64 switch (type) {
65
66 case RTM_NEWLINK:{
67 bool is_new = !l;
68
69 if (!l) {
70 r = link_new(m, &l, ifindex);
71 if (r < 0)
72 goto fail;
73 }
74
75 r = link_update_rtnl(l, mm);
76 if (r < 0)
77 goto fail;
78
79 if (is_new)
80 log_debug("Found new link %i/%s", ifindex, l->name);
81
82 break;
83 }
84
85 case RTM_DELLINK:
86 if (l) {
87 log_debug("Removing link %i/%s", l->ifindex, l->name);
88 link_free(l);
89 }
90
91 break;
92 }
93
94 return 0;
95
96 fail:
97 log_warning("Failed to process RTNL link message: %s", strerror(-r));
98 return 0;
99 }
100
101 static int manager_process_address(sd_rtnl *rtnl, sd_rtnl_message *mm, void *userdata) {
102 Manager *m = userdata;
103 union in_addr_union address;
104 uint16_t type;
105 int r, ifindex, family;
106 LinkAddress *a;
107 Link *l;
108
109 assert(rtnl);
110 assert(mm);
111 assert(m);
112
113 r = sd_rtnl_message_get_type(mm, &type);
114 if (r < 0)
115 goto fail;
116
117 r = sd_rtnl_message_addr_get_ifindex(mm, &ifindex);
118 if (r < 0)
119 goto fail;
120
121 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
122 if (!l)
123 return 0;
124
125 r = sd_rtnl_message_addr_get_family(mm, &family);
126 if (r < 0)
127 goto fail;
128
129 switch (family) {
130
131 case AF_INET:
132 r = sd_rtnl_message_read_in_addr(mm, IFA_LOCAL, &address.in);
133 if (r < 0) {
134 r = sd_rtnl_message_read_in_addr(mm, IFA_ADDRESS, &address.in);
135 if (r < 0)
136 goto fail;
137 }
138
139 break;
140
141 case AF_INET6:
142 r = sd_rtnl_message_read_in6_addr(mm, IFA_LOCAL, &address.in6);
143 if (r < 0) {
144 r = sd_rtnl_message_read_in6_addr(mm, IFA_ADDRESS, &address.in6);
145 if (r < 0)
146 goto fail;
147 }
148
149 break;
150
151 default:
152 return 0;
153 }
154
155 a = link_find_address(l, family, &address);
156
157 switch (type) {
158
159 case RTM_NEWADDR:
160
161 if (!a) {
162 r = link_address_new(l, &a, family, &address);
163 if (r < 0)
164 return r;
165 }
166
167 r = link_address_update_rtnl(a, mm);
168 if (r < 0)
169 return r;
170
171 break;
172
173 case RTM_DELADDR:
174 if (a)
175 link_address_free(a);
176 break;
177 }
178
179 return 0;
180
181 fail:
182 log_warning("Failed to process RTNL address message: %s", strerror(-r));
183 return 0;
184 }
185
186
187 static int manager_rtnl_listen(Manager *m) {
188 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
189 sd_rtnl_message *i;
190 int r;
191
192 assert(m);
193
194 /* First, subscibe to interfaces coming and going */
195 r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR, RTNLGRP_IPV6_IFADDR);
196 if (r < 0)
197 return r;
198
199 r = sd_rtnl_attach_event(m->rtnl, m->event, 0);
200 if (r < 0)
201 return r;
202
203 r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, manager_process_link, m);
204 if (r < 0)
205 return r;
206
207 r = sd_rtnl_add_match(m->rtnl, RTM_DELLINK, manager_process_link, m);
208 if (r < 0)
209 return r;
210
211 r = sd_rtnl_add_match(m->rtnl, RTM_NEWADDR, manager_process_address, m);
212 if (r < 0)
213 return r;
214
215 r = sd_rtnl_add_match(m->rtnl, RTM_DELADDR, manager_process_address, m);
216 if (r < 0)
217 return r;
218
219 /* Then, enumerate all links */
220 r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
221 if (r < 0)
222 return r;
223
224 r = sd_rtnl_message_request_dump(req, true);
225 if (r < 0)
226 return r;
227
228 r = sd_rtnl_call(m->rtnl, req, 0, &reply);
229 if (r < 0)
230 return r;
231
232 for (i = reply; i; i = sd_rtnl_message_next(i)) {
233 r = manager_process_link(m->rtnl, i, m);
234 if (r < 0)
235 return r;
236 }
237
238 req = sd_rtnl_message_unref(req);
239 reply = sd_rtnl_message_unref(reply);
240
241 /* Finally, enumerate all addresses, too */
242 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, AF_UNSPEC);
243 if (r < 0)
244 return r;
245
246 r = sd_rtnl_message_request_dump(req, true);
247 if (r < 0)
248 return r;
249
250 r = sd_rtnl_call(m->rtnl, req, 0, &reply);
251 if (r < 0)
252 return r;
253
254 for (i = reply; i; i = sd_rtnl_message_next(i)) {
255 r = manager_process_address(m->rtnl, i, m);
256 if (r < 0)
257 return r;
258 }
259
260 return r;
261 }
262
263 static int on_network_event(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
264 Manager *m = userdata;
265 Iterator i;
266 Link *l;
267 int r;
268
269 assert(m);
270
271 sd_network_monitor_flush(m->network_monitor);
272
273 HASHMAP_FOREACH(l, m->links, i) {
274 r = link_update_monitor(l);
275 if (r < 0)
276 log_warning("Failed to update monitor information for %i: %s", l->ifindex, strerror(-r));
277 }
278
279 r = manager_write_resolv_conf(m);
280 if (r < 0)
281 log_warning("Could not update resolv.conf: %s", strerror(-r));
282
283 return 0;
284 }
285
286 static int manager_network_monitor_listen(Manager *m) {
287 int r, fd, events;
288
289 assert(m);
290
291 r = sd_network_monitor_new(&m->network_monitor, NULL);
292 if (r < 0)
293 return r;
294
295 fd = sd_network_monitor_get_fd(m->network_monitor);
296 if (fd < 0)
297 return fd;
298
299 events = sd_network_monitor_get_events(m->network_monitor);
300 if (events < 0)
301 return events;
302
303 r = sd_event_add_io(m->event, &m->network_event_source, fd, events, &on_network_event, m);
304 if (r < 0)
305 return r;
306
307 return 0;
308 }
309
310 static int determine_hostname(char **ret) {
311 _cleanup_free_ char *h = NULL, *n = NULL;
312 int r;
313
314 assert(ret);
315
316 h = gethostname_malloc();
317 if (!h)
318 return log_oom();
319
320 if (!utf8_is_valid(h)) {
321 log_error("System hostname is not UTF-8 clean.");
322 return -EINVAL;
323 }
324
325 r = dns_name_normalize(h, &n);
326 if (r < 0) {
327 log_error("System hostname '%s' cannot be normalized.", h);
328 return r;
329 }
330
331 *ret = n;
332 n = NULL;
333
334 return 0;
335 }
336
337 static int on_hostname_change(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
338 _cleanup_free_ char *h = NULL;
339 Manager *m = userdata;
340 int r;
341
342 assert(m);
343
344 r = determine_hostname(&h);
345 if (r < 0)
346 return 0; /* ignore invalid hostnames */
347
348 if (streq(h, m->hostname))
349 return 0;
350
351 log_info("System hostname changed to '%s'.", h);
352 free(m->hostname);
353 m->hostname = h;
354 h = NULL;
355
356 manager_refresh_rrs(m);
357
358 return 0;
359 }
360
361 static int manager_watch_hostname(Manager *m) {
362 _cleanup_free_ char *h = NULL;
363 int r;
364
365 assert(m);
366
367 m->hostname_fd = open("/proc/sys/kernel/hostname", O_RDONLY|O_CLOEXEC|O_NDELAY|O_NOCTTY);
368 if (m->hostname_fd < 0) {
369 log_warning("Failed to watch hostname: %m");
370 return 0;
371 }
372
373 r = sd_event_add_io(m->event, &m->hostname_event_source, m->hostname_fd, 0, on_hostname_change, m);
374 if (r < 0) {
375 if (r == -EPERM)
376 /* kernels prior to 3.2 don't support polling this file. Ignore the failure. */
377 m->hostname_fd = safe_close(m->hostname_fd);
378 else {
379 log_error("Failed to add hostname event source: %s", strerror(-r));
380 return r;
381 }
382 }
383
384 r = determine_hostname(&m->hostname);
385 if (r < 0) {
386 log_info("Defaulting to hostname 'linux'.");
387 m->hostname = strdup("linux");
388 if (!m->hostname)
389 return log_oom();
390 } else
391 log_info("Using system hostname '%s'.", m->hostname);
392
393 return 0;
394 }
395
396 int manager_new(Manager **ret) {
397 _cleanup_(manager_freep) Manager *m = NULL;
398 int r;
399
400 assert(ret);
401
402 m = new0(Manager, 1);
403 if (!m)
404 return -ENOMEM;
405
406 m->dns_ipv4_fd = m->dns_ipv6_fd = -1;
407 m->llmnr_ipv4_udp_fd = m->llmnr_ipv6_udp_fd = -1;
408 m->llmnr_ipv4_tcp_fd = m->llmnr_ipv6_tcp_fd = -1;
409 m->hostname_fd = -1;
410
411 m->llmnr_support = SUPPORT_YES;
412
413 r = manager_parse_dns_server(m, DNS_SERVER_FALLBACK, DNS_SERVERS);
414 if (r < 0)
415 return r;
416
417 r = sd_event_default(&m->event);
418 if (r < 0)
419 return r;
420
421 sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
422 sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
423
424 sd_event_set_watchdog(m->event, true);
425
426 r = manager_watch_hostname(m);
427 if (r < 0)
428 return r;
429
430 r = dns_scope_new(m, &m->unicast_scope, NULL, DNS_PROTOCOL_DNS, AF_UNSPEC);
431 if (r < 0)
432 return r;
433
434 r = manager_network_monitor_listen(m);
435 if (r < 0)
436 return r;
437
438 r = manager_rtnl_listen(m);
439 if (r < 0)
440 return r;
441
442 r = manager_connect_bus(m);
443 if (r < 0)
444 return r;
445
446 r = manager_llmnr_ipv4_udp_fd(m);
447 if (r < 0)
448 return r;
449 r = manager_llmnr_ipv6_udp_fd(m);
450 if (r < 0)
451 return r;
452 r = manager_llmnr_ipv4_tcp_fd(m);
453 if (r < 0)
454 return r;
455 r = manager_llmnr_ipv6_tcp_fd(m);
456 if (r < 0)
457 return r;
458
459 *ret = m;
460 m = NULL;
461
462 return 0;
463 }
464
465 Manager *manager_free(Manager *m) {
466 Link *l;
467
468 if (!m)
469 return NULL;
470
471 while (m->dns_queries)
472 dns_query_free(m->dns_queries);
473
474 hashmap_free(m->dns_transactions);
475
476 while ((l = hashmap_first(m->links)))
477 link_free(l);
478 hashmap_free(m->links);
479
480 dns_scope_free(m->unicast_scope);
481
482 while (m->dns_servers)
483 dns_server_free(m->dns_servers);
484 while (m->fallback_dns_servers)
485 dns_server_free(m->fallback_dns_servers);
486
487 sd_event_source_unref(m->network_event_source);
488 sd_network_monitor_unref(m->network_monitor);
489
490 sd_event_source_unref(m->dns_ipv4_event_source);
491 sd_event_source_unref(m->dns_ipv6_event_source);
492 safe_close(m->dns_ipv4_fd);
493 safe_close(m->dns_ipv6_fd);
494
495 sd_event_source_unref(m->llmnr_ipv4_udp_event_source);
496 sd_event_source_unref(m->llmnr_ipv6_udp_event_source);
497 safe_close(m->llmnr_ipv4_udp_fd);
498 safe_close(m->llmnr_ipv6_udp_fd);
499
500 sd_event_source_unref(m->llmnr_ipv4_tcp_event_source);
501 sd_event_source_unref(m->llmnr_ipv6_tcp_event_source);
502 safe_close(m->llmnr_ipv4_tcp_fd);
503 safe_close(m->llmnr_ipv6_tcp_fd);
504
505 sd_event_source_unref(m->bus_retry_event_source);
506 sd_bus_unref(m->bus);
507
508 sd_event_unref(m->event);
509
510 dns_resource_key_unref(m->host_ipv4_key);
511 dns_resource_key_unref(m->host_ipv6_key);
512
513 safe_close(m->hostname_fd);
514 sd_event_source_unref(m->hostname_event_source);
515 free(m->hostname);
516
517 free(m);
518
519 return NULL;
520 }
521
522 static void write_resolve_conf_server(DnsServer *s, FILE *f, unsigned *count) {
523 _cleanup_free_ char *t = NULL;
524 int r;
525
526 assert(s);
527 assert(f);
528 assert(count);
529
530 r = in_addr_to_string(s->family, &s->address, &t);
531 if (r < 0) {
532 log_warning("Invalid DNS address. Ignoring: %s", strerror(-r));
533 return;
534 }
535
536 if (*count == MAXNS)
537 fputs("# Too many DNS servers configured, the following entries may be ignored\n", f);
538
539 fprintf(f, "nameserver %s\n", t);
540 (*count) ++;
541 }
542
543 int manager_write_resolv_conf(Manager *m) {
544 static const char path[] = "/run/systemd/resolve/resolv.conf";
545 _cleanup_free_ char *temp_path = NULL;
546 _cleanup_fclose_ FILE *f = NULL;
547 unsigned count = 0;
548 DnsServer *s;
549 Iterator i;
550 Link *l;
551 int r;
552
553 assert(m);
554
555 r = fopen_temporary(path, &f, &temp_path);
556 if (r < 0)
557 return r;
558
559 fchmod(fileno(f), 0644);
560
561 fputs("# This file is managed by systemd-resolved(8). Do not edit.\n#\n"
562 "# Third party programs must not access this file directly, but\n"
563 "# only through the symlink at /etc/resolv.conf. To manage\n"
564 "# resolv.conf(5) in a different way, replace the symlink by a\n"
565 "# static file or a different symlink.\n\n", f);
566
567 LIST_FOREACH(servers, s, m->dns_servers)
568 write_resolve_conf_server(s, f, &count);
569
570 HASHMAP_FOREACH(l, m->links, i)
571 LIST_FOREACH(servers, s, l->dns_servers)
572 write_resolve_conf_server(s, f, &count);
573
574 if (count == 0) {
575 LIST_FOREACH(servers, s, m->fallback_dns_servers)
576 write_resolve_conf_server(s, f, &count);
577 }
578
579 r = fflush_and_check(f);
580 if (r < 0)
581 goto fail;
582
583 if (rename(temp_path, path) < 0) {
584 r = -errno;
585 goto fail;
586 }
587
588 return 0;
589
590 fail:
591 unlink(path);
592 unlink(temp_path);
593 return r;
594 }
595
596 int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) {
597 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
598 union {
599 struct cmsghdr header; /* For alignment */
600 uint8_t buffer[CMSG_SPACE(MAX(sizeof(struct in_pktinfo), sizeof(struct in6_pktinfo)))
601 + CMSG_SPACE(int) /* ttl/hoplimit */
602 + EXTRA_CMSG_SPACE /* kernel appears to require extra buffer space */];
603 } control;
604 union sockaddr_union sa;
605 struct msghdr mh = {};
606 struct cmsghdr *cmsg;
607 struct iovec iov;
608 int ms = 0, r;
609 ssize_t l;
610
611 assert(m);
612 assert(fd >= 0);
613 assert(ret);
614
615 r = ioctl(fd, FIONREAD, &ms);
616 if (r < 0)
617 return -errno;
618 if (ms < 0)
619 return -EIO;
620
621 r = dns_packet_new(&p, protocol, ms);
622 if (r < 0)
623 return r;
624
625 iov.iov_base = DNS_PACKET_DATA(p);
626 iov.iov_len = p->allocated;
627
628 mh.msg_name = &sa.sa;
629 mh.msg_namelen = sizeof(sa);
630 mh.msg_iov = &iov;
631 mh.msg_iovlen = 1;
632 mh.msg_control = &control;
633 mh.msg_controllen = sizeof(control);
634
635 l = recvmsg(fd, &mh, 0);
636 if (l < 0) {
637 if (errno == EAGAIN || errno == EINTR)
638 return 0;
639
640 return -errno;
641 }
642
643 if (l <= 0)
644 return -EIO;
645
646 assert(!(mh.msg_flags & MSG_CTRUNC));
647 assert(!(mh.msg_flags & MSG_TRUNC));
648
649 p->size = (size_t) l;
650
651 p->family = sa.sa.sa_family;
652 p->ipproto = IPPROTO_UDP;
653 if (p->family == AF_INET) {
654 p->sender.in = sa.in.sin_addr;
655 p->sender_port = be16toh(sa.in.sin_port);
656 } else if (p->family == AF_INET6) {
657 p->sender.in6 = sa.in6.sin6_addr;
658 p->sender_port = be16toh(sa.in6.sin6_port);
659 p->ifindex = sa.in6.sin6_scope_id;
660 } else
661 return -EAFNOSUPPORT;
662
663 for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
664
665 if (cmsg->cmsg_level == IPPROTO_IPV6) {
666 assert(p->family == AF_INET6);
667
668 switch (cmsg->cmsg_type) {
669
670 case IPV6_PKTINFO: {
671 struct in6_pktinfo *i = (struct in6_pktinfo*) CMSG_DATA(cmsg);
672
673 if (p->ifindex <= 0)
674 p->ifindex = i->ipi6_ifindex;
675
676 p->destination.in6 = i->ipi6_addr;
677 break;
678 }
679
680 case IPV6_HOPLIMIT:
681 p->ttl = *(int *) CMSG_DATA(cmsg);
682 break;
683
684 }
685 } else if (cmsg->cmsg_level == IPPROTO_IP) {
686 assert(p->family == AF_INET);
687
688 switch (cmsg->cmsg_type) {
689
690 case IP_PKTINFO: {
691 struct in_pktinfo *i = (struct in_pktinfo*) CMSG_DATA(cmsg);
692
693 if (p->ifindex <= 0)
694 p->ifindex = i->ipi_ifindex;
695
696 p->destination.in = i->ipi_addr;
697 break;
698 }
699
700 case IP_TTL:
701 p->ttl = *(int *) CMSG_DATA(cmsg);
702 break;
703 }
704 }
705 }
706
707 /* The Linux kernel sets the interface index to the loopback
708 * device if the packet came from the local host since it
709 * avoids the routing table in such a case. Let's unset the
710 * interface index in such a case. */
711 if (p->ifindex > 0 && manager_ifindex_is_loopback(m, p->ifindex) != 0)
712 p->ifindex = 0;
713
714 /* If we don't know the interface index still, we look for the
715 * first local interface with a matching address. Yuck! */
716 if (p->ifindex <= 0)
717 p->ifindex = manager_find_ifindex(m, p->family, &p->destination);
718
719 *ret = p;
720 p = NULL;
721
722 return 1;
723 }
724
725 static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
726 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
727 DnsTransaction *t = NULL;
728 Manager *m = userdata;
729 int r;
730
731 r = manager_recv(m, fd, DNS_PROTOCOL_DNS, &p);
732 if (r <= 0)
733 return r;
734
735 if (dns_packet_validate_reply(p) > 0) {
736 t = hashmap_get(m->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
737 if (!t)
738 return 0;
739
740 dns_transaction_process_reply(t, p);
741
742 } else
743 log_debug("Invalid DNS packet.");
744
745 return 0;
746 }
747
748 int manager_dns_ipv4_fd(Manager *m) {
749 const int one = 1;
750 int r;
751
752 assert(m);
753
754 if (m->dns_ipv4_fd >= 0)
755 return m->dns_ipv4_fd;
756
757 m->dns_ipv4_fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
758 if (m->dns_ipv4_fd < 0)
759 return -errno;
760
761 r = setsockopt(m->dns_ipv4_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
762 if (r < 0) {
763 r = -errno;
764 goto fail;
765 }
766
767 r = sd_event_add_io(m->event, &m->dns_ipv4_event_source, m->dns_ipv4_fd, EPOLLIN, on_dns_packet, m);
768 if (r < 0)
769 goto fail;
770
771 return m->dns_ipv4_fd;
772
773 fail:
774 m->dns_ipv4_fd = safe_close(m->dns_ipv4_fd);
775 return r;
776 }
777
778 int manager_dns_ipv6_fd(Manager *m) {
779 const int one = 1;
780 int r;
781
782 assert(m);
783
784 if (m->dns_ipv6_fd >= 0)
785 return m->dns_ipv6_fd;
786
787 m->dns_ipv6_fd = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
788 if (m->dns_ipv6_fd < 0)
789 return -errno;
790
791 r = setsockopt(m->dns_ipv6_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
792 if (r < 0) {
793 r = -errno;
794 goto fail;
795 }
796
797 r = sd_event_add_io(m->event, &m->dns_ipv6_event_source, m->dns_ipv6_fd, EPOLLIN, on_dns_packet, m);
798 if (r < 0)
799 goto fail;
800
801 return m->dns_ipv6_fd;
802
803 fail:
804 m->dns_ipv6_fd = safe_close(m->dns_ipv6_fd);
805 return r;
806 }
807
808 static int sendmsg_loop(int fd, struct msghdr *mh, int flags) {
809 int r;
810
811 assert(fd >= 0);
812 assert(mh);
813
814 for (;;) {
815 if (sendmsg(fd, mh, flags) >= 0)
816 return 0;
817
818 if (errno == EINTR)
819 continue;
820
821 if (errno != EAGAIN)
822 return -errno;
823
824 r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
825 if (r < 0)
826 return r;
827 if (r == 0)
828 return -ETIMEDOUT;
829 }
830 }
831
832 static int manager_ipv4_send(Manager *m, int fd, int ifindex, const struct in_addr *addr, uint16_t port, DnsPacket *p) {
833 union sockaddr_union sa = {
834 .in.sin_family = AF_INET,
835 };
836 union {
837 struct cmsghdr header; /* For alignment */
838 uint8_t buffer[CMSG_SPACE(sizeof(struct in_pktinfo))];
839 } control;
840 struct msghdr mh = {};
841 struct iovec iov;
842
843 assert(m);
844 assert(fd >= 0);
845 assert(addr);
846 assert(port > 0);
847 assert(p);
848
849 iov.iov_base = DNS_PACKET_DATA(p);
850 iov.iov_len = p->size;
851
852 sa.in.sin_addr = *addr;
853 sa.in.sin_port = htobe16(port),
854
855 mh.msg_iov = &iov;
856 mh.msg_iovlen = 1;
857 mh.msg_name = &sa.sa;
858 mh.msg_namelen = sizeof(sa.in);
859
860 if (ifindex > 0) {
861 struct cmsghdr *cmsg;
862 struct in_pktinfo *pi;
863
864 zero(control);
865
866 mh.msg_control = &control;
867 mh.msg_controllen = CMSG_LEN(sizeof(struct in_pktinfo));
868
869 cmsg = CMSG_FIRSTHDR(&mh);
870 cmsg->cmsg_len = mh.msg_controllen;
871 cmsg->cmsg_level = IPPROTO_IP;
872 cmsg->cmsg_type = IP_PKTINFO;
873
874 pi = (struct in_pktinfo*) CMSG_DATA(cmsg);
875 pi->ipi_ifindex = ifindex;
876 }
877
878 return sendmsg_loop(fd, &mh, 0);
879 }
880
881 static int manager_ipv6_send(Manager *m, int fd, int ifindex, const struct in6_addr *addr, uint16_t port, DnsPacket *p) {
882 union sockaddr_union sa = {
883 .in6.sin6_family = AF_INET6,
884 };
885 union {
886 struct cmsghdr header; /* For alignment */
887 uint8_t buffer[CMSG_SPACE(sizeof(struct in6_pktinfo))];
888 } control;
889 struct msghdr mh = {};
890 struct iovec iov;
891
892 assert(m);
893 assert(fd >= 0);
894 assert(addr);
895 assert(port > 0);
896 assert(p);
897
898 iov.iov_base = DNS_PACKET_DATA(p);
899 iov.iov_len = p->size;
900
901 sa.in6.sin6_addr = *addr;
902 sa.in6.sin6_port = htobe16(port),
903 sa.in6.sin6_scope_id = ifindex;
904
905 mh.msg_iov = &iov;
906 mh.msg_iovlen = 1;
907 mh.msg_name = &sa.sa;
908 mh.msg_namelen = sizeof(sa.in6);
909
910 if (ifindex > 0) {
911 struct cmsghdr *cmsg;
912 struct in6_pktinfo *pi;
913
914 zero(control);
915
916 mh.msg_control = &control;
917 mh.msg_controllen = CMSG_LEN(sizeof(struct in6_pktinfo));
918
919 cmsg = CMSG_FIRSTHDR(&mh);
920 cmsg->cmsg_len = mh.msg_controllen;
921 cmsg->cmsg_level = IPPROTO_IPV6;
922 cmsg->cmsg_type = IPV6_PKTINFO;
923
924 pi = (struct in6_pktinfo*) CMSG_DATA(cmsg);
925 pi->ipi6_ifindex = ifindex;
926 }
927
928 return sendmsg_loop(fd, &mh, 0);
929 }
930
931 int manager_send(Manager *m, int fd, int ifindex, int family, const union in_addr_union *addr, uint16_t port, DnsPacket *p) {
932 assert(m);
933 assert(fd >= 0);
934 assert(addr);
935 assert(port > 0);
936 assert(p);
937
938 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));
939
940 if (family == AF_INET)
941 return manager_ipv4_send(m, fd, ifindex, &addr->in, port, p);
942 else if (family == AF_INET6)
943 return manager_ipv6_send(m, fd, ifindex, &addr->in6, port, p);
944
945 return -EAFNOSUPPORT;
946 }
947
948 bool manager_known_dns_server(Manager *m, int family, const union in_addr_union *in_addr) {
949 DnsServer *s;
950
951 assert(m);
952 assert(in_addr);
953
954 LIST_FOREACH(servers, s, m->dns_servers)
955 if (s->family == family && in_addr_equal(family, &s->address, in_addr))
956 return true;
957
958 LIST_FOREACH(servers, s, m->fallback_dns_servers)
959 if (s->family == family && in_addr_equal(family, &s->address, in_addr))
960 return true;
961
962 return false;
963 }
964
965 static DnsServer *manager_set_dns_server(Manager *m, DnsServer *s) {
966 assert(m);
967
968 if (m->current_dns_server == s)
969 return s;
970
971 if (s) {
972 _cleanup_free_ char *ip = NULL;
973
974 in_addr_to_string(s->family, &s->address, &ip);
975 log_info("Switching to system DNS server %s.", strna(ip));
976 } else
977 log_info("No system DNS server set.");
978
979 m->current_dns_server = s;
980 return s;
981 }
982
983 DnsServer *manager_get_dns_server(Manager *m) {
984 Link *l;
985 assert(m);
986
987 if (!m->current_dns_server)
988 manager_set_dns_server(m, m->dns_servers);
989
990 if (!m->current_dns_server) {
991 bool found = false;
992 Iterator i;
993
994 /* No DNS servers configured, let's see if there are
995 * any on any links. If not, we use the fallback
996 * servers */
997
998 HASHMAP_FOREACH(l, m->links, i)
999 if (l->dns_servers) {
1000 found = true;
1001 break;
1002 }
1003
1004 if (!found)
1005 manager_set_dns_server(m, m->fallback_dns_servers);
1006 }
1007
1008 return m->current_dns_server;
1009 }
1010
1011 void manager_next_dns_server(Manager *m) {
1012 assert(m);
1013
1014 /* If there's currently no DNS server set, then the next
1015 * manager_get_dns_server() will find one */
1016 if (!m->current_dns_server)
1017 return;
1018
1019 /* Change to the next one */
1020 if (m->current_dns_server->servers_next) {
1021 manager_set_dns_server(m, m->current_dns_server->servers_next);
1022 return;
1023 }
1024
1025 /* If there was no next one, then start from the beginning of
1026 * the list */
1027 if (m->current_dns_server->type == DNS_SERVER_FALLBACK)
1028 manager_set_dns_server(m, m->fallback_dns_servers);
1029 else
1030 manager_set_dns_server(m, m->dns_servers);
1031 }
1032
1033 uint32_t manager_find_mtu(Manager *m) {
1034 uint32_t mtu = 0;
1035 Link *l;
1036 Iterator i;
1037
1038 /* If we don't know on which link a DNS packet would be
1039 * delivered, let's find the largest MTU that works on all
1040 * interfaces we know of */
1041
1042 HASHMAP_FOREACH(l, m->links, i) {
1043 if (l->mtu <= 0)
1044 continue;
1045
1046 if (mtu <= 0 || l->mtu < mtu)
1047 mtu = l->mtu;
1048 }
1049
1050 return mtu;
1051 }
1052
1053 static int on_llmnr_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
1054 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
1055 DnsTransaction *t = NULL;
1056 Manager *m = userdata;
1057 int r;
1058
1059 r = manager_recv(m, fd, DNS_PROTOCOL_LLMNR, &p);
1060 if (r <= 0)
1061 return r;
1062
1063 if (dns_packet_validate_reply(p) > 0) {
1064 log_debug("Got reply packet for id %u", DNS_PACKET_ID(p));
1065
1066 t = hashmap_get(m->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
1067 if (!t)
1068 return 0;
1069
1070 dns_transaction_process_reply(t, p);
1071
1072 } else if (dns_packet_validate_query(p) > 0) {
1073 Link *l;
1074
1075 l = hashmap_get(m->links, INT_TO_PTR(p->ifindex));
1076 if (l) {
1077 DnsScope *scope = NULL;
1078
1079 if (p->family == AF_INET)
1080 scope = l->llmnr_ipv4_scope;
1081 else if (p->family == AF_INET6)
1082 scope = l->llmnr_ipv6_scope;
1083
1084 if (scope)
1085 dns_scope_process_query(scope, NULL, p);
1086 }
1087 } else
1088 log_debug("Invalid LLMNR packet.");
1089
1090 return 0;
1091 }
1092
1093 int manager_llmnr_ipv4_udp_fd(Manager *m) {
1094 union sockaddr_union sa = {
1095 .in.sin_family = AF_INET,
1096 .in.sin_port = htobe16(5355),
1097 };
1098 static const int one = 1, pmtu = IP_PMTUDISC_DONT, ttl = 255;
1099 int r;
1100
1101 assert(m);
1102
1103 if (m->llmnr_ipv4_udp_fd >= 0)
1104 return m->llmnr_ipv4_udp_fd;
1105
1106 m->llmnr_ipv4_udp_fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1107 if (m->llmnr_ipv4_udp_fd < 0)
1108 return -errno;
1109
1110 /* RFC 4795, section 2.5 recommends setting the TTL of UDP packets to 255. */
1111 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
1112 if (r < 0) {
1113 r = -errno;
1114 goto fail;
1115 }
1116
1117 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
1118 if (r < 0) {
1119 r = -errno;
1120 goto fail;
1121 }
1122
1123 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MULTICAST_LOOP, &one, sizeof(one));
1124 if (r < 0) {
1125 r = -errno;
1126 goto fail;
1127 }
1128
1129 r = setsockopt(m->llmnr_ipv4_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1130 if (r < 0) {
1131 r = -errno;
1132 goto fail;
1133 }
1134
1135 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
1136 if (r < 0) {
1137 r = -errno;
1138 goto fail;
1139 }
1140
1141 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_RECVTTL, &one, sizeof(one));
1142 if (r < 0) {
1143 r = -errno;
1144 goto fail;
1145 }
1146
1147 /* Disable Don't-Fragment bit in the IP header */
1148 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu));
1149 if (r < 0) {
1150 r = -errno;
1151 goto fail;
1152 }
1153
1154 r = bind(m->llmnr_ipv4_udp_fd, &sa.sa, sizeof(sa.in));
1155 if (r < 0) {
1156 r = -errno;
1157 goto fail;
1158 }
1159
1160 r = sd_event_add_io(m->event, &m->llmnr_ipv4_udp_event_source, m->llmnr_ipv4_udp_fd, EPOLLIN, on_llmnr_packet, m);
1161 if (r < 0)
1162 goto fail;
1163
1164 return m->llmnr_ipv4_udp_fd;
1165
1166 fail:
1167 m->llmnr_ipv4_udp_fd = safe_close(m->llmnr_ipv4_udp_fd);
1168 return r;
1169 }
1170
1171 int manager_llmnr_ipv6_udp_fd(Manager *m) {
1172 union sockaddr_union sa = {
1173 .in6.sin6_family = AF_INET6,
1174 .in6.sin6_port = htobe16(5355),
1175 };
1176 static const int one = 1, ttl = 255;
1177 int r;
1178
1179 assert(m);
1180
1181 if (m->llmnr_ipv6_udp_fd >= 0)
1182 return m->llmnr_ipv6_udp_fd;
1183
1184 m->llmnr_ipv6_udp_fd = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1185 if (m->llmnr_ipv6_udp_fd < 0)
1186 return -errno;
1187
1188 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl));
1189 if (r < 0) {
1190 r = -errno;
1191 goto fail;
1192 }
1193
1194 /* RFC 4795, section 2.5 recommends setting the TTL of UDP packets to 255. */
1195 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl));
1196 if (r < 0) {
1197 r = -errno;
1198 goto fail;
1199 }
1200
1201 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &one, sizeof(one));
1202 if (r < 0) {
1203 r = -errno;
1204 goto fail;
1205 }
1206
1207 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
1208 if (r < 0) {
1209 r = -errno;
1210 goto fail;
1211 }
1212
1213 r = setsockopt(m->llmnr_ipv6_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1214 if (r < 0) {
1215 r = -errno;
1216 goto fail;
1217 }
1218
1219 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
1220 if (r < 0) {
1221 r = -errno;
1222 goto fail;
1223 }
1224
1225 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &one, sizeof(one));
1226 if (r < 0) {
1227 r = -errno;
1228 goto fail;
1229 }
1230
1231 r = bind(m->llmnr_ipv6_udp_fd, &sa.sa, sizeof(sa.in6));
1232 if (r < 0) {
1233 r = -errno;
1234 goto fail;
1235 }
1236
1237 r = sd_event_add_io(m->event, &m->llmnr_ipv6_udp_event_source, m->llmnr_ipv6_udp_fd, EPOLLIN, on_llmnr_packet, m);
1238 if (r < 0) {
1239 r = -errno;
1240 goto fail;
1241 }
1242
1243 return m->llmnr_ipv6_udp_fd;
1244
1245 fail:
1246 m->llmnr_ipv6_udp_fd = safe_close(m->llmnr_ipv6_udp_fd);
1247 return r;
1248 }
1249
1250 static int on_llmnr_stream_packet(DnsStream *s) {
1251 assert(s);
1252
1253 if (dns_packet_validate_query(s->read_packet) > 0) {
1254 Link *l;
1255
1256 l = hashmap_get(s->manager->links, INT_TO_PTR(s->read_packet->ifindex));
1257 if (l) {
1258 DnsScope *scope = NULL;
1259
1260 if (s->read_packet->family == AF_INET)
1261 scope = l->llmnr_ipv4_scope;
1262 else if (s->read_packet->family == AF_INET6)
1263 scope = l->llmnr_ipv6_scope;
1264
1265 if (scope) {
1266 dns_scope_process_query(scope, s, s->read_packet);
1267
1268 /* If no reply packet was set, we free the stream */
1269 if (s->write_packet)
1270 return 0;
1271 }
1272 }
1273 }
1274
1275 dns_stream_free(s);
1276 return 0;
1277 }
1278
1279 static int on_llmnr_stream(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
1280 DnsStream *stream;
1281 Manager *m = userdata;
1282 int cfd, r;
1283
1284 cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
1285 if (cfd < 0) {
1286 if (errno == EAGAIN || errno == EINTR)
1287 return 0;
1288
1289 return -errno;
1290 }
1291
1292 r = dns_stream_new(m, &stream, DNS_PROTOCOL_LLMNR, cfd);
1293 if (r < 0) {
1294 safe_close(cfd);
1295 return r;
1296 }
1297
1298 stream->on_packet = on_llmnr_stream_packet;
1299 return 0;
1300 }
1301
1302 int manager_llmnr_ipv4_tcp_fd(Manager *m) {
1303 union sockaddr_union sa = {
1304 .in.sin_family = AF_INET,
1305 .in.sin_port = htobe16(5355),
1306 };
1307 static const int one = 1, pmtu = IP_PMTUDISC_DONT;
1308 int r;
1309
1310 assert(m);
1311
1312 if (m->llmnr_ipv4_tcp_fd >= 0)
1313 return m->llmnr_ipv4_tcp_fd;
1314
1315 m->llmnr_ipv4_tcp_fd = socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1316 if (m->llmnr_ipv4_tcp_fd < 0)
1317 return -errno;
1318
1319 /* RFC 4795, section 2.5. requires setting the TTL of TCP streams to 1 */
1320 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_TTL, &one, sizeof(one));
1321 if (r < 0) {
1322 r = -errno;
1323 goto fail;
1324 }
1325
1326 r = setsockopt(m->llmnr_ipv4_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1327 if (r < 0) {
1328 r = -errno;
1329 goto fail;
1330 }
1331
1332 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
1333 if (r < 0) {
1334 r = -errno;
1335 goto fail;
1336 }
1337
1338 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_RECVTTL, &one, sizeof(one));
1339 if (r < 0) {
1340 r = -errno;
1341 goto fail;
1342 }
1343
1344 /* Disable Don't-Fragment bit in the IP header */
1345 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu));
1346 if (r < 0) {
1347 r = -errno;
1348 goto fail;
1349 }
1350
1351 r = bind(m->llmnr_ipv4_tcp_fd, &sa.sa, sizeof(sa.in));
1352 if (r < 0) {
1353 r = -errno;
1354 goto fail;
1355 }
1356
1357 r = listen(m->llmnr_ipv4_tcp_fd, SOMAXCONN);
1358 if (r < 0) {
1359 r = -errno;
1360 goto fail;
1361 }
1362
1363 r = sd_event_add_io(m->event, &m->llmnr_ipv4_tcp_event_source, m->llmnr_ipv4_tcp_fd, EPOLLIN, on_llmnr_stream, m);
1364 if (r < 0)
1365 goto fail;
1366
1367 return m->llmnr_ipv4_tcp_fd;
1368
1369 fail:
1370 m->llmnr_ipv4_tcp_fd = safe_close(m->llmnr_ipv4_tcp_fd);
1371 return r;
1372 }
1373
1374 int manager_llmnr_ipv6_tcp_fd(Manager *m) {
1375 union sockaddr_union sa = {
1376 .in6.sin6_family = AF_INET6,
1377 .in6.sin6_port = htobe16(5355),
1378 };
1379 static const int one = 1;
1380 int r;
1381
1382 assert(m);
1383
1384 if (m->llmnr_ipv6_tcp_fd >= 0)
1385 return m->llmnr_ipv6_tcp_fd;
1386
1387 m->llmnr_ipv6_tcp_fd = socket(AF_INET6, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1388 if (m->llmnr_ipv6_tcp_fd < 0)
1389 return -errno;
1390
1391 /* RFC 4795, section 2.5. requires setting the TTL of TCP streams to 1 */
1392 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &one, sizeof(one));
1393 if (r < 0) {
1394 r = -errno;
1395 goto fail;
1396 }
1397
1398 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
1399 if (r < 0) {
1400 r = -errno;
1401 goto fail;
1402 }
1403
1404 r = setsockopt(m->llmnr_ipv6_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1405 if (r < 0) {
1406 r = -errno;
1407 goto fail;
1408 }
1409
1410 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
1411 if (r < 0) {
1412 r = -errno;
1413 goto fail;
1414 }
1415
1416 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &one, sizeof(one));
1417 if (r < 0) {
1418 r = -errno;
1419 goto fail;
1420 }
1421
1422 r = bind(m->llmnr_ipv6_tcp_fd, &sa.sa, sizeof(sa.in6));
1423 if (r < 0) {
1424 r = -errno;
1425 goto fail;
1426 }
1427
1428 r = listen(m->llmnr_ipv6_tcp_fd, SOMAXCONN);
1429 if (r < 0) {
1430 r = -errno;
1431 goto fail;
1432 }
1433
1434 r = sd_event_add_io(m->event, &m->llmnr_ipv6_tcp_event_source, m->llmnr_ipv6_tcp_fd, EPOLLIN, on_llmnr_stream, m);
1435 if (r < 0) {
1436 r = -errno;
1437 goto fail;
1438 }
1439
1440 return m->llmnr_ipv6_tcp_fd;
1441
1442 fail:
1443 m->llmnr_ipv6_tcp_fd = safe_close(m->llmnr_ipv6_tcp_fd);
1444 return r;
1445 }
1446
1447 int manager_ifindex_is_loopback(Manager *m, int ifindex) {
1448 Link *l;
1449 assert(m);
1450
1451 if (ifindex <= 0)
1452 return -EINVAL;
1453
1454 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
1455 if (l->flags & IFF_LOOPBACK)
1456 return 1;
1457
1458 return 0;
1459 }
1460
1461 int manager_find_ifindex(Manager *m, int family, const union in_addr_union *in_addr) {
1462 LinkAddress *a;
1463
1464 assert(m);
1465
1466 a = manager_find_link_address(m, family, in_addr);
1467 if (a)
1468 return a->link->ifindex;
1469
1470 return 0;
1471 }
1472
1473 void manager_refresh_rrs(Manager *m) {
1474 Iterator i;
1475 Link *l;
1476
1477 assert(m);
1478
1479 m->host_ipv4_key = dns_resource_key_unref(m->host_ipv4_key);
1480 m->host_ipv6_key = dns_resource_key_unref(m->host_ipv6_key);
1481
1482 HASHMAP_FOREACH(l, m->links, i) {
1483 link_add_rrs(l, true);
1484 link_add_rrs(l, false);
1485 }
1486 }
1487
1488 int manager_next_hostname(Manager *m) {
1489 const char *p;
1490 uint64_t u;
1491 char *h;
1492
1493 assert(m);
1494
1495 p = strchr(m->hostname, 0);
1496 assert(p);
1497
1498 while (p > m->hostname) {
1499 if (!strchr("0123456789", p[-1]))
1500 break;
1501
1502 p--;
1503 }
1504
1505 if (*p == 0 || safe_atou64(p, &u) < 0 || u <= 0)
1506 u = 1;
1507
1508 u++;
1509
1510 if (asprintf(&h, "%.*s%" PRIu64, (int) (p - m->hostname), m->hostname, u) < 0)
1511 return -ENOMEM;
1512
1513 log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m->hostname, h);
1514
1515 free(m->hostname);
1516 m->hostname = h;
1517
1518 manager_refresh_rrs(m);
1519
1520 return 0;
1521 }
1522
1523 LinkAddress* manager_find_link_address(Manager *m, int family, const union in_addr_union *in_addr) {
1524 Iterator i;
1525 Link *l;
1526
1527 assert(m);
1528
1529 HASHMAP_FOREACH(l, m->links, i) {
1530 LinkAddress *a;
1531
1532 a = link_find_address(l, family, in_addr);
1533 if (a)
1534 return a;
1535 }
1536
1537 return NULL;
1538 }
1539
1540 int manager_our_packet(Manager *m, DnsPacket *p) {
1541 assert(m);
1542 assert(p);
1543
1544 return !!manager_find_link_address(m, p->family, &p->sender);
1545 }
1546
1547 static const char* const support_table[_SUPPORT_MAX] = {
1548 [SUPPORT_NO] = "no",
1549 [SUPPORT_YES] = "yes",
1550 [SUPPORT_RESOLVE] = "resolve",
1551 };
1552 DEFINE_STRING_TABLE_LOOKUP(support, Support);