Diff for /embedaddon/dnsmasq/src/dnsmasq.c between versions 1.1.1.4 and 1.1.1.5

version 1.1.1.4, 2021/03/17 00:56:46 version 1.1.1.5, 2023/09/27 11:02:07
Line 1 Line 1
/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley/* dnsmasq is Copyright (c) 2000-2022 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 17 Line 17
 /* Declare static char *compiler_opts  in config.h */  /* Declare static char *compiler_opts  in config.h */
 #define DNSMASQ_COMPILE_OPTS  #define DNSMASQ_COMPILE_OPTS
   
   /* dnsmasq.h has to be included first as it sources config.h */
 #include "dnsmasq.h"  #include "dnsmasq.h"
   
   #if defined(HAVE_IDN) || defined(HAVE_LIBIDN2) || defined(LOCALEDIR)
   #include <locale.h>
   #endif
   
 struct daemon *daemon;  struct daemon *daemon;
   
 static volatile pid_t pid = 0;  static volatile pid_t pid = 0;
 static volatile int pipewrite;  static volatile int pipewrite;
   
static int set_dns_listeners(time_t now);static void set_dns_listeners(void);
 static void check_dns_listeners(time_t now);  static void check_dns_listeners(time_t now);
 static void sig_handler(int sig);  static void sig_handler(int sig);
 static void async_event(int pipe, time_t now);  static void async_event(int pipe, time_t now);
Line 34  static void poll_resolv(int force, int do_reload, time Line 39  static void poll_resolv(int force, int do_reload, time
   
 int main (int argc, char **argv)  int main (int argc, char **argv)
 {  {
   int bind_fallback = 0;  
   time_t now;    time_t now;
   struct sigaction sigact;    struct sigaction sigact;
   struct iname *if_tmp;    struct iname *if_tmp;
Line 59  int main (int argc, char **argv) Line 63  int main (int argc, char **argv)
   int did_bind = 0;    int did_bind = 0;
   struct server *serv;    struct server *serv;
   char *netlink_warn;    char *netlink_warn;
   #else
     int bind_fallback = 0;
 #endif   #endif 
 #if defined(HAVE_DHCP) || defined(HAVE_DHCP6)  #if defined(HAVE_DHCP) || defined(HAVE_DHCP6)
   struct dhcp_context *context;    struct dhcp_context *context;
Line 68  int main (int argc, char **argv) Line 74  int main (int argc, char **argv)
   int tftp_prefix_missing = 0;    int tftp_prefix_missing = 0;
 #endif  #endif
   
#ifdef LOCALEDIR#if defined(HAVE_IDN) || defined(HAVE_LIBIDN2) || defined(LOCALEDIR)
   setlocale(LC_ALL, "");    setlocale(LC_ALL, "");
   #endif
   #ifdef LOCALEDIR
   bindtextdomain("dnsmasq", LOCALEDIR);     bindtextdomain("dnsmasq", LOCALEDIR); 
   textdomain("dnsmasq");    textdomain("dnsmasq");
 #endif  #endif
Line 109  int main (int argc, char **argv) Line 117  int main (int argc, char **argv)
   daemon->packet_buff_sz = daemon->edns_pktsz + MAXDNAME + RRFIXEDSZ;    daemon->packet_buff_sz = daemon->edns_pktsz + MAXDNAME + RRFIXEDSZ;
   daemon->packet = safe_malloc(daemon->packet_buff_sz);    daemon->packet = safe_malloc(daemon->packet_buff_sz);
       
   daemon->addrbuff = safe_malloc(ADDRSTRLEN);  
   if (option_bool(OPT_EXTRALOG))    if (option_bool(OPT_EXTRALOG))
     daemon->addrbuff2 = safe_malloc(ADDRSTRLEN);      daemon->addrbuff2 = safe_malloc(ADDRSTRLEN);
       
Line 135  int main (int argc, char **argv) Line 142  int main (int argc, char **argv)
     }      }
 #endif  #endif
   
   #if defined(HAVE_CONNTRACK) && defined(HAVE_UBUS)
     /* CONNTRACK UBUS code uses this buffer, so if not allocated above,
        we need to allocate it here. */
     if (option_bool(OPT_CMARK_ALST_EN) && !daemon->workspacename)
       daemon->workspacename = safe_malloc(MAXDNAME);
   #endif
     
 #ifdef HAVE_DHCP  #ifdef HAVE_DHCP
   if (!daemon->lease_file)    if (!daemon->lease_file)
     {      {
Line 205  int main (int argc, char **argv) Line 219  int main (int argc, char **argv)
 #endif  #endif
   
 #ifdef HAVE_CONNTRACK  #ifdef HAVE_CONNTRACK
  if (option_bool(OPT_CONNTRACK) && (daemon->query_port != 0 || daemon->osport))  if (option_bool(OPT_CONNTRACK))
    die (_("cannot use --conntrack AND --query-port"), NULL, EC_BADCONF);     {
       if (daemon->query_port != 0 || daemon->osport)
         die (_("cannot use --conntrack AND --query-port"), NULL, EC_BADCONF);
 
       need_cap_net_admin = 1;
     }
 #else  #else
   if (option_bool(OPT_CONNTRACK))    if (option_bool(OPT_CONNTRACK))
     die(_("conntrack support not available: set HAVE_CONNTRACK in src/config.h"), NULL, EC_BADCONF);      die(_("conntrack support not available: set HAVE_CONNTRACK in src/config.h"), NULL, EC_BADCONF);
Line 237  int main (int argc, char **argv) Line 256  int main (int argc, char **argv)
     die(_("Ubus not available: set HAVE_UBUS in src/config.h"), NULL, EC_BADCONF);      die(_("Ubus not available: set HAVE_UBUS in src/config.h"), NULL, EC_BADCONF);
 #endif  #endif
       
     /* Handle only one of min_port/max_port being set. */
     if (daemon->min_port != 0 && daemon->max_port == 0)
       daemon->max_port = MAX_PORT;
     
     if (daemon->max_port != 0 && daemon->min_port == 0)
       daemon->min_port = MIN_PORT;
      
   if (daemon->max_port < daemon->min_port)    if (daemon->max_port < daemon->min_port)
     die(_("max_port cannot be smaller than min_port"), NULL, EC_BADCONF);      die(_("max_port cannot be smaller than min_port"), NULL, EC_BADCONF);
   
     if (daemon->max_port != 0 &&
         daemon->max_port - daemon->min_port + 1 < daemon->randport_limit)
       die(_("port_limit must not be larger than available port range"), NULL, EC_BADCONF);
     
   now = dnsmasq_time();    now = dnsmasq_time();
   
   if (daemon->auth_zones)    if (daemon->auth_zones)
Line 327  int main (int argc, char **argv) Line 357  int main (int argc, char **argv)
     }      }
 #endif  #endif
   
   #ifdef HAVE_NFTSET
     if (daemon->nftsets)
       {
         nftset_init();
   #  ifdef HAVE_LINUX_NETWORK
         need_cap_net_admin = 1;
   #  endif
       }
   #endif
   
 #if  defined(HAVE_LINUX_NETWORK)  #if  defined(HAVE_LINUX_NETWORK)
   netlink_warn = netlink_init();    netlink_warn = netlink_init();
 #elif defined(HAVE_BSD_NETWORK)  #elif defined(HAVE_BSD_NETWORK)
Line 351  int main (int argc, char **argv) Line 391  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();        bound_device = whichdevice();
         
       if (daemon->dhcp)  
         {  
           if (!daemon->relay4 && bound_device)  
             {  
               bindtodevice(bound_device, daemon->dhcpfd);  
               did_bind = 1;  
             }  
           if (daemon->enable_pxe && bound_device)  
             {  
               bindtodevice(bound_device, daemon->pxefd);  
               did_bind = 1;  
             }  
         }  
 #endif  
   
#if defined(HAVE_LINUX_NETWORK) && defined(HAVE_DHCP6)      if ((did_bind = bind_dhcp_devices(bound_device)) & 2)
      if (daemon->doing_dhcp6 && !daemon->relay6 && bound_device)        die(_("failed to set SO_BINDTODEVICE on DHCP socket: %s"), NULL, EC_BADNET);    
        { 
          bindtodevice(bound_device, daemon->dhcp6fd); 
          did_bind = 1; 
        } 
 #endif  #endif
     }      }
   else     else 
Line 392  int main (int argc, char **argv) Line 413  int main (int argc, char **argv)
       cache_init();        cache_init();
       blockdata_init();        blockdata_init();
       hash_questions_init();        hash_questions_init();
   
         /* Scale random socket pool by ftabsize, but
            limit it based on available fds. */
         daemon->numrrand = daemon->ftabsize/2;
         if (daemon->numrrand > max_fd/3)
           daemon->numrrand = max_fd/3;
         /* safe_malloc returns zero'd memory */
         daemon->randomsocks = safe_malloc(daemon->numrrand * sizeof(struct randfd));
     }      }
   
 #ifdef HAVE_INOTIFY  #ifdef HAVE_INOTIFY
Line 415  int main (int argc, char **argv) Line 444  int main (int argc, char **argv)
 #ifdef HAVE_DBUS  #ifdef HAVE_DBUS
     {      {
       char *err;        char *err;
       daemon->dbus = NULL;  
       daemon->watches = NULL;  
       if ((err = dbus_init()))        if ((err = dbus_init()))
         die(_("DBus error: %s"), err, EC_MISC);          die(_("DBus error: %s"), err, EC_MISC);
     }      }
Line 427  int main (int argc, char **argv) Line 454  int main (int argc, char **argv)
   if (option_bool(OPT_UBUS))    if (option_bool(OPT_UBUS))
 #ifdef HAVE_UBUS  #ifdef HAVE_UBUS
     {      {
      daemon->ubus = NULL;      char *err;
      ubus_init();      if ((err = ubus_init()))
         die(_("UBus error: %s"), err, EC_MISC);
     }      }
 #else  #else
   die(_("UBus not available: set HAVE_UBUS in src/config.h"), NULL, EC_BADCONF);    die(_("UBus not available: set HAVE_UBUS in src/config.h"), NULL, EC_BADCONF);
Line 691  int main (int argc, char **argv) Line 719  int main (int argc, char **argv)
    /* if we are to run scripts, we need to fork a helper before dropping root. */     /* if we are to run scripts, we need to fork a helper before dropping root. */
   daemon->helperfd = -1;    daemon->helperfd = -1;
 #ifdef HAVE_SCRIPT   #ifdef HAVE_SCRIPT 
  if ((daemon->dhcp || daemon->dhcp6 || option_bool(OPT_TFTP) || option_bool(OPT_SCRIPT_ARP)) &&   if ((daemon->dhcp ||
        daemon->dhcp6 ||
        daemon->relay6 ||
        option_bool(OPT_TFTP) ||
        option_bool(OPT_SCRIPT_ARP)) && 
       (daemon->lease_change_command || daemon->luascript))        (daemon->lease_change_command || daemon->luascript))
       daemon->helperfd = create_helper(pipewrite, err_pipe[1], script_uid, script_gid, max_fd);        daemon->helperfd = create_helper(pipewrite, err_pipe[1], script_uid, script_gid, max_fd);
 #endif  #endif
Line 895  int main (int argc, char **argv) Line 927  int main (int argc, char **argv)
     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));
       
   #ifndef HAVE_LINUX_NETWORK
   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"));
   #endif
   
   if (option_bool(OPT_NOWILD))    if (option_bool(OPT_NOWILD))
     warn_bound_listeners();      warn_bound_listeners();
Line 980  int main (int argc, char **argv) Line 1014  int main (int argc, char **argv)
          a single file will be sent to may clients (the file only needs           a single file will be sent to may clients (the file only needs
          one fd). */           one fd). */
   
      max_fd -= 30; /* use other than TFTP */      max_fd -= 30 + daemon->numrrand; /* use other than TFTP */
               
       if (max_fd < 0)        if (max_fd < 0)
         max_fd = 5;          max_fd = 5;
Line 1010  int main (int argc, char **argv) Line 1044  int main (int argc, char **argv)
     close(err_pipe[1]);      close(err_pipe[1]);
       
   if (daemon->port != 0)    if (daemon->port != 0)
    check_servers();    check_servers(0);
       
   pid = getpid();    pid = getpid();
   
Line 1025  int main (int argc, char **argv) Line 1059  int main (int argc, char **argv)
       
   while (1)    while (1)
     {      {
      int t, timeout = -1;      int timeout = fast_retry(now);
               
       poll_reset();        poll_reset();
               
       /* if we are out of resources, find how long we have to wait  
          for some to come free, we'll loop around then and restart  
          listening for queries */  
       if ((t = set_dns_listeners(now)) != 0)  
         timeout = t * 1000;  
   
       /* Whilst polling for the dbus, or doing a tftp transfer, wake every quarter second */        /* Whilst polling for the dbus, or doing a tftp transfer, wake every quarter second */
      if (daemon->tftp_trans ||      if ((daemon->tftp_trans || (option_bool(OPT_DBUS) && !daemon->dbus)) &&
          (option_bool(OPT_DBUS) && !daemon->dbus))          (timeout == -1 || timeout > 250))
         timeout = 250;          timeout = 250;
      
       /* Wake every second whilst waiting for DAD to complete */        /* Wake every second whilst waiting for DAD to complete */
      else if (is_dad_listeners())      else if (is_dad_listeners() &&
                (timeout == -1 || timeout > 1000))
         timeout = 1000;          timeout = 1000;
         
         set_dns_listeners();
   
 #ifdef HAVE_DBUS  #ifdef HAVE_DBUS
      set_dbus_listeners();      if (option_bool(OPT_DBUS))
         set_dbus_listeners();
 #endif  #endif
      
 #ifdef HAVE_UBUS  #ifdef HAVE_UBUS
       if (option_bool(OPT_UBUS))        if (option_bool(OPT_UBUS))
         set_ubus_listeners();          set_ubus_listeners();
 #endif  #endif
                
 #ifdef HAVE_DHCP  #ifdef HAVE_DHCP
   #  if defined(HAVE_LINUX_NETWORK)
         if (bind_dhcp_devices(bound_device) & 2)
           {
             static int warned = 0;
             if (!warned)
               {
                 my_syslog(LOG_ERR, _("error binding DHCP socket to device %s"), bound_device);
                 warned = 1;
               }
           }
   # endif
       if (daemon->dhcp || daemon->relay4)        if (daemon->dhcp || daemon->relay4)
         {          {
           poll_listen(daemon->dhcpfd, POLLIN);            poll_listen(daemon->dhcpfd, POLLIN);
Line 1097  int main (int argc, char **argv) Line 1140  int main (int argc, char **argv)
       while (helper_buf_empty() && do_tftp_script_run());        while (helper_buf_empty() && do_tftp_script_run());
 #    endif  #    endif
   
   #    ifdef HAVE_DHCP6
         while (helper_buf_empty() && do_snoop_script_run());
   #    endif
         
       if (!helper_buf_empty())        if (!helper_buf_empty())
         poll_listen(daemon->helperfd, POLLOUT);          poll_listen(daemon->helperfd, POLLOUT);
 #else  #else
Line 1172  int main (int argc, char **argv) Line 1219  int main (int argc, char **argv)
               
 #ifdef HAVE_DBUS  #ifdef HAVE_DBUS
       /* if we didn't create a DBus connection, retry now. */         /* if we didn't create a DBus connection, retry now. */ 
     if (option_bool(OPT_DBUS) && !daemon->dbus)      if (option_bool(OPT_DBUS))
         {          {
          char *err;          if (!daemon->dbus)
          if ((err = dbus_init()))            {
            my_syslog(LOG_WARNING, _("DBus error: %s"), err);              char *err  = dbus_init();
          if (daemon->dbus)
            my_syslog(LOG_INFO, _("connected to system DBus"));              if (daemon->dbus)
                 my_syslog(LOG_INFO, _("connected to system DBus"));
               else if (err)
                 {
                   my_syslog(LOG_ERR, _("DBus error: %s"), err);
                   reset_option_bool(OPT_DBUS); /* fatal error, stop trying. */
                 }
             }
           
           check_dbus_listeners();
         }          }
       check_dbus_listeners();  
 #endif  #endif
   
 #ifdef HAVE_UBUS  #ifdef HAVE_UBUS
         /* if we didn't create a UBus connection, retry now. */
       if (option_bool(OPT_UBUS))        if (option_bool(OPT_UBUS))
        {        {
          /* if we didn't create a UBus connection, retry now. */          if (!daemon->ubus)
          if (!daemon->ubus)            {
            {              char *err = ubus_init();
              ubus_init(); 
            } 
   
          check_ubus_listeners();              if (daemon->ubus)
        }                my_syslog(LOG_INFO, _("connected to system UBus"));
               else if (err)
                 {
                   my_syslog(LOG_ERR, _("UBus error: %s"), err);
                   reset_option_bool(OPT_UBUS); /* fatal error, stop trying. */
                 }
             }
           
           check_ubus_listeners();
         }
 #endif  #endif
   
       check_dns_listeners(now);        check_dns_listeners(now);
Line 1426  static void async_event(int pipe, time_t now) Line 1489  static void async_event(int pipe, time_t now)
               }                }
   
             if (check)              if (check)
              check_servers();              check_servers(0);
           }            }
   
 #ifdef HAVE_DHCP  #ifdef HAVE_DHCP
Line 1537  static void async_event(int pipe, time_t now) Line 1600  static void async_event(int pipe, time_t now)
           {            {
             /* block in writes until all done */              /* block in writes until all done */
             if ((i = fcntl(daemon->helperfd, F_GETFL)) != -1)              if ((i = fcntl(daemon->helperfd, F_GETFL)) != -1)
              fcntl(daemon->helperfd, F_SETFL, i & ~O_NONBLOCK)              while(retry_send(fcntl(daemon->helperfd, F_SETFL, i & ~O_NONBLOCK)));
             do {              do {
               helper_write();                helper_write();
             } while (!helper_buf_empty() || do_script_run(now));              } while (!helper_buf_empty() || do_script_run(now));
Line 1607  static void poll_resolv(int force, int do_reload, time Line 1670  static void poll_resolv(int force, int do_reload, time
     else      else
       {        {
         res->logged = 0;          res->logged = 0;
        if (force || (statbuf.st_mtime != res->mtime))        if (force || (statbuf.st_mtime != res->mtime || statbuf.st_ino != res->ino))
           {            {
             res->mtime = statbuf.st_mtime;              res->mtime = statbuf.st_mtime;
               res->ino = statbuf.st_ino;
             if (difftime(statbuf.st_mtime, last_change) > 0.0)              if (difftime(statbuf.st_mtime, last_change) > 0.0)
               {                {
                 last_change = statbuf.st_mtime;                  last_change = statbuf.st_mtime;
Line 1625  static void poll_resolv(int force, int do_reload, time Line 1689  static void poll_resolv(int force, int do_reload, time
         {          {
           my_syslog(LOG_INFO, _("reading %s"), latest->name);            my_syslog(LOG_INFO, _("reading %s"), latest->name);
           warned = 0;            warned = 0;
          check_servers();          check_servers(0);
           if (option_bool(OPT_RELOAD) && do_reload)            if (option_bool(OPT_RELOAD) && do_reload)
             clear_cache_and_reload(now);              clear_cache_and_reload(now);
         }          }
       else         else 
         {          {
             /* If we're delaying things, we don't call check_servers(), but 
                reload_servers() may have deleted some servers, rendering the server_array
                invalid, so just rebuild that here. Once reload_servers() succeeds,
                we call check_servers() above, which calls build_server_array itself. */
             build_server_array();
           latest->mtime = 0;            latest->mtime = 0;
           if (!warned)            if (!warned)
             {              {
Line 1668  void clear_cache_and_reload(time_t now) Line 1737  void clear_cache_and_reload(time_t now)
 #endif  #endif
 }  }
   
static int set_dns_listeners(time_t now)static void set_dns_listeners(void)
 {  {
   struct serverfd *serverfdp;    struct serverfd *serverfdp;
   struct listener *listener;    struct listener *listener;
  int wait = 0, i;  struct randfd_list *rfl;
   int i;
       
 #ifdef HAVE_TFTP  #ifdef HAVE_TFTP
   int  tftp = 0;    int  tftp = 0;
Line 1685  static int set_dns_listeners(time_t now) Line 1755  static int set_dns_listeners(time_t now)
       }        }
 #endif  #endif
       
   /* will we be able to get memory? */  
   if (daemon->port != 0)  
     get_new_frec(now, &wait, NULL);  
     
   for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)    for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
     poll_listen(serverfdp->fd, POLLIN);      poll_listen(serverfdp->fd, POLLIN);
           
  if (daemon->port != 0 && !daemon->osport)  for (i = 0; i < daemon->numrrand; i++)
    for (i = 0; i < RANDOM_SOCKS; i++)    if (daemon->randomsocks[i].refcount != 0)
      if (daemon->randomsocks[i].refcount != 0)      poll_listen(daemon->randomsocks[i].fd, POLLIN);
        poll_listen(daemon->randomsocks[i].fd, POLLIN);
            /* Check overflow random sockets too. */
   for (rfl = daemon->rfl_poll; rfl; rfl = rfl->next)
     poll_listen(rfl->rfd->fd, POLLIN);
   
   /* check to see if we have free tcp process slots. */
   for (i = MAX_PROCS - 1; i >= 0; i--)
     if (daemon->tcp_pids[i] == 0 && daemon->tcp_pipes[i] == -1)
       break;
 
   for (listener = daemon->listeners; listener; listener = listener->next)    for (listener = daemon->listeners; listener; listener = listener->next)
     {      {
      /* only listen for queries if we have resources */      if (listener->fd != -1)
      if (listener->fd != -1 && wait == 0) 
         poll_listen(listener->fd, POLLIN);          poll_listen(listener->fd, POLLIN);
              
      /* death of a child goes through the select loop, so      /* Only listen for TCP connections when a process slot
         we don't need to explicitly arrange to wake up here */         is available. Death of a child goes through the select loop, so
      if  (listener->tcpfd != -1)         we don't need to explicitly arrange to wake up here,
        for (i = 0; i < MAX_PROCS; i++)         we'll be called again when a slot becomes available. */
          if (daemon->tcp_pids[i] == 0 && daemon->tcp_pipes[i] == -1)      if  (listener->tcpfd != -1 && i >= 0)
            {        poll_listen(listener->tcpfd, POLLIN);
              poll_listen(listener->tcpfd, POLLIN);      
              break; 
            } 
 
 #ifdef HAVE_TFTP  #ifdef HAVE_TFTP
       /* tftp == 0 in single-port mode. */        /* tftp == 0 in single-port mode. */
       if (tftp <= daemon->tftp_max && listener->tftpfd != -1)        if (tftp <= daemon->tftp_max && listener->tftpfd != -1)
         poll_listen(listener->tftpfd, POLLIN);          poll_listen(listener->tftpfd, POLLIN);
 #endif  #endif
   
     }      }
       
   if (!option_bool(OPT_DEBUG))    if (!option_bool(OPT_DEBUG))
     for (i = 0; i < MAX_PROCS; i++)      for (i = 0; i < MAX_PROCS; i++)
       if (daemon->tcp_pipes[i] != -1)        if (daemon->tcp_pipes[i] != -1)
         poll_listen(daemon->tcp_pipes[i], POLLIN);          poll_listen(daemon->tcp_pipes[i], POLLIN);
     
   return wait;  
 }  }
   
 static void check_dns_listeners(time_t now)  static void check_dns_listeners(time_t now)
 {  {
   struct serverfd *serverfdp;    struct serverfd *serverfdp;
   struct listener *listener;    struct listener *listener;
     struct randfd_list *rfl;
   int i;    int i;
   int pipefd[2];    int pipefd[2];
       
   for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)    for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
     if (poll_check(serverfdp->fd, POLLIN))      if (poll_check(serverfdp->fd, POLLIN))
      reply_query(serverfdp->fd, serverfdp->source_addr.sa.sa_family, now);      reply_query(serverfdp->fd, now);
       
  if (daemon->port != 0 && !daemon->osport)  for (i = 0; i < daemon->numrrand; i++)
    for (i = 0; i < RANDOM_SOCKS; i++)    if (daemon->randomsocks[i].refcount != 0 && 
      if (daemon->randomsocks[i].refcount != 0 &&         poll_check(daemon->randomsocks[i].fd, POLLIN))
          poll_check(daemon->randomsocks[i].fd, POLLIN))      reply_query(daemon->randomsocks[i].fd, now);
        reply_query(daemon->randomsocks[i].fd, daemon->randomsocks[i].family, now); 
   
     /* Check overflow random sockets too. */
     for (rfl = daemon->rfl_poll; rfl; rfl = rfl->next)
       if (poll_check(rfl->rfd->fd, POLLIN))
         reply_query(rfl->rfd->fd, now);
   
   /* Races. The child process can die before we read all of the data from the    /* Races. The child process can die before we read all of the data from the
      pipe, or vice versa. Therefore send tcp_pids to zero when we wait() the        pipe, or vice versa. Therefore send tcp_pids to zero when we wait() the 
      process, and tcp_pipes to -1 and close the FD when we read the last       process, and tcp_pipes to -1 and close the FD when we read the last
Line 1773  static void check_dns_listeners(time_t now) Line 1845  static void check_dns_listeners(time_t now)
         tftp_request(listener, now);          tftp_request(listener, now);
 #endif  #endif
   
      if (listener->tcpfd != -1 && poll_check(listener->tcpfd, POLLIN))      /* check to see if we have a free tcp process slot.
          Note that we can't assume that because we had
          at least one a poll() time, that we still do.
          There may be more waiting connections after
          poll() returns then free process slots. */
       for (i = MAX_PROCS - 1; i >= 0; i--)
         if (daemon->tcp_pids[i] == 0 && daemon->tcp_pipes[i] == -1)
           break;
 
       if (listener->tcpfd != -1 && i >= 0 && poll_check(listener->tcpfd, POLLIN))
         {          {
           int confd, client_ok = 1;            int confd, client_ok = 1;
           struct irec *iface = NULL;            struct irec *iface = NULL;
Line 1863  static void check_dns_listeners(time_t now) Line 1944  static void check_dns_listeners(time_t now)
                 close(pipefd[0]);                  close(pipefd[0]);
               else                else
                 {                  {
                   int i;  
 #ifdef HAVE_LINUX_NETWORK  #ifdef HAVE_LINUX_NETWORK
                   /* The child process inherits the netlink socket,                     /* The child process inherits the netlink socket, 
                      which it never uses, but when the parent (us)                        which it never uses, but when the parent (us) 
Line 1883  static void check_dns_listeners(time_t now) Line 1963  static void check_dns_listeners(time_t now)
                   read_write(pipefd[0], &a, 1, 1);                    read_write(pipefd[0], &a, 1, 1);
 #endif  #endif
   
                  for (i = 0; i < MAX_PROCS; i++)                  /* i holds index of free slot */
                    if (daemon->tcp_pids[i] == 0 && daemon->tcp_pipes[i] == -1)                  daemon->tcp_pids[i] = p;
                      {                  daemon->tcp_pipes[i] = pipefd[0];
                        daemon->tcp_pids[i] = p; 
                        daemon->tcp_pipes[i] = pipefd[0]; 
                        break; 
                      } 
                 }                  }
               close(confd);                close(confd);
   
Line 1939  static void check_dns_listeners(time_t now) Line 2015  static void check_dns_listeners(time_t now)
                  attribute from the listening socket.                    attribute from the listening socket. 
                  Reset that here. */                   Reset that here. */
               if ((flags = fcntl(confd, F_GETFL, 0)) != -1)                if ((flags = fcntl(confd, F_GETFL, 0)) != -1)
                fcntl(confd, F_SETFL, flags & ~O_NONBLOCK);                while(retry_send(fcntl(confd, F_SETFL, flags & ~O_NONBLOCK)));
                               
               buff = tcp_request(confd, now, &tcp_addr, netmask, auth_dns);                buff = tcp_request(confd, now, &tcp_addr, netmask, auth_dns);
                                 
               shutdown(confd, SHUT_RDWR);  
               close(confd);  
                 
               if (buff)                if (buff)
                 free(buff);                  free(buff);
                               
Line 2068  int delay_dhcp(time_t start, int sec, int fd, uint32_t Line 2141  int delay_dhcp(time_t start, int sec, int fd, uint32_t
       poll_reset();        poll_reset();
       if (fd != -1)        if (fd != -1)
         poll_listen(fd, POLLIN);          poll_listen(fd, POLLIN);
      set_dns_listeners(now);      set_dns_listeners();
       set_log_writer();        set_log_writer();
               
 #ifdef HAVE_DHCP6  #ifdef HAVE_DHCP6

Removed from v.1.1.1.4  
changed lines
  Added in v.1.1.1.5


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