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