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