]> git.ipfire.org Git - thirdparty/systemd.git/blame_incremental - src/resolve/resolved-manager.c
resolved: actually, the peer with the lower IP address wins conflicts
[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_bus_slot_unref(m->prepare_for_sleep_slot);
558 sd_event_source_unref(m->bus_retry_event_source);
559 sd_bus_unref(m->bus);
560
561 sd_event_unref(m->event);
562
563 dns_resource_key_unref(m->host_ipv4_key);
564 dns_resource_key_unref(m->host_ipv6_key);
565
566 safe_close(m->hostname_fd);
567 sd_event_source_unref(m->hostname_event_source);
568 free(m->hostname);
569
570 free(m);
571
572 return NULL;
573}
574
575int manager_read_resolv_conf(Manager *m) {
576 _cleanup_fclose_ FILE *f = NULL;
577 struct stat st, own;
578 char line[LINE_MAX];
579 DnsServer *s, *nx;
580 usec_t t;
581 int r;
582
583 assert(m);
584
585 /* Reads the system /etc/resolv.conf, if it exists and is not
586 * symlinked to our own resolv.conf instance */
587
588 if (!m->read_resolv_conf)
589 return 0;
590
591 r = stat("/etc/resolv.conf", &st);
592 if (r < 0) {
593 if (errno != ENOENT)
594 log_warning("Failed to open /etc/resolv.conf: %m");
595 r = -errno;
596 goto clear;
597 }
598
599 /* Have we already seen the file? */
600 t = timespec_load(&st.st_mtim);
601 if (t == m->resolv_conf_mtime)
602 return 0;
603
604 m->resolv_conf_mtime = t;
605
606 /* Is it symlinked to our own file? */
607 if (stat("/run/systemd/resolve/resolv.conf", &own) >= 0 &&
608 st.st_dev == own.st_dev &&
609 st.st_ino == own.st_ino) {
610 r = 0;
611 goto clear;
612 }
613
614 f = fopen("/etc/resolv.conf", "re");
615 if (!f) {
616 if (errno != ENOENT)
617 log_warning("Failed to open /etc/resolv.conf: %m");
618 r = -errno;
619 goto clear;
620 }
621
622 if (fstat(fileno(f), &st) < 0) {
623 log_error("Failed to stat open file: %m");
624 r = -errno;
625 goto clear;
626 }
627
628 LIST_FOREACH(servers, s, m->dns_servers)
629 s->marked = true;
630
631 FOREACH_LINE(line, f, r = -errno; goto clear) {
632 union in_addr_union address;
633 int family;
634 char *l;
635 const char *a;
636
637 truncate_nl(line);
638
639 l = strstrip(line);
640 if (*l == '#' || *l == ';')
641 continue;
642
643 a = first_word(l, "nameserver");
644 if (!a)
645 continue;
646
647 r = in_addr_from_string_auto(a, &family, &address);
648 if (r < 0) {
649 log_warning("Failed to parse name server %s.", a);
650 continue;
651 }
652
653 LIST_FOREACH(servers, s, m->dns_servers)
654 if (s->family == family && in_addr_equal(family, &s->address, &address) > 0)
655 break;
656
657 if (s)
658 s->marked = false;
659 else {
660 r = dns_server_new(m, NULL, DNS_SERVER_SYSTEM, NULL, family, &address);
661 if (r < 0)
662 goto clear;
663 }
664 }
665
666 LIST_FOREACH_SAFE(servers, s, nx, m->dns_servers)
667 if (s->marked)
668 dns_server_free(s);
669
670 return 0;
671
672clear:
673 while (m->dns_servers)
674 dns_server_free(m->dns_servers);
675
676 return r;
677}
678
679static void write_resolve_conf_server(DnsServer *s, FILE *f, unsigned *count) {
680 _cleanup_free_ char *t = NULL;
681 int r;
682
683 assert(s);
684 assert(f);
685 assert(count);
686
687 r = in_addr_to_string(s->family, &s->address, &t);
688 if (r < 0) {
689 log_warning("Invalid DNS address. Ignoring: %s", strerror(-r));
690 return;
691 }
692
693 if (*count == MAXNS)
694 fputs("# Too many DNS servers configured, the following entries may be ignored\n", f);
695
696 fprintf(f, "nameserver %s\n", t);
697 (*count) ++;
698}
699
700int manager_write_resolv_conf(Manager *m) {
701 static const char path[] = "/run/systemd/resolve/resolv.conf";
702 _cleanup_free_ char *temp_path = NULL;
703 _cleanup_fclose_ FILE *f = NULL;
704 unsigned count = 0;
705 DnsServer *s;
706 Iterator i;
707 Link *l;
708 int r;
709
710 assert(m);
711
712 /* Read the system /etc/resolv.conf first */
713 manager_read_resolv_conf(m);
714
715 r = fopen_temporary(path, &f, &temp_path);
716 if (r < 0)
717 return r;
718
719 fchmod(fileno(f), 0644);
720
721 fputs("# This file is managed by systemd-resolved(8). Do not edit.\n#\n"
722 "# Third party programs must not access this file directly, but\n"
723 "# only through the symlink at /etc/resolv.conf. To manage\n"
724 "# resolv.conf(5) in a different way, replace the symlink by a\n"
725 "# static file or a different symlink.\n\n", f);
726
727 LIST_FOREACH(servers, s, m->dns_servers)
728 write_resolve_conf_server(s, f, &count);
729
730 HASHMAP_FOREACH(l, m->links, i)
731 LIST_FOREACH(servers, s, l->dns_servers)
732 write_resolve_conf_server(s, f, &count);
733
734 if (count == 0) {
735 LIST_FOREACH(servers, s, m->fallback_dns_servers)
736 write_resolve_conf_server(s, f, &count);
737 }
738
739 r = fflush_and_check(f);
740 if (r < 0)
741 goto fail;
742
743 if (rename(temp_path, path) < 0) {
744 r = -errno;
745 goto fail;
746 }
747
748 return 0;
749
750fail:
751 unlink(path);
752 unlink(temp_path);
753 return r;
754}
755
756int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) {
757 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
758 union {
759 struct cmsghdr header; /* For alignment */
760 uint8_t buffer[CMSG_SPACE(MAX(sizeof(struct in_pktinfo), sizeof(struct in6_pktinfo)))
761 + CMSG_SPACE(int) /* ttl/hoplimit */
762 + EXTRA_CMSG_SPACE /* kernel appears to require extra buffer space */];
763 } control;
764 union sockaddr_union sa;
765 struct msghdr mh = {};
766 struct cmsghdr *cmsg;
767 struct iovec iov;
768 int ms = 0, r;
769 ssize_t l;
770
771 assert(m);
772 assert(fd >= 0);
773 assert(ret);
774
775 r = ioctl(fd, FIONREAD, &ms);
776 if (r < 0)
777 return -errno;
778 if (ms < 0)
779 return -EIO;
780
781 r = dns_packet_new(&p, protocol, ms);
782 if (r < 0)
783 return r;
784
785 iov.iov_base = DNS_PACKET_DATA(p);
786 iov.iov_len = p->allocated;
787
788 mh.msg_name = &sa.sa;
789 mh.msg_namelen = sizeof(sa);
790 mh.msg_iov = &iov;
791 mh.msg_iovlen = 1;
792 mh.msg_control = &control;
793 mh.msg_controllen = sizeof(control);
794
795 l = recvmsg(fd, &mh, 0);
796 if (l < 0) {
797 if (errno == EAGAIN || errno == EINTR)
798 return 0;
799
800 return -errno;
801 }
802
803 if (l <= 0)
804 return -EIO;
805
806 assert(!(mh.msg_flags & MSG_CTRUNC));
807 assert(!(mh.msg_flags & MSG_TRUNC));
808
809 p->size = (size_t) l;
810
811 p->family = sa.sa.sa_family;
812 p->ipproto = IPPROTO_UDP;
813 if (p->family == AF_INET) {
814 p->sender.in = sa.in.sin_addr;
815 p->sender_port = be16toh(sa.in.sin_port);
816 } else if (p->family == AF_INET6) {
817 p->sender.in6 = sa.in6.sin6_addr;
818 p->sender_port = be16toh(sa.in6.sin6_port);
819 p->ifindex = sa.in6.sin6_scope_id;
820 } else
821 return -EAFNOSUPPORT;
822
823 for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
824
825 if (cmsg->cmsg_level == IPPROTO_IPV6) {
826 assert(p->family == AF_INET6);
827
828 switch (cmsg->cmsg_type) {
829
830 case IPV6_PKTINFO: {
831 struct in6_pktinfo *i = (struct in6_pktinfo*) CMSG_DATA(cmsg);
832
833 if (p->ifindex <= 0)
834 p->ifindex = i->ipi6_ifindex;
835
836 p->destination.in6 = i->ipi6_addr;
837 break;
838 }
839
840 case IPV6_HOPLIMIT:
841 p->ttl = *(int *) CMSG_DATA(cmsg);
842 break;
843
844 }
845 } else if (cmsg->cmsg_level == IPPROTO_IP) {
846 assert(p->family == AF_INET);
847
848 switch (cmsg->cmsg_type) {
849
850 case IP_PKTINFO: {
851 struct in_pktinfo *i = (struct in_pktinfo*) CMSG_DATA(cmsg);
852
853 if (p->ifindex <= 0)
854 p->ifindex = i->ipi_ifindex;
855
856 p->destination.in = i->ipi_addr;
857 break;
858 }
859
860 case IP_TTL:
861 p->ttl = *(int *) CMSG_DATA(cmsg);
862 break;
863 }
864 }
865 }
866
867 /* The Linux kernel sets the interface index to the loopback
868 * device if the packet came from the local host since it
869 * avoids the routing table in such a case. Let's unset the
870 * interface index in such a case. */
871 if (p->ifindex > 0 && manager_ifindex_is_loopback(m, p->ifindex) != 0)
872 p->ifindex = 0;
873
874 /* If we don't know the interface index still, we look for the
875 * first local interface with a matching address. Yuck! */
876 if (p->ifindex <= 0)
877 p->ifindex = manager_find_ifindex(m, p->family, &p->destination);
878
879 *ret = p;
880 p = NULL;
881
882 return 1;
883}
884
885static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
886 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
887 DnsTransaction *t = NULL;
888 Manager *m = userdata;
889 int r;
890
891 r = manager_recv(m, fd, DNS_PROTOCOL_DNS, &p);
892 if (r <= 0)
893 return r;
894
895 if (dns_packet_validate_reply(p) > 0) {
896 t = hashmap_get(m->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
897 if (!t)
898 return 0;
899
900 dns_transaction_process_reply(t, p);
901
902 } else
903 log_debug("Invalid DNS packet.");
904
905 return 0;
906}
907
908int manager_dns_ipv4_fd(Manager *m) {
909 const int one = 1;
910 int r;
911
912 assert(m);
913
914 if (m->dns_ipv4_fd >= 0)
915 return m->dns_ipv4_fd;
916
917 m->dns_ipv4_fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
918 if (m->dns_ipv4_fd < 0)
919 return -errno;
920
921 r = setsockopt(m->dns_ipv4_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
922 if (r < 0) {
923 r = -errno;
924 goto fail;
925 }
926
927 r = sd_event_add_io(m->event, &m->dns_ipv4_event_source, m->dns_ipv4_fd, EPOLLIN, on_dns_packet, m);
928 if (r < 0)
929 goto fail;
930
931 return m->dns_ipv4_fd;
932
933fail:
934 m->dns_ipv4_fd = safe_close(m->dns_ipv4_fd);
935 return r;
936}
937
938int manager_dns_ipv6_fd(Manager *m) {
939 const int one = 1;
940 int r;
941
942 assert(m);
943
944 if (m->dns_ipv6_fd >= 0)
945 return m->dns_ipv6_fd;
946
947 m->dns_ipv6_fd = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
948 if (m->dns_ipv6_fd < 0)
949 return -errno;
950
951 r = setsockopt(m->dns_ipv6_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
952 if (r < 0) {
953 r = -errno;
954 goto fail;
955 }
956
957 r = sd_event_add_io(m->event, &m->dns_ipv6_event_source, m->dns_ipv6_fd, EPOLLIN, on_dns_packet, m);
958 if (r < 0)
959 goto fail;
960
961 return m->dns_ipv6_fd;
962
963fail:
964 m->dns_ipv6_fd = safe_close(m->dns_ipv6_fd);
965 return r;
966}
967
968static int sendmsg_loop(int fd, struct msghdr *mh, int flags) {
969 int r;
970
971 assert(fd >= 0);
972 assert(mh);
973
974 for (;;) {
975 if (sendmsg(fd, mh, flags) >= 0)
976 return 0;
977
978 if (errno == EINTR)
979 continue;
980
981 if (errno != EAGAIN)
982 return -errno;
983
984 r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
985 if (r < 0)
986 return r;
987 if (r == 0)
988 return -ETIMEDOUT;
989 }
990}
991
992static int manager_ipv4_send(Manager *m, int fd, int ifindex, const struct in_addr *addr, uint16_t port, DnsPacket *p) {
993 union sockaddr_union sa = {
994 .in.sin_family = AF_INET,
995 };
996 union {
997 struct cmsghdr header; /* For alignment */
998 uint8_t buffer[CMSG_SPACE(sizeof(struct in_pktinfo))];
999 } control;
1000 struct msghdr mh = {};
1001 struct iovec iov;
1002
1003 assert(m);
1004 assert(fd >= 0);
1005 assert(addr);
1006 assert(port > 0);
1007 assert(p);
1008
1009 iov.iov_base = DNS_PACKET_DATA(p);
1010 iov.iov_len = p->size;
1011
1012 sa.in.sin_addr = *addr;
1013 sa.in.sin_port = htobe16(port),
1014
1015 mh.msg_iov = &iov;
1016 mh.msg_iovlen = 1;
1017 mh.msg_name = &sa.sa;
1018 mh.msg_namelen = sizeof(sa.in);
1019
1020 if (ifindex > 0) {
1021 struct cmsghdr *cmsg;
1022 struct in_pktinfo *pi;
1023
1024 zero(control);
1025
1026 mh.msg_control = &control;
1027 mh.msg_controllen = CMSG_LEN(sizeof(struct in_pktinfo));
1028
1029 cmsg = CMSG_FIRSTHDR(&mh);
1030 cmsg->cmsg_len = mh.msg_controllen;
1031 cmsg->cmsg_level = IPPROTO_IP;
1032 cmsg->cmsg_type = IP_PKTINFO;
1033
1034 pi = (struct in_pktinfo*) CMSG_DATA(cmsg);
1035 pi->ipi_ifindex = ifindex;
1036 }
1037
1038 return sendmsg_loop(fd, &mh, 0);
1039}
1040
1041static int manager_ipv6_send(Manager *m, int fd, int ifindex, const struct in6_addr *addr, uint16_t port, DnsPacket *p) {
1042 union sockaddr_union sa = {
1043 .in6.sin6_family = AF_INET6,
1044 };
1045 union {
1046 struct cmsghdr header; /* For alignment */
1047 uint8_t buffer[CMSG_SPACE(sizeof(struct in6_pktinfo))];
1048 } control;
1049 struct msghdr mh = {};
1050 struct iovec iov;
1051
1052 assert(m);
1053 assert(fd >= 0);
1054 assert(addr);
1055 assert(port > 0);
1056 assert(p);
1057
1058 iov.iov_base = DNS_PACKET_DATA(p);
1059 iov.iov_len = p->size;
1060
1061 sa.in6.sin6_addr = *addr;
1062 sa.in6.sin6_port = htobe16(port),
1063 sa.in6.sin6_scope_id = ifindex;
1064
1065 mh.msg_iov = &iov;
1066 mh.msg_iovlen = 1;
1067 mh.msg_name = &sa.sa;
1068 mh.msg_namelen = sizeof(sa.in6);
1069
1070 if (ifindex > 0) {
1071 struct cmsghdr *cmsg;
1072 struct in6_pktinfo *pi;
1073
1074 zero(control);
1075
1076 mh.msg_control = &control;
1077 mh.msg_controllen = CMSG_LEN(sizeof(struct in6_pktinfo));
1078
1079 cmsg = CMSG_FIRSTHDR(&mh);
1080 cmsg->cmsg_len = mh.msg_controllen;
1081 cmsg->cmsg_level = IPPROTO_IPV6;
1082 cmsg->cmsg_type = IPV6_PKTINFO;
1083
1084 pi = (struct in6_pktinfo*) CMSG_DATA(cmsg);
1085 pi->ipi6_ifindex = ifindex;
1086 }
1087
1088 return sendmsg_loop(fd, &mh, 0);
1089}
1090
1091int manager_send(Manager *m, int fd, int ifindex, int family, const union in_addr_union *addr, uint16_t port, DnsPacket *p) {
1092 assert(m);
1093 assert(fd >= 0);
1094 assert(addr);
1095 assert(port > 0);
1096 assert(p);
1097
1098 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));
1099
1100 if (family == AF_INET)
1101 return manager_ipv4_send(m, fd, ifindex, &addr->in, port, p);
1102 else if (family == AF_INET6)
1103 return manager_ipv6_send(m, fd, ifindex, &addr->in6, port, p);
1104
1105 return -EAFNOSUPPORT;
1106}
1107
1108DnsServer* manager_find_dns_server(Manager *m, int family, const union in_addr_union *in_addr) {
1109 DnsServer *s;
1110
1111 assert(m);
1112 assert(in_addr);
1113
1114 LIST_FOREACH(servers, s, m->dns_servers)
1115 if (s->family == family && in_addr_equal(family, &s->address, in_addr) > 0)
1116 return s;
1117
1118 LIST_FOREACH(servers, s, m->fallback_dns_servers)
1119 if (s->family == family && in_addr_equal(family, &s->address, in_addr) > 0)
1120 return s;
1121
1122 return NULL;
1123}
1124
1125DnsServer *manager_set_dns_server(Manager *m, DnsServer *s) {
1126 assert(m);
1127
1128 if (m->current_dns_server == s)
1129 return s;
1130
1131 if (s) {
1132 _cleanup_free_ char *ip = NULL;
1133
1134 in_addr_to_string(s->family, &s->address, &ip);
1135 log_info("Switching to system DNS server %s.", strna(ip));
1136 }
1137
1138 m->current_dns_server = s;
1139
1140 if (m->unicast_scope)
1141 dns_cache_flush(&m->unicast_scope->cache);
1142
1143 return s;
1144}
1145
1146DnsServer *manager_get_dns_server(Manager *m) {
1147 Link *l;
1148 assert(m);
1149
1150 /* Try to read updates resolv.conf */
1151 manager_read_resolv_conf(m);
1152
1153 if (!m->current_dns_server)
1154 manager_set_dns_server(m, m->dns_servers);
1155
1156 if (!m->current_dns_server) {
1157 bool found = false;
1158 Iterator i;
1159
1160 /* No DNS servers configured, let's see if there are
1161 * any on any links. If not, we use the fallback
1162 * servers */
1163
1164 HASHMAP_FOREACH(l, m->links, i)
1165 if (l->dns_servers) {
1166 found = true;
1167 break;
1168 }
1169
1170 if (!found)
1171 manager_set_dns_server(m, m->fallback_dns_servers);
1172 }
1173
1174 return m->current_dns_server;
1175}
1176
1177void manager_next_dns_server(Manager *m) {
1178 assert(m);
1179
1180 /* If there's currently no DNS server set, then the next
1181 * manager_get_dns_server() will find one */
1182 if (!m->current_dns_server)
1183 return;
1184
1185 /* Change to the next one */
1186 if (m->current_dns_server->servers_next) {
1187 manager_set_dns_server(m, m->current_dns_server->servers_next);
1188 return;
1189 }
1190
1191 /* If there was no next one, then start from the beginning of
1192 * the list */
1193 if (m->current_dns_server->type == DNS_SERVER_FALLBACK)
1194 manager_set_dns_server(m, m->fallback_dns_servers);
1195 else
1196 manager_set_dns_server(m, m->dns_servers);
1197}
1198
1199uint32_t manager_find_mtu(Manager *m) {
1200 uint32_t mtu = 0;
1201 Link *l;
1202 Iterator i;
1203
1204 /* If we don't know on which link a DNS packet would be
1205 * delivered, let's find the largest MTU that works on all
1206 * interfaces we know of */
1207
1208 HASHMAP_FOREACH(l, m->links, i) {
1209 if (l->mtu <= 0)
1210 continue;
1211
1212 if (mtu <= 0 || l->mtu < mtu)
1213 mtu = l->mtu;
1214 }
1215
1216 return mtu;
1217}
1218
1219static int on_llmnr_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
1220 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
1221 DnsTransaction *t = NULL;
1222 Manager *m = userdata;
1223 DnsScope *scope;
1224 int r;
1225
1226 r = manager_recv(m, fd, DNS_PROTOCOL_LLMNR, &p);
1227 if (r <= 0)
1228 return r;
1229
1230 scope = manager_find_scope(m, p);
1231 if (!scope) {
1232 log_warning("Got LLMNR UDP packet on unknown scope. Ignoring.");
1233 return 0;
1234 }
1235
1236 if (dns_packet_validate_reply(p) > 0) {
1237 log_debug("Got reply packet for id %u", DNS_PACKET_ID(p));
1238
1239 dns_scope_check_conflicts(scope, p);
1240
1241 t = hashmap_get(m->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
1242 if (t)
1243 dns_transaction_process_reply(t, p);
1244
1245 } else if (dns_packet_validate_query(p) > 0) {
1246 log_debug("Got query packet for id %u", DNS_PACKET_ID(p));
1247
1248 dns_scope_process_query(scope, NULL, p);
1249 } else
1250 log_debug("Invalid LLMNR UDP packet.");
1251
1252 return 0;
1253}
1254
1255int manager_llmnr_ipv4_udp_fd(Manager *m) {
1256 union sockaddr_union sa = {
1257 .in.sin_family = AF_INET,
1258 .in.sin_port = htobe16(5355),
1259 };
1260 static const int one = 1, pmtu = IP_PMTUDISC_DONT, ttl = 255;
1261 int r;
1262
1263 assert(m);
1264
1265 if (m->llmnr_ipv4_udp_fd >= 0)
1266 return m->llmnr_ipv4_udp_fd;
1267
1268 m->llmnr_ipv4_udp_fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1269 if (m->llmnr_ipv4_udp_fd < 0)
1270 return -errno;
1271
1272 /* RFC 4795, section 2.5 recommends setting the TTL of UDP packets to 255. */
1273 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
1274 if (r < 0) {
1275 r = -errno;
1276 goto fail;
1277 }
1278
1279 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
1280 if (r < 0) {
1281 r = -errno;
1282 goto fail;
1283 }
1284
1285 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MULTICAST_LOOP, &one, sizeof(one));
1286 if (r < 0) {
1287 r = -errno;
1288 goto fail;
1289 }
1290
1291 r = setsockopt(m->llmnr_ipv4_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1292 if (r < 0) {
1293 r = -errno;
1294 goto fail;
1295 }
1296
1297 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
1298 if (r < 0) {
1299 r = -errno;
1300 goto fail;
1301 }
1302
1303 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_RECVTTL, &one, sizeof(one));
1304 if (r < 0) {
1305 r = -errno;
1306 goto fail;
1307 }
1308
1309 /* Disable Don't-Fragment bit in the IP header */
1310 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu));
1311 if (r < 0) {
1312 r = -errno;
1313 goto fail;
1314 }
1315
1316 r = bind(m->llmnr_ipv4_udp_fd, &sa.sa, sizeof(sa.in));
1317 if (r < 0) {
1318 r = -errno;
1319 goto fail;
1320 }
1321
1322 r = sd_event_add_io(m->event, &m->llmnr_ipv4_udp_event_source, m->llmnr_ipv4_udp_fd, EPOLLIN, on_llmnr_packet, m);
1323 if (r < 0)
1324 goto fail;
1325
1326 return m->llmnr_ipv4_udp_fd;
1327
1328fail:
1329 m->llmnr_ipv4_udp_fd = safe_close(m->llmnr_ipv4_udp_fd);
1330 return r;
1331}
1332
1333int manager_llmnr_ipv6_udp_fd(Manager *m) {
1334 union sockaddr_union sa = {
1335 .in6.sin6_family = AF_INET6,
1336 .in6.sin6_port = htobe16(5355),
1337 };
1338 static const int one = 1, ttl = 255;
1339 int r;
1340
1341 assert(m);
1342
1343 if (m->llmnr_ipv6_udp_fd >= 0)
1344 return m->llmnr_ipv6_udp_fd;
1345
1346 m->llmnr_ipv6_udp_fd = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1347 if (m->llmnr_ipv6_udp_fd < 0)
1348 return -errno;
1349
1350 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl));
1351 if (r < 0) {
1352 r = -errno;
1353 goto fail;
1354 }
1355
1356 /* RFC 4795, section 2.5 recommends setting the TTL of UDP packets to 255. */
1357 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl));
1358 if (r < 0) {
1359 r = -errno;
1360 goto fail;
1361 }
1362
1363 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &one, sizeof(one));
1364 if (r < 0) {
1365 r = -errno;
1366 goto fail;
1367 }
1368
1369 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
1370 if (r < 0) {
1371 r = -errno;
1372 goto fail;
1373 }
1374
1375 r = setsockopt(m->llmnr_ipv6_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1376 if (r < 0) {
1377 r = -errno;
1378 goto fail;
1379 }
1380
1381 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
1382 if (r < 0) {
1383 r = -errno;
1384 goto fail;
1385 }
1386
1387 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &one, sizeof(one));
1388 if (r < 0) {
1389 r = -errno;
1390 goto fail;
1391 }
1392
1393 r = bind(m->llmnr_ipv6_udp_fd, &sa.sa, sizeof(sa.in6));
1394 if (r < 0) {
1395 r = -errno;
1396 goto fail;
1397 }
1398
1399 r = sd_event_add_io(m->event, &m->llmnr_ipv6_udp_event_source, m->llmnr_ipv6_udp_fd, EPOLLIN, on_llmnr_packet, m);
1400 if (r < 0) {
1401 r = -errno;
1402 goto fail;
1403 }
1404
1405 return m->llmnr_ipv6_udp_fd;
1406
1407fail:
1408 m->llmnr_ipv6_udp_fd = safe_close(m->llmnr_ipv6_udp_fd);
1409 return r;
1410}
1411
1412static int on_llmnr_stream_packet(DnsStream *s) {
1413 DnsScope *scope;
1414
1415 assert(s);
1416
1417 scope = manager_find_scope(s->manager, s->read_packet);
1418 if (!scope) {
1419 log_warning("Got LLMNR TCP packet on unknown scope. Ignroing.");
1420 return 0;
1421 }
1422
1423 if (dns_packet_validate_query(s->read_packet) > 0) {
1424 log_debug("Got query packet for id %u", DNS_PACKET_ID(s->read_packet));
1425
1426 dns_scope_process_query(scope, s, s->read_packet);
1427
1428 /* If no reply packet was set, we free the stream */
1429 if (s->write_packet)
1430 return 0;
1431 } else
1432 log_debug("Invalid LLMNR TCP packet.");
1433
1434 dns_stream_free(s);
1435 return 0;
1436}
1437
1438static int on_llmnr_stream(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
1439 DnsStream *stream;
1440 Manager *m = userdata;
1441 int cfd, r;
1442
1443 cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
1444 if (cfd < 0) {
1445 if (errno == EAGAIN || errno == EINTR)
1446 return 0;
1447
1448 return -errno;
1449 }
1450
1451 r = dns_stream_new(m, &stream, DNS_PROTOCOL_LLMNR, cfd);
1452 if (r < 0) {
1453 safe_close(cfd);
1454 return r;
1455 }
1456
1457 stream->on_packet = on_llmnr_stream_packet;
1458 return 0;
1459}
1460
1461int manager_llmnr_ipv4_tcp_fd(Manager *m) {
1462 union sockaddr_union sa = {
1463 .in.sin_family = AF_INET,
1464 .in.sin_port = htobe16(5355),
1465 };
1466 static const int one = 1, pmtu = IP_PMTUDISC_DONT;
1467 int r;
1468
1469 assert(m);
1470
1471 if (m->llmnr_ipv4_tcp_fd >= 0)
1472 return m->llmnr_ipv4_tcp_fd;
1473
1474 m->llmnr_ipv4_tcp_fd = socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1475 if (m->llmnr_ipv4_tcp_fd < 0)
1476 return -errno;
1477
1478 /* RFC 4795, section 2.5. requires setting the TTL of TCP streams to 1 */
1479 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_TTL, &one, sizeof(one));
1480 if (r < 0) {
1481 r = -errno;
1482 goto fail;
1483 }
1484
1485 r = setsockopt(m->llmnr_ipv4_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1486 if (r < 0) {
1487 r = -errno;
1488 goto fail;
1489 }
1490
1491 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
1492 if (r < 0) {
1493 r = -errno;
1494 goto fail;
1495 }
1496
1497 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_RECVTTL, &one, sizeof(one));
1498 if (r < 0) {
1499 r = -errno;
1500 goto fail;
1501 }
1502
1503 /* Disable Don't-Fragment bit in the IP header */
1504 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu));
1505 if (r < 0) {
1506 r = -errno;
1507 goto fail;
1508 }
1509
1510 r = bind(m->llmnr_ipv4_tcp_fd, &sa.sa, sizeof(sa.in));
1511 if (r < 0) {
1512 r = -errno;
1513 goto fail;
1514 }
1515
1516 r = listen(m->llmnr_ipv4_tcp_fd, SOMAXCONN);
1517 if (r < 0) {
1518 r = -errno;
1519 goto fail;
1520 }
1521
1522 r = sd_event_add_io(m->event, &m->llmnr_ipv4_tcp_event_source, m->llmnr_ipv4_tcp_fd, EPOLLIN, on_llmnr_stream, m);
1523 if (r < 0)
1524 goto fail;
1525
1526 return m->llmnr_ipv4_tcp_fd;
1527
1528fail:
1529 m->llmnr_ipv4_tcp_fd = safe_close(m->llmnr_ipv4_tcp_fd);
1530 return r;
1531}
1532
1533int manager_llmnr_ipv6_tcp_fd(Manager *m) {
1534 union sockaddr_union sa = {
1535 .in6.sin6_family = AF_INET6,
1536 .in6.sin6_port = htobe16(5355),
1537 };
1538 static const int one = 1;
1539 int r;
1540
1541 assert(m);
1542
1543 if (m->llmnr_ipv6_tcp_fd >= 0)
1544 return m->llmnr_ipv6_tcp_fd;
1545
1546 m->llmnr_ipv6_tcp_fd = socket(AF_INET6, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1547 if (m->llmnr_ipv6_tcp_fd < 0)
1548 return -errno;
1549
1550 /* RFC 4795, section 2.5. requires setting the TTL of TCP streams to 1 */
1551 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &one, sizeof(one));
1552 if (r < 0) {
1553 r = -errno;
1554 goto fail;
1555 }
1556
1557 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
1558 if (r < 0) {
1559 r = -errno;
1560 goto fail;
1561 }
1562
1563 r = setsockopt(m->llmnr_ipv6_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1564 if (r < 0) {
1565 r = -errno;
1566 goto fail;
1567 }
1568
1569 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
1570 if (r < 0) {
1571 r = -errno;
1572 goto fail;
1573 }
1574
1575 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &one, sizeof(one));
1576 if (r < 0) {
1577 r = -errno;
1578 goto fail;
1579 }
1580
1581 r = bind(m->llmnr_ipv6_tcp_fd, &sa.sa, sizeof(sa.in6));
1582 if (r < 0) {
1583 r = -errno;
1584 goto fail;
1585 }
1586
1587 r = listen(m->llmnr_ipv6_tcp_fd, SOMAXCONN);
1588 if (r < 0) {
1589 r = -errno;
1590 goto fail;
1591 }
1592
1593 r = sd_event_add_io(m->event, &m->llmnr_ipv6_tcp_event_source, m->llmnr_ipv6_tcp_fd, EPOLLIN, on_llmnr_stream, m);
1594 if (r < 0) {
1595 r = -errno;
1596 goto fail;
1597 }
1598
1599 return m->llmnr_ipv6_tcp_fd;
1600
1601fail:
1602 m->llmnr_ipv6_tcp_fd = safe_close(m->llmnr_ipv6_tcp_fd);
1603 return r;
1604}
1605
1606int manager_ifindex_is_loopback(Manager *m, int ifindex) {
1607 Link *l;
1608 assert(m);
1609
1610 if (ifindex <= 0)
1611 return -EINVAL;
1612
1613 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
1614 if (l->flags & IFF_LOOPBACK)
1615 return 1;
1616
1617 return 0;
1618}
1619
1620int manager_find_ifindex(Manager *m, int family, const union in_addr_union *in_addr) {
1621 LinkAddress *a;
1622
1623 assert(m);
1624
1625 a = manager_find_link_address(m, family, in_addr);
1626 if (a)
1627 return a->link->ifindex;
1628
1629 return 0;
1630}
1631
1632void manager_refresh_rrs(Manager *m) {
1633 Iterator i;
1634 Link *l;
1635
1636 assert(m);
1637
1638 m->host_ipv4_key = dns_resource_key_unref(m->host_ipv4_key);
1639 m->host_ipv6_key = dns_resource_key_unref(m->host_ipv6_key);
1640
1641 HASHMAP_FOREACH(l, m->links, i) {
1642 link_add_rrs(l, true);
1643 link_add_rrs(l, false);
1644 }
1645}
1646
1647int manager_next_hostname(Manager *m) {
1648 const char *p;
1649 uint64_t u;
1650 char *h;
1651
1652 assert(m);
1653
1654 p = strchr(m->hostname, 0);
1655 assert(p);
1656
1657 while (p > m->hostname) {
1658 if (!strchr("0123456789", p[-1]))
1659 break;
1660
1661 p--;
1662 }
1663
1664 if (*p == 0 || safe_atou64(p, &u) < 0 || u <= 0)
1665 u = 1;
1666
1667 u++;
1668
1669 if (asprintf(&h, "%.*s%" PRIu64, (int) (p - m->hostname), m->hostname, u) < 0)
1670 return -ENOMEM;
1671
1672 log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m->hostname, h);
1673
1674 free(m->hostname);
1675 m->hostname = h;
1676
1677 manager_refresh_rrs(m);
1678
1679 return 0;
1680}
1681
1682LinkAddress* manager_find_link_address(Manager *m, int family, const union in_addr_union *in_addr) {
1683 Iterator i;
1684 Link *l;
1685
1686 assert(m);
1687
1688 HASHMAP_FOREACH(l, m->links, i) {
1689 LinkAddress *a;
1690
1691 a = link_find_address(l, family, in_addr);
1692 if (a)
1693 return a;
1694 }
1695
1696 return NULL;
1697}
1698
1699bool manager_our_packet(Manager *m, DnsPacket *p) {
1700 assert(m);
1701 assert(p);
1702
1703 return !!manager_find_link_address(m, p->family, &p->sender);
1704}
1705
1706DnsScope* manager_find_scope(Manager *m, DnsPacket *p) {
1707 Link *l;
1708
1709 assert(m);
1710 assert(p);
1711
1712 l = hashmap_get(m->links, INT_TO_PTR(p->ifindex));
1713 if (!l)
1714 return NULL;
1715
1716 if (p->protocol == DNS_PROTOCOL_LLMNR) {
1717 if (p->family == AF_INET)
1718 return l->llmnr_ipv4_scope;
1719 else if (p->family == AF_INET6)
1720 return l->llmnr_ipv6_scope;
1721 }
1722
1723 return NULL;
1724}
1725
1726void manager_verify_all(Manager *m) {
1727 DnsScope *s;
1728
1729 assert(m);
1730
1731 LIST_FOREACH(scopes, s, m->dns_scopes)
1732 dns_zone_verify_all(&s->zone);
1733}
1734
1735static const char* const support_table[_SUPPORT_MAX] = {
1736 [SUPPORT_NO] = "no",
1737 [SUPPORT_YES] = "yes",
1738 [SUPPORT_RESOLVE] = "resolve",
1739};
1740DEFINE_STRING_TABLE_LOOKUP(support, Support);