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