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