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