]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/resolved-manager.c
Reject invalid quoted strings
[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"
74b2466e
LP
36#include "resolved.h"
37
38#define SEND_TIMEOUT_USEC (200 * USEC_PER_MSEC)
39
40static int manager_process_link(sd_rtnl *rtnl, sd_rtnl_message *mm, void *userdata) {
41 Manager *m = userdata;
42 uint16_t type;
43 Link *l;
44 int ifindex, r;
45
46 assert(rtnl);
47 assert(m);
48 assert(mm);
49
50 r = sd_rtnl_message_get_type(mm, &type);
51 if (r < 0)
52 goto fail;
53
54 r = sd_rtnl_message_link_get_ifindex(mm, &ifindex);
55 if (r < 0)
56 goto fail;
57
58 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
59
60 switch (type) {
61
a2a416f7
LP
62 case RTM_NEWLINK:{
63 bool is_new = !l;
74b2466e 64
a2a416f7 65 if (!l) {
74b2466e
LP
66 r = link_new(m, &l, ifindex);
67 if (r < 0)
68 goto fail;
69 }
70
71 r = link_update_rtnl(l, mm);
72 if (r < 0)
73 goto fail;
74
a2a416f7
LP
75 if (is_new)
76 log_debug("Found new link %i/%s", ifindex, l->name);
77
74b2466e 78 break;
a2a416f7 79 }
74b2466e
LP
80
81 case RTM_DELLINK:
82 if (l) {
a2a416f7 83 log_debug("Removing link %i/%s", l->ifindex, l->name);
74b2466e
LP
84 link_free(l);
85 }
86
87 break;
88 }
89
90 return 0;
91
92fail:
93 log_warning("Failed to process RTNL link message: %s", strerror(-r));
94 return 0;
95}
96
97static int manager_process_address(sd_rtnl *rtnl, sd_rtnl_message *mm, void *userdata) {
98 Manager *m = userdata;
99 union in_addr_union address;
74b2466e 100 uint16_t type;
0dd25fb9 101 int r, ifindex, family;
74b2466e
LP
102 LinkAddress *a;
103 Link *l;
104
105 assert(rtnl);
106 assert(mm);
107 assert(m);
108
109 r = sd_rtnl_message_get_type(mm, &type);
110 if (r < 0)
111 goto fail;
112
113 r = sd_rtnl_message_addr_get_ifindex(mm, &ifindex);
114 if (r < 0)
115 goto fail;
116
117 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
118 if (!l)
119 return 0;
120
121 r = sd_rtnl_message_addr_get_family(mm, &family);
122 if (r < 0)
123 goto fail;
124
125 switch (family) {
126
127 case AF_INET:
128 r = sd_rtnl_message_read_in_addr(mm, IFA_LOCAL, &address.in);
129 if (r < 0) {
130 r = sd_rtnl_message_read_in_addr(mm, IFA_ADDRESS, &address.in);
131 if (r < 0)
132 goto fail;
133 }
134
135 break;
136
137 case AF_INET6:
138 r = sd_rtnl_message_read_in6_addr(mm, IFA_LOCAL, &address.in6);
139 if (r < 0) {
140 r = sd_rtnl_message_read_in6_addr(mm, IFA_ADDRESS, &address.in6);
141 if (r < 0)
142 goto fail;
143 }
144
145 break;
146
147 default:
148 return 0;
149 }
150
151 a = link_find_address(l, family, &address);
152
153 switch (type) {
154
155 case RTM_NEWADDR:
156
157 if (!a) {
158 r = link_address_new(l, &a, family, &address);
159 if (r < 0)
160 return r;
161 }
162
163 r = link_address_update_rtnl(a, mm);
164 if (r < 0)
165 return r;
166
167 break;
168
169 case RTM_DELADDR:
170 if (a)
171 link_address_free(a);
172 break;
173 }
174
175 return 0;
176
177fail:
178 log_warning("Failed to process RTNL address message: %s", strerror(-r));
179 return 0;
180}
181
182
183static int manager_rtnl_listen(Manager *m) {
184 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
185 sd_rtnl_message *i;
186 int r;
187
188 assert(m);
189
190 /* First, subscibe to interfaces coming and going */
191 r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR, RTNLGRP_IPV6_IFADDR);
192 if (r < 0)
193 return r;
194
195 r = sd_rtnl_attach_event(m->rtnl, m->event, 0);
196 if (r < 0)
197 return r;
198
199 r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, manager_process_link, m);
200 if (r < 0)
201 return r;
202
203 r = sd_rtnl_add_match(m->rtnl, RTM_DELLINK, manager_process_link, m);
204 if (r < 0)
205 return r;
206
207 r = sd_rtnl_add_match(m->rtnl, RTM_NEWADDR, manager_process_address, m);
208 if (r < 0)
209 return r;
091a364c 210
74b2466e
LP
211 r = sd_rtnl_add_match(m->rtnl, RTM_DELADDR, manager_process_address, m);
212 if (r < 0)
213 return r;
214
215 /* Then, enumerate all links */
216 r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
217 if (r < 0)
218 return r;
219
220 r = sd_rtnl_message_request_dump(req, true);
221 if (r < 0)
222 return r;
223
224 r = sd_rtnl_call(m->rtnl, req, 0, &reply);
225 if (r < 0)
226 return r;
227
228 for (i = reply; i; i = sd_rtnl_message_next(i)) {
229 r = manager_process_link(m->rtnl, i, m);
230 if (r < 0)
231 return r;
232 }
233
234 req = sd_rtnl_message_unref(req);
235 reply = sd_rtnl_message_unref(reply);
236
237 /* Finally, enumerate all addresses, too */
238 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, AF_UNSPEC);
239 if (r < 0)
240 return r;
241
242 r = sd_rtnl_message_request_dump(req, true);
243 if (r < 0)
244 return r;
245
246 r = sd_rtnl_call(m->rtnl, req, 0, &reply);
247 if (r < 0)
248 return r;
249
250 for (i = reply; i; i = sd_rtnl_message_next(i)) {
251 r = manager_process_address(m->rtnl, i, m);
252 if (r < 0)
253 return r;
254 }
255
256 return r;
257}
258
259static int on_network_event(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
260 Manager *m = userdata;
261 Iterator i;
262 Link *l;
263 int r;
264
265 assert(m);
266
267 sd_network_monitor_flush(m->network_monitor);
268
269 HASHMAP_FOREACH(l, m->links, i) {
270 r = link_update_monitor(l);
271 if (r < 0)
272 log_warning("Failed to update monitor information for %i: %s", l->ifindex, strerror(-r));
273 }
274
275 r = manager_write_resolv_conf(m);
276 if (r < 0)
277 log_warning("Could not update resolv.conf: %s", strerror(-r));
278
279 return 0;
280}
281
282static int manager_network_monitor_listen(Manager *m) {
283 int r, fd, events;
284
285 assert(m);
286
0014a4ad 287 r = sd_network_monitor_new(&m->network_monitor, NULL);
74b2466e
LP
288 if (r < 0)
289 return r;
290
291 fd = sd_network_monitor_get_fd(m->network_monitor);
292 if (fd < 0)
293 return fd;
294
295 events = sd_network_monitor_get_events(m->network_monitor);
296 if (events < 0)
297 return events;
298
299 r = sd_event_add_io(m->event, &m->network_event_source, fd, events, &on_network_event, m);
300 if (r < 0)
301 return r;
302
303 return 0;
304}
305
306static int parse_dns_server_string(Manager *m, const char *string) {
a2a5291b 307 const char *word, *state;
091a364c
TG
308 size_t length;
309 int r;
310
311 assert(m);
312 assert(string);
313
314 FOREACH_WORD_QUOTED(word, length, string, state) {
74b2466e 315 char buffer[length+1];
0dd25fb9 316 int family;
74b2466e 317 union in_addr_union addr;
091a364c 318
74b2466e
LP
319 memcpy(buffer, word, length);
320 buffer[length] = 0;
091a364c 321
74b2466e 322 r = in_addr_from_string_auto(buffer, &family, &addr);
091a364c 323 if (r < 0) {
74b2466e 324 log_warning("Ignoring invalid DNS address '%s'", buffer);
091a364c
TG
325 continue;
326 }
327
74b2466e
LP
328 /* filter out duplicates */
329 if (manager_find_dns_server(m, family, &addr))
330 continue;
331
6073b6f2 332 r = dns_server_new(m, NULL, NULL, family, &addr);
74b2466e
LP
333 if (r < 0)
334 return r;
091a364c
TG
335 }
336
337 return 0;
338}
339
340int config_parse_dnsv(
341 const char *unit,
342 const char *filename,
343 unsigned line,
344 const char *section,
345 unsigned section_line,
346 const char *lvalue,
347 int ltype,
348 const char *rvalue,
349 void *data,
350 void *userdata) {
351
352 Manager *m = userdata;
74b2466e 353 int r;
091a364c
TG
354
355 assert(filename);
356 assert(lvalue);
357 assert(rvalue);
358 assert(m);
359
74b2466e
LP
360 /* Empty assignment means clear the list */
361 if (isempty(rvalue)) {
362 while (m->dns_servers)
363 dns_server_free(m->dns_servers);
364
365 return 0;
091a364c
TG
366 }
367
74b2466e
LP
368 r = parse_dns_server_string(m, rvalue);
369 if (r < 0) {
370 log_error("Failed to parse DNS server string");
371 return r;
372 }
091a364c
TG
373
374 return 0;
375}
376
74b2466e 377int manager_parse_config_file(Manager *m) {
091a364c
TG
378 assert(m);
379
36f822c4
ZJS
380 return config_parse(NULL, "/etc/systemd/resolved.conf", NULL,
381 "Resolve\0",
382 config_item_perf_lookup, resolved_gperf_lookup,
383 false, false, true, m);
091a364c
TG
384}
385
386int manager_new(Manager **ret) {
74b2466e 387 _cleanup_(manager_freep) Manager *m = NULL;
091a364c
TG
388 int r;
389
c92e531c
LP
390 assert(ret);
391
091a364c
TG
392 m = new0(Manager, 1);
393 if (!m)
394 return -ENOMEM;
395
74b2466e 396 m->dns_ipv4_fd = m->dns_ipv6_fd = -1;
1716f6dc 397 m->llmnr_ipv4_udp_fd = m->llmnr_ipv6_udp_fd = -1;
623a4c97 398 m->llmnr_ipv4_tcp_fd = m->llmnr_ipv6_tcp_fd = -1;
1716f6dc
LP
399
400 m->use_llmnr = true;
091a364c 401
faa133f3 402 r = parse_dns_server_string(m, DNS_SERVERS);
091a364c
TG
403 if (r < 0)
404 return r;
405
623a4c97
LP
406 m->hostname = gethostname_malloc();
407 if (!m->hostname)
408 return -ENOMEM;
409
091a364c
TG
410 r = sd_event_default(&m->event);
411 if (r < 0)
412 return r;
413
414 sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
415 sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
416
417 sd_event_set_watchdog(m->event, true);
418
1716f6dc 419 r = dns_scope_new(m, &m->unicast_scope, NULL, DNS_PROTOCOL_DNS, AF_UNSPEC);
74b2466e
LP
420 if (r < 0)
421 return r;
422
423 r = manager_network_monitor_listen(m);
424 if (r < 0)
425 return r;
426
427 r = manager_rtnl_listen(m);
428 if (r < 0)
429 return r;
430
431 r = manager_connect_bus(m);
432 if (r < 0)
433 return r;
434
623a4c97
LP
435 r = manager_llmnr_ipv4_udp_fd(m);
436 if (r < 0)
437 return r;
438 r = manager_llmnr_ipv6_udp_fd(m);
439 if (r < 0)
440 return r;
441 r = manager_llmnr_ipv4_tcp_fd(m);
442 if (r < 0)
443 return r;
444 r = manager_llmnr_ipv6_tcp_fd(m);
445 if (r < 0)
446 return r;
447
091a364c
TG
448 *ret = m;
449 m = NULL;
450
451 return 0;
452}
453
74b2466e
LP
454Manager *manager_free(Manager *m) {
455 Link *l;
091a364c
TG
456
457 if (!m)
74b2466e
LP
458 return NULL;
459
460 while (m->dns_queries)
461 dns_query_free(m->dns_queries);
462
463 hashmap_free(m->dns_query_transactions);
464
465 while ((l = hashmap_first(m->links)))
466 link_free(l);
467 hashmap_free(m->links);
468
469 dns_scope_free(m->unicast_scope);
470
471 while (m->dns_servers)
472 dns_server_free(m->dns_servers);
091a364c 473
096b6773
LP
474 sd_event_source_unref(m->network_event_source);
475 sd_network_monitor_unref(m->network_monitor);
091a364c 476
74b2466e
LP
477 sd_event_source_unref(m->dns_ipv4_event_source);
478 sd_event_source_unref(m->dns_ipv6_event_source);
74b2466e
LP
479 safe_close(m->dns_ipv4_fd);
480 safe_close(m->dns_ipv6_fd);
481
1716f6dc
LP
482 sd_event_source_unref(m->llmnr_ipv4_udp_event_source);
483 sd_event_source_unref(m->llmnr_ipv6_udp_event_source);
484 safe_close(m->llmnr_ipv4_udp_fd);
485 safe_close(m->llmnr_ipv6_udp_fd);
486
623a4c97
LP
487 sd_event_source_unref(m->llmnr_ipv4_tcp_event_source);
488 sd_event_source_unref(m->llmnr_ipv6_tcp_event_source);
489 safe_close(m->llmnr_ipv4_tcp_fd);
490 safe_close(m->llmnr_ipv6_tcp_fd);
491
74b2466e
LP
492 sd_event_source_unref(m->bus_retry_event_source);
493 sd_bus_unref(m->bus);
091a364c 494
74b2466e 495 sd_event_unref(m->event);
623a4c97
LP
496
497 dns_resource_key_unref(m->host_ipv4_key);
498 dns_resource_key_unref(m->host_ipv6_key);
499 free(m->hostname);
091a364c 500 free(m);
74b2466e
LP
501
502 return NULL;
091a364c
TG
503}
504
74b2466e
LP
505static void write_resolve_conf_server(DnsServer *s, FILE *f, unsigned *count) {
506 _cleanup_free_ char *t = NULL;
507 int r;
091a364c 508
74b2466e 509 assert(s);
091a364c 510 assert(f);
091a364c
TG
511 assert(count);
512
74b2466e 513 r = in_addr_to_string(s->family, &s->address, &t);
1716f6dc 514 if (r < 0) {
091a364c
TG
515 log_warning("Invalid DNS address. Ignoring.");
516 return;
517 }
518
519 if (*count == MAXNS)
74b2466e 520 fputs("# Too many DNS servers configured, the following entries may be ignored\n", f);
091a364c 521
74b2466e 522 fprintf(f, "nameserver %s\n", t);
091a364c
TG
523 (*count) ++;
524}
525
74b2466e 526int manager_write_resolv_conf(Manager *m) {
b686acb2 527 const char *path = "/run/systemd/resolve/resolv.conf";
091a364c
TG
528 _cleanup_free_ char *temp_path = NULL;
529 _cleanup_fclose_ FILE *f = NULL;
091a364c 530 unsigned count = 0;
74b2466e
LP
531 DnsServer *s;
532 Iterator i;
533 Link *l;
534 int r;
091a364c
TG
535
536 assert(m);
537
b686acb2 538 r = fopen_temporary(path, &f, &temp_path);
091a364c
TG
539 if (r < 0)
540 return r;
541
542 fchmod(fileno(f), 0644);
543
544 fputs("# This file is managed by systemd-resolved(8). Do not edit.\n#\n"
545 "# Third party programs must not access this file directly, but\n"
546 "# only through the symlink at /etc/resolv.conf. To manage\n"
547 "# resolv.conf(5) in a different way, replace the symlink by a\n"
548 "# static file or a different symlink.\n\n", f);
549
6073b6f2
TG
550 HASHMAP_FOREACH(l, m->links, i)
551 LIST_FOREACH(servers, s, l->dns_servers)
74b2466e 552 write_resolve_conf_server(s, f, &count);
091a364c 553
74b2466e
LP
554 LIST_FOREACH(servers, s, m->dns_servers)
555 write_resolve_conf_server(s, f, &count);
091a364c 556
74b2466e
LP
557 r = fflush_and_check(f);
558 if (r < 0)
559 goto fail;
560
561 if (rename(temp_path, path) < 0) {
562 r = -errno;
563 goto fail;
564 }
091a364c 565
74b2466e 566 return 0;
091a364c 567
74b2466e
LP
568fail:
569 unlink(path);
570 unlink(temp_path);
571 return r;
572}
091a364c 573
1716f6dc 574int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) {
74b2466e 575 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
1716f6dc
LP
576 union {
577 struct cmsghdr header; /* For alignment */
578 uint8_t buffer[CMSG_SPACE(MAX(sizeof(struct in_pktinfo), sizeof(struct in6_pktinfo)))
579 + CMSG_SPACE(int) /* ttl/hoplimit */
623a4c97 580 + EXTRA_CMSG_SPACE /* kernel appears to require extra buffer space */];
1716f6dc
LP
581 } control;
582 union sockaddr_union sa;
74b2466e 583 struct msghdr mh = {};
1716f6dc 584 struct cmsghdr *cmsg;
74b2466e 585 struct iovec iov;
1716f6dc 586 int ms = 0, r;
74b2466e
LP
587 ssize_t l;
588
589 assert(m);
1716f6dc 590 assert(fd >= 0);
74b2466e
LP
591 assert(ret);
592
74b2466e
LP
593 r = ioctl(fd, FIONREAD, &ms);
594 if (r < 0)
595 return -errno;
596 if (ms < 0)
597 return -EIO;
598
1716f6dc 599 r = dns_packet_new(&p, protocol, ms);
74b2466e
LP
600 if (r < 0)
601 return r;
602
603 iov.iov_base = DNS_PACKET_DATA(p);
604 iov.iov_len = p->allocated;
605
1716f6dc
LP
606 mh.msg_name = &sa.sa;
607 mh.msg_namelen = sizeof(sa);
74b2466e
LP
608 mh.msg_iov = &iov;
609 mh.msg_iovlen = 1;
1716f6dc
LP
610 mh.msg_control = &control;
611 mh.msg_controllen = sizeof(control);
74b2466e
LP
612
613 l = recvmsg(fd, &mh, 0);
614 if (l < 0) {
ad867662 615 if (errno == EAGAIN || errno == EINTR)
74b2466e
LP
616 return 0;
617
618 return -errno;
091a364c
TG
619 }
620
74b2466e
LP
621 if (l <= 0)
622 return -EIO;
091a364c 623
1716f6dc
LP
624 assert(!(mh.msg_flags & MSG_CTRUNC));
625 assert(!(mh.msg_flags & MSG_TRUNC));
626
74b2466e 627 p->size = (size_t) l;
091a364c 628
1716f6dc 629 p->family = sa.sa.sa_family;
623a4c97
LP
630 p->ipproto = IPPROTO_UDP;
631 if (p->family == AF_INET) {
1716f6dc 632 p->sender.in = sa.in.sin_addr;
623a4c97
LP
633 p->sender_port = be16toh(sa.in.sin_port);
634 } else if (p->family == AF_INET6) {
1716f6dc 635 p->sender.in6 = sa.in6.sin6_addr;
623a4c97
LP
636 p->sender_port = be16toh(sa.in6.sin6_port);
637 p->ifindex = sa.in6.sin6_scope_id;
638 } else
1716f6dc 639 return -EAFNOSUPPORT;
74b2466e 640
1716f6dc 641 for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
74b2466e 642
1716f6dc
LP
643 if (cmsg->cmsg_level == IPPROTO_IPV6) {
644 assert(p->family == AF_INET6);
74b2466e 645
1716f6dc 646 switch (cmsg->cmsg_type) {
74b2466e 647
1716f6dc
LP
648 case IPV6_PKTINFO: {
649 struct in6_pktinfo *i = (struct in6_pktinfo*) CMSG_DATA(cmsg);
74b2466e 650
623a4c97
LP
651 if (p->ifindex <= 0)
652 p->ifindex = i->ipi6_ifindex;
653
1716f6dc
LP
654 p->destination.in6 = i->ipi6_addr;
655 break;
656 }
74b2466e 657
1716f6dc
LP
658 case IPV6_HOPLIMIT:
659 p->ttl = *(int *) CMSG_DATA(cmsg);
660 break;
74b2466e 661
1716f6dc
LP
662 }
663 } else if (cmsg->cmsg_level == IPPROTO_IP) {
664 assert(p->family == AF_INET);
74b2466e 665
1716f6dc 666 switch (cmsg->cmsg_type) {
74b2466e 667
1716f6dc
LP
668 case IP_PKTINFO: {
669 struct in_pktinfo *i = (struct in_pktinfo*) CMSG_DATA(cmsg);
091a364c 670
623a4c97
LP
671 if (p->ifindex <= 0)
672 p->ifindex = i->ipi_ifindex;
673
1716f6dc
LP
674 p->destination.in = i->ipi_addr;
675 break;
676 }
74b2466e 677
623a4c97 678 case IP_TTL:
1716f6dc
LP
679 p->ttl = *(int *) CMSG_DATA(cmsg);
680 break;
681 }
682 }
683 }
74b2466e 684
623a4c97
LP
685 /* The Linux kernel sets the interface index to the loopback
686 * device if the packet came from the local host since it
687 * avoids the routing table in such a case. Let's unset the
688 * interface index in such a case. */
689 if (p->ifindex > 0 && manager_ifindex_is_loopback(m, p->ifindex) != 0)
690 p->ifindex = 0;
691
692 /* If we don't know the interface index still, we look for the
693 * first local interface with a matching address. Yuck! */
694 if (p->ifindex <= 0)
695 p->ifindex = manager_find_ifindex(m, p->family, &p->destination);
696
74b2466e
LP
697 *ret = p;
698 p = NULL;
699
700 return 1;
701}
702
1716f6dc 703static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
74b2466e
LP
704 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
705 DnsQueryTransaction *t = NULL;
706 Manager *m = userdata;
707 int r;
708
1716f6dc 709 r = manager_recv(m, fd, DNS_PROTOCOL_DNS, &p);
74b2466e
LP
710 if (r <= 0)
711 return r;
712
623a4c97 713 if (dns_packet_validate_reply(p) > 0) {
1716f6dc
LP
714 t = hashmap_get(m->dns_query_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
715 if (!t)
716 return 0;
74b2466e 717
faa133f3 718 dns_query_transaction_process_reply(t, p);
623a4c97 719
1716f6dc 720 } else
623a4c97 721 log_debug("Invalid DNS packet.");
74b2466e 722
ad867662 723 return 0;
74b2466e
LP
724}
725
726int manager_dns_ipv4_fd(Manager *m) {
1716f6dc 727 const int one = 1;
74b2466e
LP
728 int r;
729
091a364c
TG
730 assert(m);
731
74b2466e
LP
732 if (m->dns_ipv4_fd >= 0)
733 return m->dns_ipv4_fd;
091a364c 734
74b2466e
LP
735 m->dns_ipv4_fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
736 if (m->dns_ipv4_fd < 0)
737 return -errno;
091a364c 738
1716f6dc
LP
739 r = setsockopt(m->dns_ipv4_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
740 if (r < 0) {
741 r = -errno;
742 goto fail;
743 }
744
745 r = sd_event_add_io(m->event, &m->dns_ipv4_event_source, m->dns_ipv4_fd, EPOLLIN, on_dns_packet, m);
74b2466e 746 if (r < 0)
1716f6dc 747 goto fail;
74b2466e
LP
748
749 return m->dns_ipv4_fd;
1716f6dc
LP
750
751fail:
752 m->dns_ipv4_fd = safe_close(m->dns_ipv4_fd);
753 return r;
091a364c
TG
754}
755
74b2466e 756int manager_dns_ipv6_fd(Manager *m) {
1716f6dc 757 const int one = 1;
74b2466e
LP
758 int r;
759
760 assert(m);
091a364c 761
74b2466e
LP
762 if (m->dns_ipv6_fd >= 0)
763 return m->dns_ipv6_fd;
764
765 m->dns_ipv6_fd = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
766 if (m->dns_ipv6_fd < 0)
767 return -errno;
768
1716f6dc
LP
769 r = setsockopt(m->dns_ipv6_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
770 if (r < 0) {
771 r = -errno;
772 goto fail;
773 }
774
775 r = sd_event_add_io(m->event, &m->dns_ipv6_event_source, m->dns_ipv6_fd, EPOLLIN, on_dns_packet, m);
091a364c 776 if (r < 0)
1716f6dc 777 goto fail;
091a364c 778
74b2466e 779 return m->dns_ipv6_fd;
1716f6dc
LP
780
781fail:
782 m->dns_ipv6_fd = safe_close(m->dns_ipv6_fd);
783 return r;
74b2466e
LP
784}
785
786static int sendmsg_loop(int fd, struct msghdr *mh, int flags) {
787 int r;
788
789 assert(fd >= 0);
790 assert(mh);
791
792 for (;;) {
793 if (sendmsg(fd, mh, flags) >= 0)
794 return 0;
795
796 if (errno == EINTR)
797 continue;
798
799 if (errno != EAGAIN)
800 return -errno;
801
802 r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
803 if (r < 0)
804 return r;
805 if (r == 0)
806 return -ETIMEDOUT;
807 }
808}
809
623a4c97 810static int manager_ipv4_send(Manager *m, int fd, int ifindex, const struct in_addr *addr, uint16_t port, DnsPacket *p) {
74b2466e
LP
811 union sockaddr_union sa = {
812 .in.sin_family = AF_INET,
74b2466e 813 };
1716f6dc
LP
814 union {
815 struct cmsghdr header; /* For alignment */
816 uint8_t buffer[CMSG_SPACE(sizeof(struct in_pktinfo))];
817 } control;
74b2466e
LP
818 struct msghdr mh = {};
819 struct iovec iov;
74b2466e
LP
820
821 assert(m);
1716f6dc
LP
822 assert(fd >= 0);
823 assert(addr);
824 assert(port > 0);
74b2466e
LP
825 assert(p);
826
74b2466e
LP
827 iov.iov_base = DNS_PACKET_DATA(p);
828 iov.iov_len = p->size;
091a364c 829
1716f6dc
LP
830 sa.in.sin_addr = *addr;
831 sa.in.sin_port = htobe16(port),
091a364c 832
74b2466e
LP
833 mh.msg_iov = &iov;
834 mh.msg_iovlen = 1;
835 mh.msg_name = &sa.sa;
836 mh.msg_namelen = sizeof(sa.in);
091a364c 837
74b2466e
LP
838 if (ifindex > 0) {
839 struct cmsghdr *cmsg;
840 struct in_pktinfo *pi;
841
842 zero(control);
843
1716f6dc 844 mh.msg_control = &control;
74b2466e
LP
845 mh.msg_controllen = CMSG_LEN(sizeof(struct in_pktinfo));
846
847 cmsg = CMSG_FIRSTHDR(&mh);
848 cmsg->cmsg_len = mh.msg_controllen;
849 cmsg->cmsg_level = IPPROTO_IP;
850 cmsg->cmsg_type = IP_PKTINFO;
851
852 pi = (struct in_pktinfo*) CMSG_DATA(cmsg);
853 pi->ipi_ifindex = ifindex;
854 }
855
856 return sendmsg_loop(fd, &mh, 0);
857}
858
623a4c97 859static int manager_ipv6_send(Manager *m, int fd, int ifindex, const struct in6_addr *addr, uint16_t port, DnsPacket *p) {
74b2466e
LP
860 union sockaddr_union sa = {
861 .in6.sin6_family = AF_INET6,
74b2466e 862 };
1716f6dc
LP
863 union {
864 struct cmsghdr header; /* For alignment */
865 uint8_t buffer[CMSG_SPACE(sizeof(struct in6_pktinfo))];
866 } control;
74b2466e
LP
867 struct msghdr mh = {};
868 struct iovec iov;
74b2466e
LP
869
870 assert(m);
1716f6dc
LP
871 assert(fd >= 0);
872 assert(addr);
873 assert(port > 0);
74b2466e
LP
874 assert(p);
875
74b2466e
LP
876 iov.iov_base = DNS_PACKET_DATA(p);
877 iov.iov_len = p->size;
878
1716f6dc
LP
879 sa.in6.sin6_addr = *addr;
880 sa.in6.sin6_port = htobe16(port),
74b2466e
LP
881 sa.in6.sin6_scope_id = ifindex;
882
883 mh.msg_iov = &iov;
884 mh.msg_iovlen = 1;
885 mh.msg_name = &sa.sa;
886 mh.msg_namelen = sizeof(sa.in6);
887
888 if (ifindex > 0) {
889 struct cmsghdr *cmsg;
890 struct in6_pktinfo *pi;
891
892 zero(control);
893
1716f6dc 894 mh.msg_control = &control;
74b2466e
LP
895 mh.msg_controllen = CMSG_LEN(sizeof(struct in6_pktinfo));
896
897 cmsg = CMSG_FIRSTHDR(&mh);
898 cmsg->cmsg_len = mh.msg_controllen;
899 cmsg->cmsg_level = IPPROTO_IPV6;
900 cmsg->cmsg_type = IPV6_PKTINFO;
901
902 pi = (struct in6_pktinfo*) CMSG_DATA(cmsg);
903 pi->ipi6_ifindex = ifindex;
904 }
905
906 return sendmsg_loop(fd, &mh, 0);
907}
908
623a4c97 909int manager_send(Manager *m, int fd, int ifindex, int family, const union in_addr_union *addr, uint16_t port, DnsPacket *p) {
1716f6dc
LP
910 assert(m);
911 assert(fd >= 0);
912 assert(addr);
913 assert(port > 0);
914 assert(p);
915
a2a416f7
LP
916 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));
917
1716f6dc
LP
918 if (family == AF_INET)
919 return manager_ipv4_send(m, fd, ifindex, &addr->in, port, p);
920 else if (family == AF_INET6)
921 return manager_ipv6_send(m, fd, ifindex, &addr->in6, port, p);
922
923 return -EAFNOSUPPORT;
924}
925
623a4c97 926DnsServer* manager_find_dns_server(Manager *m, int family, const union in_addr_union *in_addr) {
74b2466e
LP
927 DnsServer *s;
928
929 assert(m);
930 assert(in_addr);
931
932 LIST_FOREACH(servers, s, m->dns_servers) {
933
934 if (s->family == family &&
935 in_addr_equal(family, &s->address, in_addr))
936 return s;
937 }
938
939 return NULL;
940}
941
942DnsServer *manager_get_dns_server(Manager *m) {
943 assert(m);
944
945 if (!m->current_dns_server)
946 m->current_dns_server = m->dns_servers;
947
948 return m->current_dns_server;
949}
950
951void manager_next_dns_server(Manager *m) {
952 assert(m);
953
954 if (!m->current_dns_server) {
955 m->current_dns_server = m->dns_servers;
956 return;
957 }
958
959 if (!m->current_dns_server)
960 return;
961
962 if (m->current_dns_server->servers_next) {
963 m->current_dns_server = m->current_dns_server->servers_next;
964 return;
965 }
966
967 m->current_dns_server = m->dns_servers;
091a364c 968}
e1c95994
LP
969
970uint32_t manager_find_mtu(Manager *m) {
971 uint32_t mtu = 0;
972 Link *l;
973 Iterator i;
974
975 /* If we don't know on which link a DNS packet would be
976 * delivered, let's find the largest MTU that works on all
977 * interfaces we know of */
978
979 HASHMAP_FOREACH(l, m->links, i) {
980 if (l->mtu <= 0)
981 continue;
982
983 if (mtu <= 0 || l->mtu < mtu)
984 mtu = l->mtu;
985 }
986
987 return mtu;
988}
1716f6dc
LP
989
990static int on_llmnr_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
991 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
992 DnsQueryTransaction *t = NULL;
993 Manager *m = userdata;
994 int r;
995
996 r = manager_recv(m, fd, DNS_PROTOCOL_LLMNR, &p);
997 if (r <= 0)
998 return r;
999
623a4c97 1000 if (dns_packet_validate_reply(p) > 0) {
a2a416f7
LP
1001 log_debug("Got reply packet for id %u", DNS_PACKET_ID(p));
1002
1716f6dc
LP
1003 t = hashmap_get(m->dns_query_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
1004 if (!t)
1005 return 0;
1006
faa133f3 1007 dns_query_transaction_process_reply(t, p);
623a4c97
LP
1008
1009 } else if (dns_packet_validate_query(p) > 0) {
1010 Link *l;
1011
1012 l = hashmap_get(m->links, INT_TO_PTR(p->ifindex));
1013 if (l) {
1014 DnsScope *scope = NULL;
1015
1016 if (p->family == AF_INET)
1017 scope = l->llmnr_ipv4_scope;
1018 else if (p->family == AF_INET6)
1019 scope = l->llmnr_ipv6_scope;
1020
1021 if (scope)
1022 dns_scope_process_query(scope, NULL, p);
1023 }
1024 } else
1025 log_debug("Invalid LLMNR packet.");
1716f6dc
LP
1026
1027 return 0;
1028}
1029
1030int manager_llmnr_ipv4_udp_fd(Manager *m) {
1031 union sockaddr_union sa = {
1032 .in.sin_family = AF_INET,
1033 .in.sin_port = htobe16(5355),
1034 };
bf3f1271 1035 static const int one = 1, pmtu = IP_PMTUDISC_DONT, ttl = 255;
1716f6dc
LP
1036 int r;
1037
1038 assert(m);
1039
1040 if (m->llmnr_ipv4_udp_fd >= 0)
1041 return m->llmnr_ipv4_udp_fd;
1042
1043 m->llmnr_ipv4_udp_fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1044 if (m->llmnr_ipv4_udp_fd < 0)
1045 return -errno;
1046
bf3f1271
LP
1047 /* RFC 4795, section 2.5 recommends setting the TTL of UDP packets to 255. */
1048 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
1716f6dc
LP
1049 if (r < 0) {
1050 r = -errno;
1051 goto fail;
1052 }
1053
bf3f1271 1054 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
1716f6dc
LP
1055 if (r < 0) {
1056 r = -errno;
1057 goto fail;
1058 }
1059
1060 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MULTICAST_LOOP, &one, sizeof(one));
1061 if (r < 0) {
1062 r = -errno;
1063 goto fail;
1064 }
1065
1066 r = setsockopt(m->llmnr_ipv4_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1067 if (r < 0) {
1068 r = -errno;
1069 goto fail;
1070 }
1071
1072 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
1073 if (r < 0) {
1074 r = -errno;
1075 goto fail;
1076 }
1077
1078 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_RECVTTL, &one, sizeof(one));
1079 if (r < 0) {
1080 r = -errno;
1081 goto fail;
1082 }
1083
1084 /* Disable Don't-Fragment bit in the IP header */
1085 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu));
1086 if (r < 0) {
1087 r = -errno;
1088 goto fail;
1089 }
1090
1091 r = bind(m->llmnr_ipv4_udp_fd, &sa.sa, sizeof(sa.in));
1092 if (r < 0) {
1093 r = -errno;
1094 goto fail;
1095 }
1096
1097 r = sd_event_add_io(m->event, &m->llmnr_ipv4_udp_event_source, m->llmnr_ipv4_udp_fd, EPOLLIN, on_llmnr_packet, m);
1098 if (r < 0)
1099 goto fail;
1100
1101 return m->llmnr_ipv4_udp_fd;
1102
1103fail:
1104 m->llmnr_ipv4_udp_fd = safe_close(m->llmnr_ipv4_udp_fd);
1105 return r;
1106}
1107
1108int manager_llmnr_ipv6_udp_fd(Manager *m) {
1109 union sockaddr_union sa = {
1110 .in6.sin6_family = AF_INET6,
1111 .in6.sin6_port = htobe16(5355),
1112 };
bf3f1271 1113 static const int one = 1, ttl = 255;
1716f6dc
LP
1114 int r;
1115
1116 assert(m);
1117
1118 if (m->llmnr_ipv6_udp_fd >= 0)
1119 return m->llmnr_ipv6_udp_fd;
1120
1121 m->llmnr_ipv6_udp_fd = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1122 if (m->llmnr_ipv6_udp_fd < 0)
1123 return -errno;
1124
bf3f1271 1125 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl));
1716f6dc
LP
1126 if (r < 0) {
1127 r = -errno;
1128 goto fail;
1129 }
1130
bf3f1271
LP
1131 /* RFC 4795, section 2.5 recommends setting the TTL of UDP packets to 255. */
1132 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl));
1716f6dc
LP
1133 if (r < 0) {
1134 r = -errno;
1135 goto fail;
1136 }
1137
1138 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &one, sizeof(one));
1139 if (r < 0) {
1140 r = -errno;
1141 goto fail;
1142 }
1143
1144 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
1145 if (r < 0) {
1146 r = -errno;
1147 goto fail;
1148 }
1149
1150 r = setsockopt(m->llmnr_ipv6_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1151 if (r < 0) {
1152 r = -errno;
1153 goto fail;
1154 }
1155
1156 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
1157 if (r < 0) {
1158 r = -errno;
1159 goto fail;
1160 }
1161
1162 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &one, sizeof(one));
1163 if (r < 0) {
1164 r = -errno;
1165 goto fail;
1166 }
1167
1168 r = bind(m->llmnr_ipv6_udp_fd, &sa.sa, sizeof(sa.in6));
1169 if (r < 0) {
1170 r = -errno;
1171 goto fail;
1172 }
1173
1174 r = sd_event_add_io(m->event, &m->llmnr_ipv6_udp_event_source, m->llmnr_ipv6_udp_fd, EPOLLIN, on_llmnr_packet, m);
1175 if (r < 0) {
1176 r = -errno;
1177 goto fail;
1178 }
1179
1180 return m->llmnr_ipv6_udp_fd;
1181
1182fail:
1183 m->llmnr_ipv6_udp_fd = safe_close(m->llmnr_ipv6_udp_fd);
1184 return r;
1185}
623a4c97
LP
1186
1187static int on_llmnr_stream_packet(DnsStream *s) {
1188 assert(s);
1189
1190 if (dns_packet_validate_query(s->read_packet) > 0) {
1191 Link *l;
1192
1193 l = hashmap_get(s->manager->links, INT_TO_PTR(s->read_packet->ifindex));
1194 if (l) {
1195 DnsScope *scope = NULL;
1196
1197 if (s->read_packet->family == AF_INET)
1198 scope = l->llmnr_ipv4_scope;
1199 else if (s->read_packet->family == AF_INET6)
1200 scope = l->llmnr_ipv6_scope;
1201
1202 if (scope) {
1203 dns_scope_process_query(scope, s, s->read_packet);
1204
1205 /* If no reply packet was set, we free the stream */
1206 if (s->write_packet)
1207 return 0;
1208 }
1209 }
1210 }
1211
1212 dns_stream_free(s);
1213 return 0;
1214}
1215
1216static int on_llmnr_stream(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
1217 DnsStream *stream;
1218 Manager *m = userdata;
1219 int cfd, r;
1220
1221 cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
1222 if (cfd < 0) {
1223 if (errno == EAGAIN || errno == EINTR)
1224 return 0;
1225
1226 return -errno;
1227 }
1228
1229 r = dns_stream_new(m, &stream, DNS_PROTOCOL_LLMNR, cfd);
1230 if (r < 0) {
1231 safe_close(cfd);
1232 return r;
1233 }
1234
1235 stream->on_packet = on_llmnr_stream_packet;
1236 return 0;
1237}
1238
1239int manager_llmnr_ipv4_tcp_fd(Manager *m) {
1240 union sockaddr_union sa = {
1241 .in.sin_family = AF_INET,
1242 .in.sin_port = htobe16(5355),
1243 };
1244 static const int one = 1, pmtu = IP_PMTUDISC_DONT;
1245 int r;
1246
1247 assert(m);
1248
1249 if (m->llmnr_ipv4_tcp_fd >= 0)
1250 return m->llmnr_ipv4_tcp_fd;
1251
1252 m->llmnr_ipv4_tcp_fd = socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1253 if (m->llmnr_ipv4_tcp_fd < 0)
1254 return -errno;
1255
bf3f1271 1256 /* RFC 4795, section 2.5. requires setting the TTL of TCP streams to 1 */
623a4c97
LP
1257 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_TTL, &one, sizeof(one));
1258 if (r < 0) {
1259 r = -errno;
1260 goto fail;
1261 }
1262
1263 r = setsockopt(m->llmnr_ipv4_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1264 if (r < 0) {
1265 r = -errno;
1266 goto fail;
1267 }
1268
1269 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
1270 if (r < 0) {
1271 r = -errno;
1272 goto fail;
1273 }
1274
1275 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_RECVTTL, &one, sizeof(one));
1276 if (r < 0) {
1277 r = -errno;
1278 goto fail;
1279 }
1280
1281 /* Disable Don't-Fragment bit in the IP header */
1282 r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu));
1283 if (r < 0) {
1284 r = -errno;
1285 goto fail;
1286 }
1287
1288 r = bind(m->llmnr_ipv4_tcp_fd, &sa.sa, sizeof(sa.in));
1289 if (r < 0) {
1290 r = -errno;
1291 goto fail;
1292 }
1293
1294 r = listen(m->llmnr_ipv4_tcp_fd, SOMAXCONN);
1295 if (r < 0) {
1296 r = -errno;
1297 goto fail;
1298 }
1299
1300 r = sd_event_add_io(m->event, &m->llmnr_ipv4_tcp_event_source, m->llmnr_ipv4_tcp_fd, EPOLLIN, on_llmnr_stream, m);
1301 if (r < 0)
1302 goto fail;
1303
1304 return m->llmnr_ipv4_tcp_fd;
1305
1306fail:
1307 m->llmnr_ipv4_tcp_fd = safe_close(m->llmnr_ipv4_tcp_fd);
1308 return r;
1309}
1310
1311int manager_llmnr_ipv6_tcp_fd(Manager *m) {
1312 union sockaddr_union sa = {
1313 .in6.sin6_family = AF_INET6,
1314 .in6.sin6_port = htobe16(5355),
1315 };
1316 static const int one = 1;
1317 int r;
1318
1319 assert(m);
1320
1321 if (m->llmnr_ipv6_tcp_fd >= 0)
1322 return m->llmnr_ipv6_tcp_fd;
1323
1324 m->llmnr_ipv6_tcp_fd = socket(AF_INET6, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1325 if (m->llmnr_ipv6_tcp_fd < 0)
1326 return -errno;
1327
bf3f1271 1328 /* RFC 4795, section 2.5. requires setting the TTL of TCP streams to 1 */
623a4c97
LP
1329 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &one, sizeof(one));
1330 if (r < 0) {
1331 r = -errno;
1332 goto fail;
1333 }
1334
1335 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
1336 if (r < 0) {
1337 r = -errno;
1338 goto fail;
1339 }
1340
1341 r = setsockopt(m->llmnr_ipv6_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1342 if (r < 0) {
1343 r = -errno;
1344 goto fail;
1345 }
1346
1347 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
1348 if (r < 0) {
1349 r = -errno;
1350 goto fail;
1351 }
1352
1353 r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &one, sizeof(one));
1354 if (r < 0) {
1355 r = -errno;
1356 goto fail;
1357 }
1358
1359 r = bind(m->llmnr_ipv6_tcp_fd, &sa.sa, sizeof(sa.in6));
1360 if (r < 0) {
1361 r = -errno;
1362 goto fail;
1363 }
1364
1365 r = listen(m->llmnr_ipv6_tcp_fd, SOMAXCONN);
1366 if (r < 0) {
1367 r = -errno;
1368 goto fail;
1369 }
1370
1371 r = sd_event_add_io(m->event, &m->llmnr_ipv6_tcp_event_source, m->llmnr_ipv6_tcp_fd, EPOLLIN, on_llmnr_stream, m);
1372 if (r < 0) {
1373 r = -errno;
1374 goto fail;
1375 }
1376
1377 return m->llmnr_ipv6_tcp_fd;
1378
1379fail:
1380 m->llmnr_ipv6_tcp_fd = safe_close(m->llmnr_ipv6_tcp_fd);
1381 return r;
1382}
1383
1384int manager_ifindex_is_loopback(Manager *m, int ifindex) {
1385 Link *l;
1386 assert(m);
1387
1388 if (ifindex <= 0)
1389 return -EINVAL;
1390
1391 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
1392 if (l->flags & IFF_LOOPBACK)
1393 return 1;
1394
1395 return 0;
1396}
1397
1398int manager_find_ifindex(Manager *m, int family, const union in_addr_union *in_addr) {
1399 Link *l;
1400 Iterator i;
1401
1402 assert(m);
1403
1404 HASHMAP_FOREACH(l, m->links, i)
1405 if (link_find_address(l, family, in_addr))
1406 return l->ifindex;
1407
1408 return 0;
1409}