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