]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/resolved-manager.c
networkd: track the MTU of each link
[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
187
188static int manager_rtnl_listen(Manager *m) {
189 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
190 sd_rtnl_message *i;
191 int r;
192
193 assert(m);
194
195 /* First, subscibe to interfaces coming and going */
196 r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR, RTNLGRP_IPV6_IFADDR);
197 if (r < 0)
198 return r;
199
200 r = sd_rtnl_attach_event(m->rtnl, m->event, 0);
201 if (r < 0)
202 return r;
203
204 r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, manager_process_link, m);
205 if (r < 0)
206 return r;
207
208 r = sd_rtnl_add_match(m->rtnl, RTM_DELLINK, manager_process_link, m);
209 if (r < 0)
210 return r;
211
212 r = sd_rtnl_add_match(m->rtnl, RTM_NEWADDR, manager_process_address, m);
213 if (r < 0)
214 return r;
091a364c 215
74b2466e
LP
216 r = sd_rtnl_add_match(m->rtnl, RTM_DELADDR, manager_process_address, m);
217 if (r < 0)
218 return r;
219
220 /* Then, enumerate all links */
221 r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
222 if (r < 0)
223 return r;
224
225 r = sd_rtnl_message_request_dump(req, true);
226 if (r < 0)
227 return r;
228
229 r = sd_rtnl_call(m->rtnl, req, 0, &reply);
230 if (r < 0)
231 return r;
232
233 for (i = reply; i; i = sd_rtnl_message_next(i)) {
234 r = manager_process_link(m->rtnl, i, m);
235 if (r < 0)
236 return r;
237 }
238
239 req = sd_rtnl_message_unref(req);
240 reply = sd_rtnl_message_unref(reply);
241
242 /* Finally, enumerate all addresses, too */
243 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, AF_UNSPEC);
244 if (r < 0)
245 return r;
246
247 r = sd_rtnl_message_request_dump(req, true);
248 if (r < 0)
249 return r;
250
251 r = sd_rtnl_call(m->rtnl, req, 0, &reply);
252 if (r < 0)
253 return r;
254
255 for (i = reply; i; i = sd_rtnl_message_next(i)) {
256 r = manager_process_address(m->rtnl, i, m);
257 if (r < 0)
258 return r;
259 }
260
261 return r;
262}
263
264static int on_network_event(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
265 Manager *m = userdata;
266 Iterator i;
267 Link *l;
268 int r;
269
270 assert(m);
271
272 sd_network_monitor_flush(m->network_monitor);
273
274 HASHMAP_FOREACH(l, m->links, i) {
275 r = link_update_monitor(l);
276 if (r < 0)
277 log_warning("Failed to update monitor information for %i: %s", l->ifindex, strerror(-r));
278 }
279
280 r = manager_write_resolv_conf(m);
281 if (r < 0)
282 log_warning("Could not update resolv.conf: %s", strerror(-r));
283
284 return 0;
285}
286
287static int manager_network_monitor_listen(Manager *m) {
288 int r, fd, events;
289
290 assert(m);
291
0014a4ad 292 r = sd_network_monitor_new(&m->network_monitor, NULL);
74b2466e
LP
293 if (r < 0)
294 return r;
295
296 fd = sd_network_monitor_get_fd(m->network_monitor);
297 if (fd < 0)
298 return fd;
299
300 events = sd_network_monitor_get_events(m->network_monitor);
301 if (events < 0)
302 return events;
303
304 r = sd_event_add_io(m->event, &m->network_event_source, fd, events, &on_network_event, m);
305 if (r < 0)
306 return r;
307
308 return 0;
309}
310
eb60f9cd
LP
311static int determine_hostname(char **ret) {
312 _cleanup_free_ char *h = NULL, *n = NULL;
313 int r;
314
315 assert(ret);
316
317 h = gethostname_malloc();
318 if (!h)
319 return log_oom();
320
321 if (!utf8_is_valid(h)) {
322 log_error("System hostname is not UTF-8 clean.");
323 return -EINVAL;
324 }
325
326 r = dns_name_normalize(h, &n);
327 if (r < 0) {
328 log_error("System hostname '%s' cannot be normalized.", h);
329 return r;
330 }
331
332 *ret = n;
333 n = NULL;
334
335 return 0;
336}
337
338static int on_hostname_change(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
339 _cleanup_free_ char *h = NULL;
340 Manager *m = userdata;
341 int r;
342
343 assert(m);
344
345 r = determine_hostname(&h);
346 if (r < 0)
347 return 0; /* ignore invalid hostnames */
348
349 if (streq(h, m->hostname))
350 return 0;
351
352 log_info("System hostname changed to '%s'.", h);
353 free(m->hostname);
354 m->hostname = h;
355 h = NULL;
356
357 manager_refresh_rrs(m);
358
359 return 0;
360}
361
362static int manager_watch_hostname(Manager *m) {
363 _cleanup_free_ char *h = NULL;
364 int r;
365
366 assert(m);
367
368 m->hostname_fd = open("/proc/sys/kernel/hostname", O_RDONLY|O_CLOEXEC|O_NDELAY|O_NOCTTY);
369 if (m->hostname_fd < 0) {
370 log_warning("Failed to watch hostname: %m");
371 return 0;
372 }
373
374 r = sd_event_add_io(m->event, &m->hostname_event_source, m->hostname_fd, 0, on_hostname_change, m);
375 if (r < 0) {
376 if (r == -EPERM)
377 /* kernels prior to 3.2 don't support polling this file. Ignore the failure. */
378 m->hostname_fd = safe_close(m->hostname_fd);
379 else {
380 log_error("Failed to add hostname event source: %s", strerror(-r));
381 return r;
382 }
383 }
384
385 r = determine_hostname(&m->hostname);
386 if (r < 0) {
387 log_info("Defaulting to hostname 'linux'.");
388 m->hostname = strdup("linux");
389 if (!m->hostname)
390 return log_oom();
391 } else
392 log_info("Using system hostname '%s'.", m->hostname);
393
394 return 0;
395}
396
091a364c 397int manager_new(Manager **ret) {
74b2466e 398 _cleanup_(manager_freep) Manager *m = NULL;
091a364c
TG
399 int r;
400
c92e531c
LP
401 assert(ret);
402
091a364c
TG
403 m = new0(Manager, 1);
404 if (!m)
405 return -ENOMEM;
406
74b2466e 407 m->dns_ipv4_fd = m->dns_ipv6_fd = -1;
1716f6dc 408 m->llmnr_ipv4_udp_fd = m->llmnr_ipv6_udp_fd = -1;
623a4c97 409 m->llmnr_ipv4_tcp_fd = m->llmnr_ipv6_tcp_fd = -1;
eb60f9cd 410 m->hostname_fd = -1;
1716f6dc 411
4e945a6f 412 m->llmnr_support = SUPPORT_YES;
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
74b2466e
LP
523static void write_resolve_conf_server(DnsServer *s, FILE *f, unsigned *count) {
524 _cleanup_free_ char *t = NULL;
525 int r;
091a364c 526
74b2466e 527 assert(s);
091a364c 528 assert(f);
091a364c
TG
529 assert(count);
530
74b2466e 531 r = in_addr_to_string(s->family, &s->address, &t);
4e945a6f
LP
532 if (r < 0) {
533 log_warning("Invalid DNS address. Ignoring: %s", strerror(-r));
091a364c
TG
534 return;
535 }
536
537 if (*count == MAXNS)
74b2466e 538 fputs("# Too many DNS servers configured, the following entries may be ignored\n", f);
091a364c 539
74b2466e 540 fprintf(f, "nameserver %s\n", t);
091a364c
TG
541 (*count) ++;
542}
543
74b2466e 544int manager_write_resolv_conf(Manager *m) {
4e945a6f 545 static const char path[] = "/run/systemd/resolve/resolv.conf";
091a364c
TG
546 _cleanup_free_ char *temp_path = NULL;
547 _cleanup_fclose_ FILE *f = NULL;
091a364c 548 unsigned count = 0;
74b2466e
LP
549 DnsServer *s;
550 Iterator i;
551 Link *l;
552 int r;
091a364c
TG
553
554 assert(m);
555
b686acb2 556 r = fopen_temporary(path, &f, &temp_path);
091a364c
TG
557 if (r < 0)
558 return r;
559
560 fchmod(fileno(f), 0644);
561
562 fputs("# This file is managed by systemd-resolved(8). Do not edit.\n#\n"
563 "# Third party programs must not access this file directly, but\n"
564 "# only through the symlink at /etc/resolv.conf. To manage\n"
565 "# resolv.conf(5) in a different way, replace the symlink by a\n"
566 "# static file or a different symlink.\n\n", f);
567
4e945a6f
LP
568 LIST_FOREACH(servers, s, m->dns_servers)
569 write_resolve_conf_server(s, f, &count);
570
6073b6f2
TG
571 HASHMAP_FOREACH(l, m->links, i)
572 LIST_FOREACH(servers, s, l->dns_servers)
74b2466e 573 write_resolve_conf_server(s, f, &count);
091a364c 574
4e945a6f
LP
575 if (count == 0) {
576 LIST_FOREACH(servers, s, m->fallback_dns_servers)
577 write_resolve_conf_server(s, f, &count);
578 }
091a364c 579
74b2466e
LP
580 r = fflush_and_check(f);
581 if (r < 0)
582 goto fail;
583
584 if (rename(temp_path, path) < 0) {
585 r = -errno;
586 goto fail;
587 }
091a364c 588
74b2466e 589 return 0;
091a364c 590
74b2466e
LP
591fail:
592 unlink(path);
593 unlink(temp_path);
594 return r;
595}
091a364c 596
1716f6dc 597int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) {
74b2466e 598 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
1716f6dc
LP
599 union {
600 struct cmsghdr header; /* For alignment */
601 uint8_t buffer[CMSG_SPACE(MAX(sizeof(struct in_pktinfo), sizeof(struct in6_pktinfo)))
602 + CMSG_SPACE(int) /* ttl/hoplimit */
623a4c97 603 + EXTRA_CMSG_SPACE /* kernel appears to require extra buffer space */];
1716f6dc
LP
604 } control;
605 union sockaddr_union sa;
74b2466e 606 struct msghdr mh = {};
1716f6dc 607 struct cmsghdr *cmsg;
74b2466e 608 struct iovec iov;
1716f6dc 609 int ms = 0, r;
74b2466e
LP
610 ssize_t l;
611
612 assert(m);
1716f6dc 613 assert(fd >= 0);
74b2466e
LP
614 assert(ret);
615
74b2466e
LP
616 r = ioctl(fd, FIONREAD, &ms);
617 if (r < 0)
618 return -errno;
619 if (ms < 0)
620 return -EIO;
621
1716f6dc 622 r = dns_packet_new(&p, protocol, ms);
74b2466e
LP
623 if (r < 0)
624 return r;
625
626 iov.iov_base = DNS_PACKET_DATA(p);
627 iov.iov_len = p->allocated;
628
1716f6dc
LP
629 mh.msg_name = &sa.sa;
630 mh.msg_namelen = sizeof(sa);
74b2466e
LP
631 mh.msg_iov = &iov;
632 mh.msg_iovlen = 1;
1716f6dc
LP
633 mh.msg_control = &control;
634 mh.msg_controllen = sizeof(control);
74b2466e
LP
635
636 l = recvmsg(fd, &mh, 0);
637 if (l < 0) {
ad867662 638 if (errno == EAGAIN || errno == EINTR)
74b2466e
LP
639 return 0;
640
641 return -errno;
091a364c
TG
642 }
643
74b2466e
LP
644 if (l <= 0)
645 return -EIO;
091a364c 646
1716f6dc
LP
647 assert(!(mh.msg_flags & MSG_CTRUNC));
648 assert(!(mh.msg_flags & MSG_TRUNC));
649
74b2466e 650 p->size = (size_t) l;
091a364c 651
1716f6dc 652 p->family = sa.sa.sa_family;
623a4c97
LP
653 p->ipproto = IPPROTO_UDP;
654 if (p->family == AF_INET) {
1716f6dc 655 p->sender.in = sa.in.sin_addr;
623a4c97
LP
656 p->sender_port = be16toh(sa.in.sin_port);
657 } else if (p->family == AF_INET6) {
1716f6dc 658 p->sender.in6 = sa.in6.sin6_addr;
623a4c97
LP
659 p->sender_port = be16toh(sa.in6.sin6_port);
660 p->ifindex = sa.in6.sin6_scope_id;
661 } else
1716f6dc 662 return -EAFNOSUPPORT;
74b2466e 663
1716f6dc 664 for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
74b2466e 665
1716f6dc
LP
666 if (cmsg->cmsg_level == IPPROTO_IPV6) {
667 assert(p->family == AF_INET6);
74b2466e 668
1716f6dc 669 switch (cmsg->cmsg_type) {
74b2466e 670
1716f6dc
LP
671 case IPV6_PKTINFO: {
672 struct in6_pktinfo *i = (struct in6_pktinfo*) CMSG_DATA(cmsg);
74b2466e 673
623a4c97
LP
674 if (p->ifindex <= 0)
675 p->ifindex = i->ipi6_ifindex;
676
1716f6dc
LP
677 p->destination.in6 = i->ipi6_addr;
678 break;
679 }
74b2466e 680
1716f6dc
LP
681 case IPV6_HOPLIMIT:
682 p->ttl = *(int *) CMSG_DATA(cmsg);
683 break;
74b2466e 684
1716f6dc
LP
685 }
686 } else if (cmsg->cmsg_level == IPPROTO_IP) {
687 assert(p->family == AF_INET);
74b2466e 688
1716f6dc 689 switch (cmsg->cmsg_type) {
74b2466e 690
1716f6dc
LP
691 case IP_PKTINFO: {
692 struct in_pktinfo *i = (struct in_pktinfo*) CMSG_DATA(cmsg);
091a364c 693
623a4c97
LP
694 if (p->ifindex <= 0)
695 p->ifindex = i->ipi_ifindex;
696
1716f6dc
LP
697 p->destination.in = i->ipi_addr;
698 break;
699 }
74b2466e 700
623a4c97 701 case IP_TTL:
1716f6dc
LP
702 p->ttl = *(int *) CMSG_DATA(cmsg);
703 break;
704 }
705 }
706 }
74b2466e 707
623a4c97
LP
708 /* The Linux kernel sets the interface index to the loopback
709 * device if the packet came from the local host since it
710 * avoids the routing table in such a case. Let's unset the
711 * interface index in such a case. */
712 if (p->ifindex > 0 && manager_ifindex_is_loopback(m, p->ifindex) != 0)
713 p->ifindex = 0;
714
715 /* If we don't know the interface index still, we look for the
716 * first local interface with a matching address. Yuck! */
717 if (p->ifindex <= 0)
718 p->ifindex = manager_find_ifindex(m, p->family, &p->destination);
719
74b2466e
LP
720 *ret = p;
721 p = NULL;
722
723 return 1;
724}
725
1716f6dc 726static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
74b2466e 727 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
ec2c5e43 728 DnsTransaction *t = NULL;
74b2466e
LP
729 Manager *m = userdata;
730 int r;
731
1716f6dc 732 r = manager_recv(m, fd, DNS_PROTOCOL_DNS, &p);
74b2466e
LP
733 if (r <= 0)
734 return r;
735
623a4c97 736 if (dns_packet_validate_reply(p) > 0) {
ec2c5e43 737 t = hashmap_get(m->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
1716f6dc
LP
738 if (!t)
739 return 0;
74b2466e 740
ec2c5e43 741 dns_transaction_process_reply(t, p);
623a4c97 742
1716f6dc 743 } else
623a4c97 744 log_debug("Invalid DNS packet.");
74b2466e 745
ad867662 746 return 0;
74b2466e
LP
747}
748
749int manager_dns_ipv4_fd(Manager *m) {
1716f6dc 750 const int one = 1;
74b2466e
LP
751 int r;
752
091a364c
TG
753 assert(m);
754
74b2466e
LP
755 if (m->dns_ipv4_fd >= 0)
756 return m->dns_ipv4_fd;
091a364c 757
74b2466e
LP
758 m->dns_ipv4_fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
759 if (m->dns_ipv4_fd < 0)
760 return -errno;
091a364c 761
1716f6dc
LP
762 r = setsockopt(m->dns_ipv4_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
763 if (r < 0) {
764 r = -errno;
765 goto fail;
766 }
767
768 r = sd_event_add_io(m->event, &m->dns_ipv4_event_source, m->dns_ipv4_fd, EPOLLIN, on_dns_packet, m);
74b2466e 769 if (r < 0)
1716f6dc 770 goto fail;
74b2466e
LP
771
772 return m->dns_ipv4_fd;
1716f6dc
LP
773
774fail:
775 m->dns_ipv4_fd = safe_close(m->dns_ipv4_fd);
776 return r;
091a364c
TG
777}
778
74b2466e 779int manager_dns_ipv6_fd(Manager *m) {
1716f6dc 780 const int one = 1;
74b2466e
LP
781 int r;
782
783 assert(m);
091a364c 784
74b2466e
LP
785 if (m->dns_ipv6_fd >= 0)
786 return m->dns_ipv6_fd;
787
788 m->dns_ipv6_fd = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
789 if (m->dns_ipv6_fd < 0)
790 return -errno;
791
1716f6dc
LP
792 r = setsockopt(m->dns_ipv6_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
793 if (r < 0) {
794 r = -errno;
795 goto fail;
796 }
797
798 r = sd_event_add_io(m->event, &m->dns_ipv6_event_source, m->dns_ipv6_fd, EPOLLIN, on_dns_packet, m);
091a364c 799 if (r < 0)
1716f6dc 800 goto fail;
091a364c 801
74b2466e 802 return m->dns_ipv6_fd;
1716f6dc
LP
803
804fail:
805 m->dns_ipv6_fd = safe_close(m->dns_ipv6_fd);
806 return r;
74b2466e
LP
807}
808
809static int sendmsg_loop(int fd, struct msghdr *mh, int flags) {
810 int r;
811
812 assert(fd >= 0);
813 assert(mh);
814
815 for (;;) {
816 if (sendmsg(fd, mh, flags) >= 0)
817 return 0;
818
819 if (errno == EINTR)
820 continue;
821
822 if (errno != EAGAIN)
823 return -errno;
824
825 r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
826 if (r < 0)
827 return r;
828 if (r == 0)
829 return -ETIMEDOUT;
830 }
831}
832
623a4c97 833static int manager_ipv4_send(Manager *m, int fd, int ifindex, const struct in_addr *addr, uint16_t port, DnsPacket *p) {
74b2466e
LP
834 union sockaddr_union sa = {
835 .in.sin_family = AF_INET,
74b2466e 836 };
1716f6dc
LP
837 union {
838 struct cmsghdr header; /* For alignment */
839 uint8_t buffer[CMSG_SPACE(sizeof(struct in_pktinfo))];
840 } control;
74b2466e
LP
841 struct msghdr mh = {};
842 struct iovec iov;
74b2466e
LP
843
844 assert(m);
1716f6dc
LP
845 assert(fd >= 0);
846 assert(addr);
847 assert(port > 0);
74b2466e
LP
848 assert(p);
849
74b2466e
LP
850 iov.iov_base = DNS_PACKET_DATA(p);
851 iov.iov_len = p->size;
091a364c 852
1716f6dc
LP
853 sa.in.sin_addr = *addr;
854 sa.in.sin_port = htobe16(port),
091a364c 855
74b2466e
LP
856 mh.msg_iov = &iov;
857 mh.msg_iovlen = 1;
858 mh.msg_name = &sa.sa;
859 mh.msg_namelen = sizeof(sa.in);
091a364c 860
74b2466e
LP
861 if (ifindex > 0) {
862 struct cmsghdr *cmsg;
863 struct in_pktinfo *pi;
864
865 zero(control);
866
1716f6dc 867 mh.msg_control = &control;
74b2466e
LP
868 mh.msg_controllen = CMSG_LEN(sizeof(struct in_pktinfo));
869
870 cmsg = CMSG_FIRSTHDR(&mh);
871 cmsg->cmsg_len = mh.msg_controllen;
872 cmsg->cmsg_level = IPPROTO_IP;
873 cmsg->cmsg_type = IP_PKTINFO;
874
875 pi = (struct in_pktinfo*) CMSG_DATA(cmsg);
876 pi->ipi_ifindex = ifindex;
877 }
878
879 return sendmsg_loop(fd, &mh, 0);
880}
881
623a4c97 882static int manager_ipv6_send(Manager *m, int fd, int ifindex, const struct in6_addr *addr, uint16_t port, DnsPacket *p) {
74b2466e
LP
883 union sockaddr_union sa = {
884 .in6.sin6_family = AF_INET6,
74b2466e 885 };
1716f6dc
LP
886 union {
887 struct cmsghdr header; /* For alignment */
888 uint8_t buffer[CMSG_SPACE(sizeof(struct in6_pktinfo))];
889 } control;
74b2466e
LP
890 struct msghdr mh = {};
891 struct iovec iov;
74b2466e
LP
892
893 assert(m);
1716f6dc
LP
894 assert(fd >= 0);
895 assert(addr);
896 assert(port > 0);
74b2466e
LP
897 assert(p);
898
74b2466e
LP
899 iov.iov_base = DNS_PACKET_DATA(p);
900 iov.iov_len = p->size;
901
1716f6dc
LP
902 sa.in6.sin6_addr = *addr;
903 sa.in6.sin6_port = htobe16(port),
74b2466e
LP
904 sa.in6.sin6_scope_id = ifindex;
905
906 mh.msg_iov = &iov;
907 mh.msg_iovlen = 1;
908 mh.msg_name = &sa.sa;
909 mh.msg_namelen = sizeof(sa.in6);
910
911 if (ifindex > 0) {
912 struct cmsghdr *cmsg;
913 struct in6_pktinfo *pi;
914
915 zero(control);
916
1716f6dc 917 mh.msg_control = &control;
74b2466e
LP
918 mh.msg_controllen = CMSG_LEN(sizeof(struct in6_pktinfo));
919
920 cmsg = CMSG_FIRSTHDR(&mh);
921 cmsg->cmsg_len = mh.msg_controllen;
922 cmsg->cmsg_level = IPPROTO_IPV6;
923 cmsg->cmsg_type = IPV6_PKTINFO;
924
925 pi = (struct in6_pktinfo*) CMSG_DATA(cmsg);
926 pi->ipi6_ifindex = ifindex;
927 }
928
929 return sendmsg_loop(fd, &mh, 0);
930}
931
623a4c97 932int manager_send(Manager *m, int fd, int ifindex, int family, const union in_addr_union *addr, uint16_t port, DnsPacket *p) {
1716f6dc
LP
933 assert(m);
934 assert(fd >= 0);
935 assert(addr);
936 assert(port > 0);
937 assert(p);
938
a2a416f7
LP
939 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));
940
1716f6dc
LP
941 if (family == AF_INET)
942 return manager_ipv4_send(m, fd, ifindex, &addr->in, port, p);
943 else if (family == AF_INET6)
944 return manager_ipv6_send(m, fd, ifindex, &addr->in6, port, p);
945
946 return -EAFNOSUPPORT;
947}
948
4e945a6f 949bool manager_known_dns_server(Manager *m, int family, const union in_addr_union *in_addr) {
74b2466e
LP
950 DnsServer *s;
951
952 assert(m);
953 assert(in_addr);
954
4e945a6f
LP
955 LIST_FOREACH(servers, s, m->dns_servers)
956 if (s->family == family && in_addr_equal(family, &s->address, in_addr))
957 return true;
74b2466e 958
4e945a6f
LP
959 LIST_FOREACH(servers, s, m->fallback_dns_servers)
960 if (s->family == family && in_addr_equal(family, &s->address, in_addr))
961 return true;
74b2466e 962
4e945a6f
LP
963 return false;
964}
965
966static DnsServer *manager_set_dns_server(Manager *m, DnsServer *s) {
967 assert(m);
968
969 if (m->current_dns_server == s)
970 return s;
971
972 if (s) {
973 _cleanup_free_ char *ip = NULL;
974
975 in_addr_to_string(s->family, &s->address, &ip);
976 log_info("Switching to system DNS server %s.", strna(ip));
977 } else
978 log_info("No system DNS server set.");
979
980 m->current_dns_server = s;
981 return s;
74b2466e
LP
982}
983
984DnsServer *manager_get_dns_server(Manager *m) {
4e945a6f 985 Link *l;
74b2466e
LP
986 assert(m);
987
988 if (!m->current_dns_server)
4e945a6f
LP
989 manager_set_dns_server(m, m->dns_servers);
990
991 if (!m->current_dns_server) {
992 bool found = false;
993 Iterator i;
994
995 /* No DNS servers configured, let's see if there are
996 * any on any links. If not, we use the fallback
997 * servers */
998
999 HASHMAP_FOREACH(l, m->links, i)
1000 if (l->dns_servers) {
1001 found = true;
1002 break;
1003 }
1004
1005 if (!found)
1006 manager_set_dns_server(m, m->fallback_dns_servers);
1007 }
74b2466e
LP
1008
1009 return m->current_dns_server;
1010}
1011
1012void manager_next_dns_server(Manager *m) {
1013 assert(m);
1014
4e945a6f
LP
1015 /* If there's currently no DNS server set, then the next
1016 * manager_get_dns_server() will find one */
74b2466e
LP
1017 if (!m->current_dns_server)
1018 return;
1019
4e945a6f 1020 /* Change to the next one */
74b2466e 1021 if (m->current_dns_server->servers_next) {
4e945a6f 1022 manager_set_dns_server(m, m->current_dns_server->servers_next);
74b2466e
LP
1023 return;
1024 }
1025
4e945a6f
LP
1026 /* If there was no next one, then start from the beginning of
1027 * the list */
1028 if (m->current_dns_server->type == DNS_SERVER_FALLBACK)
1029 manager_set_dns_server(m, m->fallback_dns_servers);
1030 else
1031 manager_set_dns_server(m, m->dns_servers);
091a364c 1032}
e1c95994
LP
1033
1034uint32_t manager_find_mtu(Manager *m) {
1035 uint32_t mtu = 0;
1036 Link *l;
1037 Iterator i;
1038
1039 /* If we don't know on which link a DNS packet would be
1040 * delivered, let's find the largest MTU that works on all
1041 * interfaces we know of */
1042
1043 HASHMAP_FOREACH(l, m->links, i) {
1044 if (l->mtu <= 0)
1045 continue;
1046
1047 if (mtu <= 0 || l->mtu < mtu)
1048 mtu = l->mtu;
1049 }
1050
1051 return mtu;
1052}
1716f6dc
LP
1053
1054static int on_llmnr_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
1055 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
ec2c5e43 1056 DnsTransaction *t = NULL;
1716f6dc
LP
1057 Manager *m = userdata;
1058 int r;
1059
1060 r = manager_recv(m, fd, DNS_PROTOCOL_LLMNR, &p);
1061 if (r <= 0)
1062 return r;
1063
623a4c97 1064 if (dns_packet_validate_reply(p) > 0) {
a2a416f7
LP
1065 log_debug("Got reply packet for id %u", DNS_PACKET_ID(p));
1066
ec2c5e43 1067 t = hashmap_get(m->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
1716f6dc
LP
1068 if (!t)
1069 return 0;
1070
ec2c5e43 1071 dns_transaction_process_reply(t, p);
623a4c97
LP
1072
1073 } else if (dns_packet_validate_query(p) > 0) {
1074 Link *l;
1075
1076 l = hashmap_get(m->links, INT_TO_PTR(p->ifindex));
1077 if (l) {
1078 DnsScope *scope = NULL;
1079
1080 if (p->family == AF_INET)
1081 scope = l->llmnr_ipv4_scope;
1082 else if (p->family == AF_INET6)
1083 scope = l->llmnr_ipv6_scope;
1084
1085 if (scope)
1086 dns_scope_process_query(scope, NULL, p);
1087 }
1088 } else
1089 log_debug("Invalid LLMNR packet.");
1716f6dc
LP
1090
1091 return 0;
1092}
1093
1094int manager_llmnr_ipv4_udp_fd(Manager *m) {
1095 union sockaddr_union sa = {
1096 .in.sin_family = AF_INET,
1097 .in.sin_port = htobe16(5355),
1098 };
bf3f1271 1099 static const int one = 1, pmtu = IP_PMTUDISC_DONT, ttl = 255;
1716f6dc
LP
1100 int r;
1101
1102 assert(m);
1103
1104 if (m->llmnr_ipv4_udp_fd >= 0)
1105 return m->llmnr_ipv4_udp_fd;
1106
1107 m->llmnr_ipv4_udp_fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1108 if (m->llmnr_ipv4_udp_fd < 0)
1109 return -errno;
1110
bf3f1271
LP
1111 /* RFC 4795, section 2.5 recommends setting the TTL of UDP packets to 255. */
1112 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
1716f6dc
LP
1113 if (r < 0) {
1114 r = -errno;
1115 goto fail;
1116 }
1117
bf3f1271 1118 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
1716f6dc
LP
1119 if (r < 0) {
1120 r = -errno;
1121 goto fail;
1122 }
1123
1124 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MULTICAST_LOOP, &one, sizeof(one));
1125 if (r < 0) {
1126 r = -errno;
1127 goto fail;
1128 }
1129
1130 r = setsockopt(m->llmnr_ipv4_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1131 if (r < 0) {
1132 r = -errno;
1133 goto fail;
1134 }
1135
1136 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
1137 if (r < 0) {
1138 r = -errno;
1139 goto fail;
1140 }
1141
1142 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_RECVTTL, &one, sizeof(one));
1143 if (r < 0) {
1144 r = -errno;
1145 goto fail;
1146 }
1147
1148 /* Disable Don't-Fragment bit in the IP header */
1149 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu));
1150 if (r < 0) {
1151 r = -errno;
1152 goto fail;
1153 }
1154
1155 r = bind(m->llmnr_ipv4_udp_fd, &sa.sa, sizeof(sa.in));
1156 if (r < 0) {
1157 r = -errno;
1158 goto fail;
1159 }
1160
1161 r = sd_event_add_io(m->event, &m->llmnr_ipv4_udp_event_source, m->llmnr_ipv4_udp_fd, EPOLLIN, on_llmnr_packet, m);
1162 if (r < 0)
1163 goto fail;
1164
1165 return m->llmnr_ipv4_udp_fd;
1166
1167fail:
1168 m->llmnr_ipv4_udp_fd = safe_close(m->llmnr_ipv4_udp_fd);
1169 return r;
1170}
1171
1172int manager_llmnr_ipv6_udp_fd(Manager *m) {
1173 union sockaddr_union sa = {
1174 .in6.sin6_family = AF_INET6,
1175 .in6.sin6_port = htobe16(5355),
1176 };
bf3f1271 1177 static const int one = 1, ttl = 255;
1716f6dc
LP
1178 int r;
1179
1180 assert(m);
1181
1182 if (m->llmnr_ipv6_udp_fd >= 0)
1183 return m->llmnr_ipv6_udp_fd;
1184
1185 m->llmnr_ipv6_udp_fd = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1186 if (m->llmnr_ipv6_udp_fd < 0)
1187 return -errno;
1188
bf3f1271 1189 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl));
1716f6dc
LP
1190 if (r < 0) {
1191 r = -errno;
1192 goto fail;
1193 }
1194
bf3f1271
LP
1195 /* RFC 4795, section 2.5 recommends setting the TTL of UDP packets to 255. */
1196 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl));
1716f6dc
LP
1197 if (r < 0) {
1198 r = -errno;
1199 goto fail;
1200 }
1201
1202 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &one, sizeof(one));
1203 if (r < 0) {
1204 r = -errno;
1205 goto fail;
1206 }
1207
1208 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
1209 if (r < 0) {
1210 r = -errno;
1211 goto fail;
1212 }
1213
1214 r = setsockopt(m->llmnr_ipv6_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1215 if (r < 0) {
1216 r = -errno;
1217 goto fail;
1218 }
1219
1220 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
1221 if (r < 0) {
1222 r = -errno;
1223 goto fail;
1224 }
1225
1226 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &one, sizeof(one));
1227 if (r < 0) {
1228 r = -errno;
1229 goto fail;
1230 }
1231
1232 r = bind(m->llmnr_ipv6_udp_fd, &sa.sa, sizeof(sa.in6));
1233 if (r < 0) {
1234 r = -errno;
1235 goto fail;
1236 }
1237
1238 r = sd_event_add_io(m->event, &m->llmnr_ipv6_udp_event_source, m->llmnr_ipv6_udp_fd, EPOLLIN, on_llmnr_packet, m);
1239 if (r < 0) {
1240 r = -errno;
1241 goto fail;
1242 }
1243
1244 return m->llmnr_ipv6_udp_fd;
1245
1246fail:
1247 m->llmnr_ipv6_udp_fd = safe_close(m->llmnr_ipv6_udp_fd);
1248 return r;
1249}
623a4c97
LP
1250
1251static int on_llmnr_stream_packet(DnsStream *s) {
1252 assert(s);
1253
1254 if (dns_packet_validate_query(s->read_packet) > 0) {
1255 Link *l;
1256
1257 l = hashmap_get(s->manager->links, INT_TO_PTR(s->read_packet->ifindex));
1258 if (l) {
1259 DnsScope *scope = NULL;
1260
1261 if (s->read_packet->family == AF_INET)
1262 scope = l->llmnr_ipv4_scope;
1263 else if (s->read_packet->family == AF_INET6)
1264 scope = l->llmnr_ipv6_scope;
1265
1266 if (scope) {
1267 dns_scope_process_query(scope, s, s->read_packet);
1268
1269 /* If no reply packet was set, we free the stream */
1270 if (s->write_packet)
1271 return 0;
1272 }
1273 }
1274 }
1275
1276 dns_stream_free(s);
1277 return 0;
1278}
1279
1280static int on_llmnr_stream(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
1281 DnsStream *stream;
1282 Manager *m = userdata;
1283 int cfd, r;
1284
1285 cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
1286 if (cfd < 0) {
1287 if (errno == EAGAIN || errno == EINTR)
1288 return 0;
1289
1290 return -errno;
1291 }
1292
1293 r = dns_stream_new(m, &stream, DNS_PROTOCOL_LLMNR, cfd);
1294 if (r < 0) {
1295 safe_close(cfd);
1296 return r;
1297 }
1298
1299 stream->on_packet = on_llmnr_stream_packet;
1300 return 0;
1301}
1302
1303int manager_llmnr_ipv4_tcp_fd(Manager *m) {
1304 union sockaddr_union sa = {
1305 .in.sin_family = AF_INET,
1306 .in.sin_port = htobe16(5355),
1307 };
1308 static const int one = 1, pmtu = IP_PMTUDISC_DONT;
1309 int r;
1310
1311 assert(m);
1312
1313 if (m->llmnr_ipv4_tcp_fd >= 0)
1314 return m->llmnr_ipv4_tcp_fd;
1315
1316 m->llmnr_ipv4_tcp_fd = socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1317 if (m->llmnr_ipv4_tcp_fd < 0)
1318 return -errno;
1319
bf3f1271 1320 /* RFC 4795, section 2.5. requires setting the TTL of TCP streams to 1 */
623a4c97
LP
1321 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_TTL, &one, sizeof(one));
1322 if (r < 0) {
1323 r = -errno;
1324 goto fail;
1325 }
1326
1327 r = setsockopt(m->llmnr_ipv4_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1328 if (r < 0) {
1329 r = -errno;
1330 goto fail;
1331 }
1332
1333 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
1334 if (r < 0) {
1335 r = -errno;
1336 goto fail;
1337 }
1338
1339 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_RECVTTL, &one, sizeof(one));
1340 if (r < 0) {
1341 r = -errno;
1342 goto fail;
1343 }
1344
1345 /* Disable Don't-Fragment bit in the IP header */
1346 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu));
1347 if (r < 0) {
1348 r = -errno;
1349 goto fail;
1350 }
1351
1352 r = bind(m->llmnr_ipv4_tcp_fd, &sa.sa, sizeof(sa.in));
1353 if (r < 0) {
1354 r = -errno;
1355 goto fail;
1356 }
1357
1358 r = listen(m->llmnr_ipv4_tcp_fd, SOMAXCONN);
1359 if (r < 0) {
1360 r = -errno;
1361 goto fail;
1362 }
1363
1364 r = sd_event_add_io(m->event, &m->llmnr_ipv4_tcp_event_source, m->llmnr_ipv4_tcp_fd, EPOLLIN, on_llmnr_stream, m);
1365 if (r < 0)
1366 goto fail;
1367
1368 return m->llmnr_ipv4_tcp_fd;
1369
1370fail:
1371 m->llmnr_ipv4_tcp_fd = safe_close(m->llmnr_ipv4_tcp_fd);
1372 return r;
1373}
1374
1375int manager_llmnr_ipv6_tcp_fd(Manager *m) {
1376 union sockaddr_union sa = {
1377 .in6.sin6_family = AF_INET6,
1378 .in6.sin6_port = htobe16(5355),
1379 };
1380 static const int one = 1;
1381 int r;
1382
1383 assert(m);
1384
1385 if (m->llmnr_ipv6_tcp_fd >= 0)
1386 return m->llmnr_ipv6_tcp_fd;
1387
1388 m->llmnr_ipv6_tcp_fd = socket(AF_INET6, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1389 if (m->llmnr_ipv6_tcp_fd < 0)
1390 return -errno;
1391
bf3f1271 1392 /* RFC 4795, section 2.5. requires setting the TTL of TCP streams to 1 */
623a4c97
LP
1393 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &one, sizeof(one));
1394 if (r < 0) {
1395 r = -errno;
1396 goto fail;
1397 }
1398
1399 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
1400 if (r < 0) {
1401 r = -errno;
1402 goto fail;
1403 }
1404
1405 r = setsockopt(m->llmnr_ipv6_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1406 if (r < 0) {
1407 r = -errno;
1408 goto fail;
1409 }
1410
1411 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
1412 if (r < 0) {
1413 r = -errno;
1414 goto fail;
1415 }
1416
1417 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &one, sizeof(one));
1418 if (r < 0) {
1419 r = -errno;
1420 goto fail;
1421 }
1422
1423 r = bind(m->llmnr_ipv6_tcp_fd, &sa.sa, sizeof(sa.in6));
1424 if (r < 0) {
1425 r = -errno;
1426 goto fail;
1427 }
1428
1429 r = listen(m->llmnr_ipv6_tcp_fd, SOMAXCONN);
1430 if (r < 0) {
1431 r = -errno;
1432 goto fail;
1433 }
1434
1435 r = sd_event_add_io(m->event, &m->llmnr_ipv6_tcp_event_source, m->llmnr_ipv6_tcp_fd, EPOLLIN, on_llmnr_stream, m);
1436 if (r < 0) {
1437 r = -errno;
1438 goto fail;
1439 }
1440
1441 return m->llmnr_ipv6_tcp_fd;
1442
1443fail:
1444 m->llmnr_ipv6_tcp_fd = safe_close(m->llmnr_ipv6_tcp_fd);
1445 return r;
1446}
1447
1448int manager_ifindex_is_loopback(Manager *m, int ifindex) {
1449 Link *l;
1450 assert(m);
1451
1452 if (ifindex <= 0)
1453 return -EINVAL;
1454
1455 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
1456 if (l->flags & IFF_LOOPBACK)
1457 return 1;
1458
1459 return 0;
1460}
1461
1462int manager_find_ifindex(Manager *m, int family, const union in_addr_union *in_addr) {
ec2c5e43
LP
1463 LinkAddress *a;
1464
1465 assert(m);
1466
4e945a6f 1467 a = manager_find_link_address(m, family, in_addr);
ec2c5e43
LP
1468 if (a)
1469 return a->link->ifindex;
1470
1471 return 0;
1472}
1473
eb60f9cd
LP
1474void manager_refresh_rrs(Manager *m) {
1475 Iterator i;
1476 Link *l;
1477
1478 assert(m);
1479
1480 m->host_ipv4_key = dns_resource_key_unref(m->host_ipv4_key);
1481 m->host_ipv6_key = dns_resource_key_unref(m->host_ipv6_key);
1482
1483 HASHMAP_FOREACH(l, m->links, i) {
1484 link_add_rrs(l, true);
1485 link_add_rrs(l, false);
1486 }
1487}
1488
ec2c5e43
LP
1489int manager_next_hostname(Manager *m) {
1490 const char *p;
ec2c5e43
LP
1491 uint64_t u;
1492 char *h;
623a4c97
LP
1493
1494 assert(m);
1495
ec2c5e43
LP
1496 p = strchr(m->hostname, 0);
1497 assert(p);
1498
1499 while (p > m->hostname) {
1500 if (!strchr("0123456789", p[-1]))
1501 break;
1502
1503 p--;
1504 }
1505
1506 if (*p == 0 || safe_atou64(p, &u) < 0 || u <= 0)
1507 u = 1;
1508
1509 u++;
1510
1511 if (asprintf(&h, "%.*s%" PRIu64, (int) (p - m->hostname), m->hostname, u) < 0)
1512 return -ENOMEM;
1513
eb60f9cd 1514 log_info("Hostname conflict, changing published hostname from '%s' to '%s'.", m->hostname, h);
ec2c5e43
LP
1515
1516 free(m->hostname);
1517 m->hostname = h;
1518
eb60f9cd 1519 manager_refresh_rrs(m);
623a4c97
LP
1520
1521 return 0;
1522}
ec2c5e43 1523
4e945a6f 1524LinkAddress* manager_find_link_address(Manager *m, int family, const union in_addr_union *in_addr) {
ec2c5e43
LP
1525 Iterator i;
1526 Link *l;
1527
1528 assert(m);
1529
1530 HASHMAP_FOREACH(l, m->links, i) {
1531 LinkAddress *a;
1532
1533 a = link_find_address(l, family, in_addr);
1534 if (a)
1535 return a;
1536 }
1537
1538 return NULL;
1539}
1540
1541int manager_our_packet(Manager *m, DnsPacket *p) {
1542 assert(m);
1543 assert(p);
1544
4e945a6f 1545 return !!manager_find_link_address(m, p->family, &p->sender);
ec2c5e43 1546}
4e945a6f
LP
1547
1548static const char* const support_table[_SUPPORT_MAX] = {
1549 [SUPPORT_NO] = "no",
1550 [SUPPORT_YES] = "yes",
1551 [SUPPORT_RESOLVE] = "resolve",
1552};
1553DEFINE_STRING_TABLE_LOOKUP(support, Support);