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