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