]> git.ipfire.org Git - thirdparty/systemd.git/blame_incremental - src/resolve/resolved-manager.c
bus: check allow-interactive-auhtorization flag when doing polkit
[thirdparty/systemd.git] / src / resolve / resolved-manager.c
... / ...
CommitLineData
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>
24#include <net/if.h>
25#include <sys/ioctl.h>
26#include <sys/poll.h>
27#include <netinet/in.h>
28
29#include "rtnl-util.h"
30#include "event-util.h"
31#include "network-util.h"
32#include "network-internal.h"
33#include "conf-parser.h"
34#include "socket-util.h"
35#include "af-list.h"
36#include "utf8.h"
37
38#include "resolved-dns-domain.h"
39#include "resolved-conf.h"
40#include "resolved-bus.h"
41#include "resolved-manager.h"
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
67 case RTM_NEWLINK:{
68 bool is_new = !l;
69
70 if (!l) {
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
80 r = link_update_monitor(l);
81 if (r < 0)
82 goto fail;
83
84 if (is_new)
85 log_debug("Found new link %i/%s", ifindex, l->name);
86
87 break;
88 }
89
90 case RTM_DELLINK:
91 if (l) {
92 log_debug("Removing link %i/%s", l->ifindex, l->name);
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;
109 uint16_t type;
110 int r, ifindex, family;
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
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;
218
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
295 r = sd_network_monitor_new(&m->network_monitor, NULL);
296 if (r < 0)
297 return r;
298
299 fd = sd_network_monitor_get_fd(m->network_monitor);
300 if (fd < 0)
301 return fd;
302
303 events = sd_network_monitor_get_events(m->network_monitor);
304 if (events < 0)
305 return events;
306
307 r = sd_event_add_io(m->event, &m->network_event_source, fd, events, &on_network_event, m);
308 if (r < 0)
309 return r;
310
311 return 0;
312}
313
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) {
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
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
429 r = manager_llmnr_ipv4_tcp_fd(m);
430 if (r == -EADDRINUSE)
431 goto eaddrinuse;
432 if (r < 0)
433 return r;
434
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 }
448
449 return 0;
450
451eaddrinuse:
452 log_warning("There appears to be another LLMNR responder running. Turning off LLMNR support.");
453 m->llmnr_support = SUPPORT_NO;
454 manager_llmnr_stop(m);
455
456 return 0;
457}
458
459int manager_new(Manager **ret) {
460 _cleanup_(manager_freep) Manager *m = NULL;
461 int r;
462
463 assert(ret);
464
465 m = new0(Manager, 1);
466 if (!m)
467 return -ENOMEM;
468
469 m->dns_ipv4_fd = m->dns_ipv6_fd = -1;
470 m->llmnr_ipv4_udp_fd = m->llmnr_ipv6_udp_fd = -1;
471 m->llmnr_ipv4_tcp_fd = m->llmnr_ipv6_tcp_fd = -1;
472 m->hostname_fd = -1;
473
474 m->llmnr_support = SUPPORT_YES;
475 m->read_resolv_conf = true;
476
477 r = manager_parse_dns_server(m, DNS_SERVER_FALLBACK, DNS_SERVERS);
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
490 r = manager_watch_hostname(m);
491 if (r < 0)
492 return r;
493
494 r = dns_scope_new(m, &m->unicast_scope, NULL, DNS_PROTOCOL_DNS, AF_UNSPEC);
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
510 *ret = m;
511 m = NULL;
512
513 return 0;
514}
515
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
528Manager *manager_free(Manager *m) {
529 Link *l;
530
531 if (!m)
532 return NULL;
533
534 while ((l = hashmap_first(m->links)))
535 link_free(l);
536
537 while (m->dns_queries)
538 dns_query_free(m->dns_queries);
539
540 dns_scope_free(m->unicast_scope);
541
542 manager_flush_dns_servers(m, DNS_SERVER_SYSTEM);
543 manager_flush_dns_servers(m, DNS_SERVER_FALLBACK);
544
545 hashmap_free(m->links);
546 hashmap_free(m->dns_transactions);
547
548 sd_event_source_unref(m->network_event_source);
549 sd_network_monitor_unref(m->network_monitor);
550
551 sd_event_source_unref(m->dns_ipv4_event_source);
552 sd_event_source_unref(m->dns_ipv6_event_source);
553 safe_close(m->dns_ipv4_fd);
554 safe_close(m->dns_ipv6_fd);
555
556 manager_llmnr_stop(m);
557
558 sd_bus_slot_unref(m->prepare_for_sleep_slot);
559 sd_event_source_unref(m->bus_retry_event_source);
560 sd_bus_unref(m->bus);
561
562 sd_event_unref(m->event);
563
564 dns_resource_key_unref(m->host_ipv4_key);
565 dns_resource_key_unref(m->host_ipv6_key);
566
567 safe_close(m->hostname_fd);
568 sd_event_source_unref(m->hostname_event_source);
569 free(m->hostname);
570
571 free(m);
572
573 return NULL;
574}
575
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
680static void write_resolv_conf_server(DnsServer *s, FILE *f, unsigned *count) {
681 _cleanup_free_ char *t = NULL;
682 int r;
683
684 assert(s);
685 assert(f);
686 assert(count);
687
688 r = in_addr_to_string(s->family, &s->address, &t);
689 if (r < 0) {
690 log_warning("Invalid DNS address. Ignoring: %s", strerror(-r));
691 return;
692 }
693
694 if (*count == MAXNS)
695 fputs("# Too many DNS servers configured, the following entries may be ignored.\n", f);
696
697 fprintf(f, "nameserver %s\n", t);
698 (*count) ++;
699}
700
701static void write_resolv_conf_search(const char *domain, FILE *f,
702 unsigned *count, unsigned *length) {
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
723int manager_write_resolv_conf(Manager *m) {
724 static const char path[] = "/run/systemd/resolve/resolv.conf";
725 _cleanup_free_ char *temp_path = NULL;
726 _cleanup_fclose_ FILE *f = NULL;
727 _cleanup_set_free_ Set *dns = NULL, *domains = NULL;
728 unsigned count = 0;
729 DnsServer *s;
730 Iterator i;
731 Link *l;
732 int r;
733
734 assert(m);
735
736 /* Read the system /etc/resolv.conf first */
737 manager_read_resolv_conf(m);
738
739 /* Add the full list to a set, to filter out duplicates */
740 dns = set_new(&dns_server_hash_ops);
741 if (!dns)
742 return -ENOMEM;
743
744 domains = set_new(&dns_name_hash_ops);
745 if (!domains)
746 return -ENOMEM;
747
748 /* First add the system-wide servers */
749 LIST_FOREACH(servers, s, m->dns_servers) {
750 r = set_put(dns, s);
751 if (r == -EEXIST)
752 continue;
753 if (r < 0)
754 return r;
755 }
756
757 /* Then, add the per-link servers and domains */
758 HASHMAP_FOREACH(l, m->links, i) {
759 char **domain;
760
761 LIST_FOREACH(servers, s, l->dns_servers) {
762 r = set_put(dns, s);
763 if (r == -EEXIST)
764 continue;
765 if (r < 0)
766 return r;
767 }
768
769 if (!l->unicast_scope)
770 continue;
771
772 STRV_FOREACH(domain, l->unicast_scope->domains) {
773 r = set_put(domains, *domain);
774 if (r == -EEXIST)
775 continue;
776 if (r < 0)
777 return r;
778 }
779 }
780
781 /* If we found nothing, add the fallback servers */
782 if (set_isempty(dns)) {
783 LIST_FOREACH(servers, s, m->fallback_dns_servers) {
784 r = set_put(dns, s);
785 if (r == -EEXIST)
786 continue;
787 if (r < 0)
788 return r;
789 }
790 }
791
792 r = fopen_temporary(path, &f, &temp_path);
793 if (r < 0)
794 return r;
795
796 fchmod(fileno(f), 0644);
797
798 fputs("# This file is managed by systemd-resolved(8). Do not edit.\n#\n"
799 "# Third party programs must not access this file directly, but\n"
800 "# only through the symlink at /etc/resolv.conf. To manage\n"
801 "# resolv.conf(5) in a different way, replace the symlink by a\n"
802 "# static file or a different symlink.\n\n", f);
803
804 if (set_isempty(dns))
805 fputs("# No DNS servers known.\n", f);
806 else {
807 SET_FOREACH(s, dns, i)
808 write_resolv_conf_server(s, f, &count);
809 }
810
811 if (!set_isempty(domains)) {
812 unsigned length = 0;
813 char *domain;
814
815 count = 0;
816
817 fputs("search", f);
818 SET_FOREACH(domain, domains, i)
819 write_resolv_conf_search(domain, f, &count, &length);
820 fputs("\n", f);
821 }
822
823 r = fflush_and_check(f);
824 if (r < 0)
825 goto fail;
826
827 if (rename(temp_path, path) < 0) {
828 r = -errno;
829 goto fail;
830 }
831
832 return 0;
833
834fail:
835 unlink(path);
836 unlink(temp_path);
837 return r;
838}
839
840int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) {
841 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
842 union {
843 struct cmsghdr header; /* For alignment */
844 uint8_t buffer[CMSG_SPACE(MAXSIZE(struct in_pktinfo, struct in6_pktinfo))
845 + CMSG_SPACE(int) /* ttl/hoplimit */
846 + EXTRA_CMSG_SPACE /* kernel appears to require extra buffer space */];
847 } control;
848 union sockaddr_union sa;
849 struct msghdr mh = {};
850 struct cmsghdr *cmsg;
851 struct iovec iov;
852 int ms = 0, r;
853 ssize_t l;
854
855 assert(m);
856 assert(fd >= 0);
857 assert(ret);
858
859 r = ioctl(fd, FIONREAD, &ms);
860 if (r < 0)
861 return -errno;
862 if (ms < 0)
863 return -EIO;
864
865 r = dns_packet_new(&p, protocol, ms);
866 if (r < 0)
867 return r;
868
869 iov.iov_base = DNS_PACKET_DATA(p);
870 iov.iov_len = p->allocated;
871
872 mh.msg_name = &sa.sa;
873 mh.msg_namelen = sizeof(sa);
874 mh.msg_iov = &iov;
875 mh.msg_iovlen = 1;
876 mh.msg_control = &control;
877 mh.msg_controllen = sizeof(control);
878
879 l = recvmsg(fd, &mh, 0);
880 if (l < 0) {
881 if (errno == EAGAIN || errno == EINTR)
882 return 0;
883
884 return -errno;
885 }
886
887 if (l <= 0)
888 return -EIO;
889
890 assert(!(mh.msg_flags & MSG_CTRUNC));
891 assert(!(mh.msg_flags & MSG_TRUNC));
892
893 p->size = (size_t) l;
894
895 p->family = sa.sa.sa_family;
896 p->ipproto = IPPROTO_UDP;
897 if (p->family == AF_INET) {
898 p->sender.in = sa.in.sin_addr;
899 p->sender_port = be16toh(sa.in.sin_port);
900 } else if (p->family == AF_INET6) {
901 p->sender.in6 = sa.in6.sin6_addr;
902 p->sender_port = be16toh(sa.in6.sin6_port);
903 p->ifindex = sa.in6.sin6_scope_id;
904 } else
905 return -EAFNOSUPPORT;
906
907 for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
908
909 if (cmsg->cmsg_level == IPPROTO_IPV6) {
910 assert(p->family == AF_INET6);
911
912 switch (cmsg->cmsg_type) {
913
914 case IPV6_PKTINFO: {
915 struct in6_pktinfo *i = (struct in6_pktinfo*) CMSG_DATA(cmsg);
916
917 if (p->ifindex <= 0)
918 p->ifindex = i->ipi6_ifindex;
919
920 p->destination.in6 = i->ipi6_addr;
921 break;
922 }
923
924 case IPV6_HOPLIMIT:
925 p->ttl = *(int *) CMSG_DATA(cmsg);
926 break;
927
928 }
929 } else if (cmsg->cmsg_level == IPPROTO_IP) {
930 assert(p->family == AF_INET);
931
932 switch (cmsg->cmsg_type) {
933
934 case IP_PKTINFO: {
935 struct in_pktinfo *i = (struct in_pktinfo*) CMSG_DATA(cmsg);
936
937 if (p->ifindex <= 0)
938 p->ifindex = i->ipi_ifindex;
939
940 p->destination.in = i->ipi_addr;
941 break;
942 }
943
944 case IP_TTL:
945 p->ttl = *(int *) CMSG_DATA(cmsg);
946 break;
947 }
948 }
949 }
950
951 /* The Linux kernel sets the interface index to the loopback
952 * device if the packet came from the local host since it
953 * avoids the routing table in such a case. Let's unset the
954 * interface index in such a case. */
955 if (p->ifindex > 0 && manager_ifindex_is_loopback(m, p->ifindex) != 0)
956 p->ifindex = 0;
957
958 /* If we don't know the interface index still, we look for the
959 * first local interface with a matching address. Yuck! */
960 if (p->ifindex <= 0)
961 p->ifindex = manager_find_ifindex(m, p->family, &p->destination);
962
963 *ret = p;
964 p = NULL;
965
966 return 1;
967}
968
969static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
970 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
971 DnsTransaction *t = NULL;
972 Manager *m = userdata;
973 int r;
974
975 r = manager_recv(m, fd, DNS_PROTOCOL_DNS, &p);
976 if (r <= 0)
977 return r;
978
979 if (dns_packet_validate_reply(p) > 0) {
980 t = hashmap_get(m->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
981 if (!t)
982 return 0;
983
984 dns_transaction_process_reply(t, p);
985
986 } else
987 log_debug("Invalid DNS packet.");
988
989 return 0;
990}
991
992int manager_dns_ipv4_fd(Manager *m) {
993 const int one = 1;
994 int r;
995
996 assert(m);
997
998 if (m->dns_ipv4_fd >= 0)
999 return m->dns_ipv4_fd;
1000
1001 m->dns_ipv4_fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1002 if (m->dns_ipv4_fd < 0)
1003 return -errno;
1004
1005 r = setsockopt(m->dns_ipv4_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
1006 if (r < 0) {
1007 r = -errno;
1008 goto fail;
1009 }
1010
1011 r = sd_event_add_io(m->event, &m->dns_ipv4_event_source, m->dns_ipv4_fd, EPOLLIN, on_dns_packet, m);
1012 if (r < 0)
1013 goto fail;
1014
1015 return m->dns_ipv4_fd;
1016
1017fail:
1018 m->dns_ipv4_fd = safe_close(m->dns_ipv4_fd);
1019 return r;
1020}
1021
1022int manager_dns_ipv6_fd(Manager *m) {
1023 const int one = 1;
1024 int r;
1025
1026 assert(m);
1027
1028 if (m->dns_ipv6_fd >= 0)
1029 return m->dns_ipv6_fd;
1030
1031 m->dns_ipv6_fd = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1032 if (m->dns_ipv6_fd < 0)
1033 return -errno;
1034
1035 r = setsockopt(m->dns_ipv6_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
1036 if (r < 0) {
1037 r = -errno;
1038 goto fail;
1039 }
1040
1041 r = sd_event_add_io(m->event, &m->dns_ipv6_event_source, m->dns_ipv6_fd, EPOLLIN, on_dns_packet, m);
1042 if (r < 0)
1043 goto fail;
1044
1045 return m->dns_ipv6_fd;
1046
1047fail:
1048 m->dns_ipv6_fd = safe_close(m->dns_ipv6_fd);
1049 return r;
1050}
1051
1052static int sendmsg_loop(int fd, struct msghdr *mh, int flags) {
1053 int r;
1054
1055 assert(fd >= 0);
1056 assert(mh);
1057
1058 for (;;) {
1059 if (sendmsg(fd, mh, flags) >= 0)
1060 return 0;
1061
1062 if (errno == EINTR)
1063 continue;
1064
1065 if (errno != EAGAIN)
1066 return -errno;
1067
1068 r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
1069 if (r < 0)
1070 return r;
1071 if (r == 0)
1072 return -ETIMEDOUT;
1073 }
1074}
1075
1076static int manager_ipv4_send(Manager *m, int fd, int ifindex, const struct in_addr *addr, uint16_t port, DnsPacket *p) {
1077 union sockaddr_union sa = {
1078 .in.sin_family = AF_INET,
1079 };
1080 union {
1081 struct cmsghdr header; /* For alignment */
1082 uint8_t buffer[CMSG_SPACE(sizeof(struct in_pktinfo))];
1083 } control;
1084 struct msghdr mh = {};
1085 struct iovec iov;
1086
1087 assert(m);
1088 assert(fd >= 0);
1089 assert(addr);
1090 assert(port > 0);
1091 assert(p);
1092
1093 iov.iov_base = DNS_PACKET_DATA(p);
1094 iov.iov_len = p->size;
1095
1096 sa.in.sin_addr = *addr;
1097 sa.in.sin_port = htobe16(port),
1098
1099 mh.msg_iov = &iov;
1100 mh.msg_iovlen = 1;
1101 mh.msg_name = &sa.sa;
1102 mh.msg_namelen = sizeof(sa.in);
1103
1104 if (ifindex > 0) {
1105 struct cmsghdr *cmsg;
1106 struct in_pktinfo *pi;
1107
1108 zero(control);
1109
1110 mh.msg_control = &control;
1111 mh.msg_controllen = CMSG_LEN(sizeof(struct in_pktinfo));
1112
1113 cmsg = CMSG_FIRSTHDR(&mh);
1114 cmsg->cmsg_len = mh.msg_controllen;
1115 cmsg->cmsg_level = IPPROTO_IP;
1116 cmsg->cmsg_type = IP_PKTINFO;
1117
1118 pi = (struct in_pktinfo*) CMSG_DATA(cmsg);
1119 pi->ipi_ifindex = ifindex;
1120 }
1121
1122 return sendmsg_loop(fd, &mh, 0);
1123}
1124
1125static int manager_ipv6_send(Manager *m, int fd, int ifindex, const struct in6_addr *addr, uint16_t port, DnsPacket *p) {
1126 union sockaddr_union sa = {
1127 .in6.sin6_family = AF_INET6,
1128 };
1129 union {
1130 struct cmsghdr header; /* For alignment */
1131 uint8_t buffer[CMSG_SPACE(sizeof(struct in6_pktinfo))];
1132 } control;
1133 struct msghdr mh = {};
1134 struct iovec iov;
1135
1136 assert(m);
1137 assert(fd >= 0);
1138 assert(addr);
1139 assert(port > 0);
1140 assert(p);
1141
1142 iov.iov_base = DNS_PACKET_DATA(p);
1143 iov.iov_len = p->size;
1144
1145 sa.in6.sin6_addr = *addr;
1146 sa.in6.sin6_port = htobe16(port),
1147 sa.in6.sin6_scope_id = ifindex;
1148
1149 mh.msg_iov = &iov;
1150 mh.msg_iovlen = 1;
1151 mh.msg_name = &sa.sa;
1152 mh.msg_namelen = sizeof(sa.in6);
1153
1154 if (ifindex > 0) {
1155 struct cmsghdr *cmsg;
1156 struct in6_pktinfo *pi;
1157
1158 zero(control);
1159
1160 mh.msg_control = &control;
1161 mh.msg_controllen = CMSG_LEN(sizeof(struct in6_pktinfo));
1162
1163 cmsg = CMSG_FIRSTHDR(&mh);
1164 cmsg->cmsg_len = mh.msg_controllen;
1165 cmsg->cmsg_level = IPPROTO_IPV6;
1166 cmsg->cmsg_type = IPV6_PKTINFO;
1167
1168 pi = (struct in6_pktinfo*) CMSG_DATA(cmsg);
1169 pi->ipi6_ifindex = ifindex;
1170 }
1171
1172 return sendmsg_loop(fd, &mh, 0);
1173}
1174
1175int manager_send(Manager *m, int fd, int ifindex, int family, const union in_addr_union *addr, uint16_t port, DnsPacket *p) {
1176 assert(m);
1177 assert(fd >= 0);
1178 assert(addr);
1179 assert(port > 0);
1180 assert(p);
1181
1182 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));
1183
1184 if (family == AF_INET)
1185 return manager_ipv4_send(m, fd, ifindex, &addr->in, port, p);
1186 else if (family == AF_INET6)
1187 return manager_ipv6_send(m, fd, ifindex, &addr->in6, port, p);
1188
1189 return -EAFNOSUPPORT;
1190}
1191
1192DnsServer* manager_find_dns_server(Manager *m, int family, const union in_addr_union *in_addr) {
1193 DnsServer *s;
1194
1195 assert(m);
1196 assert(in_addr);
1197
1198 LIST_FOREACH(servers, s, m->dns_servers)
1199 if (s->family == family && in_addr_equal(family, &s->address, in_addr) > 0)
1200 return s;
1201
1202 LIST_FOREACH(servers, s, m->fallback_dns_servers)
1203 if (s->family == family && in_addr_equal(family, &s->address, in_addr) > 0)
1204 return s;
1205
1206 return NULL;
1207}
1208
1209DnsServer *manager_set_dns_server(Manager *m, DnsServer *s) {
1210 assert(m);
1211
1212 if (m->current_dns_server == s)
1213 return s;
1214
1215 if (s) {
1216 _cleanup_free_ char *ip = NULL;
1217
1218 in_addr_to_string(s->family, &s->address, &ip);
1219 log_info("Switching to system DNS server %s.", strna(ip));
1220 }
1221
1222 m->current_dns_server = s;
1223
1224 if (m->unicast_scope)
1225 dns_cache_flush(&m->unicast_scope->cache);
1226
1227 return s;
1228}
1229
1230DnsServer *manager_get_dns_server(Manager *m) {
1231 Link *l;
1232 assert(m);
1233
1234 /* Try to read updates resolv.conf */
1235 manager_read_resolv_conf(m);
1236
1237 if (!m->current_dns_server)
1238 manager_set_dns_server(m, m->dns_servers);
1239
1240 if (!m->current_dns_server) {
1241 bool found = false;
1242 Iterator i;
1243
1244 /* No DNS servers configured, let's see if there are
1245 * any on any links. If not, we use the fallback
1246 * servers */
1247
1248 HASHMAP_FOREACH(l, m->links, i)
1249 if (l->dns_servers) {
1250 found = true;
1251 break;
1252 }
1253
1254 if (!found)
1255 manager_set_dns_server(m, m->fallback_dns_servers);
1256 }
1257
1258 return m->current_dns_server;
1259}
1260
1261void manager_next_dns_server(Manager *m) {
1262 assert(m);
1263
1264 /* If there's currently no DNS server set, then the next
1265 * manager_get_dns_server() will find one */
1266 if (!m->current_dns_server)
1267 return;
1268
1269 /* Change to the next one */
1270 if (m->current_dns_server->servers_next) {
1271 manager_set_dns_server(m, m->current_dns_server->servers_next);
1272 return;
1273 }
1274
1275 /* If there was no next one, then start from the beginning of
1276 * the list */
1277 if (m->current_dns_server->type == DNS_SERVER_FALLBACK)
1278 manager_set_dns_server(m, m->fallback_dns_servers);
1279 else
1280 manager_set_dns_server(m, m->dns_servers);
1281}
1282
1283uint32_t manager_find_mtu(Manager *m) {
1284 uint32_t mtu = 0;
1285 Link *l;
1286 Iterator i;
1287
1288 /* If we don't know on which link a DNS packet would be
1289 * delivered, let's find the largest MTU that works on all
1290 * interfaces we know of */
1291
1292 HASHMAP_FOREACH(l, m->links, i) {
1293 if (l->mtu <= 0)
1294 continue;
1295
1296 if (mtu <= 0 || l->mtu < mtu)
1297 mtu = l->mtu;
1298 }
1299
1300 return mtu;
1301}
1302
1303static int on_llmnr_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
1304 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
1305 DnsTransaction *t = NULL;
1306 Manager *m = userdata;
1307 DnsScope *scope;
1308 int r;
1309
1310 r = manager_recv(m, fd, DNS_PROTOCOL_LLMNR, &p);
1311 if (r <= 0)
1312 return r;
1313
1314 scope = manager_find_scope(m, p);
1315 if (!scope) {
1316 log_warning("Got LLMNR UDP packet on unknown scope. Ignoring.");
1317 return 0;
1318 }
1319
1320 if (dns_packet_validate_reply(p) > 0) {
1321 log_debug("Got reply packet for id %u", DNS_PACKET_ID(p));
1322
1323 dns_scope_check_conflicts(scope, p);
1324
1325 t = hashmap_get(m->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
1326 if (t)
1327 dns_transaction_process_reply(t, p);
1328
1329 } else if (dns_packet_validate_query(p) > 0) {
1330 log_debug("Got query packet for id %u", DNS_PACKET_ID(p));
1331
1332 dns_scope_process_query(scope, NULL, p);
1333 } else
1334 log_debug("Invalid LLMNR UDP packet.");
1335
1336 return 0;
1337}
1338
1339int manager_llmnr_ipv4_udp_fd(Manager *m) {
1340 union sockaddr_union sa = {
1341 .in.sin_family = AF_INET,
1342 .in.sin_port = htobe16(5355),
1343 };
1344 static const int one = 1, pmtu = IP_PMTUDISC_DONT, ttl = 255;
1345 int r;
1346
1347 assert(m);
1348
1349 if (m->llmnr_ipv4_udp_fd >= 0)
1350 return m->llmnr_ipv4_udp_fd;
1351
1352 m->llmnr_ipv4_udp_fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1353 if (m->llmnr_ipv4_udp_fd < 0)
1354 return -errno;
1355
1356 /* RFC 4795, section 2.5 recommends setting the TTL of UDP packets to 255. */
1357 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
1358 if (r < 0) {
1359 r = -errno;
1360 goto fail;
1361 }
1362
1363 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
1364 if (r < 0) {
1365 r = -errno;
1366 goto fail;
1367 }
1368
1369 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MULTICAST_LOOP, &one, sizeof(one));
1370 if (r < 0) {
1371 r = -errno;
1372 goto fail;
1373 }
1374
1375 r = setsockopt(m->llmnr_ipv4_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1376 if (r < 0) {
1377 r = -errno;
1378 goto fail;
1379 }
1380
1381 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_PKTINFO, &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_RECVTTL, &one, sizeof(one));
1388 if (r < 0) {
1389 r = -errno;
1390 goto fail;
1391 }
1392
1393 /* Disable Don't-Fragment bit in the IP header */
1394 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu));
1395 if (r < 0) {
1396 r = -errno;
1397 goto fail;
1398 }
1399
1400 r = bind(m->llmnr_ipv4_udp_fd, &sa.sa, sizeof(sa.in));
1401 if (r < 0) {
1402 r = -errno;
1403 goto fail;
1404 }
1405
1406 r = sd_event_add_io(m->event, &m->llmnr_ipv4_udp_event_source, m->llmnr_ipv4_udp_fd, EPOLLIN, on_llmnr_packet, m);
1407 if (r < 0)
1408 goto fail;
1409
1410 return m->llmnr_ipv4_udp_fd;
1411
1412fail:
1413 m->llmnr_ipv4_udp_fd = safe_close(m->llmnr_ipv4_udp_fd);
1414 return r;
1415}
1416
1417int manager_llmnr_ipv6_udp_fd(Manager *m) {
1418 union sockaddr_union sa = {
1419 .in6.sin6_family = AF_INET6,
1420 .in6.sin6_port = htobe16(5355),
1421 };
1422 static const int one = 1, ttl = 255;
1423 int r;
1424
1425 assert(m);
1426
1427 if (m->llmnr_ipv6_udp_fd >= 0)
1428 return m->llmnr_ipv6_udp_fd;
1429
1430 m->llmnr_ipv6_udp_fd = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1431 if (m->llmnr_ipv6_udp_fd < 0)
1432 return -errno;
1433
1434 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl));
1435 if (r < 0) {
1436 r = -errno;
1437 goto fail;
1438 }
1439
1440 /* RFC 4795, section 2.5 recommends setting the TTL of UDP packets to 255. */
1441 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl));
1442 if (r < 0) {
1443 r = -errno;
1444 goto fail;
1445 }
1446
1447 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &one, sizeof(one));
1448 if (r < 0) {
1449 r = -errno;
1450 goto fail;
1451 }
1452
1453 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
1454 if (r < 0) {
1455 r = -errno;
1456 goto fail;
1457 }
1458
1459 r = setsockopt(m->llmnr_ipv6_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1460 if (r < 0) {
1461 r = -errno;
1462 goto fail;
1463 }
1464
1465 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &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_RECVHOPLIMIT, &one, sizeof(one));
1472 if (r < 0) {
1473 r = -errno;
1474 goto fail;
1475 }
1476
1477 r = bind(m->llmnr_ipv6_udp_fd, &sa.sa, sizeof(sa.in6));
1478 if (r < 0) {
1479 r = -errno;
1480 goto fail;
1481 }
1482
1483 r = sd_event_add_io(m->event, &m->llmnr_ipv6_udp_event_source, m->llmnr_ipv6_udp_fd, EPOLLIN, on_llmnr_packet, m);
1484 if (r < 0) {
1485 r = -errno;
1486 goto fail;
1487 }
1488
1489 return m->llmnr_ipv6_udp_fd;
1490
1491fail:
1492 m->llmnr_ipv6_udp_fd = safe_close(m->llmnr_ipv6_udp_fd);
1493 return r;
1494}
1495
1496static int on_llmnr_stream_packet(DnsStream *s) {
1497 DnsScope *scope;
1498
1499 assert(s);
1500
1501 scope = manager_find_scope(s->manager, s->read_packet);
1502 if (!scope) {
1503 log_warning("Got LLMNR TCP packet on unknown scope. Ignroing.");
1504 return 0;
1505 }
1506
1507 if (dns_packet_validate_query(s->read_packet) > 0) {
1508 log_debug("Got query packet for id %u", DNS_PACKET_ID(s->read_packet));
1509
1510 dns_scope_process_query(scope, s, s->read_packet);
1511
1512 /* If no reply packet was set, we free the stream */
1513 if (s->write_packet)
1514 return 0;
1515 } else
1516 log_debug("Invalid LLMNR TCP packet.");
1517
1518 dns_stream_free(s);
1519 return 0;
1520}
1521
1522static int on_llmnr_stream(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
1523 DnsStream *stream;
1524 Manager *m = userdata;
1525 int cfd, r;
1526
1527 cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
1528 if (cfd < 0) {
1529 if (errno == EAGAIN || errno == EINTR)
1530 return 0;
1531
1532 return -errno;
1533 }
1534
1535 r = dns_stream_new(m, &stream, DNS_PROTOCOL_LLMNR, cfd);
1536 if (r < 0) {
1537 safe_close(cfd);
1538 return r;
1539 }
1540
1541 stream->on_packet = on_llmnr_stream_packet;
1542 return 0;
1543}
1544
1545int manager_llmnr_ipv4_tcp_fd(Manager *m) {
1546 union sockaddr_union sa = {
1547 .in.sin_family = AF_INET,
1548 .in.sin_port = htobe16(5355),
1549 };
1550 static const int one = 1, pmtu = IP_PMTUDISC_DONT;
1551 int r;
1552
1553 assert(m);
1554
1555 if (m->llmnr_ipv4_tcp_fd >= 0)
1556 return m->llmnr_ipv4_tcp_fd;
1557
1558 m->llmnr_ipv4_tcp_fd = socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1559 if (m->llmnr_ipv4_tcp_fd < 0)
1560 return -errno;
1561
1562 /* RFC 4795, section 2.5. requires setting the TTL of TCP streams to 1 */
1563 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_TTL, &one, sizeof(one));
1564 if (r < 0) {
1565 r = -errno;
1566 goto fail;
1567 }
1568
1569 r = setsockopt(m->llmnr_ipv4_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1570 if (r < 0) {
1571 r = -errno;
1572 goto fail;
1573 }
1574
1575 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_PKTINFO, &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_RECVTTL, &one, sizeof(one));
1582 if (r < 0) {
1583 r = -errno;
1584 goto fail;
1585 }
1586
1587 /* Disable Don't-Fragment bit in the IP header */
1588 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu));
1589 if (r < 0) {
1590 r = -errno;
1591 goto fail;
1592 }
1593
1594 r = bind(m->llmnr_ipv4_tcp_fd, &sa.sa, sizeof(sa.in));
1595 if (r < 0) {
1596 r = -errno;
1597 goto fail;
1598 }
1599
1600 r = listen(m->llmnr_ipv4_tcp_fd, SOMAXCONN);
1601 if (r < 0) {
1602 r = -errno;
1603 goto fail;
1604 }
1605
1606 r = sd_event_add_io(m->event, &m->llmnr_ipv4_tcp_event_source, m->llmnr_ipv4_tcp_fd, EPOLLIN, on_llmnr_stream, m);
1607 if (r < 0)
1608 goto fail;
1609
1610 return m->llmnr_ipv4_tcp_fd;
1611
1612fail:
1613 m->llmnr_ipv4_tcp_fd = safe_close(m->llmnr_ipv4_tcp_fd);
1614 return r;
1615}
1616
1617int manager_llmnr_ipv6_tcp_fd(Manager *m) {
1618 union sockaddr_union sa = {
1619 .in6.sin6_family = AF_INET6,
1620 .in6.sin6_port = htobe16(5355),
1621 };
1622 static const int one = 1;
1623 int r;
1624
1625 assert(m);
1626
1627 if (m->llmnr_ipv6_tcp_fd >= 0)
1628 return m->llmnr_ipv6_tcp_fd;
1629
1630 m->llmnr_ipv6_tcp_fd = socket(AF_INET6, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1631 if (m->llmnr_ipv6_tcp_fd < 0)
1632 return -errno;
1633
1634 /* RFC 4795, section 2.5. requires setting the TTL of TCP streams to 1 */
1635 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &one, sizeof(one));
1636 if (r < 0) {
1637 r = -errno;
1638 goto fail;
1639 }
1640
1641 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
1642 if (r < 0) {
1643 r = -errno;
1644 goto fail;
1645 }
1646
1647 r = setsockopt(m->llmnr_ipv6_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1648 if (r < 0) {
1649 r = -errno;
1650 goto fail;
1651 }
1652
1653 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &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_RECVHOPLIMIT, &one, sizeof(one));
1660 if (r < 0) {
1661 r = -errno;
1662 goto fail;
1663 }
1664
1665 r = bind(m->llmnr_ipv6_tcp_fd, &sa.sa, sizeof(sa.in6));
1666 if (r < 0) {
1667 r = -errno;
1668 goto fail;
1669 }
1670
1671 r = listen(m->llmnr_ipv6_tcp_fd, SOMAXCONN);
1672 if (r < 0) {
1673 r = -errno;
1674 goto fail;
1675 }
1676
1677 r = sd_event_add_io(m->event, &m->llmnr_ipv6_tcp_event_source, m->llmnr_ipv6_tcp_fd, EPOLLIN, on_llmnr_stream, m);
1678 if (r < 0) {
1679 r = -errno;
1680 goto fail;
1681 }
1682
1683 return m->llmnr_ipv6_tcp_fd;
1684
1685fail:
1686 m->llmnr_ipv6_tcp_fd = safe_close(m->llmnr_ipv6_tcp_fd);
1687 return r;
1688}
1689
1690/* lo having ifindex 1 is hardcoded in the kernel */
1691#define LOOPBACK_IFINDEX 1
1692
1693int manager_ifindex_is_loopback(Manager *m, int ifindex) {
1694 Link *l;
1695 assert(m);
1696
1697 if (ifindex <= 0)
1698 return -EINVAL;
1699
1700 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
1701 if (!l)
1702 /* in case we don't yet track the link, rely on the hardcoded value */
1703 return ifindex == LOOPBACK_IFINDEX;
1704 else if (l->flags & IFF_LOOPBACK)
1705 return 1;
1706
1707 return 0;
1708}
1709
1710int manager_find_ifindex(Manager *m, int family, const union in_addr_union *in_addr) {
1711 LinkAddress *a;
1712
1713 assert(m);
1714
1715 a = manager_find_link_address(m, family, in_addr);
1716 if (a)
1717 return a->link->ifindex;
1718
1719 return 0;
1720}
1721
1722void manager_refresh_rrs(Manager *m) {
1723 Iterator i;
1724 Link *l;
1725
1726 assert(m);
1727
1728 m->host_ipv4_key = dns_resource_key_unref(m->host_ipv4_key);
1729 m->host_ipv6_key = dns_resource_key_unref(m->host_ipv6_key);
1730
1731 HASHMAP_FOREACH(l, m->links, i) {
1732 link_add_rrs(l, true);
1733 link_add_rrs(l, false);
1734 }
1735}
1736
1737int manager_next_hostname(Manager *m) {
1738 const char *p;
1739 uint64_t u, a;
1740 char *h;
1741
1742 assert(m);
1743
1744 p = strchr(m->hostname, 0);
1745 assert(p);
1746
1747 while (p > m->hostname) {
1748 if (!strchr("0123456789", p[-1]))
1749 break;
1750
1751 p--;
1752 }
1753
1754 if (*p == 0 || safe_atou64(p, &u) < 0 || u <= 0)
1755 u = 1;
1756
1757 /* Add a random number to the old value. This way we can avoid
1758 * that two hosts pick the same hostname, win on IPv4 and lose
1759 * on IPv6 (or vice versa), and pick the same hostname
1760 * replacement hostname, ad infinitum. We still want the
1761 * numbers to go up monotonically, hence we just add a random
1762 * value 1..10 */
1763
1764 random_bytes(&a, sizeof(a));
1765 u += 1 + a % 10;
1766
1767 if (asprintf(&h, "%.*s%" PRIu64, (int) (p - m->hostname), m->hostname, u) < 0)
1768 return -ENOMEM;
1769
1770 log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m->hostname, h);
1771
1772 free(m->hostname);
1773 m->hostname = h;
1774
1775 manager_refresh_rrs(m);
1776
1777 return 0;
1778}
1779
1780LinkAddress* manager_find_link_address(Manager *m, int family, const union in_addr_union *in_addr) {
1781 Iterator i;
1782 Link *l;
1783
1784 assert(m);
1785
1786 HASHMAP_FOREACH(l, m->links, i) {
1787 LinkAddress *a;
1788
1789 a = link_find_address(l, family, in_addr);
1790 if (a)
1791 return a;
1792 }
1793
1794 return NULL;
1795}
1796
1797bool manager_our_packet(Manager *m, DnsPacket *p) {
1798 assert(m);
1799 assert(p);
1800
1801 return !!manager_find_link_address(m, p->family, &p->sender);
1802}
1803
1804DnsScope* manager_find_scope(Manager *m, DnsPacket *p) {
1805 Link *l;
1806
1807 assert(m);
1808 assert(p);
1809
1810 l = hashmap_get(m->links, INT_TO_PTR(p->ifindex));
1811 if (!l)
1812 return NULL;
1813
1814 if (p->protocol == DNS_PROTOCOL_LLMNR) {
1815 if (p->family == AF_INET)
1816 return l->llmnr_ipv4_scope;
1817 else if (p->family == AF_INET6)
1818 return l->llmnr_ipv6_scope;
1819 }
1820
1821 return NULL;
1822}
1823
1824void manager_verify_all(Manager *m) {
1825 DnsScope *s;
1826
1827 assert(m);
1828
1829 LIST_FOREACH(scopes, s, m->dns_scopes)
1830 dns_zone_verify_all(&s->zone);
1831}
1832
1833void manager_flush_dns_servers(Manager *m, DnsServerType t) {
1834 assert(m);
1835
1836 if (t == DNS_SERVER_SYSTEM)
1837 while (m->dns_servers)
1838 dns_server_free(m->dns_servers);
1839
1840 if (t == DNS_SERVER_FALLBACK)
1841 while (m->fallback_dns_servers)
1842 dns_server_free(m->fallback_dns_servers);
1843}
1844
1845static const char* const support_table[_SUPPORT_MAX] = {
1846 [SUPPORT_NO] = "no",
1847 [SUPPORT_YES] = "yes",
1848 [SUPPORT_RESOLVE] = "resolve",
1849};
1850DEFINE_STRING_TABLE_LOOKUP(support, Support);