Diff for /embedaddon/dnsmasq/src/dnsmasq.c between versions 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2013/07/29 19:37:40 version 1.1.1.2, 2014/06/15 16:31:38
Line 1 Line 1
/* dnsmasq is Copyright (c) 2000-2013 Simon Kelley/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
   
    This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
Line 50  int main (int argc, char **argv) Line 50  int main (int argc, char **argv)
 #if defined(HAVE_LINUX_NETWORK)  #if defined(HAVE_LINUX_NETWORK)
   cap_user_header_t hdr = NULL;    cap_user_header_t hdr = NULL;
   cap_user_data_t data = NULL;    cap_user_data_t data = NULL;
     char *bound_device = NULL;
     int did_bind = 0;
 #endif   #endif 
   #if defined(HAVE_DHCP) || defined(HAVE_DHCP6)
   struct dhcp_context *context;    struct dhcp_context *context;
     struct dhcp_relay *relay;
   #endif
   
 #ifdef LOCALEDIR  #ifdef LOCALEDIR
   setlocale(LC_ALL, "");    setlocale(LC_ALL, "");
Line 76  int main (int argc, char **argv) Line 81  int main (int argc, char **argv)
   umask(022); /* known umask, create leases and pid files as 0644 */    umask(022); /* known umask, create leases and pid files as 0644 */
   
   read_opts(argc, argv, compile_opts);    read_opts(argc, argv, compile_opts);
     
   if (daemon->edns_pktsz < PACKETSZ)    if (daemon->edns_pktsz < PACKETSZ)
     daemon->edns_pktsz = PACKETSZ;      daemon->edns_pktsz = PACKETSZ;
   #ifdef HAVE_DNSSEC
     /* Enforce min packet big enough for DNSSEC */
     if (option_bool(OPT_DNSSEC_VALID) && daemon->edns_pktsz < EDNS_PKTSZ)
       daemon->edns_pktsz = EDNS_PKTSZ;
   #endif
   
   daemon->packet_buff_sz = daemon->edns_pktsz > DNSMASQ_PACKETSZ ?     daemon->packet_buff_sz = daemon->edns_pktsz > DNSMASQ_PACKETSZ ? 
     daemon->edns_pktsz : DNSMASQ_PACKETSZ;      daemon->edns_pktsz : DNSMASQ_PACKETSZ;
   daemon->packet = safe_malloc(daemon->packet_buff_sz);    daemon->packet = safe_malloc(daemon->packet_buff_sz);
  
   daemon->addrbuff = safe_malloc(ADDRSTRLEN);    daemon->addrbuff = safe_malloc(ADDRSTRLEN);
     
   #ifdef HAVE_DNSSEC
     if (option_bool(OPT_DNSSEC_VALID))
       {
         daemon->keyname = safe_malloc(MAXDNAME);
         daemon->workspacename = safe_malloc(MAXDNAME);
       }
   #endif
   
   
 #ifdef HAVE_DHCP  #ifdef HAVE_DHCP
   if (!daemon->lease_file)    if (!daemon->lease_file)
     {      {
Line 126  int main (int argc, char **argv) Line 144  int main (int argc, char **argv)
     }      }
 #endif  #endif
       
     if (option_bool(OPT_DNSSEC_VALID))
       {
   #ifdef HAVE_DNSSEC
         if (!daemon->ds)
           die(_("No trust anchors provided for DNSSEC"), NULL, EC_BADCONF);
         
         if (daemon->cachesize < CACHESIZ)
           die(_("Cannot reduce cache size from default when DNSSEC enabled"), NULL, EC_BADCONF);
   #else 
         die(_("DNSSEC not available: set HAVE_DNSSEC in src/config.h"), NULL, EC_BADCONF);
   #endif
       }
   
 #ifndef HAVE_TFTP  #ifndef HAVE_TFTP
   if (option_bool(OPT_TFTP))    if (option_bool(OPT_TFTP))
     die(_("TFTP server not available: set HAVE_TFTP in src/config.h"), NULL, EC_BADCONF);      die(_("TFTP server not available: set HAVE_TFTP in src/config.h"), NULL, EC_BADCONF);
Line 166  int main (int argc, char **argv) Line 197  int main (int argc, char **argv)
   daemon->soa_sn = now;    daemon->soa_sn = now;
 #endif  #endif
       
#ifdef HAVE_DHCP#ifdef HAVE_DHCP6
  if (daemon->dhcp || daemon->dhcp6)  if (daemon->dhcp6)
    {     {
       daemon->doing_ra = option_bool(OPT_RA);
               
#  ifdef HAVE_DHCP6      for (context = daemon->dhcp6; context; context = context->next)
      if (daemon->dhcp6) 
         {          {
          daemon->doing_ra = option_bool(OPT_RA);          if (context->flags & CONTEXT_DHCP)
                      daemon->doing_dhcp6 = 1;
          for (context = daemon->dhcp6; context; context = context->next)          if (context->flags & CONTEXT_RA)
            {            daemon->doing_ra = 1;
              if (context->flags & CONTEXT_DHCP)#if !defined(HAVE_LINUX_NETWORK) && !defined(HAVE_BSD_NETWORK)
                daemon->doing_dhcp6 = 1;          if (context->flags & CONTEXT_TEMPLATE)
              if (context->flags & CONTEXT_RA)            die (_("dhcp-range constructor not available on this platform"), NULL, EC_BADCONF);
                daemon->doing_ra = 1; 
#ifndef  HAVE_LINUX_NETWORK 
              if (context->flags & CONTEXT_TEMPLATE) 
                die (_("dhcp-range constructor not available on this platform"), NULL, EC_BADCONF); 
 #endif   #endif 
             }  
         }          }
#  endif    }
#endif
      /* Note that order matters here, we must call lease_init before  
         creating any file descriptors which shouldn't be leaked#ifdef HAVE_DHCP
         to the lease-script init process. We need to call common_init  /* Note that order matters here, we must call lease_init before
         before lease_init to allocate buffers it uses.*/     creating any file descriptors which shouldn't be leaked
      to the lease-script init process. We need to call common_init
      before lease_init to allocate buffers it uses.*/
   if (daemon->dhcp || daemon->doing_dhcp6 || daemon->relay4 || daemon->relay6)
     {
       dhcp_common_init();
       if (daemon->dhcp || daemon->doing_dhcp6)        if (daemon->dhcp || daemon->doing_dhcp6)
        {        lease_init(now);
          dhcp_common_init();    }
          lease_init(now);  
        }  if (daemon->dhcp || daemon->relay4)
    dhcp_init();
      if (daemon->dhcp)  
        dhcp_init(); 
  
 #  ifdef HAVE_DHCP6  #  ifdef HAVE_DHCP6
      if (daemon->doing_ra)  if (daemon->doing_ra || daemon->doing_dhcp6 || daemon->relay6)
        ra_init(now);    ra_init(now);
        
      if (daemon->doing_dhcp6)  if (daemon->doing_dhcp6 || daemon->relay6)
        dhcp6_init();    dhcp6_init();
 #  endif  #  endif
     }  
   
 #endif  #endif
   
Line 218  int main (int argc, char **argv) Line 246  int main (int argc, char **argv)
     ipset_init();      ipset_init();
 #endif  #endif
   
#ifdef HAVE_LINUX_NETWORK#if  defined(HAVE_LINUX_NETWORK)
   netlink_init();    netlink_init();
  #elif defined(HAVE_BSD_NETWORK)
  if (option_bool(OPT_NOWILD) && option_bool(OPT_CLEVERBIND))  route_init();
    die(_("cannot set --bind-interfaces and --bind-dynamic"), NULL, EC_BADCONF); 
 #endif  #endif
   
  if (!enumerate_interfaces())  if (option_bool(OPT_NOWILD) && option_bool(OPT_CLEVERBIND))
     die(_("cannot set --bind-interfaces and --bind-dynamic"), NULL, EC_BADCONF);
   
   if (!enumerate_interfaces(1) || !enumerate_interfaces(0))
     die(_("failed to find list of interfaces: %s"), NULL, EC_MISC);      die(_("failed to find list of interfaces: %s"), NULL, EC_MISC);
       
   if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND))     if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND)) 
Line 239  int main (int argc, char **argv) Line 269  int main (int argc, char **argv)
   
 #if defined(HAVE_LINUX_NETWORK) && defined(HAVE_DHCP)  #if defined(HAVE_LINUX_NETWORK) && defined(HAVE_DHCP)
       /* after enumerate_interfaces()  */        /* after enumerate_interfaces()  */
         bound_device = whichdevice();
         
       if (daemon->dhcp)        if (daemon->dhcp)
         {          {
          bindtodevice(daemon->dhcpfd);          if (!daemon->relay4 && bound_device)
          if (daemon->enable_pxe)            {
            bindtodevice(daemon->pxefd);              bindtodevice(bound_device, daemon->dhcpfd);
               did_bind = 1;
             }
           if (daemon->enable_pxe && bound_device)
             {
               bindtodevice(bound_device, daemon->pxefd);
               did_bind = 1;
             }
         }          }
 #endif  #endif
   
 #if defined(HAVE_LINUX_NETWORK) && defined(HAVE_DHCP6)  #if defined(HAVE_LINUX_NETWORK) && defined(HAVE_DHCP6)
      if (daemon->dhcp6)      if (daemon->doing_dhcp6 && !daemon->relay6 && bound_device)
        bindtodevice(daemon->dhcp6fd);        {
           bindtodevice(bound_device, daemon->dhcp6fd);
           did_bind = 1;
         }
 #endif  #endif
     }      }
   else     else 
Line 257  int main (int argc, char **argv) Line 299  int main (int argc, char **argv)
     
 #ifdef HAVE_DHCP6  #ifdef HAVE_DHCP6
   /* after enumerate_interfaces() */    /* after enumerate_interfaces() */
  if (daemon->doing_dhcp6 || daemon->doing_ra)  if (daemon->doing_dhcp6 || daemon->relay6 || daemon->doing_ra)
     join_multicast(1);      join_multicast(1);
   
     /* After netlink_init() and before create_helper() */
     lease_make_duid(now);
 #endif  #endif
       
   if (daemon->port != 0)    if (daemon->port != 0)
    cache_init();    {
       cache_init();
 #ifdef HAVE_DNSSEC
       blockdata_init();
 #endif
     }
           
   if (option_bool(OPT_DBUS))    if (option_bool(OPT_DBUS))
 #ifdef HAVE_DBUS  #ifdef HAVE_DBUS
Line 347  int main (int argc, char **argv) Line 397  int main (int argc, char **argv)
   piperead = pipefd[0];    piperead = pipefd[0];
   pipewrite = pipefd[1];    pipewrite = pipefd[1];
   /* prime the pipe to load stuff first time. */    /* prime the pipe to load stuff first time. */
  send_event(pipewrite, EVENT_RELOAD, 0, NULL);   send_event(pipewrite, EVENT_INIT, 0, NULL); 
   
   err_pipe[1] = -1;    err_pipe[1] = -1;
       
Line 612  int main (int argc, char **argv) Line 662  int main (int argc, char **argv)
     }      }
 #endif  #endif
   
     if (option_bool(OPT_LOCAL_SERVICE))
       my_syslog(LOG_INFO, _("DNS service limited to local subnets"));
     
   #ifdef HAVE_DNSSEC
     if (option_bool(OPT_DNSSEC_VALID))
       {
         my_syslog(LOG_INFO, _("DNSSEC validation enabled"));
         if (option_bool(OPT_DNSSEC_TIME))
           my_syslog(LOG_INFO, _("DNSSEC signature timestamps not checked until first cache reload"));
       }
   #endif
   
   if (log_err != 0)    if (log_err != 0)
     my_syslog(LOG_WARNING, _("warning: failed to change owner of %s: %s"),       my_syslog(LOG_WARNING, _("warning: failed to change owner of %s: %s"), 
               daemon->log_file, strerror(log_err));                daemon->log_file, strerror(log_err));
  
   if (bind_fallback)    if (bind_fallback)
     my_syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations"));      my_syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations"));
   
     if (option_bool(OPT_NOWILD))
       warn_bound_listeners();
   
     warn_int_names();
       
   if (!option_bool(OPT_NOWILD))     if (!option_bool(OPT_NOWILD)) 
     for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)      for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
Line 641  int main (int argc, char **argv) Line 708  int main (int argc, char **argv)
   for (context = daemon->dhcp; context; context = context->next)    for (context = daemon->dhcp; context; context = context->next)
     log_context(AF_INET, context);      log_context(AF_INET, context);
   
     for (relay = daemon->relay4; relay; relay = relay->next)
       log_relay(AF_INET, relay);
   
 #  ifdef HAVE_DHCP6  #  ifdef HAVE_DHCP6
   for (context = daemon->dhcp6; context; context = context->next)    for (context = daemon->dhcp6; context; context = context->next)
     log_context(AF_INET6, context);      log_context(AF_INET6, context);
   
     for (relay = daemon->relay6; relay; relay = relay->next)
       log_relay(AF_INET6, relay);
     
   if (daemon->doing_dhcp6 || daemon->doing_ra)    if (daemon->doing_dhcp6 || daemon->doing_ra)
     dhcp_construct_contexts(now);      dhcp_construct_contexts(now);
       
Line 652  int main (int argc, char **argv) Line 725  int main (int argc, char **argv)
     my_syslog(MS_DHCP | LOG_INFO, _("IPv6 router advertisement enabled"));      my_syslog(MS_DHCP | LOG_INFO, _("IPv6 router advertisement enabled"));
 #  endif  #  endif
   
   #  ifdef HAVE_LINUX_NETWORK
     if (did_bind)
       my_syslog(MS_DHCP | LOG_INFO, _("DHCP, sockets bound exclusively to interface %s"), bound_device);
   #  endif
   
   /* after dhcp_contruct_contexts */    /* after dhcp_contruct_contexts */
   if (daemon->dhcp || daemon->doing_dhcp6)    if (daemon->dhcp || daemon->doing_dhcp6)
     lease_find_interfaces(now);      lease_find_interfaces(now);
Line 749  int main (int argc, char **argv) Line 827  int main (int argc, char **argv)
 #endif    #endif  
       
 #ifdef HAVE_DHCP  #ifdef HAVE_DHCP
      if (daemon->dhcp)      if (daemon->dhcp || daemon->relay4)
         {          {
           FD_SET(daemon->dhcpfd, &rset);            FD_SET(daemon->dhcpfd, &rset);
           bump_maxfd(daemon->dhcpfd, &maxfd);            bump_maxfd(daemon->dhcpfd, &maxfd);
Line 762  int main (int argc, char **argv) Line 840  int main (int argc, char **argv)
 #endif  #endif
   
 #ifdef HAVE_DHCP6  #ifdef HAVE_DHCP6
      if (daemon->doing_dhcp6)      if (daemon->doing_dhcp6 || daemon->relay6)
         {          {
           FD_SET(daemon->dhcp6fd, &rset);            FD_SET(daemon->dhcp6fd, &rset);
           bump_maxfd(daemon->dhcp6fd, &maxfd);            bump_maxfd(daemon->dhcp6fd, &maxfd);
Line 775  int main (int argc, char **argv) Line 853  int main (int argc, char **argv)
         }          }
 #endif  #endif
   
#ifdef HAVE_LINUX_NETWORK#if defined(HAVE_LINUX_NETWORK)
       FD_SET(daemon->netlinkfd, &rset);        FD_SET(daemon->netlinkfd, &rset);
       bump_maxfd(daemon->netlinkfd, &maxfd);        bump_maxfd(daemon->netlinkfd, &maxfd);
   #elif defined(HAVE_BSD_NETWORK)
         FD_SET(daemon->routefd, &rset);
         bump_maxfd(daemon->routefd, &maxfd);
 #endif  #endif
      
       FD_SET(piperead, &rset);        FD_SET(piperead, &rset);
       bump_maxfd(piperead, &maxfd);        bump_maxfd(piperead, &maxfd);
   
Line 820  int main (int argc, char **argv) Line 901  int main (int argc, char **argv)
       now = dnsmasq_time();        now = dnsmasq_time();
   
       check_log_writer(&wset);        check_log_writer(&wset);
      
       /* prime. */
       enumerate_interfaces(1);
 
       /* Check the interfaces to see if any have exited DAD state        /* Check the interfaces to see if any have exited DAD state
          and if so, bind the address. */           and if so, bind the address. */
       if (is_dad_listeners())        if (is_dad_listeners())
         {          {
          enumerate_interfaces();          enumerate_interfaces(0);
           /* NB, is_dad_listeners() == 1 --> we're binding interfaces */            /* NB, is_dad_listeners() == 1 --> we're binding interfaces */
           create_bound_listeners(0);            create_bound_listeners(0);
             warn_bound_listeners();
         }          }
   
#ifdef HAVE_LINUX_NETWORK#if defined(HAVE_LINUX_NETWORK)
       if (FD_ISSET(daemon->netlinkfd, &rset))        if (FD_ISSET(daemon->netlinkfd, &rset))
         netlink_multicast(now);          netlink_multicast(now);
   #elif defined(HAVE_BSD_NETWORK)
         if (FD_ISSET(daemon->routefd, &rset))
           route_sock(now);
 #endif  #endif
   
       /* Check for changes to resolv files once per second max. */        /* Check for changes to resolv files once per second max. */
Line 871  int main (int argc, char **argv) Line 959  int main (int argc, char **argv)
 #endif        #endif      
   
 #ifdef HAVE_DHCP  #ifdef HAVE_DHCP
      if (daemon->dhcp)      if (daemon->dhcp || daemon->relay4)
         {          {
           if (FD_ISSET(daemon->dhcpfd, &rset))            if (FD_ISSET(daemon->dhcpfd, &rset))
             dhcp_packet(now, 0);              dhcp_packet(now, 0);
Line 880  int main (int argc, char **argv) Line 968  int main (int argc, char **argv)
         }          }
   
 #ifdef HAVE_DHCP6  #ifdef HAVE_DHCP6
      if (daemon->doing_dhcp6 && FD_ISSET(daemon->dhcp6fd, &rset))      if ((daemon->doing_dhcp6 || daemon->relay6) && FD_ISSET(daemon->dhcp6fd, &rset))
         dhcp6_packet(now);          dhcp6_packet(now);
   
       if (daemon->doing_ra && FD_ISSET(daemon->icmp6fd, &rset))        if (daemon->doing_ra && FD_ISSET(daemon->icmp6fd, &rset))
Line 1036  static void async_event(int pipe, time_t now) Line 1124  static void async_event(int pipe, time_t now)
 {  {
   pid_t p;    pid_t p;
   struct event_desc ev;    struct event_desc ev;
  int i;  int i, check = 0;
   char *msg;    char *msg;
       
   /* NOTE: the memory used to return msg is leaked: use msgs in events only    /* NOTE: the memory used to return msg is leaked: use msgs in events only
Line 1046  static void async_event(int pipe, time_t now) Line 1134  static void async_event(int pipe, time_t now)
     switch (ev.event)      switch (ev.event)
       {        {
       case EVENT_RELOAD:        case EVENT_RELOAD:
   #ifdef HAVE_DNSSEC
           if (option_bool(OPT_DNSSEC_VALID) && option_bool(OPT_DNSSEC_TIME))
             {
               my_syslog(LOG_INFO, _("now checking DNSSEC signature timestamps"));
               reset_option_bool(OPT_DNSSEC_TIME);
             } 
   #endif
           /* fall through */
           
         case EVENT_INIT:
         clear_cache_and_reload(now);          clear_cache_and_reload(now);
        if (daemon->port != 0 && daemon->resolv_files && option_bool(OPT_NO_POLL))        
         if (daemon->port != 0)
           {            {
            reload_servers(daemon->resolv_files->name);            if (daemon->resolv_files && option_bool(OPT_NO_POLL))
            check_servers();              {
                 reload_servers(daemon->resolv_files->name);
                 check = 1;
               }
 
             if (daemon->servers_file)
               {
                 read_servers_file();
                 check = 1;
               }
 
             if (check)
               check_servers();
           }            }
   
 #ifdef HAVE_DHCP  #ifdef HAVE_DHCP
         rerun_scripts();          rerun_scripts();
 #endif  #endif
Line 1223  void poll_resolv(int force, int do_reload, time_t now) Line 1335  void poll_resolv(int force, int do_reload, time_t now)
   
 void clear_cache_and_reload(time_t now)  void clear_cache_and_reload(time_t now)
 {  {
     (void)now;
   
   if (daemon->port != 0)    if (daemon->port != 0)
     cache_reload();      cache_reload();
       
Line 1265  static int set_dns_listeners(time_t now, fd_set *set,  Line 1379  static int set_dns_listeners(time_t now, fd_set *set, 
       
   /* will we be able to get memory? */    /* will we be able to get memory? */
   if (daemon->port != 0)    if (daemon->port != 0)
    get_new_frec(now, &wait);    get_new_frec(now, &wait, 0);
       
   for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)    for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
     {      {
Line 1352  static void check_dns_listeners(fd_set *set, time_t no Line 1466  static void check_dns_listeners(fd_set *set, time_t no
                       
           if (confd == -1)            if (confd == -1)
             continue;              continue;
          
           if (getsockname(confd, (struct sockaddr *)&tcp_addr, &tcp_len) == -1)            if (getsockname(confd, (struct sockaddr *)&tcp_addr, &tcp_len) == -1)
             {              {
               close(confd);                close(confd);
               continue;                continue;
             }              }
             
             /* Make sure that the interface list is up-to-date.
                
                We do this here as we may need the results below, and
                the DNS code needs them for --interface-name stuff.
   
           if (option_bool(OPT_NOWILD))             Multiple calls to enumerate_interfaces() per select loop are
            iface = listener->iface; /* May be NULL */             inhibited, so calls to it in the child process (which doesn't select())
           else              have no effect. This avoids two processes reading from the same
             {             netlink fd and screwing the pooch entirely.
               int if_index;          */
               char intr_name[IF_NAMESIZE]; 
     
               /* In full wildcard mode, need to refresh interface list.          enumerate_interfaces(0);
                  This happens automagically in CLEVERBIND */          
               if (!option_bool(OPT_CLEVERBIND))          if (option_bool(OPT_NOWILD))
                 enumerate_interfaces();            iface = listener->iface; /* May be NULL */
                         else 
               /* if we can find the arrival interface, check it's one that's allowed */            {
               if ((if_index = tcp_interface(confd, tcp_addr.sa.sa_family)) != 0 &&              int if_index;
                   indextoname(listener->tcpfd, if_index, intr_name))              char intr_name[IF_NAMESIZE];
                 {              
                   struct all_addr addr;              /* if we can find the arrival interface, check it's one that's allowed */
                   addr.addr.addr4 = tcp_addr.in.sin_addr;              if ((if_index = tcp_interface(confd, tcp_addr.sa.sa_family)) != 0 &&
                   indextoname(listener->tcpfd, if_index, intr_name))
                 {
                   struct all_addr addr;
                   addr.addr.addr4 = tcp_addr.in.sin_addr;
 #ifdef HAVE_IPV6  #ifdef HAVE_IPV6
                   if (tcp_addr.sa.sa_family == AF_INET6)                  if (tcp_addr.sa.sa_family == AF_INET6)
                     addr.addr.addr6 = tcp_addr.in6.sin6_addr;                    addr.addr.addr6 = tcp_addr.in6.sin6_addr;
 #endif  #endif
                                     
                   for (iface = daemon->interfaces; iface; iface = iface->next)                  for (iface = daemon->interfaces; iface; iface = iface->next)
                     if (iface->index == if_index)                    if (iface->index == if_index)
                       break;                      break;
                                     
                   if (!iface && !loopback_exception(listener->tcpfd, tcp_addr.sa.sa_family, &addr, intr_name))                  if (!iface && !loopback_exception(listener->tcpfd, tcp_addr.sa.sa_family, &addr, intr_name))
                     client_ok = 0;                    client_ok = 0;
                 }                }
                             
               if (option_bool(OPT_CLEVERBIND))              if (option_bool(OPT_CLEVERBIND))
                 iface = listener->iface; /* May be NULL */                iface = listener->iface; /* May be NULL */
               else              else
                 {                {
                    /* Check for allowed interfaces when binding the wildcard address:                  /* Check for allowed interfaces when binding the wildcard address:
                       we do this by looking for an interface with the same address as                      we do this by looking for an interface with the same address as 
                       the local address of the TCP connection, then looking to see if that's                     the local address of the TCP connection, then looking to see if that's
                       an allowed interface. As a side effect, we get the netmask of the                     an allowed interface. As a side effect, we get the netmask of the
                      interface too, for localisation. */                     interface too, for localisation. */
                                     
                   for (iface = daemon->interfaces; iface; iface = iface->next)                  for (iface = daemon->interfaces; iface; iface = iface->next)
                     if (sockaddr_isequal(&iface->addr, &tcp_addr))                    if (sockaddr_isequal(&iface->addr, &tcp_addr))
                       break;                      break;
                                     
                   if (!iface)                  if (!iface)
                     client_ok = 0;                    client_ok = 0;
                 }                }
             }            }
                            
           if (!client_ok)            if (!client_ok)
             {              {
               shutdown(confd, SHUT_RDWR);                shutdown(confd, SHUT_RDWR);

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>