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