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