chiark / gitweb /
dns-domain: introduce macros for accessing all DNS header fields
[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 <linux/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         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
175 fail:
176         log_warning("Failed to process RTNL address message: %s", strerror(-r));
177         return 0;
178 }
179
180
181 static 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
257 static 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
280 static int manager_network_monitor_listen(Manager *m) {
281         int r, fd, events;
282
283         assert(m);
284
285         r = sd_network_monitor_new(NULL, &m->network_monitor);
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
304 static 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
338 int 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
375 int manager_parse_config_file(Manager *m) {
376         int r;
377
378         assert(m);
379
380         r = config_parse(NULL, "/etc/systemd/resolved.conf", NULL,
381                          "Resolve\0",
382                          config_item_perf_lookup, resolved_gperf_lookup,
383                          false, false, m);
384         if (r < 0)
385                 log_warning("Failed to parse configuration file: %s", strerror(-r));
386
387         return 0;
388 }
389
390 int manager_new(Manager **ret) {
391         _cleanup_(manager_freep) Manager *m = NULL;
392         int r;
393
394         assert(ret);
395
396         m = new0(Manager, 1);
397         if (!m)
398                 return -ENOMEM;
399
400         m->dns_ipv4_fd = m->dns_ipv6_fd = -1;
401
402         r = parse_dns_server_string(m, /* "172.31.0.125 2001:4860:4860::8888 2001:4860:4860::8889" */ DNS_SERVERS);
403         if (r < 0)
404                 return r;
405
406         r = sd_event_default(&m->event);
407         if (r < 0)
408                 return r;
409
410         sd_event_add_signal(m->event, NULL, SIGTERM, NULL,  NULL);
411         sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
412
413         sd_event_set_watchdog(m->event, true);
414
415         r = dns_scope_new(m, &m->unicast_scope, DNS_SCOPE_DNS);
416         if (r < 0)
417                 return r;
418
419         r = manager_network_monitor_listen(m);
420         if (r < 0)
421                 return r;
422
423         r = manager_rtnl_listen(m);
424         if (r < 0)
425                 return r;
426
427         r = manager_connect_bus(m);
428         if (r < 0)
429                 return r;
430
431         *ret = m;
432         m = NULL;
433
434         return 0;
435 }
436
437 Manager *manager_free(Manager *m) {
438         Link *l;
439
440         if (!m)
441                 return NULL;
442
443         while (m->dns_queries)
444                 dns_query_free(m->dns_queries);
445
446         hashmap_free(m->dns_query_transactions);
447
448         while ((l = hashmap_first(m->links)))
449                link_free(l);
450         hashmap_free(m->links);
451
452         dns_scope_free(m->unicast_scope);
453
454         while (m->dns_servers)
455                 dns_server_free(m->dns_servers);
456
457         sd_event_source_unref(m->network_event_source);
458         sd_network_monitor_unref(m->network_monitor);
459
460         sd_event_source_unref(m->dns_ipv4_event_source);
461         sd_event_source_unref(m->dns_ipv6_event_source);
462
463         safe_close(m->dns_ipv4_fd);
464         safe_close(m->dns_ipv6_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_dns_ipv4_recv(Manager *m, DnsPacket **ret) {
549         _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
550         struct msghdr mh = {};
551         int fd, ms = 0, r;
552         struct iovec iov;
553         ssize_t l;
554
555         assert(m);
556         assert(ret);
557
558         fd = manager_dns_ipv4_fd(m);
559         if (fd < 0)
560                 return fd;
561
562         r = ioctl(fd, FIONREAD, &ms);
563         if (r < 0)
564                 return -errno;
565         if (ms < 0)
566                 return -EIO;
567
568         r = dns_packet_new(&p, ms);
569         if (r < 0)
570                 return r;
571
572         iov.iov_base = DNS_PACKET_DATA(p);
573         iov.iov_len = p->allocated;
574
575         mh.msg_iov = &iov;
576         mh.msg_iovlen = 1;
577
578         l = recvmsg(fd, &mh, 0);
579         if (l < 0) {
580                 if (errno == EAGAIN)
581                         return 0;
582
583                 return -errno;
584         }
585
586         if (l <= 0)
587                 return -EIO;
588
589         p->size = (size_t) l;
590
591         *ret = p;
592         p = NULL;
593
594         return 1;
595 }
596
597 int manager_dns_ipv6_recv(Manager *m, DnsPacket **ret) {
598         _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
599         struct msghdr mh = {};
600         struct iovec iov;
601         int fd, ms = 0, r;
602         ssize_t l;
603
604         assert(m);
605         assert(ret);
606
607         fd = manager_dns_ipv6_fd(m);
608         if (fd < 0)
609                 return fd;
610
611         r = ioctl(fd, FIONREAD, &ms);
612         if (r < 0)
613                 return -errno;
614         if (ms < 0)
615                 return -EIO;
616
617         r = dns_packet_new(&p, ms);
618         if (r < 0)
619                 return r;
620
621         iov.iov_base = DNS_PACKET_DATA(p);
622         iov.iov_len = p->allocated;
623
624         mh.msg_iov = &iov;
625         mh.msg_iovlen = 1;
626
627         l = recvmsg(fd, &mh, 0);
628         if (l < 0) {
629                 if (errno == EAGAIN)
630                         return 0;
631
632                 return -errno;
633         }
634
635         if (l <= 0)
636                 return -EIO;
637
638         p->size = (size_t) l;
639
640         *ret = p;
641         p = NULL;
642
643         return 1;
644 }
645
646 static int on_dns_ipv4_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
647         _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
648         DnsQueryTransaction *t = NULL;
649         Manager *m = userdata;
650         int r;
651
652         r = manager_dns_ipv4_recv(m, &p);
653         if (r <= 0)
654                 return r;
655
656         t = hashmap_get(m->dns_query_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
657         if (!t)
658                 return 0;
659
660         return dns_query_transaction_reply(t, p);
661 }
662
663 static int on_dns_ipv6_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
664         _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
665         DnsQueryTransaction *t = NULL;
666         Manager *m = userdata;
667         int r;
668
669         r = manager_dns_ipv6_recv(m, &p);
670         if (r <= 0)
671                 return r;
672
673         t = hashmap_get(m->dns_query_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
674         if (!t)
675                 return 0;
676
677         return dns_query_transaction_reply(t, p);
678 }
679
680 int manager_dns_ipv4_fd(Manager *m) {
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 = sd_event_add_io(m->event, &m->dns_ipv4_event_source, m->dns_ipv4_fd, EPOLLIN, on_dns_ipv4_packet, m);
693         if (r < 0)
694                 return r;
695
696         return m->dns_ipv4_fd;
697 }
698
699 int manager_dns_ipv6_fd(Manager *m) {
700         int r;
701
702         assert(m);
703
704         if (m->dns_ipv6_fd >= 0)
705                 return m->dns_ipv6_fd;
706
707         m->dns_ipv6_fd = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
708         if (m->dns_ipv6_fd < 0)
709                 return -errno;
710
711         r = sd_event_add_io(m->event, &m->dns_ipv6_event_source, m->dns_ipv6_fd, EPOLLIN, on_dns_ipv6_packet, m);
712         if (r < 0)
713                 return r;
714
715         return m->dns_ipv6_fd;
716 }
717
718 static int sendmsg_loop(int fd, struct msghdr *mh, int flags) {
719         int r;
720
721         assert(fd >= 0);
722         assert(mh);
723
724         for (;;) {
725                 if (sendmsg(fd, mh, flags) >= 0)
726                         return 0;
727
728                 if (errno == EINTR)
729                         continue;
730
731                 if (errno != EAGAIN)
732                         return -errno;
733
734                 r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
735                 if (r < 0)
736                         return r;
737                 if (r == 0)
738                         return -ETIMEDOUT;
739         }
740 }
741
742 int manager_dns_ipv4_send(Manager *m, DnsServer *srv, int ifindex, DnsPacket *p) {
743         union sockaddr_union sa = {
744                 .in.sin_family = AF_INET,
745                 .in.sin_port = htobe16(53),
746         };
747         struct msghdr mh = {};
748         struct iovec iov;
749         uint8_t control[CMSG_SPACE(sizeof(struct in_pktinfo))];
750         int fd;
751
752         assert(m);
753         assert(srv);
754         assert(p);
755
756         fd = manager_dns_ipv4_fd(m);
757         if (fd < 0)
758                 return fd;
759
760         iov.iov_base = DNS_PACKET_DATA(p);
761         iov.iov_len = p->size;
762
763         sa.in.sin_addr = srv->address.in;
764
765         mh.msg_iov = &iov;
766         mh.msg_iovlen = 1;
767         mh.msg_name = &sa.sa;
768         mh.msg_namelen = sizeof(sa.in);
769
770         if (ifindex > 0) {
771                 struct cmsghdr *cmsg;
772                 struct in_pktinfo *pi;
773
774                 zero(control);
775
776                 mh.msg_control = control;
777                 mh.msg_controllen = CMSG_LEN(sizeof(struct in_pktinfo));
778
779                 cmsg = CMSG_FIRSTHDR(&mh);
780                 cmsg->cmsg_len = mh.msg_controllen;
781                 cmsg->cmsg_level = IPPROTO_IP;
782                 cmsg->cmsg_type = IP_PKTINFO;
783
784                 pi = (struct in_pktinfo*) CMSG_DATA(cmsg);
785                 pi->ipi_ifindex = ifindex;
786         }
787
788         return sendmsg_loop(fd, &mh, 0);
789 }
790
791 int manager_dns_ipv6_send(Manager *m, DnsServer *srv, int ifindex, DnsPacket *p) {
792         union sockaddr_union sa = {
793                 .in6.sin6_family = AF_INET6,
794                 .in6.sin6_port = htobe16(53),
795         };
796
797         struct msghdr mh = {};
798         struct iovec iov;
799         uint8_t control[CMSG_SPACE(sizeof(struct in6_pktinfo))];
800         int fd;
801
802         assert(m);
803         assert(srv);
804         assert(p);
805
806         fd = manager_dns_ipv6_fd(m);
807         if (fd < 0)
808                 return fd;
809
810         iov.iov_base = DNS_PACKET_DATA(p);
811         iov.iov_len = p->size;
812
813         sa.in6.sin6_addr = srv->address.in6;
814         sa.in6.sin6_scope_id = ifindex;
815
816         mh.msg_iov = &iov;
817         mh.msg_iovlen = 1;
818         mh.msg_name = &sa.sa;
819         mh.msg_namelen = sizeof(sa.in6);
820
821         if (ifindex > 0) {
822                 struct cmsghdr *cmsg;
823                 struct in6_pktinfo *pi;
824
825                 zero(control);
826
827                 mh.msg_control = control;
828                 mh.msg_controllen = CMSG_LEN(sizeof(struct in6_pktinfo));
829
830                 cmsg = CMSG_FIRSTHDR(&mh);
831                 cmsg->cmsg_len = mh.msg_controllen;
832                 cmsg->cmsg_level = IPPROTO_IPV6;
833                 cmsg->cmsg_type = IPV6_PKTINFO;
834
835                 pi = (struct in6_pktinfo*) CMSG_DATA(cmsg);
836                 pi->ipi6_ifindex = ifindex;
837         }
838
839         return sendmsg_loop(fd, &mh, 0);
840 }
841
842 DnsServer* manager_find_dns_server(Manager *m, unsigned char family, union in_addr_union *in_addr) {
843         DnsServer *s;
844
845         assert(m);
846         assert(in_addr);
847
848         LIST_FOREACH(servers, s, m->dns_servers) {
849
850                 if (s->family == family &&
851                     in_addr_equal(family, &s->address, in_addr))
852                         return s;
853         }
854
855         return NULL;
856 }
857
858 DnsServer *manager_get_dns_server(Manager *m) {
859         assert(m);
860
861         if (!m->current_dns_server)
862                 m->current_dns_server = m->dns_servers;
863
864         return m->current_dns_server;
865 }
866
867 void manager_next_dns_server(Manager *m) {
868         assert(m);
869
870         if (!m->current_dns_server) {
871                 m->current_dns_server = m->dns_servers;
872                 return;
873         }
874
875         if (!m->current_dns_server)
876                 return;
877
878         if (m->current_dns_server->servers_next) {
879                 m->current_dns_server = m->current_dns_server->servers_next;
880                 return;
881         }
882
883         m->current_dns_server = m->dns_servers;
884 }