]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-manager.c
resolved: don't read DHCP leases
[thirdparty/systemd.git] / src / resolve / resolved-manager.c
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>
24 #include <net/if.h>
25 #include <sys/ioctl.h>
26 #include <sys/poll.h>
27 #include <netinet/in.h>
28
29 #include "rtnl-util.h"
30 #include "event-util.h"
31 #include "network-util.h"
32 #include "network-internal.h"
33 #include "conf-parser.h"
34 #include "socket-util.h"
35 #include "resolved.h"
36
37 #define SEND_TIMEOUT_USEC (200 * USEC_PER_MSEC)
38
39 static int manager_process_link(sd_rtnl *rtnl, sd_rtnl_message *mm, void *userdata) {
40 Manager *m = userdata;
41 uint16_t type;
42 Link *l;
43 int ifindex, r;
44
45 assert(rtnl);
46 assert(m);
47 assert(mm);
48
49 r = sd_rtnl_message_get_type(mm, &type);
50 if (r < 0)
51 goto fail;
52
53 r = sd_rtnl_message_link_get_ifindex(mm, &ifindex);
54 if (r < 0)
55 goto fail;
56
57 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
58
59 switch (type) {
60
61 case RTM_NEWLINK:
62 if (!l) {
63 log_debug("Found link %i", ifindex);
64
65 r = link_new(m, &l, ifindex);
66 if (r < 0)
67 goto fail;
68 }
69
70 r = link_update_rtnl(l, mm);
71 if (r < 0)
72 goto fail;
73
74 break;
75
76 case RTM_DELLINK:
77 if (l) {
78 log_debug("Removing link %i", l->ifindex);
79 link_free(l);
80 }
81
82 break;
83 }
84
85 return 0;
86
87 fail:
88 log_warning("Failed to process RTNL link message: %s", strerror(-r));
89 return 0;
90 }
91
92 static int manager_process_address(sd_rtnl *rtnl, sd_rtnl_message *mm, void *userdata) {
93 Manager *m = userdata;
94 union in_addr_union address;
95 uint16_t type;
96 int r, ifindex, family;
97 LinkAddress *a;
98 Link *l;
99
100 assert(rtnl);
101 assert(mm);
102 assert(m);
103
104 r = sd_rtnl_message_get_type(mm, &type);
105 if (r < 0)
106 goto fail;
107
108 r = sd_rtnl_message_addr_get_ifindex(mm, &ifindex);
109 if (r < 0)
110 goto fail;
111
112 l = hashmap_get(m->links, INT_TO_PTR(ifindex));
113 if (!l)
114 return 0;
115
116 r = sd_rtnl_message_addr_get_family(mm, &family);
117 if (r < 0)
118 goto fail;
119
120 switch (family) {
121
122 case AF_INET:
123 r = sd_rtnl_message_read_in_addr(mm, IFA_LOCAL, &address.in);
124 if (r < 0) {
125 r = sd_rtnl_message_read_in_addr(mm, IFA_ADDRESS, &address.in);
126 if (r < 0)
127 goto fail;
128 }
129
130 break;
131
132 case AF_INET6:
133 r = sd_rtnl_message_read_in6_addr(mm, IFA_LOCAL, &address.in6);
134 if (r < 0) {
135 r = sd_rtnl_message_read_in6_addr(mm, IFA_ADDRESS, &address.in6);
136 if (r < 0)
137 goto fail;
138 }
139
140 break;
141
142 default:
143 return 0;
144 }
145
146 a = link_find_address(l, family, &address);
147
148 switch (type) {
149
150 case RTM_NEWADDR:
151
152 if (!a) {
153 r = link_address_new(l, &a, family, &address);
154 if (r < 0)
155 return r;
156 }
157
158 r = link_address_update_rtnl(a, mm);
159 if (r < 0)
160 return r;
161
162 break;
163
164 case RTM_DELADDR:
165 if (a)
166 link_address_free(a);
167 break;
168 }
169
170 return 0;
171
172 fail:
173 log_warning("Failed to process RTNL address message: %s", strerror(-r));
174 return 0;
175 }
176
177
178 static int manager_rtnl_listen(Manager *m) {
179 _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
180 sd_rtnl_message *i;
181 int r;
182
183 assert(m);
184
185 /* First, subscibe to interfaces coming and going */
186 r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR, RTNLGRP_IPV6_IFADDR);
187 if (r < 0)
188 return r;
189
190 r = sd_rtnl_attach_event(m->rtnl, m->event, 0);
191 if (r < 0)
192 return r;
193
194 r = sd_rtnl_add_match(m->rtnl, RTM_NEWLINK, manager_process_link, m);
195 if (r < 0)
196 return r;
197
198 r = sd_rtnl_add_match(m->rtnl, RTM_DELLINK, manager_process_link, m);
199 if (r < 0)
200 return r;
201
202 r = sd_rtnl_add_match(m->rtnl, RTM_NEWADDR, manager_process_address, m);
203 if (r < 0)
204 return r;
205
206 r = sd_rtnl_add_match(m->rtnl, RTM_DELADDR, manager_process_address, m);
207 if (r < 0)
208 return r;
209
210 /* Then, enumerate all links */
211 r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
212 if (r < 0)
213 return r;
214
215 r = sd_rtnl_message_request_dump(req, true);
216 if (r < 0)
217 return r;
218
219 r = sd_rtnl_call(m->rtnl, req, 0, &reply);
220 if (r < 0)
221 return r;
222
223 for (i = reply; i; i = sd_rtnl_message_next(i)) {
224 r = manager_process_link(m->rtnl, i, m);
225 if (r < 0)
226 return r;
227 }
228
229 req = sd_rtnl_message_unref(req);
230 reply = sd_rtnl_message_unref(reply);
231
232 /* Finally, enumerate all addresses, too */
233 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, AF_UNSPEC);
234 if (r < 0)
235 return r;
236
237 r = sd_rtnl_message_request_dump(req, true);
238 if (r < 0)
239 return r;
240
241 r = sd_rtnl_call(m->rtnl, req, 0, &reply);
242 if (r < 0)
243 return r;
244
245 for (i = reply; i; i = sd_rtnl_message_next(i)) {
246 r = manager_process_address(m->rtnl, i, m);
247 if (r < 0)
248 return r;
249 }
250
251 return r;
252 }
253
254 static int on_network_event(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
255 Manager *m = userdata;
256 Iterator i;
257 Link *l;
258 int r;
259
260 assert(m);
261
262 sd_network_monitor_flush(m->network_monitor);
263
264 HASHMAP_FOREACH(l, m->links, i) {
265 r = link_update_monitor(l);
266 if (r < 0)
267 log_warning("Failed to update monitor information for %i: %s", l->ifindex, strerror(-r));
268 }
269
270 r = manager_write_resolv_conf(m);
271 if (r < 0)
272 log_warning("Could not update resolv.conf: %s", strerror(-r));
273
274 return 0;
275 }
276
277 static int manager_network_monitor_listen(Manager *m) {
278 int r, fd, events;
279
280 assert(m);
281
282 r = sd_network_monitor_new(&m->network_monitor, NULL);
283 if (r < 0)
284 return r;
285
286 fd = sd_network_monitor_get_fd(m->network_monitor);
287 if (fd < 0)
288 return fd;
289
290 events = sd_network_monitor_get_events(m->network_monitor);
291 if (events < 0)
292 return events;
293
294 r = sd_event_add_io(m->event, &m->network_event_source, fd, events, &on_network_event, m);
295 if (r < 0)
296 return r;
297
298 return 0;
299 }
300
301 static int parse_dns_server_string(Manager *m, const char *string) {
302 char *word, *state;
303 size_t length;
304 int r;
305
306 assert(m);
307 assert(string);
308
309 FOREACH_WORD_QUOTED(word, length, string, state) {
310 char buffer[length+1];
311 int family;
312 union in_addr_union addr;
313
314 memcpy(buffer, word, length);
315 buffer[length] = 0;
316
317 r = in_addr_from_string_auto(buffer, &family, &addr);
318 if (r < 0) {
319 log_warning("Ignoring invalid DNS address '%s'", buffer);
320 continue;
321 }
322
323 /* filter out duplicates */
324 if (manager_find_dns_server(m, family, &addr))
325 continue;
326
327 r = dns_server_new(m, NULL, NULL, family, &addr);
328 if (r < 0)
329 return r;
330 }
331
332 return 0;
333 }
334
335 int config_parse_dnsv(
336 const char *unit,
337 const char *filename,
338 unsigned line,
339 const char *section,
340 unsigned section_line,
341 const char *lvalue,
342 int ltype,
343 const char *rvalue,
344 void *data,
345 void *userdata) {
346
347 Manager *m = userdata;
348 int r;
349
350 assert(filename);
351 assert(lvalue);
352 assert(rvalue);
353 assert(m);
354
355 /* Empty assignment means clear the list */
356 if (isempty(rvalue)) {
357 while (m->dns_servers)
358 dns_server_free(m->dns_servers);
359
360 return 0;
361 }
362
363 r = parse_dns_server_string(m, rvalue);
364 if (r < 0) {
365 log_error("Failed to parse DNS server string");
366 return r;
367 }
368
369 return 0;
370 }
371
372 int manager_parse_config_file(Manager *m) {
373 assert(m);
374
375 return config_parse(NULL, "/etc/systemd/resolved.conf", NULL,
376 "Resolve\0",
377 config_item_perf_lookup, resolved_gperf_lookup,
378 false, false, true, m);
379 }
380
381 int manager_new(Manager **ret) {
382 _cleanup_(manager_freep) Manager *m = NULL;
383 int r;
384
385 assert(ret);
386
387 m = new0(Manager, 1);
388 if (!m)
389 return -ENOMEM;
390
391 m->dns_ipv4_fd = m->dns_ipv6_fd = -1;
392 m->llmnr_ipv4_udp_fd = m->llmnr_ipv6_udp_fd = -1;
393
394 m->use_llmnr = true;
395
396 r = parse_dns_server_string(m, DNS_SERVERS);
397 if (r < 0)
398 return r;
399
400 r = sd_event_default(&m->event);
401 if (r < 0)
402 return r;
403
404 sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
405 sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
406
407 sd_event_set_watchdog(m->event, true);
408
409 r = dns_scope_new(m, &m->unicast_scope, NULL, DNS_PROTOCOL_DNS, AF_UNSPEC);
410 if (r < 0)
411 return r;
412
413 r = manager_network_monitor_listen(m);
414 if (r < 0)
415 return r;
416
417 r = manager_rtnl_listen(m);
418 if (r < 0)
419 return r;
420
421 r = manager_connect_bus(m);
422 if (r < 0)
423 return r;
424
425 *ret = m;
426 m = NULL;
427
428 return 0;
429 }
430
431 Manager *manager_free(Manager *m) {
432 Link *l;
433
434 if (!m)
435 return NULL;
436
437 while (m->dns_queries)
438 dns_query_free(m->dns_queries);
439
440 hashmap_free(m->dns_query_transactions);
441
442 while ((l = hashmap_first(m->links)))
443 link_free(l);
444 hashmap_free(m->links);
445
446 dns_scope_free(m->unicast_scope);
447
448 while (m->dns_servers)
449 dns_server_free(m->dns_servers);
450
451 sd_event_source_unref(m->network_event_source);
452 sd_network_monitor_unref(m->network_monitor);
453
454 sd_event_source_unref(m->dns_ipv4_event_source);
455 sd_event_source_unref(m->dns_ipv6_event_source);
456 safe_close(m->dns_ipv4_fd);
457 safe_close(m->dns_ipv6_fd);
458
459 sd_event_source_unref(m->llmnr_ipv4_udp_event_source);
460 sd_event_source_unref(m->llmnr_ipv6_udp_event_source);
461 safe_close(m->llmnr_ipv4_udp_fd);
462 safe_close(m->llmnr_ipv6_udp_fd);
463
464 sd_event_source_unref(m->bus_retry_event_source);
465 sd_bus_unref(m->bus);
466
467 sd_event_unref(m->event);
468 free(m);
469
470 return NULL;
471 }
472
473 static void write_resolve_conf_server(DnsServer *s, FILE *f, unsigned *count) {
474 _cleanup_free_ char *t = NULL;
475 int r;
476
477 assert(s);
478 assert(f);
479 assert(count);
480
481 r = in_addr_to_string(s->family, &s->address, &t);
482 if (r < 0) {
483 log_warning("Invalid DNS address. Ignoring.");
484 return;
485 }
486
487 if (*count == MAXNS)
488 fputs("# Too many DNS servers configured, the following entries may be ignored\n", f);
489
490 fprintf(f, "nameserver %s\n", t);
491 (*count) ++;
492 }
493
494 int manager_write_resolv_conf(Manager *m) {
495 const char *path = "/run/systemd/resolve/resolv.conf";
496 _cleanup_free_ char *temp_path = NULL;
497 _cleanup_fclose_ FILE *f = NULL;
498 unsigned count = 0;
499 DnsServer *s;
500 Iterator i;
501 Link *l;
502 int r;
503
504 assert(m);
505
506 r = fopen_temporary(path, &f, &temp_path);
507 if (r < 0)
508 return r;
509
510 fchmod(fileno(f), 0644);
511
512 fputs("# This file is managed by systemd-resolved(8). Do not edit.\n#\n"
513 "# Third party programs must not access this file directly, but\n"
514 "# only through the symlink at /etc/resolv.conf. To manage\n"
515 "# resolv.conf(5) in a different way, replace the symlink by a\n"
516 "# static file or a different symlink.\n\n", f);
517
518 HASHMAP_FOREACH(l, m->links, i)
519 LIST_FOREACH(servers, s, l->dns_servers)
520 write_resolve_conf_server(s, f, &count);
521
522 LIST_FOREACH(servers, s, m->dns_servers)
523 write_resolve_conf_server(s, f, &count);
524
525 r = fflush_and_check(f);
526 if (r < 0)
527 goto fail;
528
529 if (rename(temp_path, path) < 0) {
530 r = -errno;
531 goto fail;
532 }
533
534 return 0;
535
536 fail:
537 unlink(path);
538 unlink(temp_path);
539 return r;
540 }
541
542 int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) {
543 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
544 union {
545 struct cmsghdr header; /* For alignment */
546 uint8_t buffer[CMSG_SPACE(MAX(sizeof(struct in_pktinfo), sizeof(struct in6_pktinfo)))
547 + CMSG_SPACE(int) /* ttl/hoplimit */
548 + 1024 /* kernel appears to require extra buffer space */];
549 } control;
550 union sockaddr_union sa;
551 struct msghdr mh = {};
552 struct cmsghdr *cmsg;
553 struct iovec iov;
554 int ms = 0, r;
555 ssize_t l;
556
557 assert(m);
558 assert(fd >= 0);
559 assert(ret);
560
561 r = ioctl(fd, FIONREAD, &ms);
562 if (r < 0)
563 return -errno;
564 if (ms < 0)
565 return -EIO;
566
567 r = dns_packet_new(&p, protocol, ms);
568 if (r < 0)
569 return r;
570
571 iov.iov_base = DNS_PACKET_DATA(p);
572 iov.iov_len = p->allocated;
573
574 mh.msg_name = &sa.sa;
575 mh.msg_namelen = sizeof(sa);
576 mh.msg_iov = &iov;
577 mh.msg_iovlen = 1;
578 mh.msg_control = &control;
579 mh.msg_controllen = sizeof(control);
580
581 l = recvmsg(fd, &mh, 0);
582 if (l < 0) {
583 if (errno == EAGAIN || errno == EINTR)
584 return 0;
585
586 return -errno;
587 }
588
589 if (l <= 0)
590 return -EIO;
591
592 assert(!(mh.msg_flags & MSG_CTRUNC));
593 assert(!(mh.msg_flags & MSG_TRUNC));
594
595 p->size = (size_t) l;
596
597 p->family = sa.sa.sa_family;
598 if (p->family == AF_INET)
599 p->sender.in = sa.in.sin_addr;
600 else if (p->family == AF_INET6)
601 p->sender.in6 = sa.in6.sin6_addr;
602 else
603 return -EAFNOSUPPORT;
604
605 for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) {
606
607 if (cmsg->cmsg_level == IPPROTO_IPV6) {
608 assert(p->family == AF_INET6);
609
610 switch (cmsg->cmsg_type) {
611
612 case IPV6_PKTINFO: {
613 struct in6_pktinfo *i = (struct in6_pktinfo*) CMSG_DATA(cmsg);
614
615 p->ifindex = i->ipi6_ifindex;
616 p->destination.in6 = i->ipi6_addr;
617 break;
618 }
619
620 case IPV6_HOPLIMIT:
621 p->ttl = *(int *) CMSG_DATA(cmsg);
622 break;
623
624 }
625 } else if (cmsg->cmsg_level == IPPROTO_IP) {
626 assert(p->family == AF_INET);
627
628 switch (cmsg->cmsg_type) {
629
630 case IP_PKTINFO: {
631 struct in_pktinfo *i = (struct in_pktinfo*) CMSG_DATA(cmsg);
632
633 p->ifindex = i->ipi_ifindex;
634 p->destination.in = i->ipi_addr;
635 break;
636 }
637
638 case IP_RECVTTL:
639 p->ttl = *(int *) CMSG_DATA(cmsg);
640 break;
641 }
642 }
643 }
644
645 *ret = p;
646 p = NULL;
647
648 return 1;
649 }
650
651 static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
652 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
653 DnsQueryTransaction *t = NULL;
654 Manager *m = userdata;
655 int r;
656
657 r = manager_recv(m, fd, DNS_PROTOCOL_DNS, &p);
658 if (r <= 0)
659 return r;
660
661 if (dns_packet_validate_reply(p) >= 0) {
662 t = hashmap_get(m->dns_query_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
663 if (!t)
664 return 0;
665
666 dns_query_transaction_process_reply(t, p);
667 } else
668 log_debug("Invalid reply packet.");
669
670 return 0;
671 }
672
673 int manager_dns_ipv4_fd(Manager *m) {
674 const int one = 1;
675 int r;
676
677 assert(m);
678
679 if (m->dns_ipv4_fd >= 0)
680 return m->dns_ipv4_fd;
681
682 m->dns_ipv4_fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
683 if (m->dns_ipv4_fd < 0)
684 return -errno;
685
686 r = setsockopt(m->dns_ipv4_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
687 if (r < 0) {
688 r = -errno;
689 goto fail;
690 }
691
692 r = sd_event_add_io(m->event, &m->dns_ipv4_event_source, m->dns_ipv4_fd, EPOLLIN, on_dns_packet, m);
693 if (r < 0)
694 goto fail;
695
696 return m->dns_ipv4_fd;
697
698 fail:
699 m->dns_ipv4_fd = safe_close(m->dns_ipv4_fd);
700 return r;
701 }
702
703 int manager_dns_ipv6_fd(Manager *m) {
704 const int one = 1;
705 int r;
706
707 assert(m);
708
709 if (m->dns_ipv6_fd >= 0)
710 return m->dns_ipv6_fd;
711
712 m->dns_ipv6_fd = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
713 if (m->dns_ipv6_fd < 0)
714 return -errno;
715
716 r = setsockopt(m->dns_ipv6_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
717 if (r < 0) {
718 r = -errno;
719 goto fail;
720 }
721
722 r = sd_event_add_io(m->event, &m->dns_ipv6_event_source, m->dns_ipv6_fd, EPOLLIN, on_dns_packet, m);
723 if (r < 0)
724 goto fail;
725
726 return m->dns_ipv6_fd;
727
728 fail:
729 m->dns_ipv6_fd = safe_close(m->dns_ipv6_fd);
730 return r;
731 }
732
733 static int sendmsg_loop(int fd, struct msghdr *mh, int flags) {
734 int r;
735
736 assert(fd >= 0);
737 assert(mh);
738
739 for (;;) {
740 if (sendmsg(fd, mh, flags) >= 0)
741 return 0;
742
743 if (errno == EINTR)
744 continue;
745
746 if (errno != EAGAIN)
747 return -errno;
748
749 r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
750 if (r < 0)
751 return r;
752 if (r == 0)
753 return -ETIMEDOUT;
754 }
755 }
756
757 static int manager_ipv4_send(Manager *m, int fd, int ifindex, struct in_addr *addr, uint16_t port, DnsPacket *p) {
758 union sockaddr_union sa = {
759 .in.sin_family = AF_INET,
760 };
761 union {
762 struct cmsghdr header; /* For alignment */
763 uint8_t buffer[CMSG_SPACE(sizeof(struct in_pktinfo))];
764 } control;
765 struct msghdr mh = {};
766 struct iovec iov;
767
768 assert(m);
769 assert(fd >= 0);
770 assert(addr);
771 assert(port > 0);
772 assert(p);
773
774 iov.iov_base = DNS_PACKET_DATA(p);
775 iov.iov_len = p->size;
776
777 sa.in.sin_addr = *addr;
778 sa.in.sin_port = htobe16(port),
779
780 mh.msg_iov = &iov;
781 mh.msg_iovlen = 1;
782 mh.msg_name = &sa.sa;
783 mh.msg_namelen = sizeof(sa.in);
784
785 if (ifindex > 0) {
786 struct cmsghdr *cmsg;
787 struct in_pktinfo *pi;
788
789 zero(control);
790
791 mh.msg_control = &control;
792 mh.msg_controllen = CMSG_LEN(sizeof(struct in_pktinfo));
793
794 cmsg = CMSG_FIRSTHDR(&mh);
795 cmsg->cmsg_len = mh.msg_controllen;
796 cmsg->cmsg_level = IPPROTO_IP;
797 cmsg->cmsg_type = IP_PKTINFO;
798
799 pi = (struct in_pktinfo*) CMSG_DATA(cmsg);
800 pi->ipi_ifindex = ifindex;
801 }
802
803 return sendmsg_loop(fd, &mh, 0);
804 }
805
806 static int manager_ipv6_send(Manager *m, int fd, int ifindex, struct in6_addr *addr, uint16_t port, DnsPacket *p) {
807 union sockaddr_union sa = {
808 .in6.sin6_family = AF_INET6,
809 };
810 union {
811 struct cmsghdr header; /* For alignment */
812 uint8_t buffer[CMSG_SPACE(sizeof(struct in6_pktinfo))];
813 } control;
814 struct msghdr mh = {};
815 struct iovec iov;
816
817 assert(m);
818 assert(fd >= 0);
819 assert(addr);
820 assert(port > 0);
821 assert(p);
822
823 iov.iov_base = DNS_PACKET_DATA(p);
824 iov.iov_len = p->size;
825
826 sa.in6.sin6_addr = *addr;
827 sa.in6.sin6_port = htobe16(port),
828 sa.in6.sin6_scope_id = ifindex;
829
830 mh.msg_iov = &iov;
831 mh.msg_iovlen = 1;
832 mh.msg_name = &sa.sa;
833 mh.msg_namelen = sizeof(sa.in6);
834
835 if (ifindex > 0) {
836 struct cmsghdr *cmsg;
837 struct in6_pktinfo *pi;
838
839 zero(control);
840
841 mh.msg_control = &control;
842 mh.msg_controllen = CMSG_LEN(sizeof(struct in6_pktinfo));
843
844 cmsg = CMSG_FIRSTHDR(&mh);
845 cmsg->cmsg_len = mh.msg_controllen;
846 cmsg->cmsg_level = IPPROTO_IPV6;
847 cmsg->cmsg_type = IPV6_PKTINFO;
848
849 pi = (struct in6_pktinfo*) CMSG_DATA(cmsg);
850 pi->ipi6_ifindex = ifindex;
851 }
852
853 return sendmsg_loop(fd, &mh, 0);
854 }
855
856 int manager_send(Manager *m, int fd, int ifindex, int family, union in_addr_union *addr, uint16_t port, DnsPacket *p) {
857 assert(m);
858 assert(fd >= 0);
859 assert(addr);
860 assert(port > 0);
861 assert(p);
862
863 if (family == AF_INET)
864 return manager_ipv4_send(m, fd, ifindex, &addr->in, port, p);
865 else if (family == AF_INET6)
866 return manager_ipv6_send(m, fd, ifindex, &addr->in6, port, p);
867
868 return -EAFNOSUPPORT;
869 }
870
871
872 DnsServer* manager_find_dns_server(Manager *m, int family, union in_addr_union *in_addr) {
873 DnsServer *s;
874
875 assert(m);
876 assert(in_addr);
877
878 LIST_FOREACH(servers, s, m->dns_servers) {
879
880 if (s->family == family &&
881 in_addr_equal(family, &s->address, in_addr))
882 return s;
883 }
884
885 return NULL;
886 }
887
888 DnsServer *manager_get_dns_server(Manager *m) {
889 assert(m);
890
891 if (!m->current_dns_server)
892 m->current_dns_server = m->dns_servers;
893
894 return m->current_dns_server;
895 }
896
897 void manager_next_dns_server(Manager *m) {
898 assert(m);
899
900 if (!m->current_dns_server) {
901 m->current_dns_server = m->dns_servers;
902 return;
903 }
904
905 if (!m->current_dns_server)
906 return;
907
908 if (m->current_dns_server->servers_next) {
909 m->current_dns_server = m->current_dns_server->servers_next;
910 return;
911 }
912
913 m->current_dns_server = m->dns_servers;
914 }
915
916 uint32_t manager_find_mtu(Manager *m) {
917 uint32_t mtu = 0;
918 Link *l;
919 Iterator i;
920
921 /* If we don't know on which link a DNS packet would be
922 * delivered, let's find the largest MTU that works on all
923 * interfaces we know of */
924
925 HASHMAP_FOREACH(l, m->links, i) {
926 if (l->mtu <= 0)
927 continue;
928
929 if (mtu <= 0 || l->mtu < mtu)
930 mtu = l->mtu;
931 }
932
933 return mtu;
934 }
935
936 static int on_llmnr_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
937 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
938 DnsQueryTransaction *t = NULL;
939 Manager *m = userdata;
940 int r;
941
942 r = manager_recv(m, fd, DNS_PROTOCOL_LLMNR, &p);
943 if (r <= 0)
944 return r;
945
946 if (dns_packet_validate_reply(p) >= 0) {
947 t = hashmap_get(m->dns_query_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
948 if (!t)
949 return 0;
950
951 dns_query_transaction_process_reply(t, p);
952 }
953
954 return 0;
955 }
956
957 int manager_llmnr_ipv4_udp_fd(Manager *m) {
958 union sockaddr_union sa = {
959 .in.sin_family = AF_INET,
960 .in.sin_port = htobe16(5355),
961 };
962 static const int one = 1, pmtu = IP_PMTUDISC_DONT;
963 int r;
964
965 assert(m);
966
967 if (m->llmnr_ipv4_udp_fd >= 0)
968 return m->llmnr_ipv4_udp_fd;
969
970 m->llmnr_ipv4_udp_fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
971 if (m->llmnr_ipv4_udp_fd < 0)
972 return -errno;
973
974 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_TTL, &one, sizeof(one));
975 if (r < 0) {
976 r = -errno;
977 goto fail;
978 }
979
980 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MULTICAST_TTL, &one, sizeof(one));
981 if (r < 0) {
982 r = -errno;
983 goto fail;
984 }
985
986 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MULTICAST_LOOP, &one, sizeof(one));
987 if (r < 0) {
988 r = -errno;
989 goto fail;
990 }
991
992 r = setsockopt(m->llmnr_ipv4_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
993 if (r < 0) {
994 r = -errno;
995 goto fail;
996 }
997
998 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
999 if (r < 0) {
1000 r = -errno;
1001 goto fail;
1002 }
1003
1004 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_RECVTTL, &one, sizeof(one));
1005 if (r < 0) {
1006 r = -errno;
1007 goto fail;
1008 }
1009
1010 /* Disable Don't-Fragment bit in the IP header */
1011 r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu));
1012 if (r < 0) {
1013 r = -errno;
1014 goto fail;
1015 }
1016
1017 r = bind(m->llmnr_ipv4_udp_fd, &sa.sa, sizeof(sa.in));
1018 if (r < 0) {
1019 r = -errno;
1020 goto fail;
1021 }
1022
1023 r = sd_event_add_io(m->event, &m->llmnr_ipv4_udp_event_source, m->llmnr_ipv4_udp_fd, EPOLLIN, on_llmnr_packet, m);
1024 if (r < 0)
1025 goto fail;
1026
1027 return m->llmnr_ipv4_udp_fd;
1028
1029 fail:
1030 m->llmnr_ipv4_udp_fd = safe_close(m->llmnr_ipv4_udp_fd);
1031 return r;
1032 }
1033
1034 int manager_llmnr_ipv6_udp_fd(Manager *m) {
1035 union sockaddr_union sa = {
1036 .in6.sin6_family = AF_INET6,
1037 .in6.sin6_port = htobe16(5355),
1038 };
1039 static const int one = 1;
1040 int r;
1041
1042 assert(m);
1043
1044 if (m->llmnr_ipv6_udp_fd >= 0)
1045 return m->llmnr_ipv6_udp_fd;
1046
1047 m->llmnr_ipv6_udp_fd = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1048 if (m->llmnr_ipv6_udp_fd < 0)
1049 return -errno;
1050
1051 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &one, sizeof(one));
1052 if (r < 0) {
1053 r = -errno;
1054 goto fail;
1055 }
1056
1057 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &one, sizeof(one));
1058 if (r < 0) {
1059 r = -errno;
1060 goto fail;
1061 }
1062
1063 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &one, sizeof(one));
1064 if (r < 0) {
1065 r = -errno;
1066 goto fail;
1067 }
1068
1069 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
1070 if (r < 0) {
1071 r = -errno;
1072 goto fail;
1073 }
1074
1075 r = setsockopt(m->llmnr_ipv6_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
1076 if (r < 0) {
1077 r = -errno;
1078 goto fail;
1079 }
1080
1081 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
1082 if (r < 0) {
1083 r = -errno;
1084 goto fail;
1085 }
1086
1087 r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &one, sizeof(one));
1088 if (r < 0) {
1089 r = -errno;
1090 goto fail;
1091 }
1092
1093 r = bind(m->llmnr_ipv6_udp_fd, &sa.sa, sizeof(sa.in6));
1094 if (r < 0) {
1095 r = -errno;
1096 goto fail;
1097 }
1098
1099 r = sd_event_add_io(m->event, &m->llmnr_ipv6_udp_event_source, m->llmnr_ipv6_udp_fd, EPOLLIN, on_llmnr_packet, m);
1100 if (r < 0) {
1101 r = -errno;
1102 goto fail;
1103 }
1104
1105 return m->llmnr_ipv6_udp_fd;
1106
1107 fail:
1108 m->llmnr_ipv6_udp_fd = safe_close(m->llmnr_ipv6_udp_fd);
1109 return r;
1110 }