nspawn: make sure that when --network-veth is used both the host and the container...
[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
a2a416f7
LP
80 if (is_new)
81 log_debug("Found new link %i/%s", ifindex, l->name);
82
74b2466e 83 break;
a2a416f7 84 }
74b2466e
LP
85
86 case RTM_DELLINK:
87 if (l) {
a2a416f7 88 log_debug("Removing link %i/%s", l->ifindex, l->name);
74b2466e
LP
89 link_free(l);
90 }
91
92 break;
93 }
94
95 return 0;
96
97fail:
98 log_warning("Failed to process RTNL link message: %s", strerror(-r));
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;
74b2466e 105 uint16_t type;
0dd25fb9 106 int r, ifindex, family;
74b2466e
LP
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("Failed to process RTNL address message: %s", strerror(-r));
184 return 0;
185}
186
74b2466e
LP
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, subscibe 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;
091a364c 214
74b2466e
LP
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("Failed to update monitor information for %i: %s", l->ifindex, strerror(-r));
277 }
278
279 r = manager_write_resolv_conf(m);
280 if (r < 0)
281 log_warning("Could not update resolv.conf: %s", strerror(-r));
282
283 return 0;
284}
285
286static int manager_network_monitor_listen(Manager *m) {
287 int r, fd, events;
288
289 assert(m);
290
0014a4ad 291 r = sd_network_monitor_new(&m->network_monitor, NULL);
74b2466e
LP
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
eb60f9cd
LP
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) {
eb60f9cd
LP
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("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 log_error("Failed to add hostname event source: %s", strerror(-r));
379 return r;
380 }
381 }
382
383 r = determine_hostname(&m->hostname);
384 if (r < 0) {
385 log_info("Defaulting to hostname 'linux'.");
386 m->hostname = strdup("linux");
387 if (!m->hostname)
388 return log_oom();
389 } else
390 log_info("Using system hostname '%s'.", m->hostname);
391
392 return 0;
393}
394
091a364c 395int manager_new(Manager **ret) {
74b2466e 396 _cleanup_(manager_freep) Manager *m = NULL;
091a364c
TG
397 int r;
398
c92e531c
LP
399 assert(ret);
400
091a364c
TG
401 m = new0(Manager, 1);
402 if (!m)
403 return -ENOMEM;
404
74b2466e 405 m->dns_ipv4_fd = m->dns_ipv6_fd = -1;
1716f6dc 406 m->llmnr_ipv4_udp_fd = m->llmnr_ipv6_udp_fd = -1;
623a4c97 407 m->llmnr_ipv4_tcp_fd = m->llmnr_ipv6_tcp_fd = -1;
eb60f9cd 408 m->hostname_fd = -1;
1716f6dc 409
4e945a6f 410 m->llmnr_support = SUPPORT_YES;
5cb36f41 411 m->read_resolv_conf = true;
091a364c 412
4e945a6f 413 r = manager_parse_dns_server(m, DNS_SERVER_FALLBACK, DNS_SERVERS);
091a364c
TG
414 if (r < 0)
415 return r;
416
417 r = sd_event_default(&m->event);
418 if (r < 0)
419 return r;
420
421 sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
422 sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
423
424 sd_event_set_watchdog(m->event, true);
425
eb60f9cd
LP
426 r = manager_watch_hostname(m);
427 if (r < 0)
428 return r;
429
1716f6dc 430 r = dns_scope_new(m, &m->unicast_scope, NULL, DNS_PROTOCOL_DNS, AF_UNSPEC);
74b2466e
LP
431 if (r < 0)
432 return r;
433
434 r = manager_network_monitor_listen(m);
435 if (r < 0)
436 return r;
437
438 r = manager_rtnl_listen(m);
439 if (r < 0)
440 return r;
441
442 r = manager_connect_bus(m);
443 if (r < 0)
444 return r;
445
623a4c97
LP
446 r = manager_llmnr_ipv4_udp_fd(m);
447 if (r < 0)
448 return r;
449 r = manager_llmnr_ipv6_udp_fd(m);
450 if (r < 0)
451 return r;
452 r = manager_llmnr_ipv4_tcp_fd(m);
453 if (r < 0)
454 return r;
455 r = manager_llmnr_ipv6_tcp_fd(m);
456 if (r < 0)
457 return r;
458
091a364c
TG
459 *ret = m;
460 m = NULL;
461
462 return 0;
463}
464
74b2466e
LP
465Manager *manager_free(Manager *m) {
466 Link *l;
091a364c
TG
467
468 if (!m)
74b2466e
LP
469 return NULL;
470
471 while (m->dns_queries)
472 dns_query_free(m->dns_queries);
473
ec2c5e43 474 hashmap_free(m->dns_transactions);
74b2466e
LP
475
476 while ((l = hashmap_first(m->links)))
477 link_free(l);
478 hashmap_free(m->links);
479
480 dns_scope_free(m->unicast_scope);
481
482 while (m->dns_servers)
483 dns_server_free(m->dns_servers);
4e945a6f
LP
484 while (m->fallback_dns_servers)
485 dns_server_free(m->fallback_dns_servers);
091a364c 486
096b6773
LP
487 sd_event_source_unref(m->network_event_source);
488 sd_network_monitor_unref(m->network_monitor);
091a364c 489
74b2466e
LP
490 sd_event_source_unref(m->dns_ipv4_event_source);
491 sd_event_source_unref(m->dns_ipv6_event_source);
74b2466e
LP
492 safe_close(m->dns_ipv4_fd);
493 safe_close(m->dns_ipv6_fd);
494
1716f6dc
LP
495 sd_event_source_unref(m->llmnr_ipv4_udp_event_source);
496 sd_event_source_unref(m->llmnr_ipv6_udp_event_source);
497 safe_close(m->llmnr_ipv4_udp_fd);
498 safe_close(m->llmnr_ipv6_udp_fd);
499
623a4c97
LP
500 sd_event_source_unref(m->llmnr_ipv4_tcp_event_source);
501 sd_event_source_unref(m->llmnr_ipv6_tcp_event_source);
502 safe_close(m->llmnr_ipv4_tcp_fd);
503 safe_close(m->llmnr_ipv6_tcp_fd);
504
74b2466e
LP
505 sd_event_source_unref(m->bus_retry_event_source);
506 sd_bus_unref(m->bus);
091a364c 507
74b2466e 508 sd_event_unref(m->event);
623a4c97
LP
509
510 dns_resource_key_unref(m->host_ipv4_key);
511 dns_resource_key_unref(m->host_ipv6_key);
eb60f9cd
LP
512
513 safe_close(m->hostname_fd);
514 sd_event_source_unref(m->hostname_event_source);
623a4c97 515 free(m->hostname);
eb60f9cd 516
091a364c 517 free(m);
74b2466e
LP
518
519 return NULL;
091a364c
TG
520}
521
5cb36f41
LP
522int manager_read_resolv_conf(Manager *m) {
523 _cleanup_fclose_ FILE *f = NULL;
524 struct stat st, own;
525 char line[LINE_MAX];
526 DnsServer *s, *nx;
527 usec_t t;
528 int r;
529
530 assert(m);
531
532 /* Reads the system /etc/resolv.conf, if it exists and is not
533 * symlinked to our own resolv.conf instance */
534
535 if (!m->read_resolv_conf)
536 return 0;
537
538 r = stat("/etc/resolv.conf", &st);
539 if (r < 0) {
540 if (errno != ENOENT)
541 log_warning("Failed to open /etc/resolv.conf: %m");
542 r = -errno;
543 goto clear;
544 }
545
546 /* Have we already seen the file? */
547 t = timespec_load(&st.st_mtim);
548 if (t == m->resolv_conf_mtime)
549 return 0;
550
551 m->resolv_conf_mtime = t;
552
553 /* Is it symlinked to our own file? */
554 if (stat("/run/systemd/resolve/resolv.conf", &own) >= 0 &&
555 st.st_dev == own.st_dev &&
556 st.st_ino == own.st_ino) {
557 r = 0;
558 goto clear;
559 }
560
561 f = fopen("/etc/resolv.conf", "re");
562 if (!f) {
563 if (errno != ENOENT)
564 log_warning("Failed to open /etc/resolv.conf: %m");
565 r = -errno;
566 goto clear;
567 }
568
569 if (fstat(fileno(f), &st) < 0) {
570 log_error("Failed to stat open file: %m");
571 r = -errno;
572 goto clear;
573 }
574
575 LIST_FOREACH(servers, s, m->dns_servers)
576 s->marked = true;
577
578 FOREACH_LINE(line, f, r = -errno; goto clear) {
579 union in_addr_union address;
580 int family;
581 char *l;
582 const char *a;
583
584 truncate_nl(line);
585
586 l = strstrip(line);
587 if (*l == '#' || *l == ';')
588 continue;
589
590 a = first_word(l, "nameserver");
591 if (!a)
592 continue;
593
594 r = in_addr_from_string_auto(a, &family, &address);
595 if (r < 0) {
596 log_warning("Failed to parse name server %s.", a);
597 continue;
598 }
599
600 LIST_FOREACH(servers, s, m->dns_servers)
601 if (s->family == family && in_addr_equal(family, &s->address, &address) > 0)
602 break;
603
604 if (s)
605 s->marked = false;
606 else {
607 r = dns_server_new(m, NULL, DNS_SERVER_SYSTEM, NULL, family, &address);
608 if (r < 0)
609 goto clear;
610 }
611 }
612
613 LIST_FOREACH_SAFE(servers, s, nx, m->dns_servers)
614 if (s->marked)
615 dns_server_free(s);
616
617 return 0;
618
619clear:
620 while (m->dns_servers)
621 dns_server_free(m->dns_servers);
622
623 return r;
624}
625
74b2466e
LP
626static void write_resolve_conf_server(DnsServer *s, FILE *f, unsigned *count) {
627 _cleanup_free_ char *t = NULL;
628 int r;
091a364c 629
74b2466e 630 assert(s);
091a364c 631 assert(f);
091a364c
TG
632 assert(count);
633
74b2466e 634 r = in_addr_to_string(s->family, &s->address, &t);
4e945a6f
LP
635 if (r < 0) {
636 log_warning("Invalid DNS address. Ignoring: %s", strerror(-r));
091a364c
TG
637 return;
638 }
639
640 if (*count == MAXNS)
74b2466e 641 fputs("# Too many DNS servers configured, the following entries may be ignored\n", f);
091a364c 642
74b2466e 643 fprintf(f, "nameserver %s\n", t);
091a364c
TG
644 (*count) ++;
645}
646
74b2466e 647int manager_write_resolv_conf(Manager *m) {
4e945a6f 648 static const char path[] = "/run/systemd/resolve/resolv.conf";
091a364c
TG
649 _cleanup_free_ char *temp_path = NULL;
650 _cleanup_fclose_ FILE *f = NULL;
091a364c 651 unsigned count = 0;
74b2466e
LP
652 DnsServer *s;
653 Iterator i;
654 Link *l;
655 int r;
091a364c
TG
656
657 assert(m);
658
5cb36f41
LP
659 /* Read the system /etc/resolv.conf first */
660 manager_read_resolv_conf(m);
661
b686acb2 662 r = fopen_temporary(path, &f, &temp_path);
091a364c
TG
663 if (r < 0)
664 return r;
665
666 fchmod(fileno(f), 0644);
667
668 fputs("# This file is managed by systemd-resolved(8). Do not edit.\n#\n"
669 "# Third party programs must not access this file directly, but\n"
670 "# only through the symlink at /etc/resolv.conf. To manage\n"
671 "# resolv.conf(5) in a different way, replace the symlink by a\n"
672 "# static file or a different symlink.\n\n", f);
673
4e945a6f
LP
674 LIST_FOREACH(servers, s, m->dns_servers)
675 write_resolve_conf_server(s, f, &count);
676
6073b6f2
TG
677 HASHMAP_FOREACH(l, m->links, i)
678 LIST_FOREACH(servers, s, l->dns_servers)
74b2466e 679 write_resolve_conf_server(s, f, &count);
091a364c 680
4e945a6f
LP
681 if (count == 0) {
682 LIST_FOREACH(servers, s, m->fallback_dns_servers)
683 write_resolve_conf_server(s, f, &count);
684 }
091a364c 685
74b2466e
LP
686 r = fflush_and_check(f);
687 if (r < 0)
688 goto fail;
689
690 if (rename(temp_path, path) < 0) {
691 r = -errno;
692 goto fail;
693 }
091a364c 694
74b2466e 695 return 0;
091a364c 696
74b2466e
LP
697fail:
698 unlink(path);
699 unlink(temp_path);
700 return r;
701}
091a364c 702
1716f6dc 703int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) {
74b2466e 704 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
1716f6dc
LP
705 union {
706 struct cmsghdr header; /* For alignment */
707 uint8_t buffer[CMSG_SPACE(MAX(sizeof(struct in_pktinfo), sizeof(struct in6_pktinfo)))
708 + CMSG_SPACE(int) /* ttl/hoplimit */
623a4c97 709 + EXTRA_CMSG_SPACE /* kernel appears to require extra buffer space */];
1716f6dc
LP
710 } control;
711 union sockaddr_union sa;
74b2466e 712 struct msghdr mh = {};
1716f6dc 713 struct cmsghdr *cmsg;
74b2466e 714 struct iovec iov;
1716f6dc 715 int ms = 0, r;
74b2466e
LP
716 ssize_t l;
717
718 assert(m);
1716f6dc 719 assert(fd >= 0);
74b2466e
LP
720 assert(ret);
721
74b2466e
LP
722 r = ioctl(fd, FIONREAD, &ms);
723 if (r < 0)
724 return -errno;
725 if (ms < 0)
726 return -EIO;
727
1716f6dc 728 r = dns_packet_new(&p, protocol, ms);
74b2466e
LP
729 if (r < 0)
730 return r;
731
732 iov.iov_base = DNS_PACKET_DATA(p);
733 iov.iov_len = p->allocated;
734
1716f6dc
LP
735 mh.msg_name = &sa.sa;
736 mh.msg_namelen = sizeof(sa);
74b2466e
LP
737 mh.msg_iov = &iov;
738 mh.msg_iovlen = 1;
1716f6dc
LP
739 mh.msg_control = &control;
740 mh.msg_controllen = sizeof(control);
74b2466e
LP
741
742 l = recvmsg(fd, &mh, 0);
743 if (l < 0) {
ad867662 744 if (errno == EAGAIN || errno == EINTR)
74b2466e
LP
745 return 0;
746
747 return -errno;
091a364c
TG
748 }
749
74b2466e
LP
750 if (l <= 0)
751 return -EIO;
091a364c 752
1716f6dc
LP
753 assert(!(mh.msg_flags & MSG_CTRUNC));
754 assert(!(mh.msg_flags & MSG_TRUNC));
755
74b2466e 756 p->size = (size_t) l;
091a364c 757
1716f6dc 758 p->family = sa.sa.sa_family;
623a4c97
LP
759 p->ipproto = IPPROTO_UDP;
760 if (p->family == AF_INET) {
1716f6dc 761 p->sender.in = sa.in.sin_addr;
623a4c97
LP
762 p->sender_port = be16toh(sa.in.sin_port);
763 } else if (p->family == AF_INET6) {
1716f6dc 764 p->sender.in6 = sa.in6.sin6_addr;
623a4c97
LP
765 p->sender_port = be16toh(sa.in6.sin6_port);
766 p->ifindex = sa.in6.sin6_scope_id;
767 } else
1716f6dc 768 return -EAFNOSUPPORT;
74b2466e 769
1716f6dc 770 for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
74b2466e 771
1716f6dc
LP
772 if (cmsg->cmsg_level == IPPROTO_IPV6) {
773 assert(p->family == AF_INET6);
74b2466e 774
1716f6dc 775 switch (cmsg->cmsg_type) {
74b2466e 776
1716f6dc
LP
777 case IPV6_PKTINFO: {
778 struct in6_pktinfo *i = (struct in6_pktinfo*) CMSG_DATA(cmsg);
74b2466e 779
623a4c97
LP
780 if (p->ifindex <= 0)
781 p->ifindex = i->ipi6_ifindex;
782
1716f6dc
LP
783 p->destination.in6 = i->ipi6_addr;
784 break;
785 }
74b2466e 786
1716f6dc
LP
787 case IPV6_HOPLIMIT:
788 p->ttl = *(int *) CMSG_DATA(cmsg);
789 break;
74b2466e 790
1716f6dc
LP
791 }
792 } else if (cmsg->cmsg_level == IPPROTO_IP) {
793 assert(p->family == AF_INET);
74b2466e 794
1716f6dc 795 switch (cmsg->cmsg_type) {
74b2466e 796
1716f6dc
LP
797 case IP_PKTINFO: {
798 struct in_pktinfo *i = (struct in_pktinfo*) CMSG_DATA(cmsg);
091a364c 799
623a4c97
LP
800 if (p->ifindex <= 0)
801 p->ifindex = i->ipi_ifindex;
802
1716f6dc
LP
803 p->destination.in = i->ipi_addr;
804 break;
805 }
74b2466e 806
623a4c97 807 case IP_TTL:
1716f6dc
LP
808 p->ttl = *(int *) CMSG_DATA(cmsg);
809 break;
810 }
811 }
812 }
74b2466e 813
623a4c97
LP
814 /* The Linux kernel sets the interface index to the loopback
815 * device if the packet came from the local host since it
816 * avoids the routing table in such a case. Let's unset the
817 * interface index in such a case. */
818 if (p->ifindex > 0 && manager_ifindex_is_loopback(m, p->ifindex) != 0)
819 p->ifindex = 0;
820
821 /* If we don't know the interface index still, we look for the
822 * first local interface with a matching address. Yuck! */
823 if (p->ifindex <= 0)
824 p->ifindex = manager_find_ifindex(m, p->family, &p->destination);
825
74b2466e
LP
826 *ret = p;
827 p = NULL;
828
829 return 1;
830}
831
1716f6dc 832static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
74b2466e 833 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
ec2c5e43 834 DnsTransaction *t = NULL;
74b2466e
LP
835 Manager *m = userdata;
836 int r;
837
1716f6dc 838 r = manager_recv(m, fd, DNS_PROTOCOL_DNS, &p);
74b2466e
LP
839 if (r <= 0)
840 return r;
841
623a4c97 842 if (dns_packet_validate_reply(p) > 0) {
ec2c5e43 843 t = hashmap_get(m->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
1716f6dc
LP
844 if (!t)
845 return 0;
74b2466e 846
ec2c5e43 847 dns_transaction_process_reply(t, p);
623a4c97 848
1716f6dc 849 } else
623a4c97 850 log_debug("Invalid DNS packet.");
74b2466e 851
ad867662 852 return 0;
74b2466e
LP
853}
854
855int manager_dns_ipv4_fd(Manager *m) {
1716f6dc 856 const int one = 1;
74b2466e
LP
857 int r;
858
091a364c
TG
859 assert(m);
860
74b2466e
LP
861 if (m->dns_ipv4_fd >= 0)
862 return m->dns_ipv4_fd;
091a364c 863
74b2466e
LP
864 m->dns_ipv4_fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
865 if (m->dns_ipv4_fd < 0)
866 return -errno;
091a364c 867
1716f6dc
LP
868 r = setsockopt(m->dns_ipv4_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
869 if (r < 0) {
870 r = -errno;
871 goto fail;
872 }
873
874 r = sd_event_add_io(m->event, &m->dns_ipv4_event_source, m->dns_ipv4_fd, EPOLLIN, on_dns_packet, m);
74b2466e 875 if (r < 0)
1716f6dc 876 goto fail;
74b2466e
LP
877
878 return m->dns_ipv4_fd;
1716f6dc
LP
879
880fail:
881 m->dns_ipv4_fd = safe_close(m->dns_ipv4_fd);
882 return r;
091a364c
TG
883}
884
74b2466e 885int manager_dns_ipv6_fd(Manager *m) {
1716f6dc 886 const int one = 1;
74b2466e
LP
887 int r;
888
889 assert(m);
091a364c 890
74b2466e
LP
891 if (m->dns_ipv6_fd >= 0)
892 return m->dns_ipv6_fd;
893
894 m->dns_ipv6_fd = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
895 if (m->dns_ipv6_fd < 0)
896 return -errno;
897
1716f6dc
LP
898 r = setsockopt(m->dns_ipv6_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
899 if (r < 0) {
900 r = -errno;
901 goto fail;
902 }
903
904 r = sd_event_add_io(m->event, &m->dns_ipv6_event_source, m->dns_ipv6_fd, EPOLLIN, on_dns_packet, m);
091a364c 905 if (r < 0)
1716f6dc 906 goto fail;
091a364c 907
74b2466e 908 return m->dns_ipv6_fd;
1716f6dc
LP
909
910fail:
911 m->dns_ipv6_fd = safe_close(m->dns_ipv6_fd);
912 return r;
74b2466e
LP
913}
914
915static int sendmsg_loop(int fd, struct msghdr *mh, int flags) {
916 int r;
917
918 assert(fd >= 0);
919 assert(mh);
920
921 for (;;) {
922 if (sendmsg(fd, mh, flags) >= 0)
923 return 0;
924
925 if (errno == EINTR)
926 continue;
927
928 if (errno != EAGAIN)
929 return -errno;
930
931 r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
932 if (r < 0)
933 return r;
934 if (r == 0)
935 return -ETIMEDOUT;
936 }
937}
938
623a4c97 939static int manager_ipv4_send(Manager *m, int fd, int ifindex, const struct in_addr *addr, uint16_t port, DnsPacket *p) {
74b2466e
LP
940 union sockaddr_union sa = {
941 .in.sin_family = AF_INET,
74b2466e 942 };
1716f6dc
LP
943 union {
944 struct cmsghdr header; /* For alignment */
945 uint8_t buffer[CMSG_SPACE(sizeof(struct in_pktinfo))];
946 } control;
74b2466e
LP
947 struct msghdr mh = {};
948 struct iovec iov;
74b2466e
LP
949
950 assert(m);
1716f6dc
LP
951 assert(fd >= 0);
952 assert(addr);
953 assert(port > 0);
74b2466e
LP
954 assert(p);
955
74b2466e
LP
956 iov.iov_base = DNS_PACKET_DATA(p);
957 iov.iov_len = p->size;
091a364c 958
1716f6dc
LP
959 sa.in.sin_addr = *addr;
960 sa.in.sin_port = htobe16(port),
091a364c 961
74b2466e
LP
962 mh.msg_iov = &iov;
963 mh.msg_iovlen = 1;
964 mh.msg_name = &sa.sa;
965 mh.msg_namelen = sizeof(sa.in);
091a364c 966
74b2466e
LP
967 if (ifindex > 0) {
968 struct cmsghdr *cmsg;
969 struct in_pktinfo *pi;
970
971 zero(control);
972
1716f6dc 973 mh.msg_control = &control;
74b2466e
LP
974 mh.msg_controllen = CMSG_LEN(sizeof(struct in_pktinfo));
975
976 cmsg = CMSG_FIRSTHDR(&mh);
977 cmsg->cmsg_len = mh.msg_controllen;
978 cmsg->cmsg_level = IPPROTO_IP;
979 cmsg->cmsg_type = IP_PKTINFO;
980
981 pi = (struct in_pktinfo*) CMSG_DATA(cmsg);
982 pi->ipi_ifindex = ifindex;
983 }
984
985 return sendmsg_loop(fd, &mh, 0);
986}
987
623a4c97 988static int manager_ipv6_send(Manager *m, int fd, int ifindex, const struct in6_addr *addr, uint16_t port, DnsPacket *p) {
74b2466e
LP
989 union sockaddr_union sa = {
990 .in6.sin6_family = AF_INET6,
74b2466e 991 };
1716f6dc
LP
992 union {
993 struct cmsghdr header; /* For alignment */
994 uint8_t buffer[CMSG_SPACE(sizeof(struct in6_pktinfo))];
995 } control;
74b2466e
LP
996 struct msghdr mh = {};
997 struct iovec iov;
74b2466e
LP
998
999 assert(m);
1716f6dc
LP
1000 assert(fd >= 0);
1001 assert(addr);
1002 assert(port > 0);
74b2466e
LP
1003 assert(p);
1004
74b2466e
LP
1005 iov.iov_base = DNS_PACKET_DATA(p);
1006 iov.iov_len = p->size;
1007
1716f6dc
LP
1008 sa.in6.sin6_addr = *addr;
1009 sa.in6.sin6_port = htobe16(port),
74b2466e
LP
1010 sa.in6.sin6_scope_id = ifindex;
1011
1012 mh.msg_iov = &iov;
1013 mh.msg_iovlen = 1;
1014 mh.msg_name = &sa.sa;
1015 mh.msg_namelen = sizeof(sa.in6);
1016
1017 if (ifindex > 0) {
1018 struct cmsghdr *cmsg;
1019 struct in6_pktinfo *pi;
1020
1021 zero(control);
1022
1716f6dc 1023 mh.msg_control = &control;
74b2466e
LP
1024 mh.msg_controllen = CMSG_LEN(sizeof(struct in6_pktinfo));
1025
1026 cmsg = CMSG_FIRSTHDR(&mh);
1027 cmsg->cmsg_len = mh.msg_controllen;
1028 cmsg->cmsg_level = IPPROTO_IPV6;
1029 cmsg->cmsg_type = IPV6_PKTINFO;
1030
1031 pi = (struct in6_pktinfo*) CMSG_DATA(cmsg);
1032 pi->ipi6_ifindex = ifindex;
1033 }
1034
1035 return sendmsg_loop(fd, &mh, 0);
1036}
1037
623a4c97 1038int manager_send(Manager *m, int fd, int ifindex, int family, const union in_addr_union *addr, uint16_t port, DnsPacket *p) {
1716f6dc
LP
1039 assert(m);
1040 assert(fd >= 0);
1041 assert(addr);
1042 assert(port > 0);
1043 assert(p);
1044
a2a416f7
LP
1045 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));
1046
1716f6dc
LP
1047 if (family == AF_INET)
1048 return manager_ipv4_send(m, fd, ifindex, &addr->in, port, p);
1049 else if (family == AF_INET6)
1050 return manager_ipv6_send(m, fd, ifindex, &addr->in6, port, p);
1051
1052 return -EAFNOSUPPORT;
1053}
1054
2c27fbca 1055DnsServer* manager_find_dns_server(Manager *m, int family, const union in_addr_union *in_addr) {
74b2466e
LP
1056 DnsServer *s;
1057
1058 assert(m);
1059 assert(in_addr);
1060
4e945a6f 1061 LIST_FOREACH(servers, s, m->dns_servers)
5cb36f41 1062 if (s->family == family && in_addr_equal(family, &s->address, in_addr) > 0)
2c27fbca 1063 return s;
74b2466e 1064
4e945a6f 1065 LIST_FOREACH(servers, s, m->fallback_dns_servers)
5cb36f41 1066 if (s->family == family && in_addr_equal(family, &s->address, in_addr) > 0)
2c27fbca 1067 return s;
74b2466e 1068
2c27fbca 1069 return NULL;
4e945a6f
LP
1070}
1071
2c27fbca 1072DnsServer *manager_set_dns_server(Manager *m, DnsServer *s) {
4e945a6f
LP
1073 assert(m);
1074
1075 if (m->current_dns_server == s)
1076 return s;
1077
1078 if (s) {
1079 _cleanup_free_ char *ip = NULL;
1080
1081 in_addr_to_string(s->family, &s->address, &ip);
1082 log_info("Switching to system DNS server %s.", strna(ip));
2c27fbca 1083 }
4e945a6f
LP
1084
1085 m->current_dns_server = s;
2c27fbca
LP
1086
1087 if (m->unicast_scope)
1088 dns_cache_flush(&m->unicast_scope->cache);
1089
4e945a6f 1090 return s;
74b2466e
LP
1091}
1092
1093DnsServer *manager_get_dns_server(Manager *m) {
4e945a6f 1094 Link *l;
74b2466e
LP
1095 assert(m);
1096
5cb36f41
LP
1097 /* Try to read updates resolv.conf */
1098 manager_read_resolv_conf(m);
1099
74b2466e 1100 if (!m->current_dns_server)
4e945a6f
LP
1101 manager_set_dns_server(m, m->dns_servers);
1102
1103 if (!m->current_dns_server) {
1104 bool found = false;
1105 Iterator i;
1106
1107 /* No DNS servers configured, let's see if there are
1108 * any on any links. If not, we use the fallback
1109 * servers */
1110
1111 HASHMAP_FOREACH(l, m->links, i)
1112 if (l->dns_servers) {
1113 found = true;
1114 break;
1115 }
1116
1117 if (!found)
1118 manager_set_dns_server(m, m->fallback_dns_servers);
1119 }
74b2466e
LP
1120
1121 return m->current_dns_server;
1122}
1123
1124void manager_next_dns_server(Manager *m) {
1125 assert(m);
1126
4e945a6f
LP
1127 /* If there's currently no DNS server set, then the next
1128 * manager_get_dns_server() will find one */
74b2466e
LP
1129 if (!m->current_dns_server)
1130 return;
1131
4e945a6f 1132 /* Change to the next one */
74b2466e 1133 if (m->current_dns_server->servers_next) {
4e945a6f 1134 manager_set_dns_server(m, m->current_dns_server->servers_next);
74b2466e
LP
1135 return;
1136 }
1137
4e945a6f
LP
1138 /* If there was no next one, then start from the beginning of
1139 * the list */
1140 if (m->current_dns_server->type == DNS_SERVER_FALLBACK)
1141 manager_set_dns_server(m, m->fallback_dns_servers);
1142 else
1143 manager_set_dns_server(m, m->dns_servers);
091a364c 1144}
e1c95994
LP
1145
1146uint32_t manager_find_mtu(Manager *m) {
1147 uint32_t mtu = 0;
1148 Link *l;
1149 Iterator i;
1150
1151 /* If we don't know on which link a DNS packet would be
1152 * delivered, let's find the largest MTU that works on all
1153 * interfaces we know of */
1154
1155 HASHMAP_FOREACH(l, m->links, i) {
1156 if (l->mtu <= 0)
1157 continue;
1158
1159 if (mtu <= 0 || l->mtu < mtu)
1160 mtu = l->mtu;
1161 }
1162
1163 return mtu;
1164}
1716f6dc
LP
1165
1166static int on_llmnr_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
1167 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
ec2c5e43 1168 DnsTransaction *t = NULL;
1716f6dc
LP
1169 Manager *m = userdata;
1170 int r;
1171
1172 r = manager_recv(m, fd, DNS_PROTOCOL_LLMNR, &p);
1173 if (r <= 0)
1174 return r;
1175
623a4c97 1176 if (dns_packet_validate_reply(p) > 0) {
a2a416f7
LP
1177 log_debug("Got reply packet for id %u", DNS_PACKET_ID(p));
1178
ec2c5e43 1179 t = hashmap_get(m->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
1716f6dc
LP
1180 if (!t)
1181 return 0;
1182
ec2c5e43 1183 dns_transaction_process_reply(t, p);
623a4c97
LP
1184
1185 } else if (dns_packet_validate_query(p) > 0) {
1186 Link *l;
1187
1188 l = hashmap_get(m->links, INT_TO_PTR(p->ifindex));
1189 if (l) {
1190 DnsScope *scope = NULL;
1191
1192 if (p->family == AF_INET)
1193 scope = l->llmnr_ipv4_scope;
1194 else if (p->family == AF_INET6)
1195 scope = l->llmnr_ipv6_scope;
1196
1197 if (scope)
1198 dns_scope_process_query(scope, NULL, p);
1199 }
1200 } else
1201 log_debug("Invalid LLMNR packet.");
1716f6dc
LP
1202
1203 return 0;
1204}
1205
1206int manager_llmnr_ipv4_udp_fd(Manager *m) {
1207 union sockaddr_union sa = {
1208 .in.sin_family = AF_INET,
1209 .in.sin_port = htobe16(5355),
1210 };
bf3f1271 1211 static const int one = 1, pmtu = IP_PMTUDISC_DONT, ttl = 255;
1716f6dc
LP
1212 int r;
1213
1214 assert(m);
1215
1216 if (m->llmnr_ipv4_udp_fd >= 0)
1217 return m->llmnr_ipv4_udp_fd;
1218
1219 m->llmnr_ipv4_udp_fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1220 if (m->llmnr_ipv4_udp_fd < 0)
1221 return -errno;
1222
bf3f1271
LP
1223 /* RFC 4795, section 2.5 recommends setting the TTL of UDP packets to 255. */
1224 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
1716f6dc
LP
1225 if (r < 0) {
1226 r = -errno;
1227 goto fail;
1228 }
1229
bf3f1271 1230 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
1716f6dc
LP
1231 if (r < 0) {
1232 r = -errno;
1233 goto fail;
1234 }
1235
1236 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MULTICAST_LOOP, &one, sizeof(one));
1237 if (r < 0) {
1238 r = -errno;
1239 goto fail;
1240 }
1241
1242 r = setsockopt(m->llmnr_ipv4_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1243 if (r < 0) {
1244 r = -errno;
1245 goto fail;
1246 }
1247
1248 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
1249 if (r < 0) {
1250 r = -errno;
1251 goto fail;
1252 }
1253
1254 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_RECVTTL, &one, sizeof(one));
1255 if (r < 0) {
1256 r = -errno;
1257 goto fail;
1258 }
1259
1260 /* Disable Don't-Fragment bit in the IP header */
1261 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu));
1262 if (r < 0) {
1263 r = -errno;
1264 goto fail;
1265 }
1266
1267 r = bind(m->llmnr_ipv4_udp_fd, &sa.sa, sizeof(sa.in));
1268 if (r < 0) {
1269 r = -errno;
1270 goto fail;
1271 }
1272
1273 r = sd_event_add_io(m->event, &m->llmnr_ipv4_udp_event_source, m->llmnr_ipv4_udp_fd, EPOLLIN, on_llmnr_packet, m);
1274 if (r < 0)
1275 goto fail;
1276
1277 return m->llmnr_ipv4_udp_fd;
1278
1279fail:
1280 m->llmnr_ipv4_udp_fd = safe_close(m->llmnr_ipv4_udp_fd);
1281 return r;
1282}
1283
1284int manager_llmnr_ipv6_udp_fd(Manager *m) {
1285 union sockaddr_union sa = {
1286 .in6.sin6_family = AF_INET6,
1287 .in6.sin6_port = htobe16(5355),
1288 };
bf3f1271 1289 static const int one = 1, ttl = 255;
1716f6dc
LP
1290 int r;
1291
1292 assert(m);
1293
1294 if (m->llmnr_ipv6_udp_fd >= 0)
1295 return m->llmnr_ipv6_udp_fd;
1296
1297 m->llmnr_ipv6_udp_fd = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1298 if (m->llmnr_ipv6_udp_fd < 0)
1299 return -errno;
1300
bf3f1271 1301 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl));
1716f6dc
LP
1302 if (r < 0) {
1303 r = -errno;
1304 goto fail;
1305 }
1306
bf3f1271
LP
1307 /* RFC 4795, section 2.5 recommends setting the TTL of UDP packets to 255. */
1308 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl));
1716f6dc
LP
1309 if (r < 0) {
1310 r = -errno;
1311 goto fail;
1312 }
1313
1314 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &one, sizeof(one));
1315 if (r < 0) {
1316 r = -errno;
1317 goto fail;
1318 }
1319
1320 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
1321 if (r < 0) {
1322 r = -errno;
1323 goto fail;
1324 }
1325
1326 r = setsockopt(m->llmnr_ipv6_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1327 if (r < 0) {
1328 r = -errno;
1329 goto fail;
1330 }
1331
1332 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
1333 if (r < 0) {
1334 r = -errno;
1335 goto fail;
1336 }
1337
1338 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &one, sizeof(one));
1339 if (r < 0) {
1340 r = -errno;
1341 goto fail;
1342 }
1343
1344 r = bind(m->llmnr_ipv6_udp_fd, &sa.sa, sizeof(sa.in6));
1345 if (r < 0) {
1346 r = -errno;
1347 goto fail;
1348 }
1349
1350 r = sd_event_add_io(m->event, &m->llmnr_ipv6_udp_event_source, m->llmnr_ipv6_udp_fd, EPOLLIN, on_llmnr_packet, m);
1351 if (r < 0) {
1352 r = -errno;
1353 goto fail;
1354 }
1355
1356 return m->llmnr_ipv6_udp_fd;
1357
1358fail:
1359 m->llmnr_ipv6_udp_fd = safe_close(m->llmnr_ipv6_udp_fd);
1360 return r;
1361}
623a4c97
LP
1362
1363static int on_llmnr_stream_packet(DnsStream *s) {
1364 assert(s);
1365
1366 if (dns_packet_validate_query(s->read_packet) > 0) {
1367 Link *l;
1368
1369 l = hashmap_get(s->manager->links, INT_TO_PTR(s->read_packet->ifindex));
1370 if (l) {
1371 DnsScope *scope = NULL;
1372
1373 if (s->read_packet->family == AF_INET)
1374 scope = l->llmnr_ipv4_scope;
1375 else if (s->read_packet->family == AF_INET6)
1376 scope = l->llmnr_ipv6_scope;
1377
1378 if (scope) {
1379 dns_scope_process_query(scope, s, s->read_packet);
1380
1381 /* If no reply packet was set, we free the stream */
1382 if (s->write_packet)
1383 return 0;
1384 }
1385 }
1386 }
1387
1388 dns_stream_free(s);
1389 return 0;
1390}
1391
1392static int on_llmnr_stream(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
1393 DnsStream *stream;
1394 Manager *m = userdata;
1395 int cfd, r;
1396
1397 cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
1398 if (cfd < 0) {
1399 if (errno == EAGAIN || errno == EINTR)
1400 return 0;
1401
1402 return -errno;
1403 }
1404
1405 r = dns_stream_new(m, &stream, DNS_PROTOCOL_LLMNR, cfd);
1406 if (r < 0) {
1407 safe_close(cfd);
1408 return r;
1409 }
1410
1411 stream->on_packet = on_llmnr_stream_packet;
1412 return 0;
1413}
1414
1415int manager_llmnr_ipv4_tcp_fd(Manager *m) {
1416 union sockaddr_union sa = {
1417 .in.sin_family = AF_INET,
1418 .in.sin_port = htobe16(5355),
1419 };
1420 static const int one = 1, pmtu = IP_PMTUDISC_DONT;
1421 int r;
1422
1423 assert(m);
1424
1425 if (m->llmnr_ipv4_tcp_fd >= 0)
1426 return m->llmnr_ipv4_tcp_fd;
1427
1428 m->llmnr_ipv4_tcp_fd = socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1429 if (m->llmnr_ipv4_tcp_fd < 0)
1430 return -errno;
1431
bf3f1271 1432 /* RFC 4795, section 2.5. requires setting the TTL of TCP streams to 1 */
623a4c97
LP
1433 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_TTL, &one, sizeof(one));
1434 if (r < 0) {
1435 r = -errno;
1436 goto fail;
1437 }
1438
1439 r = setsockopt(m->llmnr_ipv4_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1440 if (r < 0) {
1441 r = -errno;
1442 goto fail;
1443 }
1444
1445 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
1446 if (r < 0) {
1447 r = -errno;
1448 goto fail;
1449 }
1450
1451 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_RECVTTL, &one, sizeof(one));
1452 if (r < 0) {
1453 r = -errno;
1454 goto fail;
1455 }
1456
1457 /* Disable Don't-Fragment bit in the IP header */
1458 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu));
1459 if (r < 0) {
1460 r = -errno;
1461 goto fail;
1462 }
1463
1464 r = bind(m->llmnr_ipv4_tcp_fd, &sa.sa, sizeof(sa.in));
1465 if (r < 0) {
1466 r = -errno;
1467 goto fail;
1468 }
1469
1470 r = listen(m->llmnr_ipv4_tcp_fd, SOMAXCONN);
1471 if (r < 0) {
1472 r = -errno;
1473 goto fail;
1474 }
1475
1476 r = sd_event_add_io(m->event, &m->llmnr_ipv4_tcp_event_source, m->llmnr_ipv4_tcp_fd, EPOLLIN, on_llmnr_stream, m);
1477 if (r < 0)
1478 goto fail;
1479
1480 return m->llmnr_ipv4_tcp_fd;
1481
1482fail:
1483 m->llmnr_ipv4_tcp_fd = safe_close(m->llmnr_ipv4_tcp_fd);
1484 return r;
1485}
1486
1487int manager_llmnr_ipv6_tcp_fd(Manager *m) {
1488 union sockaddr_union sa = {
1489 .in6.sin6_family = AF_INET6,
1490 .in6.sin6_port = htobe16(5355),
1491 };
1492 static const int one = 1;
1493 int r;
1494
1495 assert(m);
1496
1497 if (m->llmnr_ipv6_tcp_fd >= 0)
1498 return m->llmnr_ipv6_tcp_fd;
1499
1500 m->llmnr_ipv6_tcp_fd = socket(AF_INET6, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1501 if (m->llmnr_ipv6_tcp_fd < 0)
1502 return -errno;
1503
bf3f1271 1504 /* RFC 4795, section 2.5. requires setting the TTL of TCP streams to 1 */
623a4c97
LP
1505 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &one, sizeof(one));
1506 if (r < 0) {
1507 r = -errno;
1508 goto fail;
1509 }
1510
1511 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
1512 if (r < 0) {
1513 r = -errno;
1514 goto fail;
1515 }
1516
1517 r = setsockopt(m->llmnr_ipv6_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1518 if (r < 0) {
1519 r = -errno;
1520 goto fail;
1521 }
1522
1523 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
1524 if (r < 0) {
1525 r = -errno;
1526 goto fail;
1527 }
1528
1529 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &one, sizeof(one));
1530 if (r < 0) {
1531 r = -errno;
1532 goto fail;
1533 }
1534
1535 r = bind(m->llmnr_ipv6_tcp_fd, &sa.sa, sizeof(sa.in6));
1536 if (r < 0) {
1537 r = -errno;
1538 goto fail;
1539 }
1540
1541 r = listen(m->llmnr_ipv6_tcp_fd, SOMAXCONN);
1542 if (r < 0) {
1543 r = -errno;
1544 goto fail;
1545 }
1546
1547 r = sd_event_add_io(m->event, &m->llmnr_ipv6_tcp_event_source, m->llmnr_ipv6_tcp_fd, EPOLLIN, on_llmnr_stream, m);
1548 if (r < 0) {
1549 r = -errno;
1550 goto fail;
1551 }
1552
1553 return m->llmnr_ipv6_tcp_fd;
1554
1555fail:
1556 m->llmnr_ipv6_tcp_fd = safe_close(m->llmnr_ipv6_tcp_fd);
1557 return r;
1558}
1559
1560int manager_ifindex_is_loopback(Manager *m, int ifindex) {
1561 Link *l;
1562 assert(m);
1563
1564 if (ifindex <= 0)
1565 return -EINVAL;
1566
1567 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
1568 if (l->flags & IFF_LOOPBACK)
1569 return 1;
1570
1571 return 0;
1572}
1573
1574int manager_find_ifindex(Manager *m, int family, const union in_addr_union *in_addr) {
ec2c5e43
LP
1575 LinkAddress *a;
1576
1577 assert(m);
1578
4e945a6f 1579 a = manager_find_link_address(m, family, in_addr);
ec2c5e43
LP
1580 if (a)
1581 return a->link->ifindex;
1582
1583 return 0;
1584}
1585
eb60f9cd
LP
1586void manager_refresh_rrs(Manager *m) {
1587 Iterator i;
1588 Link *l;
1589
1590 assert(m);
1591
1592 m->host_ipv4_key = dns_resource_key_unref(m->host_ipv4_key);
1593 m->host_ipv6_key = dns_resource_key_unref(m->host_ipv6_key);
1594
1595 HASHMAP_FOREACH(l, m->links, i) {
1596 link_add_rrs(l, true);
1597 link_add_rrs(l, false);
1598 }
1599}
1600
ec2c5e43
LP
1601int manager_next_hostname(Manager *m) {
1602 const char *p;
ec2c5e43
LP
1603 uint64_t u;
1604 char *h;
623a4c97
LP
1605
1606 assert(m);
1607
ec2c5e43
LP
1608 p = strchr(m->hostname, 0);
1609 assert(p);
1610
1611 while (p > m->hostname) {
1612 if (!strchr("0123456789", p[-1]))
1613 break;
1614
1615 p--;
1616 }
1617
1618 if (*p == 0 || safe_atou64(p, &u) < 0 || u <= 0)
1619 u = 1;
1620
1621 u++;
1622
1623 if (asprintf(&h, "%.*s%" PRIu64, (int) (p - m->hostname), m->hostname, u) < 0)
1624 return -ENOMEM;
1625
eb60f9cd 1626 log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m->hostname, h);
ec2c5e43
LP
1627
1628 free(m->hostname);
1629 m->hostname = h;
1630
eb60f9cd 1631 manager_refresh_rrs(m);
623a4c97
LP
1632
1633 return 0;
1634}
ec2c5e43 1635
4e945a6f 1636LinkAddress* manager_find_link_address(Manager *m, int family, const union in_addr_union *in_addr) {
ec2c5e43
LP
1637 Iterator i;
1638 Link *l;
1639
1640 assert(m);
1641
1642 HASHMAP_FOREACH(l, m->links, i) {
1643 LinkAddress *a;
1644
1645 a = link_find_address(l, family, in_addr);
1646 if (a)
1647 return a;
1648 }
1649
1650 return NULL;
1651}
1652
1653int manager_our_packet(Manager *m, DnsPacket *p) {
1654 assert(m);
1655 assert(p);
1656
4e945a6f 1657 return !!manager_find_link_address(m, p->family, &p->sender);
ec2c5e43 1658}
4e945a6f
LP
1659
1660static const char* const support_table[_SUPPORT_MAX] = {
1661 [SUPPORT_NO] = "no",
1662 [SUPPORT_YES] = "yes",
1663 [SUPPORT_RESOLVE] = "resolve",
1664};
1665DEFINE_STRING_TABLE_LOOKUP(support, Support);