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