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