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