chiark / gitweb /
resolved: support for TCP DNS queries
[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 || errno == EINTR)
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 || errno == EINTR)
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         dns_query_transaction_reply(t, p);
661         return 0;
662 }
663
664 static int on_dns_ipv6_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
665         _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
666         DnsQueryTransaction *t = NULL;
667         Manager *m = userdata;
668         int r;
669
670         r = manager_dns_ipv6_recv(m, &p);
671         if (r <= 0)
672                 return r;
673
674         t = hashmap_get(m->dns_query_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
675         if (!t)
676                 return 0;
677
678         dns_query_transaction_reply(t, p);
679         return 0;
680 }
681
682 int manager_dns_ipv4_fd(Manager *m) {
683         int r;
684
685         assert(m);
686
687         if (m->dns_ipv4_fd >= 0)
688                 return m->dns_ipv4_fd;
689
690         m->dns_ipv4_fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
691         if (m->dns_ipv4_fd < 0)
692                 return -errno;
693
694         r = sd_event_add_io(m->event, &m->dns_ipv4_event_source, m->dns_ipv4_fd, EPOLLIN, on_dns_ipv4_packet, m);
695         if (r < 0)
696                 return r;
697
698         return m->dns_ipv4_fd;
699 }
700
701 int manager_dns_ipv6_fd(Manager *m) {
702         int r;
703
704         assert(m);
705
706         if (m->dns_ipv6_fd >= 0)
707                 return m->dns_ipv6_fd;
708
709         m->dns_ipv6_fd = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
710         if (m->dns_ipv6_fd < 0)
711                 return -errno;
712
713         r = sd_event_add_io(m->event, &m->dns_ipv6_event_source, m->dns_ipv6_fd, EPOLLIN, on_dns_ipv6_packet, m);
714         if (r < 0)
715                 return r;
716
717         return m->dns_ipv6_fd;
718 }
719
720 static int sendmsg_loop(int fd, struct msghdr *mh, int flags) {
721         int r;
722
723         assert(fd >= 0);
724         assert(mh);
725
726         for (;;) {
727                 if (sendmsg(fd, mh, flags) >= 0)
728                         return 0;
729
730                 if (errno == EINTR)
731                         continue;
732
733                 if (errno != EAGAIN)
734                         return -errno;
735
736                 r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC);
737                 if (r < 0)
738                         return r;
739                 if (r == 0)
740                         return -ETIMEDOUT;
741         }
742 }
743
744 int manager_dns_ipv4_send(Manager *m, DnsServer *srv, int ifindex, DnsPacket *p) {
745         union sockaddr_union sa = {
746                 .in.sin_family = AF_INET,
747                 .in.sin_port = htobe16(53),
748         };
749         struct msghdr mh = {};
750         struct iovec iov;
751         uint8_t control[CMSG_SPACE(sizeof(struct in_pktinfo))];
752         int fd;
753
754         assert(m);
755         assert(srv);
756         assert(p);
757
758         fd = manager_dns_ipv4_fd(m);
759         if (fd < 0)
760                 return fd;
761
762         iov.iov_base = DNS_PACKET_DATA(p);
763         iov.iov_len = p->size;
764
765         sa.in.sin_addr = srv->address.in;
766
767         mh.msg_iov = &iov;
768         mh.msg_iovlen = 1;
769         mh.msg_name = &sa.sa;
770         mh.msg_namelen = sizeof(sa.in);
771
772         if (ifindex > 0) {
773                 struct cmsghdr *cmsg;
774                 struct in_pktinfo *pi;
775
776                 zero(control);
777
778                 mh.msg_control = control;
779                 mh.msg_controllen = CMSG_LEN(sizeof(struct in_pktinfo));
780
781                 cmsg = CMSG_FIRSTHDR(&mh);
782                 cmsg->cmsg_len = mh.msg_controllen;
783                 cmsg->cmsg_level = IPPROTO_IP;
784                 cmsg->cmsg_type = IP_PKTINFO;
785
786                 pi = (struct in_pktinfo*) CMSG_DATA(cmsg);
787                 pi->ipi_ifindex = ifindex;
788         }
789
790         return sendmsg_loop(fd, &mh, 0);
791 }
792
793 int manager_dns_ipv6_send(Manager *m, DnsServer *srv, int ifindex, DnsPacket *p) {
794         union sockaddr_union sa = {
795                 .in6.sin6_family = AF_INET6,
796                 .in6.sin6_port = htobe16(53),
797         };
798
799         struct msghdr mh = {};
800         struct iovec iov;
801         uint8_t control[CMSG_SPACE(sizeof(struct in6_pktinfo))];
802         int fd;
803
804         assert(m);
805         assert(srv);
806         assert(p);
807
808         fd = manager_dns_ipv6_fd(m);
809         if (fd < 0)
810                 return fd;
811
812         iov.iov_base = DNS_PACKET_DATA(p);
813         iov.iov_len = p->size;
814
815         sa.in6.sin6_addr = srv->address.in6;
816         sa.in6.sin6_scope_id = ifindex;
817
818         mh.msg_iov = &iov;
819         mh.msg_iovlen = 1;
820         mh.msg_name = &sa.sa;
821         mh.msg_namelen = sizeof(sa.in6);
822
823         if (ifindex > 0) {
824                 struct cmsghdr *cmsg;
825                 struct in6_pktinfo *pi;
826
827                 zero(control);
828
829                 mh.msg_control = control;
830                 mh.msg_controllen = CMSG_LEN(sizeof(struct in6_pktinfo));
831
832                 cmsg = CMSG_FIRSTHDR(&mh);
833                 cmsg->cmsg_len = mh.msg_controllen;
834                 cmsg->cmsg_level = IPPROTO_IPV6;
835                 cmsg->cmsg_type = IPV6_PKTINFO;
836
837                 pi = (struct in6_pktinfo*) CMSG_DATA(cmsg);
838                 pi->ipi6_ifindex = ifindex;
839         }
840
841         return sendmsg_loop(fd, &mh, 0);
842 }
843
844 DnsServer* manager_find_dns_server(Manager *m, unsigned char family, union in_addr_union *in_addr) {
845         DnsServer *s;
846
847         assert(m);
848         assert(in_addr);
849
850         LIST_FOREACH(servers, s, m->dns_servers) {
851
852                 if (s->family == family &&
853                     in_addr_equal(family, &s->address, in_addr))
854                         return s;
855         }
856
857         return NULL;
858 }
859
860 DnsServer *manager_get_dns_server(Manager *m) {
861         assert(m);
862
863         if (!m->current_dns_server)
864                 m->current_dns_server = m->dns_servers;
865
866         return m->current_dns_server;
867 }
868
869 void manager_next_dns_server(Manager *m) {
870         assert(m);
871
872         if (!m->current_dns_server) {
873                 m->current_dns_server = m->dns_servers;
874                 return;
875         }
876
877         if (!m->current_dns_server)
878                 return;
879
880         if (m->current_dns_server->servers_next) {
881                 m->current_dns_server = m->current_dns_server->servers_next;
882                 return;
883         }
884
885         m->current_dns_server = m->dns_servers;
886 }