chiark / gitweb /
barrier: fix race in test-code
[elogind.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 }