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