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