source: src/router/dnsmasq/src/network.c @ 31703

Last change on this file since 31703 was 31703, checked in by brainslayer, 11 days ago

latest dnsmasq

File size: 43.2 KB
Line 
1/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
2
3   This program is free software; you can redistribute it and/or modify
4   it under the terms of the GNU General Public License as published by
5   the Free Software Foundation; version 2 dated June, 1991, or
6   (at your option) version 3 dated 29 June, 2007.
7 
8   This program is distributed in the hope that it will be useful,
9   but WITHOUT ANY WARRANTY; without even the implied warranty of
10   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11   GNU General Public License for more details.
12     
13   You should have received a copy of the GNU General Public License
14   along with this program.  If not, see <http://www.gnu.org/licenses/>.
15*/
16
17#include "dnsmasq.h"
18
19#ifdef HAVE_LINUX_NETWORK
20
21int indextoname(int fd, int index, char *name)
22{
23  struct ifreq ifr;
24 
25  if (index == 0)
26    return 0;
27
28  ifr.ifr_ifindex = index;
29  if (ioctl(fd, SIOCGIFNAME, &ifr) == -1)
30    return 0;
31
32  strncpy(name, ifr.ifr_name, IF_NAMESIZE);
33
34  return 1;
35}
36
37
38#elif defined(HAVE_SOLARIS_NETWORK)
39
40#include <zone.h>
41#include <alloca.h>
42#ifndef LIFC_UNDER_IPMP
43#  define LIFC_UNDER_IPMP 0
44#endif
45
46int indextoname(int fd, int index, char *name)
47{
48  int64_t lifc_flags;
49  struct lifnum lifn;
50  int numifs, bufsize, i;
51  struct lifconf lifc;
52  struct lifreq *lifrp;
53 
54  if (index == 0)
55    return 0;
56 
57  if (getzoneid() == GLOBAL_ZONEID)
58    {
59      if (!if_indextoname(index, name))
60        return 0;
61      return 1;
62    }
63 
64  lifc_flags = LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES | LIFC_UNDER_IPMP;
65  lifn.lifn_family = AF_UNSPEC;
66  lifn.lifn_flags = lifc_flags;
67  if (ioctl(fd, SIOCGLIFNUM, &lifn) < 0)
68    return 0;
69 
70  numifs = lifn.lifn_count;
71  bufsize = numifs * sizeof(struct lifreq);
72 
73  lifc.lifc_family = AF_UNSPEC;
74  lifc.lifc_flags = lifc_flags;
75  lifc.lifc_len = bufsize;
76  lifc.lifc_buf = alloca(bufsize);
77 
78  if (ioctl(fd, SIOCGLIFCONF, &lifc) < 0) 
79    return 0;
80 
81  lifrp = lifc.lifc_req;
82  for (i = lifc.lifc_len / sizeof(struct lifreq); i; i--, lifrp++)
83    {
84      struct lifreq lifr;
85      strncpy(lifr.lifr_name, lifrp->lifr_name, IF_NAMESIZE);
86      if (ioctl(fd, SIOCGLIFINDEX, &lifr) < 0)
87        return 0;
88     
89      if (lifr.lifr_index == index) {
90        strncpy(name, lifr.lifr_name, IF_NAMESIZE);
91        return 1;
92      }
93    }
94  return 0;
95}
96
97
98#else
99
100int indextoname(int fd, int index, char *name)
101{
102  (void)fd;
103
104  if (index == 0 || !if_indextoname(index, name))
105    return 0;
106
107  return 1;
108}
109
110#endif
111
112int iface_check(int family, struct all_addr *addr, char *name, int *auth)
113{
114  struct iname *tmp;
115  int ret = 1, match_addr = 0;
116
117  /* Note: have to check all and not bail out early, so that we set the
118     "used" flags.
119
120     May be called with family == AF_LOCALto check interface by name only. */
121 
122  if (auth)
123    *auth = 0;
124 
125  if (daemon->if_names || daemon->if_addrs)
126    {
127      ret = 0;
128
129      for (tmp = daemon->if_names; tmp; tmp = tmp->next)
130        if (tmp->name && wildcard_match(tmp->name, name))
131          ret = tmp->used = 1;
132               
133      if (addr)
134        for (tmp = daemon->if_addrs; tmp; tmp = tmp->next)
135          if (tmp->addr.sa.sa_family == family)
136            {
137              if (family == AF_INET &&
138                  tmp->addr.in.sin_addr.s_addr == addr->addr.addr4.s_addr)
139                ret = match_addr = tmp->used = 1;
140#ifdef HAVE_IPV6
141              else if (family == AF_INET6 &&
142                       IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr,
143                                          &addr->addr.addr6))
144                ret = match_addr = tmp->used = 1;
145#endif
146            }         
147    }
148 
149  if (!match_addr)
150    for (tmp = daemon->if_except; tmp; tmp = tmp->next)
151      if (tmp->name && wildcard_match(tmp->name, name))
152        ret = 0;
153   
154
155  for (tmp = daemon->authinterface; tmp; tmp = tmp->next)
156    if (tmp->name)
157      {
158        if (strcmp(tmp->name, name) == 0 &&
159            (tmp->addr.sa.sa_family == 0 || tmp->addr.sa.sa_family == family))
160          break;
161      }
162    else if (addr && tmp->addr.sa.sa_family == AF_INET && family == AF_INET &&
163             tmp->addr.in.sin_addr.s_addr == addr->addr.addr4.s_addr)
164      break;
165#ifdef HAVE_IPV6
166    else if (addr && tmp->addr.sa.sa_family == AF_INET6 && family == AF_INET6 &&
167             IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr, &addr->addr.addr6))
168      break;
169#endif     
170
171  if (tmp && auth)
172    {
173      *auth = 1;
174      ret = 1;
175    }
176
177  return ret;
178}
179
180
181/* Fix for problem that the kernel sometimes reports the loopback interface as the
182   arrival interface when a packet originates locally, even when sent to address of
183   an interface other than the loopback. Accept packet if it arrived via a loopback
184   interface, even when we're not accepting packets that way, as long as the destination
185   address is one we're believing. Interface list must be up-to-date before calling. */
186int loopback_exception(int fd, int family, struct all_addr *addr, char *name)   
187{
188  struct ifreq ifr;
189  struct irec *iface;
190
191  strncpy(ifr.ifr_name, name, IF_NAMESIZE);
192  if (ioctl(fd, SIOCGIFFLAGS, &ifr) != -1 &&
193      ifr.ifr_flags & IFF_LOOPBACK)
194    {
195      for (iface = daemon->interfaces; iface; iface = iface->next)
196        if (iface->addr.sa.sa_family == family)
197          {
198            if (family == AF_INET)
199              {
200                if (iface->addr.in.sin_addr.s_addr == addr->addr.addr4.s_addr)
201                  return 1;
202              }
203#ifdef HAVE_IPV6
204            else if (IN6_ARE_ADDR_EQUAL(&iface->addr.in6.sin6_addr, &addr->addr.addr6))
205              return 1;
206#endif
207           
208          }
209    }
210  return 0;
211}
212
213/* If we're configured with something like --interface=eth0:0 then we'll listen correctly
214   on the relevant address, but the name of the arrival interface, derived from the
215   index won't match the config. Check that we found an interface address for the arrival
216   interface: daemon->interfaces must be up-to-date. */
217int label_exception(int index, int family, struct all_addr *addr)
218{
219  struct irec *iface;
220
221  /* labels only supported on IPv4 addresses. */
222  if (family != AF_INET)
223    return 0;
224
225  for (iface = daemon->interfaces; iface; iface = iface->next)
226    if (iface->index == index && iface->addr.sa.sa_family == AF_INET &&
227        iface->addr.in.sin_addr.s_addr == addr->addr.addr4.s_addr)
228      return 1;
229
230  return 0;
231}
232
233struct iface_param {
234  struct addrlist *spare;
235  int fd;
236};
237
238static int iface_allowed(struct iface_param *param, int if_index, char *label,
239                         union mysockaddr *addr, struct in_addr netmask, int prefixlen, int iface_flags)
240{
241  struct irec *iface;
242  int mtu = 0, loopback;
243  struct ifreq ifr;
244  int tftp_ok = !!option_bool(OPT_TFTP);
245  int dhcp_ok = 1;
246  int auth_dns = 0;
247  int is_label = 0;
248#if defined(HAVE_DHCP) || defined(HAVE_TFTP)
249  struct iname *tmp;
250#endif
251
252  (void)prefixlen;
253
254  if (!indextoname(param->fd, if_index, ifr.ifr_name) ||
255      ioctl(param->fd, SIOCGIFFLAGS, &ifr) == -1)
256    return 0;
257   
258  loopback = ifr.ifr_flags & IFF_LOOPBACK;
259 
260  if (loopback)
261    dhcp_ok = 0;
262 
263  if (ioctl(param->fd, SIOCGIFMTU, &ifr) != -1)
264    mtu = ifr.ifr_mtu;
265 
266  if (!label)
267    label = ifr.ifr_name;
268  else
269    is_label = strcmp(label, ifr.ifr_name);
270 
271  /* maintain a list of all addresses on all interfaces for --local-service option */
272  if (option_bool(OPT_LOCAL_SERVICE))
273    {
274      struct addrlist *al;
275
276      if (param->spare)
277        {
278          al = param->spare;
279          param->spare = al->next;
280        }
281      else
282        al = whine_malloc(sizeof(struct addrlist));
283     
284      if (al)
285        {
286          al->next = daemon->interface_addrs;
287          daemon->interface_addrs = al;
288          al->prefixlen = prefixlen;
289         
290          if (addr->sa.sa_family == AF_INET)
291            {
292              al->addr.addr.addr4 = addr->in.sin_addr;
293              al->flags = 0;
294            }
295#ifdef HAVE_IPV6
296          else
297            {
298              al->addr.addr.addr6 = addr->in6.sin6_addr;
299              al->flags = ADDRLIST_IPV6;
300            }
301#endif
302        }
303    }
304 
305#ifdef HAVE_IPV6
306  if (addr->sa.sa_family != AF_INET6 || !IN6_IS_ADDR_LINKLOCAL(&addr->in6.sin6_addr))
307#endif
308    {
309      struct interface_name *int_name;
310      struct addrlist *al;
311#ifdef HAVE_AUTH
312      struct auth_zone *zone;
313      struct auth_name_list *name;
314
315      /* Find subnets in auth_zones */
316      for (zone = daemon->auth_zones; zone; zone = zone->next)
317        for (name = zone->interface_names; name; name = name->next)
318          if (wildcard_match(name->name, label))
319            {
320              if (addr->sa.sa_family == AF_INET && (name->flags & AUTH4))
321                {
322                  if (param->spare)
323                    {
324                      al = param->spare;
325                      param->spare = al->next;
326                    }
327                  else
328                    al = whine_malloc(sizeof(struct addrlist));
329                 
330                  if (al)
331                    {
332                      al->next = zone->subnet;
333                      zone->subnet = al;
334                      al->prefixlen = prefixlen;
335                      al->addr.addr.addr4 = addr->in.sin_addr;
336                      al->flags = 0;
337                    }
338                }
339             
340#ifdef HAVE_IPV6
341              if (addr->sa.sa_family == AF_INET6 && (name->flags & AUTH6))
342                {
343                  if (param->spare)
344                    {
345                      al = param->spare;
346                      param->spare = al->next;
347                    }
348                  else
349                    al = whine_malloc(sizeof(struct addrlist));
350                 
351                  if (al)
352                    {
353                      al->next = zone->subnet;
354                      zone->subnet = al;
355                      al->prefixlen = prefixlen;
356                      al->addr.addr.addr6 = addr->in6.sin6_addr;
357                      al->flags = ADDRLIST_IPV6;
358                    }
359                }
360#endif
361             
362            }
363#endif
364       
365      /* Update addresses from interface_names. These are a set independent
366         of the set we're listening on. */ 
367      for (int_name = daemon->int_names; int_name; int_name = int_name->next)
368        if (strncmp(label, int_name->intr, IF_NAMESIZE) == 0 &&
369            (addr->sa.sa_family == int_name->family || int_name->family == 0))
370          {
371            if (param->spare)
372              {
373                al = param->spare;
374                param->spare = al->next;
375              }
376            else
377              al = whine_malloc(sizeof(struct addrlist));
378           
379            if (al)
380              {
381                al->next = int_name->addr;
382                int_name->addr = al;
383               
384                if (addr->sa.sa_family == AF_INET)
385                  {
386                    al->addr.addr.addr4 = addr->in.sin_addr;
387                    al->flags = 0;
388                  }
389#ifdef HAVE_IPV6
390                else
391                 {
392                    al->addr.addr.addr6 = addr->in6.sin6_addr;
393                    al->flags = ADDRLIST_IPV6;
394                    /* Privacy addresses and addresses still undergoing DAD and deprecated addresses
395                       don't appear in forward queries, but will in reverse ones. */
396                    if (!(iface_flags & IFACE_PERMANENT) || (iface_flags & (IFACE_DEPRECATED | IFACE_TENTATIVE)))
397                      al->flags |= ADDRLIST_REVONLY;
398                 }
399#endif
400              }
401          }
402    }
403 
404  /* check whether the interface IP has been added already
405     we call this routine multiple times. */
406  for (iface = daemon->interfaces; iface; iface = iface->next)
407    if (sockaddr_isequal(&iface->addr, addr))
408      {
409        iface->dad = !!(iface_flags & IFACE_TENTATIVE);
410        iface->found = 1; /* for garbage collection */
411        return 1;
412      }
413
414 /* If we are restricting the set of interfaces to use, make
415     sure that loopback interfaces are in that set. */
416  if (daemon->if_names && loopback)
417    {
418      struct iname *lo;
419      for (lo = daemon->if_names; lo; lo = lo->next)
420        if (lo->name && strcmp(lo->name, ifr.ifr_name) == 0)
421          break;
422     
423      if (!lo && (lo = whine_malloc(sizeof(struct iname))))
424        {
425          if ((lo->name = whine_malloc(strlen(ifr.ifr_name)+1)))
426            {
427              strcpy(lo->name, ifr.ifr_name);
428              lo->used = 1;
429              lo->next = daemon->if_names;
430              daemon->if_names = lo;
431            }
432          else
433            free(lo);
434        }
435    }
436 
437  if (addr->sa.sa_family == AF_INET &&
438      !iface_check(AF_INET, (struct all_addr *)&addr->in.sin_addr, label, &auth_dns))
439    return 1;
440
441#ifdef HAVE_IPV6
442  if (addr->sa.sa_family == AF_INET6 &&
443      !iface_check(AF_INET6, (struct all_addr *)&addr->in6.sin6_addr, label, &auth_dns))
444    return 1;
445#endif
446   
447#ifdef HAVE_DHCP
448  /* No DHCP where we're doing auth DNS. */
449  if (auth_dns)
450    {
451      tftp_ok = 0;
452      dhcp_ok = 0;
453    }
454  else
455    for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
456      if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
457        {
458          tftp_ok = 0;
459          dhcp_ok = 0;
460        }
461#endif
462 
463 
464#ifdef HAVE_TFTP
465  if (daemon->tftp_interfaces)
466    {
467      /* dedicated tftp interface list */
468      tftp_ok = 0;
469      for (tmp = daemon->tftp_interfaces; tmp; tmp = tmp->next)
470        if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
471          tftp_ok = 1;
472    }
473#endif
474 
475  /* add to list */
476  if ((iface = whine_malloc(sizeof(struct irec))))
477    {
478      iface->addr = *addr;
479      iface->netmask = netmask;
480      iface->tftp_ok = tftp_ok;
481      iface->dhcp_ok = dhcp_ok;
482      iface->dns_auth = auth_dns;
483      iface->mtu = mtu;
484      iface->dad = !!(iface_flags & IFACE_TENTATIVE);
485      iface->found = 1;
486      iface->done = iface->multicast_done = iface->warned = 0;
487      iface->index = if_index;
488      iface->label = is_label;
489      if ((iface->name = whine_malloc(strlen(ifr.ifr_name)+1)))
490        {
491          strcpy(iface->name, ifr.ifr_name);
492          iface->next = daemon->interfaces;
493          daemon->interfaces = iface;
494          return 1;
495        }
496      free(iface);
497
498    }
499 
500  errno = ENOMEM;
501  return 0;
502}
503
504#ifdef HAVE_IPV6
505static int iface_allowed_v6(struct in6_addr *local, int prefix,
506                            int scope, int if_index, int flags,
507                            int preferred, int valid, void *vparam)
508{
509  union mysockaddr addr;
510  struct in_addr netmask; /* dummy */
511  netmask.s_addr = 0;
512
513  (void)scope; /* warning */
514  (void)preferred;
515  (void)valid;
516 
517  memset(&addr, 0, sizeof(addr));
518#ifdef HAVE_SOCKADDR_SA_LEN
519  addr.in6.sin6_len = sizeof(addr.in6);
520#endif
521  addr.in6.sin6_family = AF_INET6;
522  addr.in6.sin6_addr = *local;
523  addr.in6.sin6_port = htons(daemon->port);
524  /* FreeBSD insists this is zero for non-linklocal addresses */
525  if (IN6_IS_ADDR_LINKLOCAL(local))
526    addr.in6.sin6_scope_id = if_index;
527  else
528    addr.in6.sin6_scope_id = 0;
529 
530  return iface_allowed((struct iface_param *)vparam, if_index, NULL, &addr, netmask, prefix, flags);
531}
532#endif
533
534static int iface_allowed_v4(struct in_addr local, int if_index, char *label,
535                            struct in_addr netmask, struct in_addr broadcast, void *vparam)
536{
537  union mysockaddr addr;
538  int prefix, bit;
539 
540  (void)broadcast; /* warning */
541
542  memset(&addr, 0, sizeof(addr));
543#ifdef HAVE_SOCKADDR_SA_LEN
544  addr.in.sin_len = sizeof(addr.in);
545#endif
546  addr.in.sin_family = AF_INET;
547  addr.in.sin_addr = local;
548  addr.in.sin_port = htons(daemon->port);
549
550  /* determine prefix length from netmask */
551  for (prefix = 32, bit = 1; (bit & ntohl(netmask.s_addr)) == 0 && prefix != 0; bit = bit << 1, prefix--);
552
553  return iface_allowed((struct iface_param *)vparam, if_index, label, &addr, netmask, prefix, 0);
554}
555   
556int enumerate_interfaces(int reset)
557{
558  static struct addrlist *spare = NULL;
559  static int done = 0;
560  struct iface_param param;
561  int errsave, ret = 1;
562  struct addrlist *addr, *tmp;
563  struct interface_name *intname;
564  struct irec *iface;
565#ifdef HAVE_AUTH
566  struct auth_zone *zone;
567#endif
568
569  /* Do this max once per select cycle  - also inhibits netlink socket use
570   in TCP child processes. */
571
572  if (reset)
573    {
574      done = 0;
575      return 1;
576    }
577
578  if (done)
579    return 1;
580
581  done = 1;
582
583  if ((param.fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
584    return 0;
585 
586  /* Mark interfaces for garbage collection */
587  for (iface = daemon->interfaces; iface; iface = iface->next)
588    iface->found = 0;
589
590  /* remove addresses stored against interface_names */
591  for (intname = daemon->int_names; intname; intname = intname->next)
592    {
593      for (addr = intname->addr; addr; addr = tmp)
594        {
595          tmp = addr->next;
596          addr->next = spare;
597          spare = addr;
598        }
599     
600      intname->addr = NULL;
601    }
602
603  /* Remove list of addresses of local interfaces */
604  for (addr = daemon->interface_addrs; addr; addr = tmp)
605    {
606      tmp = addr->next;
607      addr->next = spare;
608      spare = addr;
609    }
610  daemon->interface_addrs = NULL;
611 
612#ifdef HAVE_AUTH
613  /* remove addresses stored against auth_zone subnets, but not
614   ones configured as address literals */
615  for (zone = daemon->auth_zones; zone; zone = zone->next)
616    if (zone->interface_names)
617      {
618        struct addrlist **up;
619        for (up = &zone->subnet, addr = zone->subnet; addr; addr = tmp)
620          {
621            tmp = addr->next;
622            if (addr->flags & ADDRLIST_LITERAL)
623              up = &addr->next;
624            else
625              {
626                *up = addr->next;
627                addr->next = spare;
628                spare = addr;
629              }
630          }
631      }
632#endif
633
634  param.spare = spare;
635 
636#ifdef HAVE_IPV6
637  ret = iface_enumerate(AF_INET6, &param, iface_allowed_v6);
638#endif
639
640  if (ret)
641    ret = iface_enumerate(AF_INET, &param, iface_allowed_v4);
642 
643  errsave = errno;
644  close(param.fd);
645 
646  if (option_bool(OPT_CLEVERBIND))
647    {
648      /* Garbage-collect listeners listening on addresses that no longer exist.
649         Does nothing when not binding interfaces or for listeners on localhost,
650         since the ->iface field is NULL. Note that this needs the protections
651         against reentrancy, hence it's here.  It also means there's a possibility,
652         in OPT_CLEVERBIND mode, that at listener will just disappear after
653         a call to enumerate_interfaces, this is checked OK on all calls. */
654      struct listener *l, *tmp, **up;
655     
656      for (up = &daemon->listeners, l = daemon->listeners; l; l = tmp)
657        {
658          tmp = l->next;
659         
660          if (!l->iface || l->iface->found)
661            up = &l->next;
662          else
663            {
664              *up = l->next;
665             
666              /* In case it ever returns */
667              l->iface->done = 0;
668             
669              if (l->fd != -1)
670                close(l->fd);
671              if (l->tcpfd != -1)
672                close(l->tcpfd);
673              if (l->tftpfd != -1)
674                close(l->tftpfd);
675             
676              free(l);
677            }
678        }
679    }
680 
681  errno = errsave;
682  spare = param.spare;
683   
684  return ret;
685}
686
687/* set NONBLOCK bit on fd: See Stevens 16.6 */
688int fix_fd(int fd)
689{
690  int flags;
691
692  if ((flags = fcntl(fd, F_GETFL)) == -1 ||
693      fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1)
694    return 0;
695 
696  return 1;
697}
698
699static int make_sock(union mysockaddr *addr, int type, int dienow)
700{
701  int family = addr->sa.sa_family;
702  int fd, rc, opt = 1;
703 
704  if ((fd = socket(family, type, 0)) == -1)
705    {
706      int port, errsave;
707      char *s;
708
709      /* No error if the kernel just doesn't support this IP flavour */
710      if (errno == EPROTONOSUPPORT ||
711          errno == EAFNOSUPPORT ||
712          errno == EINVAL)
713        return -1;
714     
715    err:
716      errsave = errno;
717      port = prettyprint_addr(addr, daemon->addrbuff);
718      if (!option_bool(OPT_NOWILD) && !option_bool(OPT_CLEVERBIND))
719        sprintf(daemon->addrbuff, "port %d", port);
720      s = _("failed to create listening socket for %s: %s");
721     
722      if (fd != -1)
723        close (fd);
724       
725      errno = errsave;
726
727      if (dienow)
728        {
729          /* failure to bind addresses given by --listen-address at this point
730             is OK if we're doing bind-dynamic */
731          if (!option_bool(OPT_CLEVERBIND))
732            die(s, daemon->addrbuff, EC_BADNET);
733        }
734      else
735        my_syslog(LOG_WARNING, s, daemon->addrbuff, strerror(errno));
736     
737      return -1;
738    }   
739 
740  if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1 || !fix_fd(fd))
741    goto err;
742 
743#ifdef HAVE_IPV6
744  if (family == AF_INET6 && setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt)) == -1)
745    goto err;
746#endif
747 
748  if ((rc = bind(fd, (struct sockaddr *)addr, sa_len(addr))) == -1)
749    goto err;
750 
751  if (type == SOCK_STREAM)
752    {
753      if (listen(fd, TCP_BACKLOG) == -1)
754        goto err;
755    }
756  else if (family == AF_INET)
757    {
758      if (!option_bool(OPT_NOWILD))
759        {
760#if defined(HAVE_LINUX_NETWORK)
761          if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &opt, sizeof(opt)) == -1)
762            goto err;
763#elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
764          if (setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &opt, sizeof(opt)) == -1 ||
765              setsockopt(fd, IPPROTO_IP, IP_RECVIF, &opt, sizeof(opt)) == -1)
766            goto err;
767#endif
768        }
769    }
770#ifdef HAVE_IPV6
771  else if (!set_ipv6pktinfo(fd))
772    goto err;
773#endif
774 
775  return fd;
776}
777
778#ifdef HAVE_IPV6 
779int set_ipv6pktinfo(int fd)
780{
781  int opt = 1;
782
783  /* The API changed around Linux 2.6.14 but the old ABI is still supported:
784     handle all combinations of headers and kernel.
785     OpenWrt note that this fixes the problem addressed by your very broken patch. */
786  daemon->v6pktinfo = IPV6_PKTINFO;
787 
788#ifdef IPV6_RECVPKTINFO
789  if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &opt, sizeof(opt)) != -1)
790    return 1;
791# ifdef IPV6_2292PKTINFO
792  else if (errno == ENOPROTOOPT && setsockopt(fd, IPPROTO_IPV6, IPV6_2292PKTINFO, &opt, sizeof(opt)) != -1)
793    {
794      daemon->v6pktinfo = IPV6_2292PKTINFO;
795      return 1;
796    }
797# endif
798#else
799  if (setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, &opt, sizeof(opt)) != -1)
800    return 1;
801#endif
802
803  return 0;
804}
805#endif
806
807
808/* Find the interface on which a TCP connection arrived, if possible, or zero otherwise. */
809int tcp_interface(int fd, int af)
810{
811  int if_index = 0;
812
813#ifdef HAVE_LINUX_NETWORK
814  int opt = 1;
815  struct cmsghdr *cmptr;
816  struct msghdr msg;
817  socklen_t len;
818 
819  /* use mshdr so that the CMSDG_* macros are available */
820  msg.msg_control = daemon->packet;
821  msg.msg_controllen = len = daemon->packet_buff_sz;
822 
823  /* we overwrote the buffer... */
824  daemon->srv_save = NULL;
825 
826  if (af == AF_INET)
827    {
828      if (setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &opt, sizeof(opt)) != -1 &&
829          getsockopt(fd, IPPROTO_IP, IP_PKTOPTIONS, msg.msg_control, &len) != -1)
830        {
831          msg.msg_controllen = len;
832          for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
833            if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
834              {
835                union {
836                  unsigned char *c;
837                  struct in_pktinfo *p;
838                } p;
839               
840                p.c = CMSG_DATA(cmptr);
841                if_index = p.p->ipi_ifindex;
842              }
843        }
844    }
845#ifdef HAVE_IPV6
846  else
847    {
848      /* Only the RFC-2292 API has the ability to find the interface for TCP connections,
849         it was removed in RFC-3542 !!!!
850
851         Fortunately, Linux kept the 2292 ABI when it moved to 3542. The following code always
852         uses the old ABI, and should work with pre- and post-3542 kernel headers */
853
854#ifdef IPV6_2292PKTOPTIONS   
855#  define PKTOPTIONS IPV6_2292PKTOPTIONS
856#else
857#  define PKTOPTIONS IPV6_PKTOPTIONS
858#endif
859
860      if (set_ipv6pktinfo(fd) &&
861          getsockopt(fd, IPPROTO_IPV6, PKTOPTIONS, msg.msg_control, &len) != -1)
862        {
863          msg.msg_controllen = len;
864          for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
865            if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == daemon->v6pktinfo)
866              {
867                union {
868                  unsigned char *c;
869                  struct in6_pktinfo *p;
870                } p;
871                p.c = CMSG_DATA(cmptr);
872               
873                if_index = p.p->ipi6_ifindex;
874              }
875        }
876    }
877#endif /* IPV6 */
878#endif /* Linux */
879 
880  return if_index;
881}
882     
883static struct listener *create_listeners(union mysockaddr *addr, int do_tftp, int dienow)
884{
885  struct listener *l = NULL;
886  int fd = -1, tcpfd = -1, tftpfd = -1;
887
888  (void)do_tftp;
889
890  if (daemon->port != 0)
891    {
892      fd = make_sock(addr, SOCK_DGRAM, dienow);
893      tcpfd = make_sock(addr, SOCK_STREAM, dienow);
894    }
895 
896#ifdef HAVE_TFTP
897  if (do_tftp)
898    {
899      if (addr->sa.sa_family == AF_INET)
900        {
901          /* port must be restored to DNS port for TCP code */
902          short save = addr->in.sin_port;
903          addr->in.sin_port = htons(TFTP_PORT);
904          tftpfd = make_sock(addr, SOCK_DGRAM, dienow);
905          addr->in.sin_port = save;
906        }
907#  ifdef HAVE_IPV6
908      else
909        {
910          short save = addr->in6.sin6_port;
911          addr->in6.sin6_port = htons(TFTP_PORT);
912          tftpfd = make_sock(addr, SOCK_DGRAM, dienow);
913          addr->in6.sin6_port = save;
914        } 
915#  endif
916    }
917#endif
918
919  if (fd != -1 || tcpfd != -1 || tftpfd != -1)
920    {
921      l = safe_malloc(sizeof(struct listener));
922      l->next = NULL;
923      l->family = addr->sa.sa_family;
924      l->fd = fd;
925      l->tcpfd = tcpfd;
926      l->tftpfd = tftpfd;       
927      l->iface = NULL;
928    }
929
930  return l;
931}
932
933void create_wildcard_listeners(void)
934{
935  union mysockaddr addr;
936  struct listener *l, *l6;
937
938  memset(&addr, 0, sizeof(addr));
939#ifdef HAVE_SOCKADDR_SA_LEN
940  addr.in.sin_len = sizeof(addr.in);
941#endif
942  addr.in.sin_family = AF_INET;
943  addr.in.sin_addr.s_addr = INADDR_ANY;
944  addr.in.sin_port = htons(daemon->port);
945
946  l = create_listeners(&addr, !!option_bool(OPT_TFTP), 1);
947
948#ifdef HAVE_IPV6
949  memset(&addr, 0, sizeof(addr));
950#  ifdef HAVE_SOCKADDR_SA_LEN
951  addr.in6.sin6_len = sizeof(addr.in6);
952#  endif
953  addr.in6.sin6_family = AF_INET6;
954  addr.in6.sin6_addr = in6addr_any;
955  addr.in6.sin6_port = htons(daemon->port);
956 
957  l6 = create_listeners(&addr, !!option_bool(OPT_TFTP), 1);
958  if (l)
959    l->next = l6;
960  else
961    l = l6;
962#endif
963
964  daemon->listeners = l;
965}
966
967void create_bound_listeners(int dienow)
968{
969  struct listener *new;
970  struct irec *iface;
971  struct iname *if_tmp;
972
973  for (iface = daemon->interfaces; iface; iface = iface->next)
974    if (!iface->done && !iface->dad && iface->found &&
975        (new = create_listeners(&iface->addr, iface->tftp_ok, dienow)))
976      {
977        new->iface = iface;
978        new->next = daemon->listeners;
979        daemon->listeners = new;
980        iface->done = 1;
981      }
982
983  /* Check for --listen-address options that haven't been used because there's
984     no interface with a matching address. These may be valid: eg it's possible
985     to listen on 127.0.1.1 even if the loopback interface is 127.0.0.1
986
987     If the address isn't valid the bind() will fail and we'll die()
988     (except in bind-dynamic mode, when we'll complain but keep trying.)
989
990     The resulting listeners have the ->iface field NULL, and this has to be
991     handled by the DNS and TFTP code. It disables --localise-queries processing
992     (no netmask) and some MTU login the tftp code. */
993
994  for (if_tmp = daemon->if_addrs; if_tmp; if_tmp = if_tmp->next)
995    if (!if_tmp->used &&
996        (new = create_listeners(&if_tmp->addr, !!option_bool(OPT_TFTP), dienow)))
997      {
998        new->next = daemon->listeners;
999        daemon->listeners = new;
1000      }
1001}
1002
1003/* In --bind-interfaces, the only access control is the addresses we're listening on.
1004   There's nothing to avoid a query to the address of an internal interface arriving via
1005   an external interface where we don't want to accept queries, except that in the usual
1006   case the addresses of internal interfaces are RFC1918. When bind-interfaces in use,
1007   and we listen on an address that looks like it's probably globally routeable, shout.
1008
1009   The fix is to use --bind-dynamic, which actually checks the arrival interface too.
1010   Tough if your platform doesn't support this.
1011
1012   Note that checking the arrival interface is supported in the standard IPv6 API and
1013   always done, so we don't warn about any IPv6 addresses here.
1014*/
1015
1016void warn_bound_listeners(void)
1017{
1018  struct irec *iface;   
1019  int advice = 0;
1020
1021  for (iface = daemon->interfaces; iface; iface = iface->next)
1022    if (!iface->dns_auth)
1023      {
1024        if (iface->addr.sa.sa_family == AF_INET)
1025          {
1026            if (!private_net(iface->addr.in.sin_addr, 1))
1027              {
1028                inet_ntop(AF_INET, &iface->addr.in.sin_addr, daemon->addrbuff, ADDRSTRLEN);
1029                iface->warned = advice = 1;
1030                my_syslog(LOG_WARNING,
1031                          _("LOUD WARNING: listening on %s may accept requests via interfaces other than %s"),
1032                          daemon->addrbuff, iface->name);
1033              }
1034          }
1035      }
1036 
1037  if (advice)
1038    my_syslog(LOG_WARNING, _("LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s)"));
1039}
1040
1041void warn_wild_labels(void)
1042{
1043  struct irec *iface;
1044
1045  for (iface = daemon->interfaces; iface; iface = iface->next)
1046    if (iface->found && iface->name && iface->label)
1047      my_syslog(LOG_WARNING, _("warning: using interface %s instead"), iface->name);
1048}
1049
1050void warn_int_names(void)
1051{
1052  struct interface_name *intname;
1053 
1054  for (intname = daemon->int_names; intname; intname = intname->next)
1055    if (!intname->addr)
1056      my_syslog(LOG_WARNING, _("warning: no addresses found for interface %s"), intname->intr);
1057}
1058 
1059int is_dad_listeners(void)
1060{
1061  struct irec *iface;
1062 
1063  if (option_bool(OPT_NOWILD))
1064    for (iface = daemon->interfaces; iface; iface = iface->next)
1065      if (iface->dad && !iface->done)
1066        return 1;
1067 
1068  return 0;
1069}
1070
1071#ifdef HAVE_DHCP6
1072void join_multicast(int dienow)     
1073{
1074  struct irec *iface, *tmp;
1075
1076  for (iface = daemon->interfaces; iface; iface = iface->next)
1077    if (iface->addr.sa.sa_family == AF_INET6 && iface->dhcp_ok && !iface->multicast_done)
1078      {
1079        /* There's an irec per address but we only want to join for multicast
1080           once per interface. Weed out duplicates. */
1081        for (tmp = daemon->interfaces; tmp; tmp = tmp->next)
1082          if (tmp->multicast_done && tmp->index == iface->index)
1083            break;
1084       
1085        iface->multicast_done = 1;
1086       
1087        if (!tmp)
1088          {
1089            struct ipv6_mreq mreq;
1090            int err = 0;
1091
1092            mreq.ipv6mr_interface = iface->index;
1093           
1094            inet_pton(AF_INET6, ALL_RELAY_AGENTS_AND_SERVERS, &mreq.ipv6mr_multiaddr);
1095           
1096            if ((daemon->doing_dhcp6 || daemon->relay6) &&
1097                setsockopt(daemon->dhcp6fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1)
1098              err = errno;
1099           
1100            inet_pton(AF_INET6, ALL_SERVERS, &mreq.ipv6mr_multiaddr);
1101           
1102            if (daemon->doing_dhcp6 &&
1103                setsockopt(daemon->dhcp6fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1)
1104              err = errno;
1105           
1106            inet_pton(AF_INET6, ALL_ROUTERS, &mreq.ipv6mr_multiaddr);
1107           
1108            if (daemon->doing_ra &&
1109                setsockopt(daemon->icmp6fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1)
1110              err = errno;
1111           
1112            if (err)
1113              {
1114                char *s = _("interface %s failed to join DHCPv6 multicast group: %s");
1115                errno = err;
1116
1117#ifdef HAVE_LINUX_NETWORK
1118                if (errno == ENOMEM)
1119                  my_syslog(LOG_ERR, _("try increasing /proc/sys/net/core/optmem_max"));
1120#endif
1121
1122                if (dienow)
1123                  die(s, iface->name, EC_BADNET);
1124                else
1125                  my_syslog(LOG_ERR, s, iface->name, strerror(errno));
1126              }
1127          }
1128      }
1129}
1130#endif
1131
1132/* return a UDP socket bound to a random port, have to cope with straying into
1133   occupied port nos and reserved ones. */
1134int random_sock(int family)
1135{
1136  int fd;
1137
1138  if ((fd = socket(family, SOCK_DGRAM, 0)) != -1)
1139    {
1140      union mysockaddr addr;
1141      unsigned int ports_avail = ((unsigned short)daemon->max_port - (unsigned short)daemon->min_port) + 1;
1142      int tries = ports_avail < 30 ? 3 * ports_avail : 100;
1143
1144      memset(&addr, 0, sizeof(addr));
1145      addr.sa.sa_family = family;
1146
1147      /* don't loop forever if all ports in use. */
1148
1149      if (fix_fd(fd))
1150        while(tries--)
1151          {
1152            unsigned short port = rand16();
1153           
1154            if (daemon->min_port != 0 || daemon->max_port != MAX_PORT)
1155              port = htons(daemon->min_port + (port % ((unsigned short)ports_avail)));
1156           
1157            if (family == AF_INET)
1158              {
1159                addr.in.sin_addr.s_addr = INADDR_ANY;
1160                addr.in.sin_port = port;
1161#ifdef HAVE_SOCKADDR_SA_LEN
1162                addr.in.sin_len = sizeof(struct sockaddr_in);
1163#endif
1164              }
1165#ifdef HAVE_IPV6
1166            else
1167              {
1168                addr.in6.sin6_addr = in6addr_any;
1169                addr.in6.sin6_port = port;
1170#ifdef HAVE_SOCKADDR_SA_LEN
1171                addr.in6.sin6_len = sizeof(struct sockaddr_in6);
1172#endif
1173              }
1174#endif
1175           
1176            if (bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == 0)
1177              return fd;
1178           
1179            if (errno != EADDRINUSE && errno != EACCES)
1180              break;
1181          }
1182
1183      close(fd);
1184    }
1185
1186  return -1;
1187}
1188 
1189
1190int local_bind(int fd, union mysockaddr *addr, char *intname, int is_tcp)
1191{
1192  union mysockaddr addr_copy = *addr;
1193
1194  /* cannot set source _port_ for TCP connections. */
1195  if (is_tcp)
1196    {
1197      if (addr_copy.sa.sa_family == AF_INET)
1198        addr_copy.in.sin_port = 0;
1199#ifdef HAVE_IPV6
1200      else
1201        addr_copy.in6.sin6_port = 0;
1202#endif
1203    }
1204 
1205  if (bind(fd, (struct sockaddr *)&addr_copy, sa_len(&addr_copy)) == -1)
1206    return 0;
1207   
1208#if defined(SO_BINDTODEVICE)
1209  if (intname[0] != 0 &&
1210      setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, intname, IF_NAMESIZE) == -1)
1211    return 0;
1212#endif
1213
1214  return 1;
1215}
1216
1217static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
1218{
1219  struct serverfd *sfd;
1220  unsigned int ifindex = 0;
1221  int errsave;
1222
1223  /* when using random ports, servers which would otherwise use
1224     the INADDR_ANY/port0 socket have sfd set to NULL */
1225  if (!daemon->osport && intname[0] == 0)
1226    {
1227      errno = 0;
1228     
1229      if (addr->sa.sa_family == AF_INET &&
1230          addr->in.sin_addr.s_addr == INADDR_ANY &&
1231          addr->in.sin_port == htons(0))
1232        return NULL;
1233
1234#ifdef HAVE_IPV6
1235      if (addr->sa.sa_family == AF_INET6 &&
1236          memcmp(&addr->in6.sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0 &&
1237          addr->in6.sin6_port == htons(0))
1238        return NULL;
1239#endif
1240    }
1241
1242  if (intname && strlen(intname) != 0)
1243    ifindex = if_nametoindex(intname); /* index == 0 when not binding to an interface */
1244     
1245  /* may have a suitable one already */
1246  for (sfd = daemon->sfds; sfd; sfd = sfd->next )
1247    if (sockaddr_isequal(&sfd->source_addr, addr) &&
1248        strcmp(intname, sfd->interface) == 0 &&
1249        ifindex == sfd->ifindex)
1250      return sfd;
1251 
1252  /* need to make a new one. */
1253  errno = ENOMEM; /* in case malloc fails. */
1254  if (!(sfd = whine_malloc(sizeof(struct serverfd))))
1255    return NULL;
1256 
1257  if ((sfd->fd = socket(addr->sa.sa_family, SOCK_DGRAM, 0)) == -1)
1258    {
1259      free(sfd);
1260      return NULL;
1261    }
1262 
1263  if (!local_bind(sfd->fd, addr, intname, 0) || !fix_fd(sfd->fd))
1264    {
1265      errsave = errno; /* save error from bind. */
1266      close(sfd->fd);
1267      free(sfd);
1268      errno = errsave;
1269      return NULL;
1270    }
1271
1272  strcpy(sfd->interface, intname);
1273  sfd->source_addr = *addr;
1274  sfd->next = daemon->sfds;
1275  sfd->ifindex = ifindex;
1276  daemon->sfds = sfd;
1277
1278  return sfd;
1279}
1280
1281/* create upstream sockets during startup, before root is dropped which may be needed
1282   this allows query_port to be a low port and interface binding */
1283void pre_allocate_sfds(void)
1284{
1285  struct server *srv;
1286 
1287  if (daemon->query_port != 0)
1288    {
1289      union  mysockaddr addr;
1290      memset(&addr, 0, sizeof(addr));
1291      addr.in.sin_family = AF_INET;
1292      addr.in.sin_addr.s_addr = INADDR_ANY;
1293      addr.in.sin_port = htons(daemon->query_port);
1294#ifdef HAVE_SOCKADDR_SA_LEN
1295      addr.in.sin_len = sizeof(struct sockaddr_in);
1296#endif
1297      allocate_sfd(&addr, "");
1298#ifdef HAVE_IPV6
1299      memset(&addr, 0, sizeof(addr));
1300      addr.in6.sin6_family = AF_INET6;
1301      addr.in6.sin6_addr = in6addr_any;
1302      addr.in6.sin6_port = htons(daemon->query_port);
1303#ifdef HAVE_SOCKADDR_SA_LEN
1304      addr.in6.sin6_len = sizeof(struct sockaddr_in6);
1305#endif
1306      allocate_sfd(&addr, "");
1307#endif
1308    }
1309 
1310  for (srv = daemon->servers; srv; srv = srv->next)
1311    if (!(srv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND)) &&
1312        !allocate_sfd(&srv->source_addr, srv->interface) &&
1313        errno != 0 &&
1314        option_bool(OPT_NOWILD))
1315      {
1316        prettyprint_addr(&srv->source_addr, daemon->namebuff);
1317        if (srv->interface[0] != 0)
1318          {
1319            strcat(daemon->namebuff, " ");
1320            strcat(daemon->namebuff, srv->interface);
1321          }
1322        die(_("failed to bind server socket for %s: %s"),
1323            daemon->namebuff, EC_BADNET);
1324      } 
1325}
1326
1327void mark_servers(int flag)
1328{
1329  struct server *serv;
1330
1331  /* mark everything with argument flag */
1332  for (serv = daemon->servers; serv; serv = serv->next)
1333    {
1334      if (serv->flags & flag)
1335        serv->flags |= SERV_MARK;
1336#ifdef HAVE_LOOP
1337      /* Give looped servers another chance */
1338      serv->flags &= ~SERV_LOOP;
1339#endif
1340    }
1341}
1342
1343void cleanup_servers(void)
1344{
1345  struct server *serv, *tmp, **up;
1346
1347  /* unlink and free anything still marked. */
1348  for (serv = daemon->servers, up = &daemon->servers; serv; serv = tmp)
1349    {
1350      tmp = serv->next;
1351      if (serv->flags & SERV_MARK)
1352       {
1353         server_gone(serv);
1354         *up = serv->next;
1355         if (serv->domain)
1356           free(serv->domain);
1357         free(serv);
1358       }
1359      else
1360       up = &serv->next;
1361    }
1362
1363#ifdef HAVE_LOOP
1364  /* Now we have a new set of servers, test for loops. */
1365  loop_send_probes();
1366#endif
1367}
1368
1369void add_update_server(int flags,
1370                       union mysockaddr *addr,
1371                       union mysockaddr *source_addr,
1372                       const char *interface,
1373                       const char *domain)
1374{
1375  struct server *serv, *next = NULL;
1376  char *domain_str = NULL;
1377 
1378  /* See if there is a suitable candidate, and unmark */
1379  for (serv = daemon->servers; serv; serv = serv->next)
1380    if (serv->flags & SERV_MARK)
1381      {
1382        if (domain)
1383          {
1384            if (!(serv->flags & SERV_HAS_DOMAIN) || !hostname_isequal(domain, serv->domain))
1385              continue;
1386          }
1387        else
1388          {
1389            if (serv->flags & SERV_HAS_DOMAIN)
1390              continue;
1391          }
1392       
1393        break;
1394      }
1395
1396  if (serv)
1397    {
1398      domain_str = serv->domain;
1399      next = serv->next;
1400    }
1401  else if ((serv = whine_malloc(sizeof (struct server))))
1402    {
1403      /* Not found, create a new one. */
1404      if (domain && !(domain_str = whine_malloc(strlen(domain)+1)))
1405        {
1406          free(serv);
1407          serv = NULL;
1408        }
1409      else
1410        {
1411          struct server *s;
1412          /* Add to the end of the chain, for order */
1413          if (!daemon->servers)
1414            daemon->servers = serv;
1415          else
1416            {
1417              for (s = daemon->servers; s->next; s = s->next);
1418              s->next = serv;
1419            }
1420          if (domain)
1421            strcpy(domain_str, domain);
1422        }
1423    }
1424 
1425  if (serv)
1426    {
1427      memset(serv, 0, sizeof(struct server));
1428      serv->flags = flags;
1429      serv->domain = domain_str;
1430      serv->next = next;
1431      serv->queries = serv->failed_queries = 0;
1432#ifdef HAVE_LOOP
1433      serv->uid = rand32();
1434#endif     
1435
1436      if (domain)
1437        serv->flags |= SERV_HAS_DOMAIN;
1438     
1439      if (interface)
1440        strcpy(serv->interface, interface);     
1441      if (addr)
1442        serv->addr = *addr;
1443      if (source_addr)
1444        serv->source_addr = *source_addr;
1445    }
1446}
1447
1448void check_servers(void)
1449{
1450  struct irec *iface;
1451  struct server *serv;
1452  struct serverfd *sfd, *tmp, **up;
1453  int port = 0, count;
1454  int locals = 0;
1455
1456  /* interface may be new since startup */
1457  if (!option_bool(OPT_NOWILD))
1458    enumerate_interfaces(0);
1459 
1460  for (sfd = daemon->sfds; sfd; sfd = sfd->next)
1461    sfd->used = 0;
1462
1463#ifdef HAVE_DNSSEC
1464 /* Disable DNSSEC validation when using server=/domain/.... servers
1465    unless there's a configured trust anchor. */
1466  for (serv = daemon->servers; serv; serv = serv->next)
1467    serv->flags |= SERV_DO_DNSSEC;
1468#endif
1469
1470  for (count = 0, serv = daemon->servers; serv; serv = serv->next)
1471    {
1472      if (!(serv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND)))
1473        {
1474          /* Init edns_pktsz for newly created server records. */
1475          if (serv->edns_pktsz == 0)
1476            serv->edns_pktsz = daemon->edns_pktsz;
1477         
1478#ifdef HAVE_DNSSEC
1479          if (option_bool(OPT_DNSSEC_VALID))
1480            {
1481              if (serv->flags & SERV_HAS_DOMAIN)
1482                {
1483                  struct ds_config *ds;
1484                  char *domain = serv->domain;
1485                 
1486                  /* .example.com is valid */
1487                  while (*domain == '.')
1488                    domain++;
1489                 
1490                  for (ds = daemon->ds; ds; ds = ds->next)
1491                    if (ds->name[0] != 0 && hostname_isequal(domain, ds->name))
1492                      break;
1493                 
1494                  if (!ds)
1495                    serv->flags &= ~SERV_DO_DNSSEC;
1496                }
1497              else if (serv->flags & SERV_FOR_NODOTS)
1498                serv->flags &= ~SERV_DO_DNSSEC;
1499            }
1500#endif
1501
1502          port = prettyprint_addr(&serv->addr, daemon->namebuff);
1503         
1504          /* 0.0.0.0 is nothing, the stack treats it like 127.0.0.1 */
1505          if (serv->addr.sa.sa_family == AF_INET &&
1506              serv->addr.in.sin_addr.s_addr == 0)
1507            {
1508              serv->flags |= SERV_MARK;
1509              continue;
1510            }
1511
1512          for (iface = daemon->interfaces; iface; iface = iface->next)
1513            if (sockaddr_isequal(&serv->addr, &iface->addr))
1514              break;
1515          if (iface)
1516            {
1517              my_syslog(LOG_WARNING, _("ignoring nameserver %s - local interface"), daemon->namebuff);
1518              serv->flags |= SERV_MARK;
1519              continue;
1520            }
1521         
1522          /* Do we need a socket set? */
1523          if (!serv->sfd &&
1524              !(serv->sfd = allocate_sfd(&serv->source_addr, serv->interface)) &&
1525              errno != 0)
1526            {
1527              my_syslog(LOG_WARNING,
1528                        _("ignoring nameserver %s - cannot make/bind socket: %s"),
1529                        daemon->namebuff, strerror(errno));
1530              serv->flags |= SERV_MARK;
1531              continue;
1532            }
1533         
1534          if (serv->sfd)
1535            serv->sfd->used = 1;
1536        }
1537     
1538      if (!(serv->flags & SERV_NO_REBIND) && !(serv->flags & SERV_LITERAL_ADDRESS))
1539        {
1540          if (++count > SERVERS_LOGGED)
1541            continue;
1542         
1543          if (serv->flags & (SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_USE_RESOLV))
1544            {
1545              char *s1, *s2, *s3 = "";
1546#ifdef HAVE_DNSSEC
1547              if (option_bool(OPT_DNSSEC_VALID) && !(serv->flags & SERV_DO_DNSSEC))
1548                s3 = _("(no DNSSEC)");
1549#endif
1550              if (!(serv->flags & SERV_HAS_DOMAIN))
1551                s1 = _("unqualified"), s2 = _("names");
1552              else if (strlen(serv->domain) == 0)
1553                s1 = _("default"), s2 = "";
1554              else
1555                s1 = _("domain"), s2 = serv->domain;
1556             
1557              if (serv->flags & SERV_NO_ADDR)
1558                {
1559                  count--;
1560                  if (++locals <= LOCALS_LOGGED)
1561                        my_syslog(LOG_INFO, _("using local addresses only for %s %s"), s1, s2);
1562                }
1563              else if (serv->flags & SERV_USE_RESOLV)
1564                my_syslog(LOG_INFO, _("using standard nameservers for %s %s"), s1, s2);
1565              else
1566                my_syslog(LOG_INFO, _("using nameserver %s#%d for %s %s %s"), daemon->namebuff, port, s1, s2, s3);
1567            }
1568#ifdef HAVE_LOOP
1569          else if (serv->flags & SERV_LOOP)
1570            my_syslog(LOG_INFO, _("NOT using nameserver %s#%d - query loop detected"), daemon->namebuff, port);
1571#endif
1572          else if (serv->interface[0] != 0)
1573            my_syslog(LOG_INFO, _("using nameserver %s#%d(via %s)"), daemon->namebuff, port, serv->interface);
1574          else
1575            my_syslog(LOG_INFO, _("using nameserver %s#%d"), daemon->namebuff, port);
1576        }
1577    }
1578 
1579  if (locals > LOCALS_LOGGED)
1580    my_syslog(LOG_INFO, _("using %d more local addresses"), locals - LOCALS_LOGGED);
1581  if (count - 1 > SERVERS_LOGGED)
1582    my_syslog(LOG_INFO, _("using %d more nameservers"), count - SERVERS_LOGGED - 1);
1583
1584  /* Remove unused sfds */
1585  for (sfd = daemon->sfds, up = &daemon->sfds; sfd; sfd = tmp)
1586    {
1587       tmp = sfd->next;
1588       if (!sfd->used)
1589        {
1590          *up = sfd->next;
1591          close(sfd->fd);
1592          free(sfd);
1593        }
1594      else
1595        up = &sfd->next;
1596    }
1597 
1598  cleanup_servers();
1599}
1600
1601/* Return zero if no servers found, in that case we keep polling.
1602   This is a protection against an update-time/write race on resolv.conf */
1603int reload_servers(char *fname)
1604{
1605  FILE *f;
1606  char *line;
1607  int gotone = 0;
1608
1609  /* buff happens to be MAXDNAME long... */
1610  if (!(f = fopen(fname, "r")))
1611    {
1612      my_syslog(LOG_ERR, _("failed to read %s: %s"), fname, strerror(errno));
1613      return 0;
1614    }
1615   
1616  mark_servers(SERV_FROM_RESOLV);
1617   
1618  while ((line = fgets(daemon->namebuff, MAXDNAME, f)))
1619    {
1620      union mysockaddr addr, source_addr;
1621      char *token = strtok(line, " \t\n\r");
1622     
1623      if (!token)
1624        continue;
1625      if (strcmp(token, "nameserver") != 0 && strcmp(token, "server") != 0)
1626        continue;
1627      if (!(token = strtok(NULL, " \t\n\r")))
1628        continue;
1629     
1630      memset(&addr, 0, sizeof(addr));
1631      memset(&source_addr, 0, sizeof(source_addr));
1632     
1633      if ((addr.in.sin_addr.s_addr = inet_addr(token)) != (in_addr_t) -1)
1634        {
1635#ifdef HAVE_SOCKADDR_SA_LEN
1636          source_addr.in.sin_len = addr.in.sin_len = sizeof(source_addr.in);
1637#endif
1638          source_addr.in.sin_family = addr.in.sin_family = AF_INET;
1639          addr.in.sin_port = htons(NAMESERVER_PORT);
1640          source_addr.in.sin_addr.s_addr = INADDR_ANY;
1641          source_addr.in.sin_port = htons(daemon->query_port);
1642        }
1643#ifdef HAVE_IPV6
1644      else
1645        {       
1646          int scope_index = 0;
1647          char *scope_id = strchr(token, '%');
1648         
1649          if (scope_id)
1650            {
1651              *(scope_id++) = 0;
1652              scope_index = if_nametoindex(scope_id);
1653            }
1654         
1655          if (inet_pton(AF_INET6, token, &addr.in6.sin6_addr) > 0)
1656            {
1657#ifdef HAVE_SOCKADDR_SA_LEN
1658              source_addr.in6.sin6_len = addr.in6.sin6_len = sizeof(source_addr.in6);
1659#endif
1660              source_addr.in6.sin6_family = addr.in6.sin6_family = AF_INET6;
1661              source_addr.in6.sin6_flowinfo = addr.in6.sin6_flowinfo = 0;
1662              addr.in6.sin6_port = htons(NAMESERVER_PORT);
1663              addr.in6.sin6_scope_id = scope_index;
1664              source_addr.in6.sin6_addr = in6addr_any;
1665              source_addr.in6.sin6_port = htons(daemon->query_port);
1666              source_addr.in6.sin6_scope_id = 0;
1667            }
1668          else
1669            continue;
1670        }
1671#else /* IPV6 */
1672      else
1673        continue;
1674#endif
1675
1676      add_update_server(SERV_FROM_RESOLV, &addr, &source_addr, NULL, NULL);
1677      gotone = 1;
1678    }
1679 
1680  fclose(f);
1681  cleanup_servers();
1682
1683  return gotone;
1684}
1685
1686/* Called when addresses are added or deleted from an interface */
1687void newaddress(time_t now)
1688{
1689  (void)now;
1690 
1691  if (option_bool(OPT_CLEVERBIND) || option_bool(OPT_LOCAL_SERVICE) ||
1692      daemon->doing_dhcp6 || daemon->relay6 || daemon->doing_ra)
1693    enumerate_interfaces(0);
1694 
1695  if (option_bool(OPT_CLEVERBIND))
1696    create_bound_listeners(0);
1697 
1698#ifdef HAVE_DHCP6
1699  if (daemon->doing_dhcp6 || daemon->relay6 || daemon->doing_ra)
1700    join_multicast(0);
1701 
1702  if (daemon->doing_dhcp6 || daemon->doing_ra)
1703    dhcp_construct_contexts(now);
1704 
1705  if (daemon->doing_dhcp6)
1706    lease_find_interfaces(now);
1707#endif
1708}
1709
1710
1711
1712
1713
Note: See TracBrowser for help on using the repository browser.