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