]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/resolved-manager.c
resolved: split out writing of resolv.conf
[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
22#include <arpa/inet.h>
23#include <resolv.h>
1716f6dc 24#include <net/if.h>
74b2466e
LP
25#include <sys/ioctl.h>
26#include <sys/poll.h>
27#include <netinet/in.h>
091a364c 28
74b2466e 29#include "rtnl-util.h"
091a364c
TG
30#include "event-util.h"
31#include "network-util.h"
091a364c
TG
32#include "network-internal.h"
33#include "conf-parser.h"
74b2466e 34#include "socket-util.h"
a2a416f7 35#include "af-list.h"
eb60f9cd 36#include "utf8.h"
4e945a6f 37
eb60f9cd 38#include "resolved-dns-domain.h"
39d8db04
LP
39#include "resolved-conf.h"
40#include "resolved-bus.h"
41#include "resolved-manager.h"
74b2466e
LP
42
43#define SEND_TIMEOUT_USEC (200 * USEC_PER_MSEC)
44
45static int manager_process_link(sd_rtnl *rtnl, sd_rtnl_message *mm, void *userdata) {
46 Manager *m = userdata;
47 uint16_t type;
48 Link *l;
49 int ifindex, r;
50
51 assert(rtnl);
52 assert(m);
53 assert(mm);
54
55 r = sd_rtnl_message_get_type(mm, &type);
56 if (r < 0)
57 goto fail;
58
59 r = sd_rtnl_message_link_get_ifindex(mm, &ifindex);
60 if (r < 0)
61 goto fail;
62
63 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
64
65 switch (type) {
66
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:
102 log_warning("Failed to process RTNL link message: %s", strerror(-r));
103 return 0;
104}
105
106static int manager_process_address(sd_rtnl *rtnl, sd_rtnl_message *mm, void *userdata) {
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
118 r = sd_rtnl_message_get_type(mm, &type);
119 if (r < 0)
120 goto fail;
121
122 r = sd_rtnl_message_addr_get_ifindex(mm, &ifindex);
123 if (r < 0)
124 goto fail;
125
126 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
127 if (!l)
128 return 0;
129
130 r = sd_rtnl_message_addr_get_family(mm, &family);
131 if (r < 0)
132 goto fail;
133
134 switch (family) {
135
136 case AF_INET:
137 r = sd_rtnl_message_read_in_addr(mm, IFA_LOCAL, &address.in);
138 if (r < 0) {
139 r = sd_rtnl_message_read_in_addr(mm, IFA_ADDRESS, &address.in);
140 if (r < 0)
141 goto fail;
142 }
143
144 break;
145
146 case AF_INET6:
147 r = sd_rtnl_message_read_in6_addr(mm, IFA_LOCAL, &address.in6);
148 if (r < 0) {
149 r = sd_rtnl_message_read_in6_addr(mm, IFA_ADDRESS, &address.in6);
150 if (r < 0)
151 goto fail;
152 }
153
154 break;
155
156 default:
157 return 0;
158 }
159
160 a = link_find_address(l, family, &address);
161
162 switch (type) {
163
164 case RTM_NEWADDR:
165
166 if (!a) {
167 r = link_address_new(l, &a, family, &address);
168 if (r < 0)
169 return r;
170 }
171
172 r = link_address_update_rtnl(a, mm);
173 if (r < 0)
174 return r;
175
176 break;
177
178 case RTM_DELADDR:
179 if (a)
180 link_address_free(a);
181 break;
182 }
183
184 return 0;
185
186fail:
187 log_warning("Failed to process RTNL address message: %s", strerror(-r));
188 return 0;
189}
190
74b2466e
LP
191static int manager_rtnl_listen(Manager *m) {
192 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
193 sd_rtnl_message *i;
194 int r;
195
196 assert(m);
197
198 /* First, subscibe to interfaces coming and going */
199 r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR, RTNLGRP_IPV6_IFADDR);
200 if (r < 0)
201 return r;
202
203 r = sd_rtnl_attach_event(m->rtnl, m->event, 0);
204 if (r < 0)
205 return r;
206
207 r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, manager_process_link, m);
208 if (r < 0)
209 return r;
210
211 r = sd_rtnl_add_match(m->rtnl, RTM_DELLINK, manager_process_link, m);
212 if (r < 0)
213 return r;
214
215 r = sd_rtnl_add_match(m->rtnl, RTM_NEWADDR, manager_process_address, m);
216 if (r < 0)
217 return r;
091a364c 218
74b2466e
LP
219 r = sd_rtnl_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_rtnl_message_request_dump(req, true);
229 if (r < 0)
230 return r;
231
232 r = sd_rtnl_call(m->rtnl, req, 0, &reply);
233 if (r < 0)
234 return r;
235
236 for (i = reply; i; i = sd_rtnl_message_next(i)) {
237 r = manager_process_link(m->rtnl, i, m);
238 if (r < 0)
239 return r;
240 }
241
242 req = sd_rtnl_message_unref(req);
243 reply = sd_rtnl_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_rtnl_message_request_dump(req, true);
251 if (r < 0)
252 return r;
253
254 r = sd_rtnl_call(m->rtnl, req, 0, &reply);
255 if (r < 0)
256 return r;
257
258 for (i = reply; i; i = sd_rtnl_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
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)
280 log_warning("Failed to update monitor information for %i: %s", l->ifindex, strerror(-r));
281 }
282
283 r = manager_write_resolv_conf(m);
284 if (r < 0)
285 log_warning("Could not update resolv.conf: %s", strerror(-r));
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) {
372 log_warning("Failed to watch hostname: %m");
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);
381 else {
382 log_error("Failed to add hostname event source: %s", strerror(-r));
383 return r;
384 }
385 }
386
387 r = determine_hostname(&m->hostname);
388 if (r < 0) {
389 log_info("Defaulting to hostname 'linux'.");
390 m->hostname = strdup("linux");
391 if (!m->hostname)
392 return log_oom();
393 } else
394 log_info("Using system hostname '%s'.", m->hostname);
395
396 return 0;
397}
398
edc501d4
LP
399static void manager_llmnr_stop(Manager *m) {
400 assert(m);
401
402 m->llmnr_ipv4_udp_event_source = sd_event_source_unref(m->llmnr_ipv4_udp_event_source);
403 m->llmnr_ipv4_udp_fd = safe_close(m->llmnr_ipv4_udp_fd);
404
405 m->llmnr_ipv6_udp_event_source = sd_event_source_unref(m->llmnr_ipv6_udp_event_source);
406 m->llmnr_ipv6_udp_fd = safe_close(m->llmnr_ipv6_udp_fd);
407
408 m->llmnr_ipv4_tcp_event_source = sd_event_source_unref(m->llmnr_ipv4_tcp_event_source);
409 m->llmnr_ipv4_tcp_fd = safe_close(m->llmnr_ipv4_tcp_fd);
410
411 m->llmnr_ipv6_tcp_event_source = sd_event_source_unref(m->llmnr_ipv6_tcp_event_source);
412 m->llmnr_ipv6_tcp_fd = safe_close(m->llmnr_ipv6_tcp_fd);
413}
414
415static int manager_llmnr_start(Manager *m) {
416 int r;
417
418 assert(m);
419
420 if (m->llmnr_support == SUPPORT_NO)
421 return 0;
422
423 r = manager_llmnr_ipv4_udp_fd(m);
424 if (r == -EADDRINUSE)
425 goto eaddrinuse;
426 if (r < 0)
427 return r;
428
edc501d4
LP
429 r = manager_llmnr_ipv4_tcp_fd(m);
430 if (r == -EADDRINUSE)
431 goto eaddrinuse;
432 if (r < 0)
433 return r;
434
90ab5042
LP
435 if (socket_ipv6_is_supported()) {
436 r = manager_llmnr_ipv6_udp_fd(m);
437 if (r == -EADDRINUSE)
438 goto eaddrinuse;
439 if (r < 0)
440 return r;
441
442 r = manager_llmnr_ipv6_tcp_fd(m);
443 if (r == -EADDRINUSE)
444 goto eaddrinuse;
445 if (r < 0)
446 return r;
447 }
edc501d4
LP
448
449 return 0;
450
451eaddrinuse:
c4147df1 452 log_warning("There appears to be another LLMNR responder running. Turning off LLMNR support.");
edc501d4
LP
453 m->llmnr_support = SUPPORT_NO;
454 manager_llmnr_stop(m);
90ab5042 455
edc501d4
LP
456 return 0;
457}
458
091a364c 459int manager_new(Manager **ret) {
74b2466e 460 _cleanup_(manager_freep) Manager *m = NULL;
091a364c
TG
461 int r;
462
c92e531c
LP
463 assert(ret);
464
091a364c
TG
465 m = new0(Manager, 1);
466 if (!m)
467 return -ENOMEM;
468
74b2466e 469 m->dns_ipv4_fd = m->dns_ipv6_fd = -1;
1716f6dc 470 m->llmnr_ipv4_udp_fd = m->llmnr_ipv6_udp_fd = -1;
623a4c97 471 m->llmnr_ipv4_tcp_fd = m->llmnr_ipv6_tcp_fd = -1;
eb60f9cd 472 m->hostname_fd = -1;
1716f6dc 473
4e945a6f 474 m->llmnr_support = SUPPORT_YES;
5cb36f41 475 m->read_resolv_conf = true;
091a364c 476
4e945a6f 477 r = manager_parse_dns_server(m, DNS_SERVER_FALLBACK, DNS_SERVERS);
091a364c
TG
478 if (r < 0)
479 return r;
480
481 r = sd_event_default(&m->event);
482 if (r < 0)
483 return r;
484
485 sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
486 sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
487
488 sd_event_set_watchdog(m->event, true);
489
eb60f9cd
LP
490 r = manager_watch_hostname(m);
491 if (r < 0)
492 return r;
493
1716f6dc 494 r = dns_scope_new(m, &m->unicast_scope, NULL, DNS_PROTOCOL_DNS, AF_UNSPEC);
74b2466e
LP
495 if (r < 0)
496 return r;
497
498 r = manager_network_monitor_listen(m);
499 if (r < 0)
500 return r;
501
502 r = manager_rtnl_listen(m);
503 if (r < 0)
504 return r;
505
506 r = manager_connect_bus(m);
507 if (r < 0)
508 return r;
509
091a364c
TG
510 *ret = m;
511 m = NULL;
512
513 return 0;
514}
515
edc501d4
LP
516int manager_start(Manager *m) {
517 int r;
518
519 assert(m);
520
521 r = manager_llmnr_start(m);
522 if (r < 0)
523 return r;
524
525 return 0;
526}
527
74b2466e
LP
528Manager *manager_free(Manager *m) {
529 Link *l;
091a364c
TG
530
531 if (!m)
74b2466e
LP
532 return NULL;
533
74b2466e
LP
534 while ((l = hashmap_first(m->links)))
535 link_free(l);
f0e15467
LP
536
537 while (m->dns_queries)
538 dns_query_free(m->dns_queries);
74b2466e
LP
539
540 dns_scope_free(m->unicast_scope);
541
3e684349
LP
542 manager_flush_dns_servers(m, DNS_SERVER_SYSTEM);
543 manager_flush_dns_servers(m, DNS_SERVER_FALLBACK);
091a364c 544
f0e15467
LP
545 hashmap_free(m->links);
546 hashmap_free(m->dns_transactions);
547
096b6773
LP
548 sd_event_source_unref(m->network_event_source);
549 sd_network_monitor_unref(m->network_monitor);
091a364c 550
74b2466e
LP
551 sd_event_source_unref(m->dns_ipv4_event_source);
552 sd_event_source_unref(m->dns_ipv6_event_source);
74b2466e
LP
553 safe_close(m->dns_ipv4_fd);
554 safe_close(m->dns_ipv6_fd);
555
edc501d4 556 manager_llmnr_stop(m);
623a4c97 557
902bb5d8 558 sd_bus_slot_unref(m->prepare_for_sleep_slot);
74b2466e
LP
559 sd_event_source_unref(m->bus_retry_event_source);
560 sd_bus_unref(m->bus);
091a364c 561
74b2466e 562 sd_event_unref(m->event);
623a4c97
LP
563
564 dns_resource_key_unref(m->host_ipv4_key);
565 dns_resource_key_unref(m->host_ipv6_key);
eb60f9cd
LP
566
567 safe_close(m->hostname_fd);
568 sd_event_source_unref(m->hostname_event_source);
623a4c97 569 free(m->hostname);
eb60f9cd 570
091a364c 571 free(m);
74b2466e
LP
572
573 return NULL;
091a364c
TG
574}
575
5cb36f41
LP
576int manager_read_resolv_conf(Manager *m) {
577 _cleanup_fclose_ FILE *f = NULL;
578 struct stat st, own;
579 char line[LINE_MAX];
580 DnsServer *s, *nx;
581 usec_t t;
582 int r;
583
584 assert(m);
585
586 /* Reads the system /etc/resolv.conf, if it exists and is not
587 * symlinked to our own resolv.conf instance */
588
589 if (!m->read_resolv_conf)
590 return 0;
591
592 r = stat("/etc/resolv.conf", &st);
593 if (r < 0) {
594 if (errno != ENOENT)
595 log_warning("Failed to open /etc/resolv.conf: %m");
596 r = -errno;
597 goto clear;
598 }
599
600 /* Have we already seen the file? */
601 t = timespec_load(&st.st_mtim);
602 if (t == m->resolv_conf_mtime)
603 return 0;
604
605 m->resolv_conf_mtime = t;
606
607 /* Is it symlinked to our own file? */
608 if (stat("/run/systemd/resolve/resolv.conf", &own) >= 0 &&
609 st.st_dev == own.st_dev &&
610 st.st_ino == own.st_ino) {
611 r = 0;
612 goto clear;
613 }
614
615 f = fopen("/etc/resolv.conf", "re");
616 if (!f) {
617 if (errno != ENOENT)
618 log_warning("Failed to open /etc/resolv.conf: %m");
619 r = -errno;
620 goto clear;
621 }
622
623 if (fstat(fileno(f), &st) < 0) {
624 log_error("Failed to stat open file: %m");
625 r = -errno;
626 goto clear;
627 }
628
629 LIST_FOREACH(servers, s, m->dns_servers)
630 s->marked = true;
631
632 FOREACH_LINE(line, f, r = -errno; goto clear) {
633 union in_addr_union address;
634 int family;
635 char *l;
636 const char *a;
637
638 truncate_nl(line);
639
640 l = strstrip(line);
641 if (*l == '#' || *l == ';')
642 continue;
643
644 a = first_word(l, "nameserver");
645 if (!a)
646 continue;
647
648 r = in_addr_from_string_auto(a, &family, &address);
649 if (r < 0) {
650 log_warning("Failed to parse name server %s.", a);
651 continue;
652 }
653
654 LIST_FOREACH(servers, s, m->dns_servers)
655 if (s->family == family && in_addr_equal(family, &s->address, &address) > 0)
656 break;
657
658 if (s)
659 s->marked = false;
660 else {
661 r = dns_server_new(m, NULL, DNS_SERVER_SYSTEM, NULL, family, &address);
662 if (r < 0)
663 goto clear;
664 }
665 }
666
667 LIST_FOREACH_SAFE(servers, s, nx, m->dns_servers)
668 if (s->marked)
669 dns_server_free(s);
670
671 return 0;
672
673clear:
674 while (m->dns_servers)
675 dns_server_free(m->dns_servers);
676
677 return r;
678}
679
bda2c408 680static void write_resolv_conf_server(DnsServer *s, FILE *f, unsigned *count) {
74b2466e
LP
681 _cleanup_free_ char *t = NULL;
682 int r;
091a364c 683
74b2466e 684 assert(s);
091a364c 685 assert(f);
091a364c
TG
686 assert(count);
687
74b2466e 688 r = in_addr_to_string(s->family, &s->address, &t);
4e945a6f
LP
689 if (r < 0) {
690 log_warning("Invalid DNS address. Ignoring: %s", strerror(-r));
091a364c
TG
691 return;
692 }
693
694 if (*count == MAXNS)
87f5a193 695 fputs("# Too many DNS servers configured, the following entries may be ignored.\n", f);
091a364c 696
74b2466e 697 fprintf(f, "nameserver %s\n", t);
091a364c
TG
698 (*count) ++;
699}
700
bda2c408 701static void write_resolv_conf_search(const char *domain, FILE *f,
a9feff3d 702 unsigned *count, unsigned *length) {
bda2c408
TG
703 assert(domain);
704 assert(f);
705 assert(length);
706
707 if (*count >= MAXDNSRCH ||
708 *length + strlen(domain) > 256) {
709 if (*count == MAXDNSRCH)
710 fputs(" # Too many search domains configured, remaining ones ignored.", f);
711 if (*length <= 256)
712 fputs(" # Total length of all search domains is too long, remaining ones ignored.", f);
713
714 return;
715 }
716
717 fprintf(f, " %s", domain);
718
719 (*length) += strlen(domain);
720 (*count) ++;
721}
722
4713135e
ZJS
723static int write_resolv_conf_contents(FILE *f, Set *dns, Set *domains) {
724 Iterator i;
725
726 fputs("# This file is managed by systemd-resolved(8). Do not edit.\n#\n"
727 "# Third party programs must not access this file directly, but\n"
728 "# only through the symlink at /etc/resolv.conf. To manage\n"
729 "# resolv.conf(5) in a different way, replace the symlink by a\n"
730 "# static file or a different symlink.\n\n", f);
731
732 if (set_isempty(dns))
733 fputs("# No DNS servers known.\n", f);
734 else {
735 DnsServer *s;
736 unsigned count = 0;
737
738 SET_FOREACH(s, dns, i)
739 write_resolv_conf_server(s, f, &count);
740 }
741
742 if (!set_isempty(domains)) {
743 unsigned length = 0, count = 0;
744 char *domain;
745
746 fputs("search", f);
747 SET_FOREACH(domain, domains, i)
748 write_resolv_conf_search(domain, f, &count, &length);
749 fputs("\n", f);
750 }
751
752 return fflush_and_check(f);
753}
754
755
74b2466e 756int manager_write_resolv_conf(Manager *m) {
4e945a6f 757 static const char path[] = "/run/systemd/resolve/resolv.conf";
091a364c
TG
758 _cleanup_free_ char *temp_path = NULL;
759 _cleanup_fclose_ FILE *f = NULL;
bda2c408 760 _cleanup_set_free_ Set *dns = NULL, *domains = NULL;
74b2466e
LP
761 DnsServer *s;
762 Iterator i;
763 Link *l;
764 int r;
091a364c
TG
765
766 assert(m);
767
5cb36f41
LP
768 /* Read the system /etc/resolv.conf first */
769 manager_read_resolv_conf(m);
770
87f5a193 771 /* Add the full list to a set, to filter out duplicates */
d5099efc 772 dns = set_new(&dns_server_hash_ops);
87f5a193
LP
773 if (!dns)
774 return -ENOMEM;
775
d5099efc 776 domains = set_new(&dns_name_hash_ops);
bda2c408
TG
777 if (!domains)
778 return -ENOMEM;
779
87f5a193
LP
780 /* First add the system-wide servers */
781 LIST_FOREACH(servers, s, m->dns_servers) {
782 r = set_put(dns, s);
783 if (r == -EEXIST)
784 continue;
785 if (r < 0)
786 return r;
787 }
788
bda2c408
TG
789 /* Then, add the per-link servers and domains */
790 HASHMAP_FOREACH(l, m->links, i) {
791 char **domain;
792
87f5a193
LP
793 LIST_FOREACH(servers, s, l->dns_servers) {
794 r = set_put(dns, s);
795 if (r == -EEXIST)
796 continue;
797 if (r < 0)
798 return r;
799 }
800
bda2c408
TG
801 if (!l->unicast_scope)
802 continue;
803
804 STRV_FOREACH(domain, l->unicast_scope->domains) {
805 r = set_put(domains, *domain);
806 if (r == -EEXIST)
807 continue;
808 if (r < 0)
809 return r;
810 }
811 }
812
87f5a193
LP
813 /* If we found nothing, add the fallback servers */
814 if (set_isempty(dns)) {
815 LIST_FOREACH(servers, s, m->fallback_dns_servers) {
816 r = set_put(dns, s);
817 if (r == -EEXIST)
818 continue;
819 if (r < 0)
820 return r;
821 }
822 }
823
b686acb2 824 r = fopen_temporary(path, &f, &temp_path);
091a364c
TG
825 if (r < 0)
826 return r;
827
828 fchmod(fileno(f), 0644);
829
4713135e 830 r = write_resolv_conf_contents(f, dns, domains);
74b2466e
LP
831 if (r < 0)
832 goto fail;
833
834 if (rename(temp_path, path) < 0) {
835 r = -errno;
836 goto fail;
837 }
091a364c 838
74b2466e 839 return 0;
091a364c 840
74b2466e
LP
841fail:
842 unlink(path);
843 unlink(temp_path);
844 return r;
845}
091a364c 846
1716f6dc 847int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) {
74b2466e 848 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
1716f6dc
LP
849 union {
850 struct cmsghdr header; /* For alignment */
40a1eebd 851 uint8_t buffer[CMSG_SPACE(MAXSIZE(struct in_pktinfo, struct in6_pktinfo))
1716f6dc 852 + CMSG_SPACE(int) /* ttl/hoplimit */
623a4c97 853 + EXTRA_CMSG_SPACE /* kernel appears to require extra buffer space */];
1716f6dc
LP
854 } control;
855 union sockaddr_union sa;
74b2466e 856 struct msghdr mh = {};
1716f6dc 857 struct cmsghdr *cmsg;
74b2466e 858 struct iovec iov;
1716f6dc 859 int ms = 0, r;
74b2466e
LP
860 ssize_t l;
861
862 assert(m);
1716f6dc 863 assert(fd >= 0);
74b2466e
LP
864 assert(ret);
865
74b2466e
LP
866 r = ioctl(fd, FIONREAD, &ms);
867 if (r < 0)
868 return -errno;
869 if (ms < 0)
870 return -EIO;
871
1716f6dc 872 r = dns_packet_new(&p, protocol, ms);
74b2466e
LP
873 if (r < 0)
874 return r;
875
876 iov.iov_base = DNS_PACKET_DATA(p);
877 iov.iov_len = p->allocated;
878
1716f6dc
LP
879 mh.msg_name = &sa.sa;
880 mh.msg_namelen = sizeof(sa);
74b2466e
LP
881 mh.msg_iov = &iov;
882 mh.msg_iovlen = 1;
1716f6dc
LP
883 mh.msg_control = &control;
884 mh.msg_controllen = sizeof(control);
74b2466e
LP
885
886 l = recvmsg(fd, &mh, 0);
887 if (l < 0) {
ad867662 888 if (errno == EAGAIN || errno == EINTR)
74b2466e
LP
889 return 0;
890
891 return -errno;
091a364c
TG
892 }
893
74b2466e
LP
894 if (l <= 0)
895 return -EIO;
091a364c 896
1716f6dc
LP
897 assert(!(mh.msg_flags & MSG_CTRUNC));
898 assert(!(mh.msg_flags & MSG_TRUNC));
899
74b2466e 900 p->size = (size_t) l;
091a364c 901
1716f6dc 902 p->family = sa.sa.sa_family;
623a4c97
LP
903 p->ipproto = IPPROTO_UDP;
904 if (p->family == AF_INET) {
1716f6dc 905 p->sender.in = sa.in.sin_addr;
623a4c97
LP
906 p->sender_port = be16toh(sa.in.sin_port);
907 } else if (p->family == AF_INET6) {
1716f6dc 908 p->sender.in6 = sa.in6.sin6_addr;
623a4c97
LP
909 p->sender_port = be16toh(sa.in6.sin6_port);
910 p->ifindex = sa.in6.sin6_scope_id;
911 } else
1716f6dc 912 return -EAFNOSUPPORT;
74b2466e 913
1716f6dc 914 for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
74b2466e 915
1716f6dc
LP
916 if (cmsg->cmsg_level == IPPROTO_IPV6) {
917 assert(p->family == AF_INET6);
74b2466e 918
1716f6dc 919 switch (cmsg->cmsg_type) {
74b2466e 920
1716f6dc
LP
921 case IPV6_PKTINFO: {
922 struct in6_pktinfo *i = (struct in6_pktinfo*) CMSG_DATA(cmsg);
74b2466e 923
623a4c97
LP
924 if (p->ifindex <= 0)
925 p->ifindex = i->ipi6_ifindex;
926
1716f6dc
LP
927 p->destination.in6 = i->ipi6_addr;
928 break;
929 }
74b2466e 930
1716f6dc
LP
931 case IPV6_HOPLIMIT:
932 p->ttl = *(int *) CMSG_DATA(cmsg);
933 break;
74b2466e 934
1716f6dc
LP
935 }
936 } else if (cmsg->cmsg_level == IPPROTO_IP) {
937 assert(p->family == AF_INET);
74b2466e 938
1716f6dc 939 switch (cmsg->cmsg_type) {
74b2466e 940
1716f6dc
LP
941 case IP_PKTINFO: {
942 struct in_pktinfo *i = (struct in_pktinfo*) CMSG_DATA(cmsg);
091a364c 943
623a4c97
LP
944 if (p->ifindex <= 0)
945 p->ifindex = i->ipi_ifindex;
946
1716f6dc
LP
947 p->destination.in = i->ipi_addr;
948 break;
949 }
74b2466e 950
623a4c97 951 case IP_TTL:
1716f6dc
LP
952 p->ttl = *(int *) CMSG_DATA(cmsg);
953 break;
954 }
955 }
956 }
74b2466e 957
623a4c97
LP
958 /* The Linux kernel sets the interface index to the loopback
959 * device if the packet came from the local host since it
960 * avoids the routing table in such a case. Let's unset the
961 * interface index in such a case. */
962 if (p->ifindex > 0 && manager_ifindex_is_loopback(m, p->ifindex) != 0)
963 p->ifindex = 0;
964
965 /* If we don't know the interface index still, we look for the
966 * first local interface with a matching address. Yuck! */
967 if (p->ifindex <= 0)
968 p->ifindex = manager_find_ifindex(m, p->family, &p->destination);
969
74b2466e
LP
970 *ret = p;
971 p = NULL;
972
973 return 1;
974}
975
1716f6dc 976static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
74b2466e 977 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
ec2c5e43 978 DnsTransaction *t = NULL;
74b2466e
LP
979 Manager *m = userdata;
980 int r;
981
1716f6dc 982 r = manager_recv(m, fd, DNS_PROTOCOL_DNS, &p);
74b2466e
LP
983 if (r <= 0)
984 return r;
985
623a4c97 986 if (dns_packet_validate_reply(p) > 0) {
ec2c5e43 987 t = hashmap_get(m->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
1716f6dc
LP
988 if (!t)
989 return 0;
74b2466e 990
ec2c5e43 991 dns_transaction_process_reply(t, p);
623a4c97 992
1716f6dc 993 } else
623a4c97 994 log_debug("Invalid DNS packet.");
74b2466e 995
ad867662 996 return 0;
74b2466e
LP
997}
998
999int manager_dns_ipv4_fd(Manager *m) {
1716f6dc 1000 const int one = 1;
74b2466e
LP
1001 int r;
1002
091a364c
TG
1003 assert(m);
1004
74b2466e
LP
1005 if (m->dns_ipv4_fd >= 0)
1006 return m->dns_ipv4_fd;
091a364c 1007
74b2466e
LP
1008 m->dns_ipv4_fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1009 if (m->dns_ipv4_fd < 0)
1010 return -errno;
091a364c 1011
1716f6dc
LP
1012 r = setsockopt(m->dns_ipv4_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
1013 if (r < 0) {
1014 r = -errno;
1015 goto fail;
1016 }
1017
1018 r = sd_event_add_io(m->event, &m->dns_ipv4_event_source, m->dns_ipv4_fd, EPOLLIN, on_dns_packet, m);
74b2466e 1019 if (r < 0)
1716f6dc 1020 goto fail;
74b2466e
LP
1021
1022 return m->dns_ipv4_fd;
1716f6dc
LP
1023
1024fail:
1025 m->dns_ipv4_fd = safe_close(m->dns_ipv4_fd);
1026 return r;
091a364c
TG
1027}
1028
74b2466e 1029int manager_dns_ipv6_fd(Manager *m) {
1716f6dc 1030 const int one = 1;
74b2466e
LP
1031 int r;
1032
1033 assert(m);
091a364c 1034
74b2466e
LP
1035 if (m->dns_ipv6_fd >= 0)
1036 return m->dns_ipv6_fd;
1037
1038 m->dns_ipv6_fd = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1039 if (m->dns_ipv6_fd < 0)
1040 return -errno;
1041
1716f6dc
LP
1042 r = setsockopt(m->dns_ipv6_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
1043 if (r < 0) {
1044 r = -errno;
1045 goto fail;
1046 }
1047
1048 r = sd_event_add_io(m->event, &m->dns_ipv6_event_source, m->dns_ipv6_fd, EPOLLIN, on_dns_packet, m);
091a364c 1049 if (r < 0)
1716f6dc 1050 goto fail;
091a364c 1051
74b2466e 1052 return m->dns_ipv6_fd;
1716f6dc
LP
1053
1054fail:
1055 m->dns_ipv6_fd = safe_close(m->dns_ipv6_fd);
1056 return r;
74b2466e
LP
1057}
1058
1059static int sendmsg_loop(int fd, struct msghdr *mh, int flags) {
1060 int r;
1061
1062 assert(fd >= 0);
1063 assert(mh);
1064
1065 for (;;) {
1066 if (sendmsg(fd, mh, flags) >= 0)
1067 return 0;
1068
1069 if (errno == EINTR)
1070 continue;
1071
1072 if (errno != EAGAIN)
1073 return -errno;
1074
1075 r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
1076 if (r < 0)
1077 return r;
1078 if (r == 0)
1079 return -ETIMEDOUT;
1080 }
1081}
1082
623a4c97 1083static int manager_ipv4_send(Manager *m, int fd, int ifindex, const struct in_addr *addr, uint16_t port, DnsPacket *p) {
74b2466e
LP
1084 union sockaddr_union sa = {
1085 .in.sin_family = AF_INET,
74b2466e 1086 };
1716f6dc
LP
1087 union {
1088 struct cmsghdr header; /* For alignment */
1089 uint8_t buffer[CMSG_SPACE(sizeof(struct in_pktinfo))];
1090 } control;
74b2466e
LP
1091 struct msghdr mh = {};
1092 struct iovec iov;
74b2466e
LP
1093
1094 assert(m);
1716f6dc
LP
1095 assert(fd >= 0);
1096 assert(addr);
1097 assert(port > 0);
74b2466e
LP
1098 assert(p);
1099
74b2466e
LP
1100 iov.iov_base = DNS_PACKET_DATA(p);
1101 iov.iov_len = p->size;
091a364c 1102
1716f6dc
LP
1103 sa.in.sin_addr = *addr;
1104 sa.in.sin_port = htobe16(port),
091a364c 1105
74b2466e
LP
1106 mh.msg_iov = &iov;
1107 mh.msg_iovlen = 1;
1108 mh.msg_name = &sa.sa;
1109 mh.msg_namelen = sizeof(sa.in);
091a364c 1110
74b2466e
LP
1111 if (ifindex > 0) {
1112 struct cmsghdr *cmsg;
1113 struct in_pktinfo *pi;
1114
1115 zero(control);
1116
1716f6dc 1117 mh.msg_control = &control;
74b2466e
LP
1118 mh.msg_controllen = CMSG_LEN(sizeof(struct in_pktinfo));
1119
1120 cmsg = CMSG_FIRSTHDR(&mh);
1121 cmsg->cmsg_len = mh.msg_controllen;
1122 cmsg->cmsg_level = IPPROTO_IP;
1123 cmsg->cmsg_type = IP_PKTINFO;
1124
1125 pi = (struct in_pktinfo*) CMSG_DATA(cmsg);
1126 pi->ipi_ifindex = ifindex;
1127 }
1128
1129 return sendmsg_loop(fd, &mh, 0);
1130}
1131
623a4c97 1132static int manager_ipv6_send(Manager *m, int fd, int ifindex, const struct in6_addr *addr, uint16_t port, DnsPacket *p) {
74b2466e
LP
1133 union sockaddr_union sa = {
1134 .in6.sin6_family = AF_INET6,
74b2466e 1135 };
1716f6dc
LP
1136 union {
1137 struct cmsghdr header; /* For alignment */
1138 uint8_t buffer[CMSG_SPACE(sizeof(struct in6_pktinfo))];
1139 } control;
74b2466e
LP
1140 struct msghdr mh = {};
1141 struct iovec iov;
74b2466e
LP
1142
1143 assert(m);
1716f6dc
LP
1144 assert(fd >= 0);
1145 assert(addr);
1146 assert(port > 0);
74b2466e
LP
1147 assert(p);
1148
74b2466e
LP
1149 iov.iov_base = DNS_PACKET_DATA(p);
1150 iov.iov_len = p->size;
1151
1716f6dc
LP
1152 sa.in6.sin6_addr = *addr;
1153 sa.in6.sin6_port = htobe16(port),
74b2466e
LP
1154 sa.in6.sin6_scope_id = ifindex;
1155
1156 mh.msg_iov = &iov;
1157 mh.msg_iovlen = 1;
1158 mh.msg_name = &sa.sa;
1159 mh.msg_namelen = sizeof(sa.in6);
1160
1161 if (ifindex > 0) {
1162 struct cmsghdr *cmsg;
1163 struct in6_pktinfo *pi;
1164
1165 zero(control);
1166
1716f6dc 1167 mh.msg_control = &control;
74b2466e
LP
1168 mh.msg_controllen = CMSG_LEN(sizeof(struct in6_pktinfo));
1169
1170 cmsg = CMSG_FIRSTHDR(&mh);
1171 cmsg->cmsg_len = mh.msg_controllen;
1172 cmsg->cmsg_level = IPPROTO_IPV6;
1173 cmsg->cmsg_type = IPV6_PKTINFO;
1174
1175 pi = (struct in6_pktinfo*) CMSG_DATA(cmsg);
1176 pi->ipi6_ifindex = ifindex;
1177 }
1178
1179 return sendmsg_loop(fd, &mh, 0);
1180}
1181
623a4c97 1182int manager_send(Manager *m, int fd, int ifindex, int family, const union in_addr_union *addr, uint16_t port, DnsPacket *p) {
1716f6dc
LP
1183 assert(m);
1184 assert(fd >= 0);
1185 assert(addr);
1186 assert(port > 0);
1187 assert(p);
1188
a2a416f7
LP
1189 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));
1190
1716f6dc
LP
1191 if (family == AF_INET)
1192 return manager_ipv4_send(m, fd, ifindex, &addr->in, port, p);
1193 else if (family == AF_INET6)
1194 return manager_ipv6_send(m, fd, ifindex, &addr->in6, port, p);
1195
1196 return -EAFNOSUPPORT;
1197}
1198
2c27fbca 1199DnsServer* manager_find_dns_server(Manager *m, int family, const union in_addr_union *in_addr) {
74b2466e
LP
1200 DnsServer *s;
1201
1202 assert(m);
1203 assert(in_addr);
1204
4e945a6f 1205 LIST_FOREACH(servers, s, m->dns_servers)
5cb36f41 1206 if (s->family == family && in_addr_equal(family, &s->address, in_addr) > 0)
2c27fbca 1207 return s;
74b2466e 1208
4e945a6f 1209 LIST_FOREACH(servers, s, m->fallback_dns_servers)
5cb36f41 1210 if (s->family == family && in_addr_equal(family, &s->address, in_addr) > 0)
2c27fbca 1211 return s;
74b2466e 1212
2c27fbca 1213 return NULL;
4e945a6f
LP
1214}
1215
2c27fbca 1216DnsServer *manager_set_dns_server(Manager *m, DnsServer *s) {
4e945a6f
LP
1217 assert(m);
1218
1219 if (m->current_dns_server == s)
1220 return s;
1221
1222 if (s) {
1223 _cleanup_free_ char *ip = NULL;
1224
1225 in_addr_to_string(s->family, &s->address, &ip);
1226 log_info("Switching to system DNS server %s.", strna(ip));
2c27fbca 1227 }
4e945a6f
LP
1228
1229 m->current_dns_server = s;
2c27fbca
LP
1230
1231 if (m->unicast_scope)
1232 dns_cache_flush(&m->unicast_scope->cache);
1233
4e945a6f 1234 return s;
74b2466e
LP
1235}
1236
1237DnsServer *manager_get_dns_server(Manager *m) {
4e945a6f 1238 Link *l;
74b2466e
LP
1239 assert(m);
1240
5cb36f41
LP
1241 /* Try to read updates resolv.conf */
1242 manager_read_resolv_conf(m);
1243
74b2466e 1244 if (!m->current_dns_server)
4e945a6f
LP
1245 manager_set_dns_server(m, m->dns_servers);
1246
1247 if (!m->current_dns_server) {
1248 bool found = false;
1249 Iterator i;
1250
1251 /* No DNS servers configured, let's see if there are
1252 * any on any links. If not, we use the fallback
1253 * servers */
1254
1255 HASHMAP_FOREACH(l, m->links, i)
1256 if (l->dns_servers) {
1257 found = true;
1258 break;
1259 }
1260
1261 if (!found)
1262 manager_set_dns_server(m, m->fallback_dns_servers);
1263 }
74b2466e
LP
1264
1265 return m->current_dns_server;
1266}
1267
1268void manager_next_dns_server(Manager *m) {
1269 assert(m);
1270
4e945a6f
LP
1271 /* If there's currently no DNS server set, then the next
1272 * manager_get_dns_server() will find one */
74b2466e
LP
1273 if (!m->current_dns_server)
1274 return;
1275
4e945a6f 1276 /* Change to the next one */
74b2466e 1277 if (m->current_dns_server->servers_next) {
4e945a6f 1278 manager_set_dns_server(m, m->current_dns_server->servers_next);
74b2466e
LP
1279 return;
1280 }
1281
4e945a6f
LP
1282 /* If there was no next one, then start from the beginning of
1283 * the list */
1284 if (m->current_dns_server->type == DNS_SERVER_FALLBACK)
1285 manager_set_dns_server(m, m->fallback_dns_servers);
1286 else
1287 manager_set_dns_server(m, m->dns_servers);
091a364c 1288}
e1c95994
LP
1289
1290uint32_t manager_find_mtu(Manager *m) {
1291 uint32_t mtu = 0;
1292 Link *l;
1293 Iterator i;
1294
1295 /* If we don't know on which link a DNS packet would be
1296 * delivered, let's find the largest MTU that works on all
1297 * interfaces we know of */
1298
1299 HASHMAP_FOREACH(l, m->links, i) {
1300 if (l->mtu <= 0)
1301 continue;
1302
1303 if (mtu <= 0 || l->mtu < mtu)
1304 mtu = l->mtu;
1305 }
1306
1307 return mtu;
1308}
1716f6dc
LP
1309
1310static int on_llmnr_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
1311 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
ec2c5e43 1312 DnsTransaction *t = NULL;
1716f6dc 1313 Manager *m = userdata;
a4076574 1314 DnsScope *scope;
1716f6dc
LP
1315 int r;
1316
1317 r = manager_recv(m, fd, DNS_PROTOCOL_LLMNR, &p);
1318 if (r <= 0)
1319 return r;
1320
a4076574
LP
1321 scope = manager_find_scope(m, p);
1322 if (!scope) {
1323 log_warning("Got LLMNR UDP packet on unknown scope. Ignoring.");
1324 return 0;
1325 }
1326
623a4c97 1327 if (dns_packet_validate_reply(p) > 0) {
a2a416f7
LP
1328 log_debug("Got reply packet for id %u", DNS_PACKET_ID(p));
1329
a4076574 1330 dns_scope_check_conflicts(scope, p);
623a4c97 1331
a4076574
LP
1332 t = hashmap_get(m->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
1333 if (t)
1334 dns_transaction_process_reply(t, p);
623a4c97 1335
a4076574
LP
1336 } else if (dns_packet_validate_query(p) > 0) {
1337 log_debug("Got query packet for id %u", DNS_PACKET_ID(p));
623a4c97 1338
a4076574 1339 dns_scope_process_query(scope, NULL, p);
623a4c97 1340 } else
a4076574 1341 log_debug("Invalid LLMNR UDP packet.");
1716f6dc
LP
1342
1343 return 0;
1344}
1345
1346int manager_llmnr_ipv4_udp_fd(Manager *m) {
1347 union sockaddr_union sa = {
1348 .in.sin_family = AF_INET,
1349 .in.sin_port = htobe16(5355),
1350 };
bf3f1271 1351 static const int one = 1, pmtu = IP_PMTUDISC_DONT, ttl = 255;
1716f6dc
LP
1352 int r;
1353
1354 assert(m);
1355
1356 if (m->llmnr_ipv4_udp_fd >= 0)
1357 return m->llmnr_ipv4_udp_fd;
1358
1359 m->llmnr_ipv4_udp_fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1360 if (m->llmnr_ipv4_udp_fd < 0)
1361 return -errno;
1362
bf3f1271
LP
1363 /* RFC 4795, section 2.5 recommends setting the TTL of UDP packets to 255. */
1364 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
1716f6dc
LP
1365 if (r < 0) {
1366 r = -errno;
1367 goto fail;
1368 }
1369
bf3f1271 1370 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
1716f6dc
LP
1371 if (r < 0) {
1372 r = -errno;
1373 goto fail;
1374 }
1375
1376 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MULTICAST_LOOP, &one, sizeof(one));
1377 if (r < 0) {
1378 r = -errno;
1379 goto fail;
1380 }
1381
1382 r = setsockopt(m->llmnr_ipv4_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1383 if (r < 0) {
1384 r = -errno;
1385 goto fail;
1386 }
1387
1388 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
1389 if (r < 0) {
1390 r = -errno;
1391 goto fail;
1392 }
1393
1394 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_RECVTTL, &one, sizeof(one));
1395 if (r < 0) {
1396 r = -errno;
1397 goto fail;
1398 }
1399
1400 /* Disable Don't-Fragment bit in the IP header */
1401 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu));
1402 if (r < 0) {
1403 r = -errno;
1404 goto fail;
1405 }
1406
1407 r = bind(m->llmnr_ipv4_udp_fd, &sa.sa, sizeof(sa.in));
1408 if (r < 0) {
1409 r = -errno;
1410 goto fail;
1411 }
1412
1413 r = sd_event_add_io(m->event, &m->llmnr_ipv4_udp_event_source, m->llmnr_ipv4_udp_fd, EPOLLIN, on_llmnr_packet, m);
1414 if (r < 0)
1415 goto fail;
1416
1417 return m->llmnr_ipv4_udp_fd;
1418
1419fail:
1420 m->llmnr_ipv4_udp_fd = safe_close(m->llmnr_ipv4_udp_fd);
1421 return r;
1422}
1423
1424int manager_llmnr_ipv6_udp_fd(Manager *m) {
1425 union sockaddr_union sa = {
1426 .in6.sin6_family = AF_INET6,
1427 .in6.sin6_port = htobe16(5355),
1428 };
bf3f1271 1429 static const int one = 1, ttl = 255;
1716f6dc
LP
1430 int r;
1431
1432 assert(m);
1433
1434 if (m->llmnr_ipv6_udp_fd >= 0)
1435 return m->llmnr_ipv6_udp_fd;
1436
1437 m->llmnr_ipv6_udp_fd = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1438 if (m->llmnr_ipv6_udp_fd < 0)
1439 return -errno;
1440
bf3f1271 1441 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl));
1716f6dc
LP
1442 if (r < 0) {
1443 r = -errno;
1444 goto fail;
1445 }
1446
bf3f1271
LP
1447 /* RFC 4795, section 2.5 recommends setting the TTL of UDP packets to 255. */
1448 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl));
1716f6dc
LP
1449 if (r < 0) {
1450 r = -errno;
1451 goto fail;
1452 }
1453
1454 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &one, sizeof(one));
1455 if (r < 0) {
1456 r = -errno;
1457 goto fail;
1458 }
1459
1460 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
1461 if (r < 0) {
1462 r = -errno;
1463 goto fail;
1464 }
1465
1466 r = setsockopt(m->llmnr_ipv6_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1467 if (r < 0) {
1468 r = -errno;
1469 goto fail;
1470 }
1471
1472 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
1473 if (r < 0) {
1474 r = -errno;
1475 goto fail;
1476 }
1477
1478 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &one, sizeof(one));
1479 if (r < 0) {
1480 r = -errno;
1481 goto fail;
1482 }
1483
1484 r = bind(m->llmnr_ipv6_udp_fd, &sa.sa, sizeof(sa.in6));
1485 if (r < 0) {
1486 r = -errno;
1487 goto fail;
1488 }
1489
1490 r = sd_event_add_io(m->event, &m->llmnr_ipv6_udp_event_source, m->llmnr_ipv6_udp_fd, EPOLLIN, on_llmnr_packet, m);
1491 if (r < 0) {
1492 r = -errno;
1493 goto fail;
1494 }
1495
1496 return m->llmnr_ipv6_udp_fd;
1497
1498fail:
1499 m->llmnr_ipv6_udp_fd = safe_close(m->llmnr_ipv6_udp_fd);
1500 return r;
1501}
623a4c97
LP
1502
1503static int on_llmnr_stream_packet(DnsStream *s) {
a4076574 1504 DnsScope *scope;
623a4c97 1505
a4076574 1506 assert(s);
623a4c97 1507
a4076574
LP
1508 scope = manager_find_scope(s->manager, s->read_packet);
1509 if (!scope) {
1510 log_warning("Got LLMNR TCP packet on unknown scope. Ignroing.");
1511 return 0;
1512 }
623a4c97 1513
a4076574
LP
1514 if (dns_packet_validate_query(s->read_packet) > 0) {
1515 log_debug("Got query packet for id %u", DNS_PACKET_ID(s->read_packet));
623a4c97 1516
a4076574 1517 dns_scope_process_query(scope, s, s->read_packet);
623a4c97 1518
a4076574
LP
1519 /* If no reply packet was set, we free the stream */
1520 if (s->write_packet)
1521 return 0;
1522 } else
1523 log_debug("Invalid LLMNR TCP packet.");
623a4c97
LP
1524
1525 dns_stream_free(s);
1526 return 0;
1527}
1528
1529static int on_llmnr_stream(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
1530 DnsStream *stream;
1531 Manager *m = userdata;
1532 int cfd, r;
1533
1534 cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
1535 if (cfd < 0) {
1536 if (errno == EAGAIN || errno == EINTR)
1537 return 0;
1538
1539 return -errno;
1540 }
1541
1542 r = dns_stream_new(m, &stream, DNS_PROTOCOL_LLMNR, cfd);
1543 if (r < 0) {
1544 safe_close(cfd);
1545 return r;
1546 }
1547
1548 stream->on_packet = on_llmnr_stream_packet;
1549 return 0;
1550}
1551
1552int manager_llmnr_ipv4_tcp_fd(Manager *m) {
1553 union sockaddr_union sa = {
1554 .in.sin_family = AF_INET,
1555 .in.sin_port = htobe16(5355),
1556 };
1557 static const int one = 1, pmtu = IP_PMTUDISC_DONT;
1558 int r;
1559
1560 assert(m);
1561
1562 if (m->llmnr_ipv4_tcp_fd >= 0)
1563 return m->llmnr_ipv4_tcp_fd;
1564
1565 m->llmnr_ipv4_tcp_fd = socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1566 if (m->llmnr_ipv4_tcp_fd < 0)
1567 return -errno;
1568
bf3f1271 1569 /* RFC 4795, section 2.5. requires setting the TTL of TCP streams to 1 */
623a4c97
LP
1570 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_TTL, &one, sizeof(one));
1571 if (r < 0) {
1572 r = -errno;
1573 goto fail;
1574 }
1575
1576 r = setsockopt(m->llmnr_ipv4_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1577 if (r < 0) {
1578 r = -errno;
1579 goto fail;
1580 }
1581
1582 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
1583 if (r < 0) {
1584 r = -errno;
1585 goto fail;
1586 }
1587
1588 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_RECVTTL, &one, sizeof(one));
1589 if (r < 0) {
1590 r = -errno;
1591 goto fail;
1592 }
1593
1594 /* Disable Don't-Fragment bit in the IP header */
1595 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu));
1596 if (r < 0) {
1597 r = -errno;
1598 goto fail;
1599 }
1600
1601 r = bind(m->llmnr_ipv4_tcp_fd, &sa.sa, sizeof(sa.in));
1602 if (r < 0) {
1603 r = -errno;
1604 goto fail;
1605 }
1606
1607 r = listen(m->llmnr_ipv4_tcp_fd, SOMAXCONN);
1608 if (r < 0) {
1609 r = -errno;
1610 goto fail;
1611 }
1612
1613 r = sd_event_add_io(m->event, &m->llmnr_ipv4_tcp_event_source, m->llmnr_ipv4_tcp_fd, EPOLLIN, on_llmnr_stream, m);
1614 if (r < 0)
1615 goto fail;
1616
1617 return m->llmnr_ipv4_tcp_fd;
1618
1619fail:
1620 m->llmnr_ipv4_tcp_fd = safe_close(m->llmnr_ipv4_tcp_fd);
1621 return r;
1622}
1623
1624int manager_llmnr_ipv6_tcp_fd(Manager *m) {
1625 union sockaddr_union sa = {
1626 .in6.sin6_family = AF_INET6,
1627 .in6.sin6_port = htobe16(5355),
1628 };
1629 static const int one = 1;
1630 int r;
1631
1632 assert(m);
1633
1634 if (m->llmnr_ipv6_tcp_fd >= 0)
1635 return m->llmnr_ipv6_tcp_fd;
1636
1637 m->llmnr_ipv6_tcp_fd = socket(AF_INET6, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1638 if (m->llmnr_ipv6_tcp_fd < 0)
1639 return -errno;
1640
bf3f1271 1641 /* RFC 4795, section 2.5. requires setting the TTL of TCP streams to 1 */
623a4c97
LP
1642 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &one, sizeof(one));
1643 if (r < 0) {
1644 r = -errno;
1645 goto fail;
1646 }
1647
1648 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
1649 if (r < 0) {
1650 r = -errno;
1651 goto fail;
1652 }
1653
1654 r = setsockopt(m->llmnr_ipv6_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1655 if (r < 0) {
1656 r = -errno;
1657 goto fail;
1658 }
1659
1660 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
1661 if (r < 0) {
1662 r = -errno;
1663 goto fail;
1664 }
1665
1666 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &one, sizeof(one));
1667 if (r < 0) {
1668 r = -errno;
1669 goto fail;
1670 }
1671
1672 r = bind(m->llmnr_ipv6_tcp_fd, &sa.sa, sizeof(sa.in6));
1673 if (r < 0) {
1674 r = -errno;
1675 goto fail;
1676 }
1677
1678 r = listen(m->llmnr_ipv6_tcp_fd, SOMAXCONN);
1679 if (r < 0) {
1680 r = -errno;
1681 goto fail;
1682 }
1683
1684 r = sd_event_add_io(m->event, &m->llmnr_ipv6_tcp_event_source, m->llmnr_ipv6_tcp_fd, EPOLLIN, on_llmnr_stream, m);
1685 if (r < 0) {
1686 r = -errno;
1687 goto fail;
1688 }
1689
1690 return m->llmnr_ipv6_tcp_fd;
1691
1692fail:
1693 m->llmnr_ipv6_tcp_fd = safe_close(m->llmnr_ipv6_tcp_fd);
1694 return r;
1695}
1696
d1c457ba
TG
1697/* lo having ifindex 1 is hardcoded in the kernel */
1698#define LOOPBACK_IFINDEX 1
1699
623a4c97
LP
1700int manager_ifindex_is_loopback(Manager *m, int ifindex) {
1701 Link *l;
1702 assert(m);
1703
1704 if (ifindex <= 0)
1705 return -EINVAL;
1706
1707 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
d1c457ba
TG
1708 if (!l)
1709 /* in case we don't yet track the link, rely on the hardcoded value */
1710 return ifindex == LOOPBACK_IFINDEX;
1711 else if (l->flags & IFF_LOOPBACK)
623a4c97
LP
1712 return 1;
1713
1714 return 0;
1715}
1716
1717int manager_find_ifindex(Manager *m, int family, const union in_addr_union *in_addr) {
ec2c5e43
LP
1718 LinkAddress *a;
1719
1720 assert(m);
1721
4e945a6f 1722 a = manager_find_link_address(m, family, in_addr);
ec2c5e43
LP
1723 if (a)
1724 return a->link->ifindex;
1725
1726 return 0;
1727}
1728
eb60f9cd
LP
1729void manager_refresh_rrs(Manager *m) {
1730 Iterator i;
1731 Link *l;
1732
1733 assert(m);
1734
1735 m->host_ipv4_key = dns_resource_key_unref(m->host_ipv4_key);
1736 m->host_ipv6_key = dns_resource_key_unref(m->host_ipv6_key);
1737
1738 HASHMAP_FOREACH(l, m->links, i) {
1739 link_add_rrs(l, true);
1740 link_add_rrs(l, false);
1741 }
1742}
1743
ec2c5e43
LP
1744int manager_next_hostname(Manager *m) {
1745 const char *p;
556a2294 1746 uint64_t u, a;
ec2c5e43 1747 char *h;
623a4c97
LP
1748
1749 assert(m);
1750
ec2c5e43
LP
1751 p = strchr(m->hostname, 0);
1752 assert(p);
1753
1754 while (p > m->hostname) {
1755 if (!strchr("0123456789", p[-1]))
1756 break;
1757
1758 p--;
1759 }
1760
1761 if (*p == 0 || safe_atou64(p, &u) < 0 || u <= 0)
1762 u = 1;
1763
556a2294
LP
1764 /* Add a random number to the old value. This way we can avoid
1765 * that two hosts pick the same hostname, win on IPv4 and lose
1766 * on IPv6 (or vice versa), and pick the same hostname
1767 * replacement hostname, ad infinitum. We still want the
1768 * numbers to go up monotonically, hence we just add a random
1769 * value 1..10 */
1770
1771 random_bytes(&a, sizeof(a));
1772 u += 1 + a % 10;
ec2c5e43
LP
1773
1774 if (asprintf(&h, "%.*s%" PRIu64, (int) (p - m->hostname), m->hostname, u) < 0)
1775 return -ENOMEM;
1776
eb60f9cd 1777 log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m->hostname, h);
ec2c5e43
LP
1778
1779 free(m->hostname);
1780 m->hostname = h;
1781
eb60f9cd 1782 manager_refresh_rrs(m);
623a4c97
LP
1783
1784 return 0;
1785}
ec2c5e43 1786
4e945a6f 1787LinkAddress* manager_find_link_address(Manager *m, int family, const union in_addr_union *in_addr) {
ec2c5e43
LP
1788 Iterator i;
1789 Link *l;
1790
1791 assert(m);
1792
1793 HASHMAP_FOREACH(l, m->links, i) {
1794 LinkAddress *a;
1795
1796 a = link_find_address(l, family, in_addr);
1797 if (a)
1798 return a;
1799 }
1800
1801 return NULL;
1802}
1803
a4076574 1804bool manager_our_packet(Manager *m, DnsPacket *p) {
ec2c5e43
LP
1805 assert(m);
1806 assert(p);
1807
4e945a6f 1808 return !!manager_find_link_address(m, p->family, &p->sender);
ec2c5e43 1809}
4e945a6f 1810
a4076574
LP
1811DnsScope* manager_find_scope(Manager *m, DnsPacket *p) {
1812 Link *l;
1813
1814 assert(m);
1815 assert(p);
1816
1817 l = hashmap_get(m->links, INT_TO_PTR(p->ifindex));
1818 if (!l)
1819 return NULL;
1820
1821 if (p->protocol == DNS_PROTOCOL_LLMNR) {
1822 if (p->family == AF_INET)
1823 return l->llmnr_ipv4_scope;
1824 else if (p->family == AF_INET6)
1825 return l->llmnr_ipv6_scope;
1826 }
1827
1828 return NULL;
1829}
1830
902bb5d8
LP
1831void manager_verify_all(Manager *m) {
1832 DnsScope *s;
1833
1834 assert(m);
1835
1836 LIST_FOREACH(scopes, s, m->dns_scopes)
1837 dns_zone_verify_all(&s->zone);
1838}
1839
3e684349
LP
1840void manager_flush_dns_servers(Manager *m, DnsServerType t) {
1841 assert(m);
1842
1843 if (t == DNS_SERVER_SYSTEM)
1844 while (m->dns_servers)
1845 dns_server_free(m->dns_servers);
1846
1847 if (t == DNS_SERVER_FALLBACK)
1848 while (m->fallback_dns_servers)
1849 dns_server_free(m->fallback_dns_servers);
1850}
1851
4e945a6f
LP
1852static const char* const support_table[_SUPPORT_MAX] = {
1853 [SUPPORT_NO] = "no",
1854 [SUPPORT_YES] = "yes",
1855 [SUPPORT_RESOLVE] = "resolve",
1856};
1857DEFINE_STRING_TABLE_LOOKUP(support, Support);