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