]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-manager.c
util-lib: split string parsing related calls from util.[ch] into parse-util.[ch]
[thirdparty/systemd.git] / src / resolve / resolved-manager.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2014 Tom Gundersen <teg@jklm.no>
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <netinet/in.h>
23 #include <poll.h>
24 #include <resolv.h>
25 #include <sys/ioctl.h>
26
27 #include "af-list.h"
28 #include "dns-domain.h"
29 #include "fd-util.h"
30 #include "fileio-label.h"
31 #include "hostname-util.h"
32 #include "io-util.h"
33 #include "netlink-util.h"
34 #include "network-internal.h"
35 #include "ordered-set.h"
36 #include "parse-util.h"
37 #include "random-util.h"
38 #include "resolved-bus.h"
39 #include "resolved-conf.h"
40 #include "resolved-llmnr.h"
41 #include "resolved-manager.h"
42 #include "socket-util.h"
43 #include "string-util.h"
44 #include "utf8.h"
45
46 #define SEND_TIMEOUT_USEC (200 * USEC_PER_MSEC)
47
48 static int manager_process_link(sd_netlink *rtnl, sd_netlink_message *mm, void *userdata) {
49 Manager *m = userdata;
50 uint16_t type;
51 Link *l;
52 int ifindex, r;
53
54 assert(rtnl);
55 assert(m);
56 assert(mm);
57
58 r = sd_netlink_message_get_type(mm, &type);
59 if (r < 0)
60 goto fail;
61
62 r = sd_rtnl_message_link_get_ifindex(mm, &ifindex);
63 if (r < 0)
64 goto fail;
65
66 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
67
68 switch (type) {
69
70 case RTM_NEWLINK:{
71 bool is_new = !l;
72
73 if (!l) {
74 r = link_new(m, &l, ifindex);
75 if (r < 0)
76 goto fail;
77 }
78
79 r = link_update_rtnl(l, mm);
80 if (r < 0)
81 goto fail;
82
83 r = link_update_monitor(l);
84 if (r < 0)
85 goto fail;
86
87 if (is_new)
88 log_debug("Found new link %i/%s", ifindex, l->name);
89
90 break;
91 }
92
93 case RTM_DELLINK:
94 if (l) {
95 log_debug("Removing link %i/%s", l->ifindex, l->name);
96 link_free(l);
97 }
98
99 break;
100 }
101
102 return 0;
103
104 fail:
105 log_warning_errno(r, "Failed to process RTNL link message: %m");
106 return 0;
107 }
108
109 static int manager_process_address(sd_netlink *rtnl, sd_netlink_message *mm, void *userdata) {
110 Manager *m = userdata;
111 union in_addr_union address;
112 uint16_t type;
113 int r, ifindex, family;
114 LinkAddress *a;
115 Link *l;
116
117 assert(rtnl);
118 assert(mm);
119 assert(m);
120
121 r = sd_netlink_message_get_type(mm, &type);
122 if (r < 0)
123 goto fail;
124
125 r = sd_rtnl_message_addr_get_ifindex(mm, &ifindex);
126 if (r < 0)
127 goto fail;
128
129 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
130 if (!l)
131 return 0;
132
133 r = sd_rtnl_message_addr_get_family(mm, &family);
134 if (r < 0)
135 goto fail;
136
137 switch (family) {
138
139 case AF_INET:
140 r = sd_netlink_message_read_in_addr(mm, IFA_LOCAL, &address.in);
141 if (r < 0) {
142 r = sd_netlink_message_read_in_addr(mm, IFA_ADDRESS, &address.in);
143 if (r < 0)
144 goto fail;
145 }
146
147 break;
148
149 case AF_INET6:
150 r = sd_netlink_message_read_in6_addr(mm, IFA_LOCAL, &address.in6);
151 if (r < 0) {
152 r = sd_netlink_message_read_in6_addr(mm, IFA_ADDRESS, &address.in6);
153 if (r < 0)
154 goto fail;
155 }
156
157 break;
158
159 default:
160 return 0;
161 }
162
163 a = link_find_address(l, family, &address);
164
165 switch (type) {
166
167 case RTM_NEWADDR:
168
169 if (!a) {
170 r = link_address_new(l, &a, family, &address);
171 if (r < 0)
172 return r;
173 }
174
175 r = link_address_update_rtnl(a, mm);
176 if (r < 0)
177 return r;
178
179 break;
180
181 case RTM_DELADDR:
182 link_address_free(a);
183 break;
184 }
185
186 return 0;
187
188 fail:
189 log_warning_errno(r, "Failed to process RTNL address message: %m");
190 return 0;
191 }
192
193 static int manager_rtnl_listen(Manager *m) {
194 _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL, *reply = NULL;
195 sd_netlink_message *i;
196 int r;
197
198 assert(m);
199
200 /* First, subscribe to interfaces coming and going */
201 r = sd_netlink_open(&m->rtnl);
202 if (r < 0)
203 return r;
204
205 r = sd_netlink_attach_event(m->rtnl, m->event, 0);
206 if (r < 0)
207 return r;
208
209 r = sd_netlink_add_match(m->rtnl, RTM_NEWLINK, manager_process_link, m);
210 if (r < 0)
211 return r;
212
213 r = sd_netlink_add_match(m->rtnl, RTM_DELLINK, manager_process_link, m);
214 if (r < 0)
215 return r;
216
217 r = sd_netlink_add_match(m->rtnl, RTM_NEWADDR, manager_process_address, m);
218 if (r < 0)
219 return r;
220
221 r = sd_netlink_add_match(m->rtnl, RTM_DELADDR, manager_process_address, m);
222 if (r < 0)
223 return r;
224
225 /* Then, enumerate all links */
226 r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
227 if (r < 0)
228 return r;
229
230 r = sd_netlink_message_request_dump(req, true);
231 if (r < 0)
232 return r;
233
234 r = sd_netlink_call(m->rtnl, req, 0, &reply);
235 if (r < 0)
236 return r;
237
238 for (i = reply; i; i = sd_netlink_message_next(i)) {
239 r = manager_process_link(m->rtnl, i, m);
240 if (r < 0)
241 return r;
242 }
243
244 req = sd_netlink_message_unref(req);
245 reply = sd_netlink_message_unref(reply);
246
247 /* Finally, enumerate all addresses, too */
248 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, AF_UNSPEC);
249 if (r < 0)
250 return r;
251
252 r = sd_netlink_message_request_dump(req, true);
253 if (r < 0)
254 return r;
255
256 r = sd_netlink_call(m->rtnl, req, 0, &reply);
257 if (r < 0)
258 return r;
259
260 for (i = reply; i; i = sd_netlink_message_next(i)) {
261 r = manager_process_address(m->rtnl, i, m);
262 if (r < 0)
263 return r;
264 }
265
266 return r;
267 }
268
269 static int on_network_event(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
270 Manager *m = userdata;
271 Iterator i;
272 Link *l;
273 int r;
274
275 assert(m);
276
277 sd_network_monitor_flush(m->network_monitor);
278
279 HASHMAP_FOREACH(l, m->links, i) {
280 r = link_update_monitor(l);
281 if (r < 0)
282 log_warning_errno(r, "Failed to update monitor information for %i: %m", l->ifindex);
283 }
284
285 r = manager_write_resolv_conf(m);
286 if (r < 0)
287 log_warning_errno(r, "Could not update resolv.conf: %m");
288
289 return 0;
290 }
291
292 static int manager_network_monitor_listen(Manager *m) {
293 int r, fd, events;
294
295 assert(m);
296
297 r = sd_network_monitor_new(&m->network_monitor, NULL);
298 if (r < 0)
299 return r;
300
301 fd = sd_network_monitor_get_fd(m->network_monitor);
302 if (fd < 0)
303 return fd;
304
305 events = sd_network_monitor_get_events(m->network_monitor);
306 if (events < 0)
307 return events;
308
309 r = sd_event_add_io(m->event, &m->network_event_source, fd, events, &on_network_event, m);
310 if (r < 0)
311 return r;
312
313 return 0;
314 }
315
316 static int determine_hostname(char **llmnr_hostname, char **mdns_hostname) {
317 _cleanup_free_ char *h = NULL, *n = NULL;
318 char label[DNS_LABEL_MAX];
319 const char *p;
320 int r, k;
321
322 assert(llmnr_hostname);
323 assert(mdns_hostname);
324
325 /* Extract and normalize the first label of the locally
326 * configured hostname, and check it's not "localhost". */
327
328 h = gethostname_malloc();
329 if (!h)
330 return log_oom();
331
332 p = h;
333 r = dns_label_unescape(&p, label, sizeof(label));
334 if (r < 0)
335 return log_error_errno(r, "Failed to unescape host name: %m");
336 if (r == 0) {
337 log_error("Couldn't find a single label in hosntame.");
338 return -EINVAL;
339 }
340
341 k = dns_label_undo_idna(label, r, label, sizeof(label));
342 if (k < 0)
343 return log_error_errno(k, "Failed to undo IDNA: %m");
344 if (k > 0)
345 r = k;
346
347 if (!utf8_is_valid(label)) {
348 log_error("System hostname is not UTF-8 clean.");
349 return -EINVAL;
350 }
351
352 r = dns_label_escape(label, r, &n);
353 if (r < 0)
354 return log_error_errno(r, "Failed to escape host name: %m");
355
356 if (is_localhost(n)) {
357 log_debug("System hostname is 'localhost', ignoring.");
358 return -EINVAL;
359 }
360
361 r = dns_name_concat(n, "local", mdns_hostname);
362 if (r < 0)
363 return log_error_errno(r, "Failed to determine mDNS hostname: %m");
364
365 *llmnr_hostname = n;
366 n = NULL;
367
368 return 0;
369 }
370
371 static int on_hostname_change(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
372 _cleanup_free_ char *llmnr_hostname = NULL, *mdns_hostname = NULL;
373 Manager *m = userdata;
374 int r;
375
376 assert(m);
377
378 r = determine_hostname(&llmnr_hostname, &mdns_hostname);
379 if (r < 0)
380 return 0; /* ignore invalid hostnames */
381
382 if (streq(llmnr_hostname, m->llmnr_hostname) && streq(mdns_hostname, m->mdns_hostname))
383 return 0;
384
385 log_info("System hostname changed to '%s'.", llmnr_hostname);
386
387 free(m->llmnr_hostname);
388 free(m->mdns_hostname);
389
390 m->llmnr_hostname = llmnr_hostname;
391 m->mdns_hostname = mdns_hostname;
392
393 llmnr_hostname = mdns_hostname = NULL;
394
395 manager_refresh_rrs(m);
396
397 return 0;
398 }
399
400 static int manager_watch_hostname(Manager *m) {
401 int r;
402
403 assert(m);
404
405 m->hostname_fd = open("/proc/sys/kernel/hostname", O_RDONLY|O_CLOEXEC|O_NDELAY|O_NOCTTY);
406 if (m->hostname_fd < 0) {
407 log_warning_errno(errno, "Failed to watch hostname: %m");
408 return 0;
409 }
410
411 r = sd_event_add_io(m->event, &m->hostname_event_source, m->hostname_fd, 0, on_hostname_change, m);
412 if (r < 0) {
413 if (r == -EPERM)
414 /* kernels prior to 3.2 don't support polling this file. Ignore the failure. */
415 m->hostname_fd = safe_close(m->hostname_fd);
416 else
417 return log_error_errno(r, "Failed to add hostname event source: %m");
418 }
419
420 r = determine_hostname(&m->llmnr_hostname, &m->mdns_hostname);
421 if (r < 0) {
422 log_info("Defaulting to hostname 'linux'.");
423 m->llmnr_hostname = strdup("linux");
424 if (!m->llmnr_hostname)
425 return log_oom();
426
427 m->mdns_hostname = strdup("linux.local");
428 if (!m->mdns_hostname)
429 return log_oom();
430 } else
431 log_info("Using system hostname '%s'.", m->llmnr_hostname);
432
433 return 0;
434 }
435
436 static int manager_sigusr1(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
437 _cleanup_free_ char *buffer = NULL;
438 _cleanup_fclose_ FILE *f = NULL;
439 Manager *m = userdata;
440 size_t size = 0;
441 DnsScope *scope;
442
443 assert(s);
444 assert(si);
445 assert(m);
446
447 f = open_memstream(&buffer, &size);
448 if (!f)
449 return log_oom();
450
451 LIST_FOREACH(scopes, scope, m->dns_scopes)
452 dns_scope_dump(scope, f);
453
454 if (fflush_and_check(f) < 0)
455 return log_oom();
456
457 log_dump(LOG_INFO, buffer);
458 return 0;
459 }
460
461 int manager_new(Manager **ret) {
462 _cleanup_(manager_freep) Manager *m = NULL;
463 int r;
464
465 assert(ret);
466
467 m = new0(Manager, 1);
468 if (!m)
469 return -ENOMEM;
470
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 (void) sd_event_add_signal(m->event, &m->sigusr1_event_source, SIGUSR1, manager_sigusr1, m);
512
513 *ret = m;
514 m = NULL;
515
516 return 0;
517 }
518
519 int manager_start(Manager *m) {
520 int r;
521
522 assert(m);
523
524 r = manager_llmnr_start(m);
525 if (r < 0)
526 return r;
527
528 return 0;
529 }
530
531 Manager *manager_free(Manager *m) {
532 Link *l;
533
534 if (!m)
535 return NULL;
536
537 while ((l = hashmap_first(m->links)))
538 link_free(l);
539
540 while (m->dns_queries)
541 dns_query_free(m->dns_queries);
542
543 manager_flush_dns_servers(m, DNS_SERVER_SYSTEM);
544 manager_flush_dns_servers(m, DNS_SERVER_FALLBACK);
545
546 dns_scope_free(m->unicast_scope);
547
548 hashmap_free(m->links);
549 hashmap_free(m->dns_transactions);
550
551 sd_event_source_unref(m->network_event_source);
552 sd_network_monitor_unref(m->network_monitor);
553
554 manager_llmnr_stop(m);
555
556 sd_bus_slot_unref(m->prepare_for_sleep_slot);
557 sd_event_source_unref(m->bus_retry_event_source);
558 sd_bus_unref(m->bus);
559
560 sd_event_source_unref(m->sigusr1_event_source);
561
562 sd_event_unref(m->event);
563
564 dns_resource_key_unref(m->llmnr_host_ipv4_key);
565 dns_resource_key_unref(m->llmnr_host_ipv6_key);
566
567 sd_event_source_unref(m->hostname_event_source);
568 safe_close(m->hostname_fd);
569 free(m->llmnr_hostname);
570 free(m->mdns_hostname);
571
572 free(m);
573
574 return NULL;
575 }
576
577 int 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_errno(errno, "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_errno(errno, "Failed to open /etc/resolv.conf: %m");
620 r = -errno;
621 goto clear;
622 }
623
624 if (fstat(fileno(f), &st) < 0) {
625 r = log_error_errno(errno, "Failed to stat open file: %m");
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 LIST_REMOVE(servers, m->dns_servers, s);
670 dns_server_unref(s);
671 }
672
673 /* Whenever /etc/resolv.conf changes, start using the first
674 * DNS server of it. This is useful to deal with broken
675 * network managing implementations (like NetworkManager),
676 * that when connecting to a VPN place both the VPN DNS
677 * servers and the local ones in /etc/resolv.conf. Without
678 * resetting the DNS server to use back to the first entry we
679 * will continue to use the local one thus being unable to
680 * resolve VPN domains. */
681 manager_set_dns_server(m, m->dns_servers);
682
683 return 0;
684
685 clear:
686 while (m->dns_servers) {
687 s = m->dns_servers;
688
689 LIST_REMOVE(servers, m->dns_servers, s);
690 dns_server_unref(s);
691 }
692
693 return r;
694 }
695
696 static void write_resolv_conf_server(DnsServer *s, FILE *f, unsigned *count) {
697 _cleanup_free_ char *t = NULL;
698 int r;
699
700 assert(s);
701 assert(f);
702 assert(count);
703
704 r = in_addr_to_string(s->family, &s->address, &t);
705 if (r < 0) {
706 log_warning_errno(r, "Invalid DNS address. Ignoring: %m");
707 return;
708 }
709
710 if (*count == MAXNS)
711 fputs("# Too many DNS servers configured, the following entries may be ignored.\n", f);
712
713 fprintf(f, "nameserver %s\n", t);
714 (*count) ++;
715 }
716
717 static void write_resolv_conf_search(
718 const char *domain, FILE *f,
719 unsigned *count,
720 unsigned *length) {
721
722 assert(domain);
723 assert(f);
724 assert(length);
725
726 if (*count >= MAXDNSRCH ||
727 *length + strlen(domain) > 256) {
728 if (*count == MAXDNSRCH)
729 fputs(" # Too many search domains configured, remaining ones ignored.", f);
730 if (*length <= 256)
731 fputs(" # Total length of all search domains is too long, remaining ones ignored.", f);
732
733 return;
734 }
735
736 fprintf(f, " %s", domain);
737
738 (*length) += strlen(domain);
739 (*count) ++;
740 }
741
742 static int write_resolv_conf_contents(FILE *f, OrderedSet *dns, OrderedSet *domains) {
743 Iterator i;
744
745 fputs("# This file is managed by systemd-resolved(8). Do not edit.\n#\n"
746 "# Third party programs must not access this file directly, but\n"
747 "# only through the symlink at /etc/resolv.conf. To manage\n"
748 "# resolv.conf(5) in a different way, replace the symlink by a\n"
749 "# static file or a different symlink.\n\n", f);
750
751 if (ordered_set_isempty(dns))
752 fputs("# No DNS servers known.\n", f);
753 else {
754 DnsServer *s;
755 unsigned count = 0;
756
757 ORDERED_SET_FOREACH(s, dns, i)
758 write_resolv_conf_server(s, f, &count);
759 }
760
761 if (!ordered_set_isempty(domains)) {
762 unsigned length = 0, count = 0;
763 char *domain;
764
765 fputs("search", f);
766 ORDERED_SET_FOREACH(domain, domains, i)
767 write_resolv_conf_search(domain, f, &count, &length);
768 fputs("\n", f);
769 }
770
771 return fflush_and_check(f);
772 }
773
774 int manager_write_resolv_conf(Manager *m) {
775 static const char path[] = "/run/systemd/resolve/resolv.conf";
776 _cleanup_free_ char *temp_path = NULL;
777 _cleanup_fclose_ FILE *f = NULL;
778 _cleanup_ordered_set_free_ OrderedSet *dns = NULL, *domains = NULL;
779 DnsServer *s;
780 Iterator i;
781 Link *l;
782 int r;
783
784 assert(m);
785
786 /* Read the system /etc/resolv.conf first */
787 manager_read_resolv_conf(m);
788
789 /* Add the full list to a set, to filter out duplicates */
790 dns = ordered_set_new(&dns_server_hash_ops);
791 if (!dns)
792 return -ENOMEM;
793
794 domains = ordered_set_new(&dns_name_hash_ops);
795 if (!domains)
796 return -ENOMEM;
797
798 /* First add the system-wide servers */
799 LIST_FOREACH(servers, s, m->dns_servers) {
800 r = ordered_set_put(dns, s);
801 if (r == -EEXIST)
802 continue;
803 if (r < 0)
804 return r;
805 }
806
807 /* Then, add the per-link servers and domains */
808 HASHMAP_FOREACH(l, m->links, i) {
809 char **domain;
810
811 LIST_FOREACH(servers, s, l->dns_servers) {
812 r = ordered_set_put(dns, s);
813 if (r == -EEXIST)
814 continue;
815 if (r < 0)
816 return r;
817 }
818
819 if (!l->unicast_scope)
820 continue;
821
822 STRV_FOREACH(domain, l->unicast_scope->domains) {
823 r = ordered_set_put(domains, *domain);
824 if (r == -EEXIST)
825 continue;
826 if (r < 0)
827 return r;
828 }
829 }
830
831 /* If we found nothing, add the fallback servers */
832 if (ordered_set_isempty(dns)) {
833 LIST_FOREACH(servers, s, m->fallback_dns_servers) {
834 r = ordered_set_put(dns, s);
835 if (r == -EEXIST)
836 continue;
837 if (r < 0)
838 return r;
839 }
840 }
841
842 r = fopen_temporary_label(path, path, &f, &temp_path);
843 if (r < 0)
844 return r;
845
846 fchmod(fileno(f), 0644);
847
848 r = write_resolv_conf_contents(f, dns, domains);
849 if (r < 0)
850 goto fail;
851
852 if (rename(temp_path, path) < 0) {
853 r = -errno;
854 goto fail;
855 }
856
857 return 0;
858
859 fail:
860 (void) unlink(path);
861 (void) unlink(temp_path);
862 return r;
863 }
864
865 int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) {
866 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
867 union {
868 struct cmsghdr header; /* For alignment */
869 uint8_t buffer[CMSG_SPACE(MAXSIZE(struct in_pktinfo, struct in6_pktinfo))
870 + CMSG_SPACE(int) /* ttl/hoplimit */
871 + EXTRA_CMSG_SPACE /* kernel appears to require extra buffer space */];
872 } control;
873 union sockaddr_union sa;
874 struct msghdr mh = {};
875 struct cmsghdr *cmsg;
876 struct iovec iov;
877 int ms = 0, r;
878 ssize_t l;
879
880 assert(m);
881 assert(fd >= 0);
882 assert(ret);
883
884 r = ioctl(fd, FIONREAD, &ms);
885 if (r < 0)
886 return -errno;
887 if (ms < 0)
888 return -EIO;
889
890 r = dns_packet_new(&p, protocol, ms);
891 if (r < 0)
892 return r;
893
894 iov.iov_base = DNS_PACKET_DATA(p);
895 iov.iov_len = p->allocated;
896
897 mh.msg_name = &sa.sa;
898 mh.msg_namelen = sizeof(sa);
899 mh.msg_iov = &iov;
900 mh.msg_iovlen = 1;
901 mh.msg_control = &control;
902 mh.msg_controllen = sizeof(control);
903
904 l = recvmsg(fd, &mh, 0);
905 if (l < 0) {
906 if (errno == EAGAIN || errno == EINTR)
907 return 0;
908
909 return -errno;
910 }
911
912 if (l <= 0)
913 return -EIO;
914
915 assert(!(mh.msg_flags & MSG_CTRUNC));
916 assert(!(mh.msg_flags & MSG_TRUNC));
917
918 p->size = (size_t) l;
919
920 p->family = sa.sa.sa_family;
921 p->ipproto = IPPROTO_UDP;
922 if (p->family == AF_INET) {
923 p->sender.in = sa.in.sin_addr;
924 p->sender_port = be16toh(sa.in.sin_port);
925 } else if (p->family == AF_INET6) {
926 p->sender.in6 = sa.in6.sin6_addr;
927 p->sender_port = be16toh(sa.in6.sin6_port);
928 p->ifindex = sa.in6.sin6_scope_id;
929 } else
930 return -EAFNOSUPPORT;
931
932 CMSG_FOREACH(cmsg, &mh) {
933
934 if (cmsg->cmsg_level == IPPROTO_IPV6) {
935 assert(p->family == AF_INET6);
936
937 switch (cmsg->cmsg_type) {
938
939 case IPV6_PKTINFO: {
940 struct in6_pktinfo *i = (struct in6_pktinfo*) CMSG_DATA(cmsg);
941
942 if (p->ifindex <= 0)
943 p->ifindex = i->ipi6_ifindex;
944
945 p->destination.in6 = i->ipi6_addr;
946 break;
947 }
948
949 case IPV6_HOPLIMIT:
950 p->ttl = *(int *) CMSG_DATA(cmsg);
951 break;
952
953 }
954 } else if (cmsg->cmsg_level == IPPROTO_IP) {
955 assert(p->family == AF_INET);
956
957 switch (cmsg->cmsg_type) {
958
959 case IP_PKTINFO: {
960 struct in_pktinfo *i = (struct in_pktinfo*) CMSG_DATA(cmsg);
961
962 if (p->ifindex <= 0)
963 p->ifindex = i->ipi_ifindex;
964
965 p->destination.in = i->ipi_addr;
966 break;
967 }
968
969 case IP_TTL:
970 p->ttl = *(int *) CMSG_DATA(cmsg);
971 break;
972 }
973 }
974 }
975
976 /* The Linux kernel sets the interface index to the loopback
977 * device if the packet came from the local host since it
978 * avoids the routing table in such a case. Let's unset the
979 * interface index in such a case. */
980 if (p->ifindex == LOOPBACK_IFINDEX)
981 p->ifindex = 0;
982
983 if (protocol != DNS_PROTOCOL_DNS) {
984 /* If we don't know the interface index still, we look for the
985 * first local interface with a matching address. Yuck! */
986 if (p->ifindex <= 0)
987 p->ifindex = manager_find_ifindex(m, p->family, &p->destination);
988 }
989
990 *ret = p;
991 p = NULL;
992
993 return 1;
994 }
995
996 static int sendmsg_loop(int fd, struct msghdr *mh, int flags) {
997 int r;
998
999 assert(fd >= 0);
1000 assert(mh);
1001
1002 for (;;) {
1003 if (sendmsg(fd, mh, flags) >= 0)
1004 return 0;
1005
1006 if (errno == EINTR)
1007 continue;
1008
1009 if (errno != EAGAIN)
1010 return -errno;
1011
1012 r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
1013 if (r < 0)
1014 return r;
1015 if (r == 0)
1016 return -ETIMEDOUT;
1017 }
1018 }
1019
1020 static int write_loop(int fd, void *message, size_t length) {
1021 int r;
1022
1023 assert(fd >= 0);
1024 assert(message);
1025
1026 for (;;) {
1027 if (write(fd, message, length) >= 0)
1028 return 0;
1029
1030 if (errno == EINTR)
1031 continue;
1032
1033 if (errno != EAGAIN)
1034 return -errno;
1035
1036 r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
1037 if (r < 0)
1038 return r;
1039 if (r == 0)
1040 return -ETIMEDOUT;
1041 }
1042 }
1043
1044 int manager_write(Manager *m, int fd, DnsPacket *p) {
1045 int r;
1046
1047 log_debug("Sending %s packet with id %u", DNS_PACKET_QR(p) ? "response" : "query", DNS_PACKET_ID(p));
1048
1049 r = write_loop(fd, DNS_PACKET_DATA(p), p->size);
1050 if (r < 0)
1051 return r;
1052
1053 return 0;
1054 }
1055
1056 static int manager_ipv4_send(Manager *m, int fd, int ifindex, const struct in_addr *addr, uint16_t port, DnsPacket *p) {
1057 union sockaddr_union sa = {
1058 .in.sin_family = AF_INET,
1059 };
1060 union {
1061 struct cmsghdr header; /* For alignment */
1062 uint8_t buffer[CMSG_SPACE(sizeof(struct in_pktinfo))];
1063 } control;
1064 struct msghdr mh = {};
1065 struct iovec iov;
1066
1067 assert(m);
1068 assert(fd >= 0);
1069 assert(addr);
1070 assert(port > 0);
1071 assert(p);
1072
1073 iov.iov_base = DNS_PACKET_DATA(p);
1074 iov.iov_len = p->size;
1075
1076 sa.in.sin_addr = *addr;
1077 sa.in.sin_port = htobe16(port),
1078
1079 mh.msg_iov = &iov;
1080 mh.msg_iovlen = 1;
1081 mh.msg_name = &sa.sa;
1082 mh.msg_namelen = sizeof(sa.in);
1083
1084 if (ifindex > 0) {
1085 struct cmsghdr *cmsg;
1086 struct in_pktinfo *pi;
1087
1088 zero(control);
1089
1090 mh.msg_control = &control;
1091 mh.msg_controllen = CMSG_LEN(sizeof(struct in_pktinfo));
1092
1093 cmsg = CMSG_FIRSTHDR(&mh);
1094 cmsg->cmsg_len = mh.msg_controllen;
1095 cmsg->cmsg_level = IPPROTO_IP;
1096 cmsg->cmsg_type = IP_PKTINFO;
1097
1098 pi = (struct in_pktinfo*) CMSG_DATA(cmsg);
1099 pi->ipi_ifindex = ifindex;
1100 }
1101
1102 return sendmsg_loop(fd, &mh, 0);
1103 }
1104
1105 static int manager_ipv6_send(Manager *m, int fd, int ifindex, const struct in6_addr *addr, uint16_t port, DnsPacket *p) {
1106 union sockaddr_union sa = {
1107 .in6.sin6_family = AF_INET6,
1108 };
1109 union {
1110 struct cmsghdr header; /* For alignment */
1111 uint8_t buffer[CMSG_SPACE(sizeof(struct in6_pktinfo))];
1112 } control;
1113 struct msghdr mh = {};
1114 struct iovec iov;
1115
1116 assert(m);
1117 assert(fd >= 0);
1118 assert(addr);
1119 assert(port > 0);
1120 assert(p);
1121
1122 iov.iov_base = DNS_PACKET_DATA(p);
1123 iov.iov_len = p->size;
1124
1125 sa.in6.sin6_addr = *addr;
1126 sa.in6.sin6_port = htobe16(port),
1127 sa.in6.sin6_scope_id = ifindex;
1128
1129 mh.msg_iov = &iov;
1130 mh.msg_iovlen = 1;
1131 mh.msg_name = &sa.sa;
1132 mh.msg_namelen = sizeof(sa.in6);
1133
1134 if (ifindex > 0) {
1135 struct cmsghdr *cmsg;
1136 struct in6_pktinfo *pi;
1137
1138 zero(control);
1139
1140 mh.msg_control = &control;
1141 mh.msg_controllen = CMSG_LEN(sizeof(struct in6_pktinfo));
1142
1143 cmsg = CMSG_FIRSTHDR(&mh);
1144 cmsg->cmsg_len = mh.msg_controllen;
1145 cmsg->cmsg_level = IPPROTO_IPV6;
1146 cmsg->cmsg_type = IPV6_PKTINFO;
1147
1148 pi = (struct in6_pktinfo*) CMSG_DATA(cmsg);
1149 pi->ipi6_ifindex = ifindex;
1150 }
1151
1152 return sendmsg_loop(fd, &mh, 0);
1153 }
1154
1155 int manager_send(Manager *m, int fd, int ifindex, int family, const union in_addr_union *addr, uint16_t port, DnsPacket *p) {
1156 assert(m);
1157 assert(fd >= 0);
1158 assert(addr);
1159 assert(port > 0);
1160 assert(p);
1161
1162 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));
1163
1164 if (family == AF_INET)
1165 return manager_ipv4_send(m, fd, ifindex, &addr->in, port, p);
1166 else if (family == AF_INET6)
1167 return manager_ipv6_send(m, fd, ifindex, &addr->in6, port, p);
1168
1169 return -EAFNOSUPPORT;
1170 }
1171
1172 DnsServer* manager_find_dns_server(Manager *m, int family, const union in_addr_union *in_addr) {
1173 DnsServer *s;
1174
1175 assert(m);
1176 assert(in_addr);
1177
1178 LIST_FOREACH(servers, s, m->dns_servers)
1179 if (s->family == family && in_addr_equal(family, &s->address, in_addr) > 0)
1180 return s;
1181
1182 LIST_FOREACH(servers, s, m->fallback_dns_servers)
1183 if (s->family == family && in_addr_equal(family, &s->address, in_addr) > 0)
1184 return s;
1185
1186 return NULL;
1187 }
1188
1189 DnsServer *manager_set_dns_server(Manager *m, DnsServer *s) {
1190 assert(m);
1191
1192 if (m->current_dns_server == s)
1193 return s;
1194
1195 if (s) {
1196 _cleanup_free_ char *ip = NULL;
1197
1198 in_addr_to_string(s->family, &s->address, &ip);
1199 log_info("Switching to system DNS server %s.", strna(ip));
1200 }
1201
1202 m->current_dns_server = s;
1203
1204 if (m->unicast_scope)
1205 dns_cache_flush(&m->unicast_scope->cache);
1206
1207 return s;
1208 }
1209
1210 DnsServer *manager_get_dns_server(Manager *m) {
1211 Link *l;
1212 assert(m);
1213
1214 /* Try to read updates resolv.conf */
1215 manager_read_resolv_conf(m);
1216
1217 if (!m->current_dns_server)
1218 manager_set_dns_server(m, m->dns_servers);
1219
1220 if (!m->current_dns_server) {
1221 bool found = false;
1222 Iterator i;
1223
1224 /* No DNS servers configured, let's see if there are
1225 * any on any links. If not, we use the fallback
1226 * servers */
1227
1228 HASHMAP_FOREACH(l, m->links, i)
1229 if (l->dns_servers) {
1230 found = true;
1231 break;
1232 }
1233
1234 if (!found)
1235 manager_set_dns_server(m, m->fallback_dns_servers);
1236 }
1237
1238 return m->current_dns_server;
1239 }
1240
1241 void manager_next_dns_server(Manager *m) {
1242 assert(m);
1243
1244 /* If there's currently no DNS server set, then the next
1245 * manager_get_dns_server() will find one */
1246 if (!m->current_dns_server)
1247 return;
1248
1249 /* Change to the next one */
1250 if (m->current_dns_server->servers_next) {
1251 manager_set_dns_server(m, m->current_dns_server->servers_next);
1252 return;
1253 }
1254
1255 /* If there was no next one, then start from the beginning of
1256 * the list */
1257 if (m->current_dns_server->type == DNS_SERVER_FALLBACK)
1258 manager_set_dns_server(m, m->fallback_dns_servers);
1259 else
1260 manager_set_dns_server(m, m->dns_servers);
1261 }
1262
1263 uint32_t manager_find_mtu(Manager *m) {
1264 uint32_t mtu = 0;
1265 Link *l;
1266 Iterator i;
1267
1268 /* If we don't know on which link a DNS packet would be
1269 * delivered, let's find the largest MTU that works on all
1270 * interfaces we know of */
1271
1272 HASHMAP_FOREACH(l, m->links, i) {
1273 if (l->mtu <= 0)
1274 continue;
1275
1276 if (mtu <= 0 || l->mtu < mtu)
1277 mtu = l->mtu;
1278 }
1279
1280 return mtu;
1281 }
1282
1283 int manager_find_ifindex(Manager *m, int family, const union in_addr_union *in_addr) {
1284 LinkAddress *a;
1285
1286 assert(m);
1287
1288 a = manager_find_link_address(m, family, in_addr);
1289 if (a)
1290 return a->link->ifindex;
1291
1292 return 0;
1293 }
1294
1295 void manager_refresh_rrs(Manager *m) {
1296 Iterator i;
1297 Link *l;
1298
1299 assert(m);
1300
1301 m->llmnr_host_ipv4_key = dns_resource_key_unref(m->llmnr_host_ipv4_key);
1302 m->llmnr_host_ipv6_key = dns_resource_key_unref(m->llmnr_host_ipv6_key);
1303
1304 HASHMAP_FOREACH(l, m->links, i) {
1305 link_add_rrs(l, true);
1306 link_add_rrs(l, false);
1307 }
1308 }
1309
1310 int manager_next_hostname(Manager *m) {
1311 const char *p;
1312 uint64_t u, a;
1313 char *h, *k;
1314 int r;
1315
1316 assert(m);
1317
1318 p = strchr(m->llmnr_hostname, 0);
1319 assert(p);
1320
1321 while (p > m->llmnr_hostname) {
1322 if (!strchr("0123456789", p[-1]))
1323 break;
1324
1325 p--;
1326 }
1327
1328 if (*p == 0 || safe_atou64(p, &u) < 0 || u <= 0)
1329 u = 1;
1330
1331 /* Add a random number to the old value. This way we can avoid
1332 * that two hosts pick the same hostname, win on IPv4 and lose
1333 * on IPv6 (or vice versa), and pick the same hostname
1334 * replacement hostname, ad infinitum. We still want the
1335 * numbers to go up monotonically, hence we just add a random
1336 * value 1..10 */
1337
1338 random_bytes(&a, sizeof(a));
1339 u += 1 + a % 10;
1340
1341 if (asprintf(&h, "%.*s%" PRIu64, (int) (p - m->llmnr_hostname), m->llmnr_hostname, u) < 0)
1342 return -ENOMEM;
1343
1344 r = dns_name_concat(h, "local", &k);
1345 if (r < 0) {
1346 free(h);
1347 return r;
1348 }
1349
1350 log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m->llmnr_hostname, h);
1351
1352 free(m->llmnr_hostname);
1353 m->llmnr_hostname = h;
1354
1355 free(m->mdns_hostname);
1356 m->mdns_hostname = k;
1357
1358 manager_refresh_rrs(m);
1359
1360 return 0;
1361 }
1362
1363 LinkAddress* manager_find_link_address(Manager *m, int family, const union in_addr_union *in_addr) {
1364 Iterator i;
1365 Link *l;
1366
1367 assert(m);
1368
1369 HASHMAP_FOREACH(l, m->links, i) {
1370 LinkAddress *a;
1371
1372 a = link_find_address(l, family, in_addr);
1373 if (a)
1374 return a;
1375 }
1376
1377 return NULL;
1378 }
1379
1380 bool manager_our_packet(Manager *m, DnsPacket *p) {
1381 assert(m);
1382 assert(p);
1383
1384 return !!manager_find_link_address(m, p->family, &p->sender);
1385 }
1386
1387 DnsScope* manager_find_scope(Manager *m, DnsPacket *p) {
1388 Link *l;
1389
1390 assert(m);
1391 assert(p);
1392
1393 l = hashmap_get(m->links, INT_TO_PTR(p->ifindex));
1394 if (!l)
1395 return NULL;
1396
1397 if (p->protocol == DNS_PROTOCOL_LLMNR) {
1398 if (p->family == AF_INET)
1399 return l->llmnr_ipv4_scope;
1400 else if (p->family == AF_INET6)
1401 return l->llmnr_ipv6_scope;
1402 }
1403
1404 return NULL;
1405 }
1406
1407 void manager_verify_all(Manager *m) {
1408 DnsScope *s;
1409
1410 assert(m);
1411
1412 LIST_FOREACH(scopes, s, m->dns_scopes)
1413 dns_zone_verify_all(&s->zone);
1414 }
1415
1416 void manager_flush_dns_servers(Manager *m, DnsServerType t) {
1417 DnsServer *s;
1418
1419 assert(m);
1420
1421 if (t == DNS_SERVER_SYSTEM)
1422 while (m->dns_servers) {
1423 s = m->dns_servers;
1424
1425 LIST_REMOVE(servers, m->dns_servers, s);
1426 dns_server_unref(s);
1427 }
1428
1429 if (t == DNS_SERVER_FALLBACK)
1430 while (m->fallback_dns_servers) {
1431 s = m->fallback_dns_servers;
1432
1433 LIST_REMOVE(servers, m->fallback_dns_servers, s);
1434 dns_server_unref(s);
1435 }
1436 }
1437
1438 int manager_is_own_hostname(Manager *m, const char *name) {
1439 int r;
1440
1441 assert(m);
1442 assert(name);
1443
1444 if (m->llmnr_hostname) {
1445 r = dns_name_equal(name, m->llmnr_hostname);
1446 if (r != 0)
1447 return r;
1448 }
1449
1450 if (m->mdns_hostname)
1451 return dns_name_equal(name, m->mdns_hostname);
1452
1453 return 0;
1454 }
1455
1456 static const char* const support_table[_SUPPORT_MAX] = {
1457 [SUPPORT_NO] = "no",
1458 [SUPPORT_YES] = "yes",
1459 [SUPPORT_RESOLVE] = "resolve",
1460 };
1461 DEFINE_STRING_TABLE_LOOKUP(support, Support);