File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / dnsmasq / src / dnsmasq.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 09:57:01 2016 UTC (7 years, 8 months ago) by misho
Branches: elwix, dnsmasq, MAIN
CVS tags: v2_76p1, HEAD
dnsmasq 2.76

    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: /* Declare static char *compiler_opts  in config.h */
   18: #define DNSMASQ_COMPILE_OPTS
   19: 
   20: #include "dnsmasq.h"
   21: 
   22: struct daemon *daemon;
   23: 
   24: static volatile pid_t pid = 0;
   25: static volatile int pipewrite;
   26: 
   27: static int set_dns_listeners(time_t now);
   28: static void check_dns_listeners(time_t now);
   29: static void sig_handler(int sig);
   30: static void async_event(int pipe, time_t now);
   31: static void fatal_event(struct event_desc *ev, char *msg);
   32: static int read_event(int fd, struct event_desc *evp, char **msg);
   33: static void poll_resolv(int force, int do_reload, time_t now);
   34: 
   35: int main (int argc, char **argv)
   36: {
   37:   int bind_fallback = 0;
   38:   time_t now;
   39:   struct sigaction sigact;
   40:   struct iname *if_tmp;
   41:   int piperead, pipefd[2], err_pipe[2];
   42:   struct passwd *ent_pw = NULL;
   43: #if defined(HAVE_SCRIPT)
   44:   uid_t script_uid = 0;
   45:   gid_t script_gid = 0;
   46: #endif
   47:   struct group *gp = NULL;
   48:   long i, max_fd = sysconf(_SC_OPEN_MAX);
   49:   char *baduser = NULL;
   50:   int log_err;
   51: #if defined(HAVE_LINUX_NETWORK)
   52:   cap_user_header_t hdr = NULL;
   53:   cap_user_data_t data = NULL;
   54:   char *bound_device = NULL;
   55:   int did_bind = 0;
   56: #endif 
   57: #if defined(HAVE_DHCP) || defined(HAVE_DHCP6)
   58:   struct dhcp_context *context;
   59:   struct dhcp_relay *relay;
   60: #endif
   61: #ifdef HAVE_TFTP
   62:   int tftp_prefix_missing = 0;
   63: #endif
   64: 
   65: #ifdef LOCALEDIR
   66:   setlocale(LC_ALL, "");
   67:   bindtextdomain("dnsmasq", LOCALEDIR); 
   68:   textdomain("dnsmasq");
   69: #endif
   70: 
   71:   sigact.sa_handler = sig_handler;
   72:   sigact.sa_flags = 0;
   73:   sigemptyset(&sigact.sa_mask);
   74:   sigaction(SIGUSR1, &sigact, NULL);
   75:   sigaction(SIGUSR2, &sigact, NULL);
   76:   sigaction(SIGHUP, &sigact, NULL);
   77:   sigaction(SIGTERM, &sigact, NULL);
   78:   sigaction(SIGALRM, &sigact, NULL);
   79:   sigaction(SIGCHLD, &sigact, NULL);
   80: 
   81:   /* ignore SIGPIPE */
   82:   sigact.sa_handler = SIG_IGN;
   83:   sigaction(SIGPIPE, &sigact, NULL);
   84: 
   85:   umask(022); /* known umask, create leases and pid files as 0644 */
   86:  
   87:   rand_init(); /* Must precede read_opts() */
   88:   
   89:   read_opts(argc, argv, compile_opts);
   90:  
   91:   if (daemon->edns_pktsz < PACKETSZ)
   92:     daemon->edns_pktsz = PACKETSZ;
   93: 
   94:   /* Min buffer size: we check after adding each record, so there must be 
   95:      memory for the largest packet, and the largest record so the
   96:      min for DNS is PACKETSZ+MAXDNAME+RRFIXEDSZ which is < 1000.
   97:      This might be increased is EDNS packet size if greater than the minimum. */ 
   98:   daemon->packet_buff_sz = daemon->edns_pktsz + MAXDNAME + RRFIXEDSZ;
   99:   daemon->packet = safe_malloc(daemon->packet_buff_sz);
  100:   
  101:   daemon->addrbuff = safe_malloc(ADDRSTRLEN);
  102:   if (option_bool(OPT_EXTRALOG))
  103:     daemon->addrbuff2 = safe_malloc(ADDRSTRLEN);
  104:   
  105: #ifdef HAVE_DNSSEC
  106:   if (option_bool(OPT_DNSSEC_VALID))
  107:     {
  108:       /* Note that both /000 and '.' are allowed within labels. These get
  109: 	 represented in presentation format using NAME_ESCAPE as an escape
  110: 	 character when in DNSSEC mode. 
  111: 	 In theory, if all the characters in a name were /000 or
  112: 	 '.' or NAME_ESCAPE then all would have to be escaped, so the 
  113: 	 presentation format would be twice as long as the spec.
  114: 
  115: 	 daemon->namebuff was previously allocated by the option-reading
  116: 	 code before we knew if we're in DNSSEC mode, so reallocate here. */
  117:       free(daemon->namebuff);
  118:       daemon->namebuff = safe_malloc(MAXDNAME * 2);
  119:       daemon->keyname = safe_malloc(MAXDNAME * 2);
  120:       daemon->workspacename = safe_malloc(MAXDNAME * 2);
  121:     }
  122: #endif
  123: 
  124: #ifdef HAVE_DHCP
  125:   if (!daemon->lease_file)
  126:     {
  127:       if (daemon->dhcp || daemon->dhcp6)
  128: 	daemon->lease_file = LEASEFILE;
  129:     }
  130: #endif
  131:   
  132:   /* Close any file descriptors we inherited apart from std{in|out|err} 
  133:      
  134:      Ensure that at least stdin, stdout and stderr (fd 0, 1, 2) exist,
  135:      otherwise file descriptors we create can end up being 0, 1, or 2 
  136:      and then get accidentally closed later when we make 0, 1, and 2 
  137:      open to /dev/null. Normally we'll be started with 0, 1 and 2 open, 
  138:      but it's not guaranteed. By opening /dev/null three times, we 
  139:      ensure that we're not using those fds for real stuff. */
  140:   for (i = 0; i < max_fd; i++)
  141:     if (i != STDOUT_FILENO && i != STDERR_FILENO && i != STDIN_FILENO)
  142:       close(i);
  143:     else
  144:       open("/dev/null", O_RDWR); 
  145: 
  146: #ifndef HAVE_LINUX_NETWORK
  147: #  if !(defined(IP_RECVDSTADDR) && defined(IP_RECVIF) && defined(IP_SENDSRCADDR))
  148:   if (!option_bool(OPT_NOWILD))
  149:     {
  150:       bind_fallback = 1;
  151:       set_option_bool(OPT_NOWILD);
  152:     }
  153: #  endif
  154:   
  155:   /* -- bind-dynamic not supported on !Linux, fall back to --bind-interfaces */
  156:   if (option_bool(OPT_CLEVERBIND))
  157:     {
  158:       bind_fallback = 1;
  159:       set_option_bool(OPT_NOWILD);
  160:       reset_option_bool(OPT_CLEVERBIND);
  161:     }
  162: #endif
  163: 
  164: #ifndef HAVE_INOTIFY
  165:   if (daemon->dynamic_dirs)
  166:     die(_("dhcp-hostsdir, dhcp-optsdir and hostsdir are not supported on this platform"), NULL, EC_BADCONF);
  167: #endif
  168:   
  169:   if (option_bool(OPT_DNSSEC_VALID))
  170:     {
  171: #ifdef HAVE_DNSSEC
  172:       struct ds_config *ds;
  173: 
  174:       /* Must have at least a root trust anchor, or the DNSSEC code
  175: 	 can loop forever. */
  176:       for (ds = daemon->ds; ds; ds = ds->next)
  177: 	if (ds->name[0] == 0)
  178: 	  break;
  179: 
  180:       if (!ds)
  181: 	die(_("no root trust anchor provided for DNSSEC"), NULL, EC_BADCONF);
  182:       
  183:       if (daemon->cachesize < CACHESIZ)
  184: 	die(_("cannot reduce cache size from default when DNSSEC enabled"), NULL, EC_BADCONF);
  185: #else 
  186:       die(_("DNSSEC not available: set HAVE_DNSSEC in src/config.h"), NULL, EC_BADCONF);
  187: #endif
  188:     }
  189: 
  190: #ifndef HAVE_TFTP
  191:   if (option_bool(OPT_TFTP))
  192:     die(_("TFTP server not available: set HAVE_TFTP in src/config.h"), NULL, EC_BADCONF);
  193: #endif
  194: 
  195: #ifdef HAVE_CONNTRACK
  196:   if (option_bool(OPT_CONNTRACK) && (daemon->query_port != 0 || daemon->osport))
  197:     die (_("cannot use --conntrack AND --query-port"), NULL, EC_BADCONF); 
  198: #else
  199:   if (option_bool(OPT_CONNTRACK))
  200:     die(_("conntrack support not available: set HAVE_CONNTRACK in src/config.h"), NULL, EC_BADCONF);
  201: #endif
  202: 
  203: #ifdef HAVE_SOLARIS_NETWORK
  204:   if (daemon->max_logs != 0)
  205:     die(_("asychronous logging is not available under Solaris"), NULL, EC_BADCONF);
  206: #endif
  207:   
  208: #ifdef __ANDROID__
  209:   if (daemon->max_logs != 0)
  210:     die(_("asychronous logging is not available under Android"), NULL, EC_BADCONF);
  211: #endif
  212: 
  213: #ifndef HAVE_AUTH
  214:   if (daemon->authserver)
  215:     die(_("authoritative DNS not available: set HAVE_AUTH in src/config.h"), NULL, EC_BADCONF);
  216: #endif
  217: 
  218: #ifndef HAVE_LOOP
  219:   if (option_bool(OPT_LOOP_DETECT))
  220:     die(_("loop detection not available: set HAVE_LOOP in src/config.h"), NULL, EC_BADCONF);
  221: #endif
  222: 
  223:   if (daemon->max_port != MAX_PORT && daemon->min_port == 0)
  224:     daemon->min_port = 1024u;
  225: 
  226:   if (daemon->max_port < daemon->min_port)
  227:     die(_("max_port cannot be smaller than min_port"), NULL, EC_BADCONF);
  228: 
  229:   now = dnsmasq_time();
  230: 
  231:   /* Create a serial at startup if not configured. */
  232:   if (daemon->authinterface && daemon->soa_sn == 0)
  233: #ifdef HAVE_BROKEN_RTC
  234:     die(_("zone serial must be configured in --auth-soa"), NULL, EC_BADCONF);
  235: #else
  236:   daemon->soa_sn = now;
  237: #endif
  238:   
  239: #ifdef HAVE_DHCP6
  240:   if (daemon->dhcp6)
  241:     {
  242:       daemon->doing_ra = option_bool(OPT_RA);
  243:       
  244:       for (context = daemon->dhcp6; context; context = context->next)
  245: 	{
  246: 	  if (context->flags & CONTEXT_DHCP)
  247: 	    daemon->doing_dhcp6 = 1;
  248: 	  if (context->flags & CONTEXT_RA)
  249: 	    daemon->doing_ra = 1;
  250: #if !defined(HAVE_LINUX_NETWORK) && !defined(HAVE_BSD_NETWORK)
  251: 	  if (context->flags & CONTEXT_TEMPLATE)
  252: 	    die (_("dhcp-range constructor not available on this platform"), NULL, EC_BADCONF);
  253: #endif 
  254: 	}
  255:     }
  256: #endif
  257:   
  258: #ifdef HAVE_DHCP
  259:   /* Note that order matters here, we must call lease_init before
  260:      creating any file descriptors which shouldn't be leaked
  261:      to the lease-script init process. We need to call common_init
  262:      before lease_init to allocate buffers it uses.
  263:      The script subsystem relies on DHCP buffers, hence the last two
  264:      conditions below. */  
  265:   if (daemon->dhcp || daemon->doing_dhcp6 || daemon->relay4 || 
  266:       daemon->relay6 || option_bool(OPT_TFTP) || option_bool(OPT_SCRIPT_ARP))
  267:     {
  268:       dhcp_common_init();
  269:       if (daemon->dhcp || daemon->doing_dhcp6)
  270: 	lease_init(now);
  271:     }
  272:   
  273:   if (daemon->dhcp || daemon->relay4)
  274:     dhcp_init();
  275:   
  276: #  ifdef HAVE_DHCP6
  277:   if (daemon->doing_ra || daemon->doing_dhcp6 || daemon->relay6)
  278:     ra_init(now);
  279:   
  280:   if (daemon->doing_dhcp6 || daemon->relay6)
  281:     dhcp6_init();
  282: #  endif
  283: 
  284: #endif
  285: 
  286: #ifdef HAVE_IPSET
  287:   if (daemon->ipsets)
  288:     ipset_init();
  289: #endif
  290: 
  291: #if  defined(HAVE_LINUX_NETWORK)
  292:   netlink_init();
  293: #elif defined(HAVE_BSD_NETWORK)
  294:   route_init();
  295: #endif
  296: 
  297:   if (option_bool(OPT_NOWILD) && option_bool(OPT_CLEVERBIND))
  298:     die(_("cannot set --bind-interfaces and --bind-dynamic"), NULL, EC_BADCONF);
  299:   
  300:   if (!enumerate_interfaces(1) || !enumerate_interfaces(0))
  301:     die(_("failed to find list of interfaces: %s"), NULL, EC_MISC);
  302:   
  303:   if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND)) 
  304:     {
  305:       create_bound_listeners(1);
  306:       
  307:       if (!option_bool(OPT_CLEVERBIND))
  308: 	for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
  309: 	  if (if_tmp->name && !if_tmp->used)
  310: 	    die(_("unknown interface %s"), if_tmp->name, EC_BADNET);
  311: 
  312: #if defined(HAVE_LINUX_NETWORK) && defined(HAVE_DHCP)
  313:       /* after enumerate_interfaces()  */
  314:       bound_device = whichdevice();
  315:       
  316:       if (daemon->dhcp)
  317: 	{
  318: 	  if (!daemon->relay4 && bound_device)
  319: 	    {
  320: 	      bindtodevice(bound_device, daemon->dhcpfd);
  321: 	      did_bind = 1;
  322: 	    }
  323: 	  if (daemon->enable_pxe && bound_device)
  324: 	    {
  325: 	      bindtodevice(bound_device, daemon->pxefd);
  326: 	      did_bind = 1;
  327: 	    }
  328: 	}
  329: #endif
  330: 
  331: #if defined(HAVE_LINUX_NETWORK) && defined(HAVE_DHCP6)
  332:       if (daemon->doing_dhcp6 && !daemon->relay6 && bound_device)
  333: 	{
  334: 	  bindtodevice(bound_device, daemon->dhcp6fd);
  335: 	  did_bind = 1;
  336: 	}
  337: #endif
  338:     }
  339:   else 
  340:     create_wildcard_listeners();
  341:  
  342: #ifdef HAVE_DHCP6
  343:   /* after enumerate_interfaces() */
  344:   if (daemon->doing_dhcp6 || daemon->relay6 || daemon->doing_ra)
  345:     join_multicast(1);
  346: 
  347:   /* After netlink_init() and before create_helper() */
  348:   lease_make_duid(now);
  349: #endif
  350:   
  351:   if (daemon->port != 0)
  352:     {
  353:       cache_init();
  354: 
  355: #ifdef HAVE_DNSSEC
  356:       blockdata_init();
  357: #endif
  358:     }
  359: 
  360: #ifdef HAVE_INOTIFY
  361:   if (daemon->port != 0 || daemon->dhcp || daemon->doing_dhcp6)
  362:     inotify_dnsmasq_init();
  363:   else
  364:     daemon->inotifyfd = -1;
  365: #endif
  366:        
  367:   if (option_bool(OPT_DBUS))
  368: #ifdef HAVE_DBUS
  369:     {
  370:       char *err;
  371:       daemon->dbus = NULL;
  372:       daemon->watches = NULL;
  373:       if ((err = dbus_init()))
  374: 	die(_("DBus error: %s"), err, EC_MISC);
  375:     }
  376: #else
  377:   die(_("DBus not available: set HAVE_DBUS in src/config.h"), NULL, EC_BADCONF);
  378: #endif
  379: 
  380:   if (daemon->port != 0)
  381:     pre_allocate_sfds();
  382: 
  383: #if defined(HAVE_SCRIPT)
  384:   /* Note getpwnam returns static storage */
  385:   if ((daemon->dhcp || daemon->dhcp6) && 
  386:       daemon->scriptuser && 
  387:       (daemon->lease_change_command || daemon->luascript))
  388:     {
  389:       if ((ent_pw = getpwnam(daemon->scriptuser)))
  390: 	{
  391: 	  script_uid = ent_pw->pw_uid;
  392: 	  script_gid = ent_pw->pw_gid;
  393: 	 }
  394:       else
  395: 	baduser = daemon->scriptuser;
  396:     }
  397: #endif
  398:   
  399:   if (daemon->username && !(ent_pw = getpwnam(daemon->username)))
  400:     baduser = daemon->username;
  401:   else if (daemon->groupname && !(gp = getgrnam(daemon->groupname)))
  402:     baduser = daemon->groupname;
  403: 
  404:   if (baduser)
  405:     die(_("unknown user or group: %s"), baduser, EC_BADCONF);
  406: 
  407:   /* implement group defaults, "dip" if available, or group associated with uid */
  408:   if (!daemon->group_set && !gp)
  409:     {
  410:       if (!(gp = getgrnam(CHGRP)) && ent_pw)
  411: 	gp = getgrgid(ent_pw->pw_gid);
  412:       
  413:       /* for error message */
  414:       if (gp)
  415: 	daemon->groupname = gp->gr_name; 
  416:     }
  417: 
  418: #if defined(HAVE_LINUX_NETWORK)
  419:   /* determine capability API version here, while we can still
  420:      call safe_malloc */
  421:   if (ent_pw && ent_pw->pw_uid != 0)
  422:     {
  423:       int capsize = 1; /* for header version 1 */
  424:       hdr = safe_malloc(sizeof(*hdr));
  425: 
  426:       /* find version supported by kernel */
  427:       memset(hdr, 0, sizeof(*hdr));
  428:       capget(hdr, NULL);
  429:       
  430:       if (hdr->version != LINUX_CAPABILITY_VERSION_1)
  431: 	{
  432: 	  /* if unknown version, use largest supported version (3) */
  433: 	  if (hdr->version != LINUX_CAPABILITY_VERSION_2)
  434: 	    hdr->version = LINUX_CAPABILITY_VERSION_3;
  435: 	  capsize = 2;
  436: 	}
  437:       
  438:       data = safe_malloc(sizeof(*data) * capsize);
  439:       memset(data, 0, sizeof(*data) * capsize);
  440:     }
  441: #endif
  442: 
  443:   /* Use a pipe to carry signals and other events back to the event loop 
  444:      in a race-free manner and another to carry errors to daemon-invoking process */
  445:   safe_pipe(pipefd, 1);
  446:   
  447:   piperead = pipefd[0];
  448:   pipewrite = pipefd[1];
  449:   /* prime the pipe to load stuff first time. */
  450:   send_event(pipewrite, EVENT_INIT, 0, NULL); 
  451: 
  452:   err_pipe[1] = -1;
  453:   
  454:   if (!option_bool(OPT_DEBUG))   
  455:     {
  456:       /* The following code "daemonizes" the process. 
  457: 	 See Stevens section 12.4 */
  458:       
  459:       if (chdir("/") != 0)
  460: 	die(_("cannot chdir to filesystem root: %s"), NULL, EC_MISC); 
  461: 
  462: #ifndef NO_FORK      
  463:       if (!option_bool(OPT_NO_FORK))
  464: 	{
  465: 	  pid_t pid;
  466: 	  
  467: 	  /* pipe to carry errors back to original process.
  468: 	     When startup is complete we close this and the process terminates. */
  469: 	  safe_pipe(err_pipe, 0);
  470: 	  
  471: 	  if ((pid = fork()) == -1)
  472: 	    /* fd == -1 since we've not forked, never returns. */
  473: 	    send_event(-1, EVENT_FORK_ERR, errno, NULL);
  474: 	   
  475: 	  if (pid != 0)
  476: 	    {
  477: 	      struct event_desc ev;
  478: 	      char *msg;
  479: 
  480: 	      /* close our copy of write-end */
  481: 	      while (retry_send(close(err_pipe[1])));
  482: 	      
  483: 	      /* check for errors after the fork */
  484: 	      if (read_event(err_pipe[0], &ev, &msg))
  485: 		fatal_event(&ev, msg);
  486: 	      
  487: 	      _exit(EC_GOOD);
  488: 	    } 
  489: 	  
  490: 	  while (retry_send(close(err_pipe[0])));
  491: 
  492: 	  /* NO calls to die() from here on. */
  493: 	  
  494: 	  setsid();
  495: 	 
  496: 	  if ((pid = fork()) == -1)
  497: 	    send_event(err_pipe[1], EVENT_FORK_ERR, errno, NULL);
  498: 	 
  499: 	  if (pid != 0)
  500: 	    _exit(0);
  501: 	}
  502: #endif
  503:             
  504:       /* write pidfile _after_ forking ! */
  505:       if (daemon->runfile)
  506: 	{
  507: 	  int fd, err = 0;
  508: 
  509: 	  sprintf(daemon->namebuff, "%d\n", (int) getpid());
  510: 
  511: 	  /* Explanation: Some installations of dnsmasq (eg Debian/Ubuntu) locate the pid-file
  512: 	     in a directory which is writable by the non-privileged user that dnsmasq runs as. This
  513: 	     allows the daemon to delete the file as part of its shutdown. This is a security hole to the 
  514: 	     extent that an attacker running as the unprivileged  user could replace the pidfile with a 
  515: 	     symlink, and have the target of that symlink overwritten as root next time dnsmasq starts. 
  516: 
  517: 	     The folowing code first deletes any existing file, and then opens it with the O_EXCL flag,
  518: 	     ensuring that the open() fails should there be any existing file (because the unlink() failed, 
  519: 	     or an attacker exploited the race between unlink() and open()). This ensures that no symlink
  520: 	     attack can succeed. 
  521: 
  522: 	     Any compromise of the non-privileged user still theoretically allows the pid-file to be
  523: 	     replaced whilst dnsmasq is running. The worst that could allow is that the usual 
  524: 	     "shutdown dnsmasq" shell command could be tricked into stopping any other process.
  525: 
  526: 	     Note that if dnsmasq is started as non-root (eg for testing) it silently ignores 
  527: 	     failure to write the pid-file.
  528: 	  */
  529: 
  530: 	  unlink(daemon->runfile); 
  531: 	  
  532: 	  if ((fd = open(daemon->runfile, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH)) == -1)
  533: 	    {
  534: 	      /* only complain if started as root */
  535: 	      if (getuid() == 0)
  536: 		err = 1;
  537: 	    }
  538: 	  else
  539: 	    {
  540: 	      if (!read_write(fd, (unsigned char *)daemon->namebuff, strlen(daemon->namebuff), 0))
  541: 		err = 1;
  542: 	      else 
  543: 		{
  544: 		  while (retry_send(close(fd)));
  545: 		  if (errno != 0)
  546: 		    err = 1;
  547: 		}
  548: 	    }
  549: 
  550: 	  if (err)
  551: 	    {
  552: 	      send_event(err_pipe[1], EVENT_PIDFILE, errno, daemon->runfile);
  553: 	      _exit(0);
  554: 	    }
  555: 	}
  556:     }
  557:   
  558:    log_err = log_start(ent_pw, err_pipe[1]);
  559: 
  560:    if (!option_bool(OPT_DEBUG)) 
  561:      {       
  562:        /* open  stdout etc to /dev/null */
  563:        int nullfd = open("/dev/null", O_RDWR);
  564:        if (nullfd != -1)
  565: 	 {
  566: 	   dup2(nullfd, STDOUT_FILENO);
  567: 	   dup2(nullfd, STDERR_FILENO);
  568: 	   dup2(nullfd, STDIN_FILENO);
  569: 	   close(nullfd);
  570: 	 }
  571:      }
  572:    
  573:    /* if we are to run scripts, we need to fork a helper before dropping root. */
  574:   daemon->helperfd = -1;
  575: #ifdef HAVE_SCRIPT 
  576:   if ((daemon->dhcp || daemon->dhcp6 || option_bool(OPT_TFTP) || option_bool(OPT_SCRIPT_ARP)) && 
  577:       (daemon->lease_change_command || daemon->luascript))
  578:       daemon->helperfd = create_helper(pipewrite, err_pipe[1], script_uid, script_gid, max_fd);
  579: #endif
  580: 
  581:   if (!option_bool(OPT_DEBUG) && getuid() == 0)   
  582:     {
  583:       int bad_capabilities = 0;
  584:       gid_t dummy;
  585:       
  586:       /* remove all supplimentary groups */
  587:       if (gp && 
  588: 	  (setgroups(0, &dummy) == -1 ||
  589: 	   setgid(gp->gr_gid) == -1))
  590: 	{
  591: 	  send_event(err_pipe[1], EVENT_GROUP_ERR, errno, daemon->groupname);
  592: 	  _exit(0);
  593: 	}
  594:   
  595:       if (ent_pw && ent_pw->pw_uid != 0)
  596: 	{     
  597: #if defined(HAVE_LINUX_NETWORK)	  
  598: 	  /* On linux, we keep CAP_NETADMIN (for ARP-injection) and
  599: 	     CAP_NET_RAW (for icmp) if we're doing dhcp. If we have yet to bind 
  600: 	     ports because of DAD, or we're doing it dynamically,
  601: 	     we need CAP_NET_BIND_SERVICE too. */
  602: 	  if (is_dad_listeners() || option_bool(OPT_CLEVERBIND))
  603: 	    data->effective = data->permitted = data->inheritable =
  604: 	      (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW) | 
  605: 	      (1 << CAP_SETUID) | (1 << CAP_NET_BIND_SERVICE);
  606: 	  else
  607: 	    data->effective = data->permitted = data->inheritable =
  608: 	      (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW) | (1 << CAP_SETUID);
  609: 	  
  610: 	  /* Tell kernel to not clear capabilities when dropping root */
  611: 	  if (capset(hdr, data) == -1 || prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1)
  612: 	    bad_capabilities = errno;
  613: 			  
  614: #elif defined(HAVE_SOLARIS_NETWORK)
  615: 	  /* http://developers.sun.com/solaris/articles/program_privileges.html */
  616: 	  priv_set_t *priv_set;
  617: 	  
  618: 	  if (!(priv_set = priv_str_to_set("basic", ",", NULL)) ||
  619: 	      priv_addset(priv_set, PRIV_NET_ICMPACCESS) == -1 ||
  620: 	      priv_addset(priv_set, PRIV_SYS_NET_CONFIG) == -1)
  621: 	    bad_capabilities = errno;
  622: 
  623: 	  if (priv_set && bad_capabilities == 0)
  624: 	    {
  625: 	      priv_inverse(priv_set);
  626: 	  
  627: 	      if (setppriv(PRIV_OFF, PRIV_LIMIT, priv_set) == -1)
  628: 		bad_capabilities = errno;
  629: 	    }
  630: 
  631: 	  if (priv_set)
  632: 	    priv_freeset(priv_set);
  633: 
  634: #endif    
  635: 
  636: 	  if (bad_capabilities != 0)
  637: 	    {
  638: 	      send_event(err_pipe[1], EVENT_CAP_ERR, bad_capabilities, NULL);
  639: 	      _exit(0);
  640: 	    }
  641: 	  
  642: 	  /* finally drop root */
  643: 	  if (setuid(ent_pw->pw_uid) == -1)
  644: 	    {
  645: 	      send_event(err_pipe[1], EVENT_USER_ERR, errno, daemon->username);
  646: 	      _exit(0);
  647: 	    }     
  648: 
  649: #ifdef HAVE_LINUX_NETWORK
  650: 	  if (is_dad_listeners() || option_bool(OPT_CLEVERBIND))
  651: 	   data->effective = data->permitted =
  652: 	     (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW) | (1 << CAP_NET_BIND_SERVICE);
  653: 	 else
  654: 	   data->effective = data->permitted = 
  655: 	     (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW);
  656: 	  data->inheritable = 0;
  657: 	  
  658: 	  /* lose the setuid and setgid capbilities */
  659: 	  if (capset(hdr, data) == -1)
  660: 	    {
  661: 	      send_event(err_pipe[1], EVENT_CAP_ERR, errno, NULL);
  662: 	      _exit(0);
  663: 	    }
  664: #endif
  665: 	  
  666: 	}
  667:     }
  668:   
  669: #ifdef HAVE_LINUX_NETWORK
  670:   free(hdr);
  671:   free(data);
  672:   if (option_bool(OPT_DEBUG)) 
  673:     prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
  674: #endif
  675: 
  676: #ifdef HAVE_TFTP
  677:   if (option_bool(OPT_TFTP))
  678:     {
  679:       DIR *dir;
  680:       struct tftp_prefix *p;
  681:       
  682:       if (daemon->tftp_prefix)
  683: 	{
  684: 	  if (!((dir = opendir(daemon->tftp_prefix))))
  685: 	    {
  686: 	      tftp_prefix_missing = 1;
  687: 	      if (!option_bool(OPT_TFTP_NO_FAIL))
  688: 	        {
  689: 	          send_event(err_pipe[1], EVENT_TFTP_ERR, errno, daemon->tftp_prefix);
  690: 	          _exit(0);
  691: 	        }
  692: 	    }
  693: 	  else
  694: 	    closedir(dir);
  695: 	}
  696: 
  697:       for (p = daemon->if_prefix; p; p = p->next)
  698: 	{
  699: 	  p->missing = 0;
  700: 	  if (!((dir = opendir(p->prefix))))
  701: 	    {
  702: 	      p->missing = 1;
  703: 	      if (!option_bool(OPT_TFTP_NO_FAIL))
  704: 		{
  705: 		  send_event(err_pipe[1], EVENT_TFTP_ERR, errno, p->prefix);
  706: 		  _exit(0);
  707: 		}
  708: 	    }
  709: 	  else
  710: 	    closedir(dir);
  711: 	}
  712:     }
  713: #endif
  714: 
  715:   if (daemon->port == 0)
  716:     my_syslog(LOG_INFO, _("started, version %s DNS disabled"), VERSION);
  717:   else if (daemon->cachesize != 0)
  718:     my_syslog(LOG_INFO, _("started, version %s cachesize %d"), VERSION, daemon->cachesize);
  719:   else
  720:     my_syslog(LOG_INFO, _("started, version %s cache disabled"), VERSION);
  721:   
  722:   my_syslog(LOG_INFO, _("compile time options: %s"), compile_opts);
  723:   
  724: #ifdef HAVE_DBUS
  725:   if (option_bool(OPT_DBUS))
  726:     {
  727:       if (daemon->dbus)
  728: 	my_syslog(LOG_INFO, _("DBus support enabled: connected to system bus"));
  729:       else
  730: 	my_syslog(LOG_INFO, _("DBus support enabled: bus connection pending"));
  731:     }
  732: #endif
  733: 
  734:   if (option_bool(OPT_LOCAL_SERVICE))
  735:     my_syslog(LOG_INFO, _("DNS service limited to local subnets"));
  736:   
  737: #ifdef HAVE_DNSSEC
  738:   if (option_bool(OPT_DNSSEC_VALID))
  739:     {
  740:       int rc;
  741: 
  742:       /* Delay creating the timestamp file until here, after we've changed user, so that
  743: 	 it has the correct owner to allow updating the mtime later. 
  744: 	 This means we have to report fatal errors via the pipe. */
  745:       if ((rc = setup_timestamp()) == -1)
  746: 	{
  747: 	  send_event(err_pipe[1], EVENT_TIME_ERR, errno, daemon->timestamp_file);
  748: 	  _exit(0);
  749: 	}
  750:       
  751:       my_syslog(LOG_INFO, _("DNSSEC validation enabled"));
  752:       
  753:       if (option_bool(OPT_DNSSEC_TIME))
  754: 	my_syslog(LOG_INFO, _("DNSSEC signature timestamps not checked until first cache reload"));
  755:       
  756:       if (rc == 1)
  757: 	my_syslog(LOG_INFO, _("DNSSEC signature timestamps not checked until system time valid"));
  758:     }
  759: #endif
  760: 
  761:   if (log_err != 0)
  762:     my_syslog(LOG_WARNING, _("warning: failed to change owner of %s: %s"), 
  763: 	      daemon->log_file, strerror(log_err));
  764:   
  765:   if (bind_fallback)
  766:     my_syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations"));
  767: 
  768:   if (option_bool(OPT_NOWILD))
  769:     warn_bound_listeners();
  770: 
  771:   warn_int_names();
  772:   
  773:   if (!option_bool(OPT_NOWILD)) 
  774:     for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
  775:       if (if_tmp->name && !if_tmp->used)
  776: 	my_syslog(LOG_WARNING, _("warning: interface %s does not currently exist"), if_tmp->name);
  777:    
  778:   if (daemon->port != 0 && option_bool(OPT_NO_RESOLV))
  779:     {
  780:       if (daemon->resolv_files && !daemon->resolv_files->is_default)
  781: 	my_syslog(LOG_WARNING, _("warning: ignoring resolv-file flag because no-resolv is set"));
  782:       daemon->resolv_files = NULL;
  783:       if (!daemon->servers)
  784: 	my_syslog(LOG_WARNING, _("warning: no upstream servers configured"));
  785:     } 
  786: 
  787:   if (daemon->max_logs != 0)
  788:     my_syslog(LOG_INFO, _("asynchronous logging enabled, queue limit is %d messages"), daemon->max_logs);
  789:   
  790: 
  791: #ifdef HAVE_DHCP
  792:   for (context = daemon->dhcp; context; context = context->next)
  793:     log_context(AF_INET, context);
  794: 
  795:   for (relay = daemon->relay4; relay; relay = relay->next)
  796:     log_relay(AF_INET, relay);
  797: 
  798: #  ifdef HAVE_DHCP6
  799:   for (context = daemon->dhcp6; context; context = context->next)
  800:     log_context(AF_INET6, context);
  801: 
  802:   for (relay = daemon->relay6; relay; relay = relay->next)
  803:     log_relay(AF_INET6, relay);
  804:   
  805:   if (daemon->doing_dhcp6 || daemon->doing_ra)
  806:     dhcp_construct_contexts(now);
  807:   
  808:   if (option_bool(OPT_RA))
  809:     my_syslog(MS_DHCP | LOG_INFO, _("IPv6 router advertisement enabled"));
  810: #  endif
  811: 
  812: #  ifdef HAVE_LINUX_NETWORK
  813:   if (did_bind)
  814:     my_syslog(MS_DHCP | LOG_INFO, _("DHCP, sockets bound exclusively to interface %s"), bound_device);
  815: #  endif
  816: 
  817:   /* after dhcp_contruct_contexts */
  818:   if (daemon->dhcp || daemon->doing_dhcp6)
  819:     lease_find_interfaces(now);
  820: #endif
  821: 
  822: #ifdef HAVE_TFTP
  823:   if (option_bool(OPT_TFTP))
  824:     {
  825:       struct tftp_prefix *p;
  826: 
  827:       my_syslog(MS_TFTP | LOG_INFO, "TFTP %s%s %s", 
  828: 		daemon->tftp_prefix ? _("root is ") : _("enabled"),
  829: 		daemon->tftp_prefix ? daemon->tftp_prefix: "",
  830: 		option_bool(OPT_TFTP_SECURE) ? _("secure mode") : "");
  831: 
  832:       if (tftp_prefix_missing)
  833: 	my_syslog(MS_TFTP | LOG_WARNING, _("warning: %s inaccessible"), daemon->tftp_prefix);
  834: 
  835:       for (p = daemon->if_prefix; p; p = p->next)
  836: 	if (p->missing)
  837: 	   my_syslog(MS_TFTP | LOG_WARNING, _("warning: TFTP directory %s inaccessible"), p->prefix);
  838: 
  839:       /* This is a guess, it assumes that for small limits, 
  840: 	 disjoint files might be served, but for large limits, 
  841: 	 a single file will be sent to may clients (the file only needs
  842: 	 one fd). */
  843: 
  844:       max_fd -= 30; /* use other than TFTP */
  845:       
  846:       if (max_fd < 0)
  847: 	max_fd = 5;
  848:       else if (max_fd < 100)
  849: 	max_fd = max_fd/2;
  850:       else
  851: 	max_fd = max_fd - 20;
  852:       
  853:       /* if we have to use a limited range of ports, 
  854: 	 that will limit the number of transfers */
  855:       if (daemon->start_tftp_port != 0 &&
  856: 	  daemon->end_tftp_port - daemon->start_tftp_port + 1 < max_fd)
  857: 	max_fd = daemon->end_tftp_port - daemon->start_tftp_port + 1;
  858: 
  859:       if (daemon->tftp_max > max_fd)
  860: 	{
  861: 	  daemon->tftp_max = max_fd;
  862: 	  my_syslog(MS_TFTP | LOG_WARNING, 
  863: 		    _("restricting maximum simultaneous TFTP transfers to %d"), 
  864: 		    daemon->tftp_max);
  865: 	}
  866:     }
  867: #endif
  868: 
  869:   /* finished start-up - release original process */
  870:   if (err_pipe[1] != -1)
  871:     while (retry_send(close(err_pipe[1])));
  872:   
  873:   if (daemon->port != 0)
  874:     check_servers();
  875:   
  876:   pid = getpid();
  877:   
  878: #ifdef HAVE_INOTIFY
  879:   /* Using inotify, have to select a resolv file at startup */
  880:   poll_resolv(1, 0, now);
  881: #endif
  882:   
  883:   while (1)
  884:     {
  885:       int t, timeout = -1;
  886:       
  887:       poll_reset();
  888:       
  889:       /* if we are out of resources, find how long we have to wait
  890: 	 for some to come free, we'll loop around then and restart
  891: 	 listening for queries */
  892:       if ((t = set_dns_listeners(now)) != 0)
  893: 	timeout = t * 1000;
  894: 
  895:       /* Whilst polling for the dbus, or doing a tftp transfer, wake every quarter second */
  896:       if (daemon->tftp_trans ||
  897: 	  (option_bool(OPT_DBUS) && !daemon->dbus))
  898: 	timeout = 250;
  899: 
  900:       /* Wake every second whilst waiting for DAD to complete */
  901:       else if (is_dad_listeners())
  902: 	timeout = 1000;
  903: 
  904: #ifdef HAVE_DBUS
  905:       set_dbus_listeners();
  906: #endif	
  907:   
  908: #ifdef HAVE_DHCP
  909:       if (daemon->dhcp || daemon->relay4)
  910: 	{
  911: 	  poll_listen(daemon->dhcpfd, POLLIN);
  912: 	  if (daemon->pxefd != -1)
  913: 	    poll_listen(daemon->pxefd, POLLIN);
  914: 	}
  915: #endif
  916: 
  917: #ifdef HAVE_DHCP6
  918:       if (daemon->doing_dhcp6 || daemon->relay6)
  919: 	poll_listen(daemon->dhcp6fd, POLLIN);
  920: 	
  921:       if (daemon->doing_ra)
  922: 	poll_listen(daemon->icmp6fd, POLLIN); 
  923: #endif
  924:     
  925: #ifdef HAVE_INOTIFY
  926:       if (daemon->inotifyfd != -1)
  927: 	poll_listen(daemon->inotifyfd, POLLIN);
  928: #endif
  929: 
  930: #if defined(HAVE_LINUX_NETWORK)
  931:       poll_listen(daemon->netlinkfd, POLLIN);
  932: #elif defined(HAVE_BSD_NETWORK)
  933:       poll_listen(daemon->routefd, POLLIN);
  934: #endif
  935:       
  936:       poll_listen(piperead, POLLIN);
  937: 
  938: #ifdef HAVE_SCRIPT
  939: #    ifdef HAVE_DHCP
  940:       while (helper_buf_empty() && do_script_run(now)); 
  941: #    endif
  942: 
  943:       /* Refresh cache */
  944:       if (option_bool(OPT_SCRIPT_ARP))
  945: 	find_mac(NULL, NULL, 0, now);
  946:       while (helper_buf_empty() && do_arp_script_run());
  947: 
  948: #    ifdef HAVE_TFTP
  949:       while (helper_buf_empty() && do_tftp_script_run());
  950: #    endif
  951: 
  952:       if (!helper_buf_empty())
  953: 	poll_listen(daemon->helperfd, POLLOUT);
  954: #else
  955:       /* need this for other side-effects */
  956: #    ifdef HAVE_DHCP
  957:       while (do_script_run(now));
  958: #    endif
  959: 
  960:       while (do_arp_script_run());
  961: 
  962: #    ifdef HAVE_TFTP 
  963:       while (do_tftp_script_run());
  964: #    endif
  965: 
  966: #endif
  967: 
  968:    
  969:       /* must do this just before select(), when we know no
  970: 	 more calls to my_syslog() can occur */
  971:       set_log_writer();
  972:       
  973:       if (do_poll(timeout) < 0)
  974: 	continue;
  975:       
  976:       now = dnsmasq_time();
  977: 
  978:       check_log_writer(0);
  979: 
  980:       /* prime. */
  981:       enumerate_interfaces(1);
  982: 
  983:       /* Check the interfaces to see if any have exited DAD state
  984: 	 and if so, bind the address. */
  985:       if (is_dad_listeners())
  986: 	{
  987: 	  enumerate_interfaces(0);
  988: 	  /* NB, is_dad_listeners() == 1 --> we're binding interfaces */
  989: 	  create_bound_listeners(0);
  990: 	  warn_bound_listeners();
  991: 	}
  992: 
  993: #if defined(HAVE_LINUX_NETWORK)
  994:       if (poll_check(daemon->netlinkfd, POLLIN))
  995: 	netlink_multicast();
  996: #elif defined(HAVE_BSD_NETWORK)
  997:       if (poll_check(daemon->routefd, POLLIN))
  998: 	route_sock();
  999: #endif
 1000: 
 1001: #ifdef HAVE_INOTIFY
 1002:       if  (daemon->inotifyfd != -1 && poll_check(daemon->inotifyfd, POLLIN) && inotify_check(now))
 1003: 	{
 1004: 	  if (daemon->port != 0 && !option_bool(OPT_NO_POLL))
 1005: 	    poll_resolv(1, 1, now);
 1006: 	} 	  
 1007: #else
 1008:       /* Check for changes to resolv files once per second max. */
 1009:       /* Don't go silent for long periods if the clock goes backwards. */
 1010:       if (daemon->last_resolv == 0 || 
 1011: 	  difftime(now, daemon->last_resolv) > 1.0 || 
 1012: 	  difftime(now, daemon->last_resolv) < -1.0)
 1013: 	{
 1014: 	  /* poll_resolv doesn't need to reload first time through, since 
 1015: 	     that's queued anyway. */
 1016: 
 1017: 	  poll_resolv(0, daemon->last_resolv != 0, now); 	  
 1018: 	  daemon->last_resolv = now;
 1019: 	}
 1020: #endif
 1021: 
 1022:       if (poll_check(piperead, POLLIN))
 1023: 	async_event(piperead, now);
 1024:       
 1025: #ifdef HAVE_DBUS
 1026:       /* if we didn't create a DBus connection, retry now. */ 
 1027:      if (option_bool(OPT_DBUS) && !daemon->dbus)
 1028: 	{
 1029: 	  char *err;
 1030: 	  if ((err = dbus_init()))
 1031: 	    my_syslog(LOG_WARNING, _("DBus error: %s"), err);
 1032: 	  if (daemon->dbus)
 1033: 	    my_syslog(LOG_INFO, _("connected to system DBus"));
 1034: 	}
 1035:       check_dbus_listeners();
 1036: #endif
 1037:       
 1038:       check_dns_listeners(now);
 1039: 
 1040: #ifdef HAVE_TFTP
 1041:       check_tftp_listeners(now);
 1042: #endif      
 1043: 
 1044: #ifdef HAVE_DHCP
 1045:       if (daemon->dhcp || daemon->relay4)
 1046: 	{
 1047: 	  if (poll_check(daemon->dhcpfd, POLLIN))
 1048: 	    dhcp_packet(now, 0);
 1049: 	  if (daemon->pxefd != -1 && poll_check(daemon->pxefd, POLLIN))
 1050: 	    dhcp_packet(now, 1);
 1051: 	}
 1052: 
 1053: #ifdef HAVE_DHCP6
 1054:       if ((daemon->doing_dhcp6 || daemon->relay6) && poll_check(daemon->dhcp6fd, POLLIN))
 1055: 	dhcp6_packet(now);
 1056: 
 1057:       if (daemon->doing_ra && poll_check(daemon->icmp6fd, POLLIN))
 1058: 	icmp6_packet(now);
 1059: #endif
 1060: 
 1061: #  ifdef HAVE_SCRIPT
 1062:       if (daemon->helperfd != -1 && poll_check(daemon->helperfd, POLLOUT))
 1063: 	helper_write();
 1064: #  endif
 1065: #endif
 1066: 
 1067:     }
 1068: }
 1069: 
 1070: static void sig_handler(int sig)
 1071: {
 1072:   if (pid == 0)
 1073:     {
 1074:       /* ignore anything other than TERM during startup
 1075: 	 and in helper proc. (helper ignore TERM too) */
 1076:       if (sig == SIGTERM)
 1077: 	exit(EC_MISC);
 1078:     }
 1079:   else if (pid != getpid())
 1080:     {
 1081:       /* alarm is used to kill TCP children after a fixed time. */
 1082:       if (sig == SIGALRM)
 1083: 	_exit(0);
 1084:     }
 1085:   else
 1086:     {
 1087:       /* master process */
 1088:       int event, errsave = errno;
 1089:       
 1090:       if (sig == SIGHUP)
 1091: 	event = EVENT_RELOAD;
 1092:       else if (sig == SIGCHLD)
 1093: 	event = EVENT_CHILD;
 1094:       else if (sig == SIGALRM)
 1095: 	event = EVENT_ALARM;
 1096:       else if (sig == SIGTERM)
 1097: 	event = EVENT_TERM;
 1098:       else if (sig == SIGUSR1)
 1099: 	event = EVENT_DUMP;
 1100:       else if (sig == SIGUSR2)
 1101: 	event = EVENT_REOPEN;
 1102:       else
 1103: 	return;
 1104: 
 1105:       send_event(pipewrite, event, 0, NULL); 
 1106:       errno = errsave;
 1107:     }
 1108: }
 1109: 
 1110: /* now == 0 -> queue immediate callback */
 1111: void send_alarm(time_t event, time_t now)
 1112: {
 1113:   if (now == 0 || event != 0)
 1114:     {
 1115:       /* alarm(0) or alarm(-ve) doesn't do what we want.... */
 1116:       if ((now == 0 || difftime(event, now) <= 0.0))
 1117: 	send_event(pipewrite, EVENT_ALARM, 0, NULL);
 1118:       else 
 1119: 	alarm((unsigned)difftime(event, now)); 
 1120:     }
 1121: }
 1122: 
 1123: void queue_event(int event)
 1124: {
 1125:   send_event(pipewrite, event, 0, NULL);
 1126: }
 1127: 
 1128: void send_event(int fd, int event, int data, char *msg)
 1129: {
 1130:   struct event_desc ev;
 1131:   struct iovec iov[2];
 1132: 
 1133:   ev.event = event;
 1134:   ev.data = data;
 1135:   ev.msg_sz = msg ? strlen(msg) : 0;
 1136:   
 1137:   iov[0].iov_base = &ev;
 1138:   iov[0].iov_len = sizeof(ev);
 1139:   iov[1].iov_base = msg;
 1140:   iov[1].iov_len = ev.msg_sz;
 1141:   
 1142:   /* error pipe, debug mode. */
 1143:   if (fd == -1)
 1144:     fatal_event(&ev, msg);
 1145:   else
 1146:     /* pipe is non-blocking and struct event_desc is smaller than
 1147:        PIPE_BUF, so this either fails or writes everything */
 1148:     while (writev(fd, iov, msg ? 2 : 1) == -1 && errno == EINTR);
 1149: }
 1150: 
 1151: /* NOTE: the memory used to return msg is leaked: use msgs in events only
 1152:    to describe fatal errors. */
 1153: static int read_event(int fd, struct event_desc *evp, char **msg)
 1154: {
 1155:   char *buf;
 1156: 
 1157:   if (!read_write(fd, (unsigned char *)evp, sizeof(struct event_desc), 1))
 1158:     return 0;
 1159:   
 1160:   *msg = NULL;
 1161:   
 1162:   if (evp->msg_sz != 0 && 
 1163:       (buf = malloc(evp->msg_sz + 1)) &&
 1164:       read_write(fd, (unsigned char *)buf, evp->msg_sz, 1))
 1165:     {
 1166:       buf[evp->msg_sz] = 0;
 1167:       *msg = buf;
 1168:     }
 1169: 
 1170:   return 1;
 1171: }
 1172:     
 1173: static void fatal_event(struct event_desc *ev, char *msg)
 1174: {
 1175:   errno = ev->data;
 1176:   
 1177:   switch (ev->event)
 1178:     {
 1179:     case EVENT_DIE:
 1180:       exit(0);
 1181: 
 1182:     case EVENT_FORK_ERR:
 1183:       die(_("cannot fork into background: %s"), NULL, EC_MISC);
 1184:   
 1185:     case EVENT_PIPE_ERR:
 1186:       die(_("failed to create helper: %s"), NULL, EC_MISC);
 1187:   
 1188:     case EVENT_CAP_ERR:
 1189:       die(_("setting capabilities failed: %s"), NULL, EC_MISC);
 1190: 
 1191:     case EVENT_USER_ERR:
 1192:       die(_("failed to change user-id to %s: %s"), msg, EC_MISC);
 1193: 
 1194:     case EVENT_GROUP_ERR:
 1195:       die(_("failed to change group-id to %s: %s"), msg, EC_MISC);
 1196:       
 1197:     case EVENT_PIDFILE:
 1198:       die(_("failed to open pidfile %s: %s"), msg, EC_FILE);
 1199: 
 1200:     case EVENT_LOG_ERR:
 1201:       die(_("cannot open log %s: %s"), msg, EC_FILE);
 1202:     
 1203:     case EVENT_LUA_ERR:
 1204:       die(_("failed to load Lua script: %s"), msg, EC_MISC);
 1205: 
 1206:     case EVENT_TFTP_ERR:
 1207:       die(_("TFTP directory %s inaccessible: %s"), msg, EC_FILE);
 1208:     
 1209:     case EVENT_TIME_ERR:
 1210:       die(_("cannot create timestamp file %s: %s" ), msg, EC_BADCONF);
 1211:     }
 1212: }	
 1213:       
 1214: static void async_event(int pipe, time_t now)
 1215: {
 1216:   pid_t p;
 1217:   struct event_desc ev;
 1218:   int i, check = 0;
 1219:   char *msg;
 1220:   
 1221:   /* NOTE: the memory used to return msg is leaked: use msgs in events only
 1222:      to describe fatal errors. */
 1223:   
 1224:   if (read_event(pipe, &ev, &msg))
 1225:     switch (ev.event)
 1226:       {
 1227:       case EVENT_RELOAD:
 1228: #ifdef HAVE_DNSSEC
 1229: 	if (option_bool(OPT_DNSSEC_VALID) && option_bool(OPT_DNSSEC_TIME))
 1230: 	  {
 1231: 	    my_syslog(LOG_INFO, _("now checking DNSSEC signature timestamps"));
 1232: 	    reset_option_bool(OPT_DNSSEC_TIME);
 1233: 	  } 
 1234: #endif
 1235: 	/* fall through */
 1236: 	
 1237:       case EVENT_INIT:
 1238: 	clear_cache_and_reload(now);
 1239: 	
 1240: 	if (daemon->port != 0)
 1241: 	  {
 1242: 	    if (daemon->resolv_files && option_bool(OPT_NO_POLL))
 1243: 	      {
 1244: 		reload_servers(daemon->resolv_files->name);
 1245: 		check = 1;
 1246: 	      }
 1247: 
 1248: 	    if (daemon->servers_file)
 1249: 	      {
 1250: 		read_servers_file();
 1251: 		check = 1;
 1252: 	      }
 1253: 
 1254: 	    if (check)
 1255: 	      check_servers();
 1256: 	  }
 1257: 
 1258: #ifdef HAVE_DHCP
 1259: 	rerun_scripts();
 1260: #endif
 1261: 	break;
 1262: 	
 1263:       case EVENT_DUMP:
 1264: 	if (daemon->port != 0)
 1265: 	  dump_cache(now);
 1266: 	break;
 1267: 	
 1268:       case EVENT_ALARM:
 1269: #ifdef HAVE_DHCP
 1270: 	if (daemon->dhcp || daemon->doing_dhcp6)
 1271: 	  {
 1272: 	    lease_prune(NULL, now);
 1273: 	    lease_update_file(now);
 1274: 	  }
 1275: #ifdef HAVE_DHCP6
 1276: 	else if (daemon->doing_ra)
 1277: 	  /* Not doing DHCP, so no lease system, manage alarms for ra only */
 1278: 	    send_alarm(periodic_ra(now), now);
 1279: #endif
 1280: #endif
 1281: 	break;
 1282: 		
 1283:       case EVENT_CHILD:
 1284: 	/* See Stevens 5.10 */
 1285: 	while ((p = waitpid(-1, NULL, WNOHANG)) != 0)
 1286: 	  if (p == -1)
 1287: 	    {
 1288: 	      if (errno != EINTR)
 1289: 		break;
 1290: 	    }      
 1291: 	  else 
 1292: 	    for (i = 0 ; i < MAX_PROCS; i++)
 1293: 	      if (daemon->tcp_pids[i] == p)
 1294: 		daemon->tcp_pids[i] = 0;
 1295: 	break;
 1296: 	
 1297:       case EVENT_KILLED:
 1298: 	my_syslog(LOG_WARNING, _("script process killed by signal %d"), ev.data);
 1299: 	break;
 1300: 
 1301:       case EVENT_EXITED:
 1302: 	my_syslog(LOG_WARNING, _("script process exited with status %d"), ev.data);
 1303: 	break;
 1304: 
 1305:       case EVENT_EXEC_ERR:
 1306: 	my_syslog(LOG_ERR, _("failed to execute %s: %s"), 
 1307: 		  daemon->lease_change_command, strerror(ev.data));
 1308: 	break;
 1309: 
 1310: 	/* necessary for fatal errors in helper */
 1311:       case EVENT_USER_ERR:
 1312:       case EVENT_DIE:
 1313:       case EVENT_LUA_ERR:
 1314: 	fatal_event(&ev, msg);
 1315: 	break;
 1316: 
 1317:       case EVENT_REOPEN:
 1318: 	/* Note: this may leave TCP-handling processes with the old file still open.
 1319: 	   Since any such process will die in CHILD_LIFETIME or probably much sooner,
 1320: 	   we leave them logging to the old file. */
 1321: 	if (daemon->log_file != NULL)
 1322: 	  log_reopen(daemon->log_file);
 1323: 	break;
 1324: 
 1325:       case EVENT_NEWADDR:
 1326: 	newaddress(now);
 1327: 	break;
 1328: 
 1329:       case EVENT_NEWROUTE:
 1330: 	resend_query();
 1331: 	/* Force re-reading resolv file right now, for luck. */
 1332: 	poll_resolv(0, 1, now);
 1333: 	break;
 1334: 
 1335:       case EVENT_TERM:
 1336: 	/* Knock all our children on the head. */
 1337: 	for (i = 0; i < MAX_PROCS; i++)
 1338: 	  if (daemon->tcp_pids[i] != 0)
 1339: 	    kill(daemon->tcp_pids[i], SIGALRM);
 1340: 	
 1341: #if defined(HAVE_SCRIPT) && defined(HAVE_DHCP)
 1342: 	/* handle pending lease transitions */
 1343: 	if (daemon->helperfd != -1)
 1344: 	  {
 1345: 	    /* block in writes until all done */
 1346: 	    if ((i = fcntl(daemon->helperfd, F_GETFL)) != -1)
 1347: 	      fcntl(daemon->helperfd, F_SETFL, i & ~O_NONBLOCK); 
 1348: 	    do {
 1349: 	      helper_write();
 1350: 	    } while (!helper_buf_empty() || do_script_run(now));
 1351: 	    while (retry_send(close(daemon->helperfd)));
 1352: 	  }
 1353: #endif
 1354: 	
 1355: 	if (daemon->lease_stream)
 1356: 	  fclose(daemon->lease_stream);
 1357: 
 1358: #ifdef HAVE_DNSSEC
 1359: 	/* update timestamp file on TERM if time is considered valid */
 1360: 	if (daemon->back_to_the_future)
 1361: 	  {
 1362: 	     if (utime(daemon->timestamp_file, NULL) == -1)
 1363: 		my_syslog(LOG_ERR, _("failed to update mtime on %s: %s"), daemon->timestamp_file, strerror(errno));
 1364: 	  }
 1365: #endif
 1366: 
 1367: 	if (daemon->runfile)
 1368: 	  unlink(daemon->runfile);
 1369: 	
 1370: 	my_syslog(LOG_INFO, _("exiting on receipt of SIGTERM"));
 1371: 	flush_log();
 1372: 	exit(EC_GOOD);
 1373:       }
 1374: }
 1375: 
 1376: static void poll_resolv(int force, int do_reload, time_t now)
 1377: {
 1378:   struct resolvc *res, *latest;
 1379:   struct stat statbuf;
 1380:   time_t last_change = 0;
 1381:   /* There may be more than one possible file. 
 1382:      Go through and find the one which changed _last_.
 1383:      Warn of any which can't be read. */
 1384: 
 1385:   if (daemon->port == 0 || option_bool(OPT_NO_POLL))
 1386:     return;
 1387:   
 1388:   for (latest = NULL, res = daemon->resolv_files; res; res = res->next)
 1389:     if (stat(res->name, &statbuf) == -1)
 1390:       {
 1391: 	if (force)
 1392: 	  {
 1393: 	    res->mtime = 0; 
 1394: 	    continue;
 1395: 	  }
 1396: 
 1397: 	if (!res->logged)
 1398: 	  my_syslog(LOG_WARNING, _("failed to access %s: %s"), res->name, strerror(errno));
 1399: 	res->logged = 1;
 1400: 	
 1401: 	if (res->mtime != 0)
 1402: 	  { 
 1403: 	    /* existing file evaporated, force selection of the latest
 1404: 	       file even if its mtime hasn't changed since we last looked */
 1405: 	    poll_resolv(1, do_reload, now);
 1406: 	    return;
 1407: 	  }
 1408:       }
 1409:     else
 1410:       {
 1411: 	res->logged = 0;
 1412: 	if (force || (statbuf.st_mtime != res->mtime))
 1413:           {
 1414:             res->mtime = statbuf.st_mtime;
 1415: 	    if (difftime(statbuf.st_mtime, last_change) > 0.0)
 1416: 	      {
 1417: 		last_change = statbuf.st_mtime;
 1418: 		latest = res;
 1419: 	      }
 1420: 	  }
 1421:       }
 1422:   
 1423:   if (latest)
 1424:     {
 1425:       static int warned = 0;
 1426:       if (reload_servers(latest->name))
 1427: 	{
 1428: 	  my_syslog(LOG_INFO, _("reading %s"), latest->name);
 1429: 	  warned = 0;
 1430: 	  check_servers();
 1431: 	  if (option_bool(OPT_RELOAD) && do_reload)
 1432: 	    clear_cache_and_reload(now);
 1433: 	}
 1434:       else 
 1435: 	{
 1436: 	  latest->mtime = 0;
 1437: 	  if (!warned)
 1438: 	    {
 1439: 	      my_syslog(LOG_WARNING, _("no servers found in %s, will retry"), latest->name);
 1440: 	      warned = 1;
 1441: 	    }
 1442: 	}
 1443:     }
 1444: }       
 1445: 
 1446: void clear_cache_and_reload(time_t now)
 1447: {
 1448:   (void)now;
 1449: 
 1450:   if (daemon->port != 0)
 1451:     cache_reload();
 1452:   
 1453: #ifdef HAVE_DHCP
 1454:   if (daemon->dhcp || daemon->doing_dhcp6)
 1455:     {
 1456:       if (option_bool(OPT_ETHERS))
 1457: 	dhcp_read_ethers();
 1458:       reread_dhcp();
 1459: #ifdef HAVE_INOTIFY
 1460:       set_dynamic_inotify(AH_DHCP_HST | AH_DHCP_OPT, 0, NULL, 0);
 1461: #endif
 1462:       dhcp_update_configs(daemon->dhcp_conf);
 1463:       lease_update_from_configs(); 
 1464:       lease_update_file(now); 
 1465:       lease_update_dns(1);
 1466:     }
 1467: #ifdef HAVE_DHCP6
 1468:   else if (daemon->doing_ra)
 1469:     /* Not doing DHCP, so no lease system, manage 
 1470:        alarms for ra only */
 1471:     send_alarm(periodic_ra(now), now);
 1472: #endif
 1473: #endif
 1474: }
 1475: 
 1476: static int set_dns_listeners(time_t now)
 1477: {
 1478:   struct serverfd *serverfdp;
 1479:   struct listener *listener;
 1480:   int wait = 0, i;
 1481:   
 1482: #ifdef HAVE_TFTP
 1483:   int  tftp = 0;
 1484:   struct tftp_transfer *transfer;
 1485:   for (transfer = daemon->tftp_trans; transfer; transfer = transfer->next)
 1486:     {
 1487:       tftp++;
 1488:       poll_listen(transfer->sockfd, POLLIN);
 1489:     }
 1490: #endif
 1491:   
 1492:   /* will we be able to get memory? */
 1493:   if (daemon->port != 0)
 1494:     get_new_frec(now, &wait, 0);
 1495:   
 1496:   for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
 1497:     poll_listen(serverfdp->fd, POLLIN);
 1498:     
 1499:   if (daemon->port != 0 && !daemon->osport)
 1500:     for (i = 0; i < RANDOM_SOCKS; i++)
 1501:       if (daemon->randomsocks[i].refcount != 0)
 1502: 	poll_listen(daemon->randomsocks[i].fd, POLLIN);
 1503: 	  
 1504:   for (listener = daemon->listeners; listener; listener = listener->next)
 1505:     {
 1506:       /* only listen for queries if we have resources */
 1507:       if (listener->fd != -1 && wait == 0)
 1508: 	poll_listen(listener->fd, POLLIN);
 1509: 	
 1510:       /* death of a child goes through the select loop, so
 1511: 	 we don't need to explicitly arrange to wake up here */
 1512:       if  (listener->tcpfd != -1)
 1513: 	for (i = 0; i < MAX_PROCS; i++)
 1514: 	  if (daemon->tcp_pids[i] == 0)
 1515: 	    {
 1516: 	      poll_listen(listener->tcpfd, POLLIN);
 1517: 	      break;
 1518: 	    }
 1519: 
 1520: #ifdef HAVE_TFTP
 1521:       if (tftp <= daemon->tftp_max && listener->tftpfd != -1)
 1522: 	poll_listen(listener->tftpfd, POLLIN);
 1523: #endif
 1524: 
 1525:     }
 1526:   
 1527:   return wait;
 1528: }
 1529: 
 1530: static void check_dns_listeners(time_t now)
 1531: {
 1532:   struct serverfd *serverfdp;
 1533:   struct listener *listener;
 1534:   int i;
 1535: 
 1536:   for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
 1537:     if (poll_check(serverfdp->fd, POLLIN))
 1538:       reply_query(serverfdp->fd, serverfdp->source_addr.sa.sa_family, now);
 1539:   
 1540:   if (daemon->port != 0 && !daemon->osport)
 1541:     for (i = 0; i < RANDOM_SOCKS; i++)
 1542:       if (daemon->randomsocks[i].refcount != 0 && 
 1543: 	  poll_check(daemon->randomsocks[i].fd, POLLIN))
 1544: 	reply_query(daemon->randomsocks[i].fd, daemon->randomsocks[i].family, now);
 1545:   
 1546:   for (listener = daemon->listeners; listener; listener = listener->next)
 1547:     {
 1548:       if (listener->fd != -1 && poll_check(listener->fd, POLLIN))
 1549: 	receive_query(listener, now); 
 1550:       
 1551: #ifdef HAVE_TFTP     
 1552:       if (listener->tftpfd != -1 && poll_check(listener->tftpfd, POLLIN))
 1553: 	tftp_request(listener, now);
 1554: #endif
 1555: 
 1556:       if (listener->tcpfd != -1 && poll_check(listener->tcpfd, POLLIN))
 1557: 	{
 1558: 	  int confd, client_ok = 1;
 1559: 	  struct irec *iface = NULL;
 1560: 	  pid_t p;
 1561: 	  union mysockaddr tcp_addr;
 1562: 	  socklen_t tcp_len = sizeof(union mysockaddr);
 1563: 
 1564: 	  while ((confd = accept(listener->tcpfd, NULL, NULL)) == -1 && errno == EINTR);
 1565: 	  
 1566: 	  if (confd == -1)
 1567: 	    continue;
 1568: 	  
 1569: 	  if (getsockname(confd, (struct sockaddr *)&tcp_addr, &tcp_len) == -1)
 1570: 	    {
 1571: 	      while (retry_send(close(confd)));
 1572: 	      continue;
 1573: 	    }
 1574: 	  
 1575: 	  /* Make sure that the interface list is up-to-date.
 1576: 	     
 1577: 	     We do this here as we may need the results below, and
 1578: 	     the DNS code needs them for --interface-name stuff.
 1579: 
 1580: 	     Multiple calls to enumerate_interfaces() per select loop are
 1581: 	     inhibited, so calls to it in the child process (which doesn't select())
 1582: 	     have no effect. This avoids two processes reading from the same
 1583: 	     netlink fd and screwing the pooch entirely.
 1584: 	  */
 1585:  
 1586: 	  enumerate_interfaces(0);
 1587: 	  
 1588: 	  if (option_bool(OPT_NOWILD))
 1589: 	    iface = listener->iface; /* May be NULL */
 1590: 	  else 
 1591: 	    {
 1592: 	      int if_index;
 1593: 	      char intr_name[IF_NAMESIZE];
 1594: 	      
 1595: 	      /* if we can find the arrival interface, check it's one that's allowed */
 1596: 	      if ((if_index = tcp_interface(confd, tcp_addr.sa.sa_family)) != 0 &&
 1597: 		  indextoname(listener->tcpfd, if_index, intr_name))
 1598: 		{
 1599: 		  struct all_addr addr;
 1600: 		  addr.addr.addr4 = tcp_addr.in.sin_addr;
 1601: #ifdef HAVE_IPV6
 1602: 		  if (tcp_addr.sa.sa_family == AF_INET6)
 1603: 		    addr.addr.addr6 = tcp_addr.in6.sin6_addr;
 1604: #endif
 1605: 		  
 1606: 		  for (iface = daemon->interfaces; iface; iface = iface->next)
 1607: 		    if (iface->index == if_index)
 1608: 		      break;
 1609: 		  
 1610: 		  if (!iface && !loopback_exception(listener->tcpfd, tcp_addr.sa.sa_family, &addr, intr_name))
 1611: 		    client_ok = 0;
 1612: 		}
 1613: 	      
 1614: 	      if (option_bool(OPT_CLEVERBIND))
 1615: 		iface = listener->iface; /* May be NULL */
 1616: 	      else
 1617: 		{
 1618: 		  /* Check for allowed interfaces when binding the wildcard address:
 1619: 		     we do this by looking for an interface with the same address as 
 1620: 		     the local address of the TCP connection, then looking to see if that's
 1621: 		     an allowed interface. As a side effect, we get the netmask of the
 1622: 		     interface too, for localisation. */
 1623: 		  
 1624: 		  for (iface = daemon->interfaces; iface; iface = iface->next)
 1625: 		    if (sockaddr_isequal(&iface->addr, &tcp_addr))
 1626: 		      break;
 1627: 		  
 1628: 		  if (!iface)
 1629: 		    client_ok = 0;
 1630: 		}
 1631: 	    }
 1632: 	  
 1633: 	  if (!client_ok)
 1634: 	    {
 1635: 	      shutdown(confd, SHUT_RDWR);
 1636: 	      while (retry_send(close(confd)));
 1637: 	    }
 1638: #ifndef NO_FORK
 1639: 	  else if (!option_bool(OPT_DEBUG) && (p = fork()) != 0)
 1640: 	    {
 1641: 	      if (p != -1)
 1642: 		{
 1643: 		  int i;
 1644: 		  for (i = 0; i < MAX_PROCS; i++)
 1645: 		    if (daemon->tcp_pids[i] == 0)
 1646: 		      {
 1647: 			daemon->tcp_pids[i] = p;
 1648: 			break;
 1649: 		      }
 1650: 		}
 1651: 	      while (retry_send(close(confd)));
 1652: 
 1653: 	      /* The child can use up to TCP_MAX_QUERIES ids, so skip that many. */
 1654: 	      daemon->log_id += TCP_MAX_QUERIES;
 1655: 	    }
 1656: #endif
 1657: 	  else
 1658: 	    {
 1659: 	      unsigned char *buff;
 1660: 	      struct server *s; 
 1661: 	      int flags;
 1662: 	      struct in_addr netmask;
 1663: 	      int auth_dns;
 1664: 
 1665: 	      if (iface)
 1666: 		{
 1667: 		  netmask = iface->netmask;
 1668: 		  auth_dns = iface->dns_auth;
 1669: 		}
 1670: 	      else
 1671: 		{
 1672: 		  netmask.s_addr = 0;
 1673: 		  auth_dns = 0;
 1674: 		}
 1675: 
 1676: #ifndef NO_FORK
 1677: 	      /* Arrange for SIGALARM after CHILD_LIFETIME seconds to
 1678: 		 terminate the process. */
 1679: 	      if (!option_bool(OPT_DEBUG))
 1680: 		alarm(CHILD_LIFETIME);
 1681: #endif
 1682: 
 1683: 	      /* start with no upstream connections. */
 1684: 	      for (s = daemon->servers; s; s = s->next)
 1685: 		 s->tcpfd = -1; 
 1686: 	      
 1687: 	      /* The connected socket inherits non-blocking
 1688: 		 attribute from the listening socket. 
 1689: 		 Reset that here. */
 1690: 	      if ((flags = fcntl(confd, F_GETFL, 0)) != -1)
 1691: 		fcntl(confd, F_SETFL, flags & ~O_NONBLOCK);
 1692: 	      
 1693: 	      buff = tcp_request(confd, now, &tcp_addr, netmask, auth_dns);
 1694: 	       
 1695: 	      shutdown(confd, SHUT_RDWR);
 1696: 	      while (retry_send(close(confd)));
 1697: 	      
 1698: 	      if (buff)
 1699: 		free(buff);
 1700: 	      
 1701: 	      for (s = daemon->servers; s; s = s->next)
 1702: 		if (s->tcpfd != -1)
 1703: 		  {
 1704: 		    shutdown(s->tcpfd, SHUT_RDWR);
 1705: 		    while (retry_send(close(s->tcpfd)));
 1706: 		  }
 1707: #ifndef NO_FORK		   
 1708: 	      if (!option_bool(OPT_DEBUG))
 1709: 		{
 1710: 		  flush_log();
 1711: 		  _exit(0);
 1712: 		}
 1713: #endif
 1714: 	    }
 1715: 	}
 1716:     }
 1717: }
 1718: 
 1719: #ifdef HAVE_DHCP
 1720: int make_icmp_sock(void)
 1721: {
 1722:   int fd;
 1723:   int zeroopt = 0;
 1724: 
 1725:   if ((fd = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP)) != -1)
 1726:     {
 1727:       if (!fix_fd(fd) ||
 1728: 	  setsockopt(fd, SOL_SOCKET, SO_DONTROUTE, &zeroopt, sizeof(zeroopt)) == -1)
 1729: 	{
 1730: 	  close(fd);
 1731: 	  fd = -1;
 1732: 	}
 1733:     }
 1734: 
 1735:   return fd;
 1736: }
 1737: 
 1738: int icmp_ping(struct in_addr addr)
 1739: {
 1740:   /* Try and get an ICMP echo from a machine. */
 1741: 
 1742:   /* Note that whilst in the three second wait, we check for 
 1743:      (and service) events on the DNS and TFTP  sockets, (so doing that
 1744:      better not use any resources our caller has in use...)
 1745:      but we remain deaf to signals or further DHCP packets. */
 1746: 
 1747:   /* There can be a problem using dnsmasq_time() to end the loop, since
 1748:      it's not monotonic, and can go backwards if the system clock is
 1749:      tweaked, leading to the code getting stuck in this loop and
 1750:      ignoring DHCP requests. To fix this, we check to see if select returned
 1751:      as a result of a timeout rather than a socket becoming available. We
 1752:      only allow this to happen as many times as it takes to get to the wait time
 1753:      in quarter-second chunks. This provides a fallback way to end loop. */ 
 1754: 
 1755:   int fd, rc;
 1756:   struct sockaddr_in saddr;
 1757:   struct { 
 1758:     struct ip ip;
 1759:     struct icmp icmp;
 1760:   } packet;
 1761:   unsigned short id = rand16();
 1762:   unsigned int i, j, timeout_count;
 1763:   int gotreply = 0;
 1764:   time_t start, now;
 1765: 
 1766: #if defined(HAVE_LINUX_NETWORK) || defined (HAVE_SOLARIS_NETWORK)
 1767:   if ((fd = make_icmp_sock()) == -1)
 1768:     return 0;
 1769: #else
 1770:   int opt = 2000;
 1771:   fd = daemon->dhcp_icmp_fd;
 1772:   setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
 1773: #endif
 1774: 
 1775:   saddr.sin_family = AF_INET;
 1776:   saddr.sin_port = 0;
 1777:   saddr.sin_addr = addr;
 1778: #ifdef HAVE_SOCKADDR_SA_LEN
 1779:   saddr.sin_len = sizeof(struct sockaddr_in);
 1780: #endif
 1781:   
 1782:   memset(&packet.icmp, 0, sizeof(packet.icmp));
 1783:   packet.icmp.icmp_type = ICMP_ECHO;
 1784:   packet.icmp.icmp_id = id;
 1785:   for (j = 0, i = 0; i < sizeof(struct icmp) / 2; i++)
 1786:     j += ((u16 *)&packet.icmp)[i];
 1787:   while (j>>16)
 1788:     j = (j & 0xffff) + (j >> 16);  
 1789:   packet.icmp.icmp_cksum = (j == 0xffff) ? j : ~j;
 1790:   
 1791:   while (retry_send(sendto(fd, (char *)&packet.icmp, sizeof(struct icmp), 0, 
 1792: 			   (struct sockaddr *)&saddr, sizeof(saddr))));
 1793:   
 1794:   for (now = start = dnsmasq_time(), timeout_count = 0; 
 1795:        (difftime(now, start) < (float)PING_WAIT) && (timeout_count < PING_WAIT * 4);)
 1796:     {
 1797:       struct sockaddr_in faddr;
 1798:       socklen_t len = sizeof(faddr);
 1799:       
 1800:       poll_reset();
 1801:       poll_listen(fd, POLLIN);
 1802:       set_dns_listeners(now);
 1803:       set_log_writer();
 1804:       
 1805: #ifdef HAVE_DHCP6
 1806:       if (daemon->doing_ra)
 1807: 	poll_listen(daemon->icmp6fd, POLLIN); 
 1808: #endif
 1809:       
 1810:       rc = do_poll(250);
 1811:       
 1812:       if (rc < 0)
 1813: 	continue;
 1814:       else if (rc == 0)
 1815: 	timeout_count++;
 1816: 
 1817:       now = dnsmasq_time();
 1818: 
 1819:       check_log_writer(0);
 1820:       check_dns_listeners(now);
 1821: 
 1822: #ifdef HAVE_DHCP6
 1823:       if (daemon->doing_ra && poll_check(daemon->icmp6fd, POLLIN))
 1824: 	icmp6_packet(now);
 1825: #endif
 1826:       
 1827: #ifdef HAVE_TFTP
 1828:       check_tftp_listeners(now);
 1829: #endif
 1830: 
 1831:       if (poll_check(fd, POLLIN) &&
 1832: 	  recvfrom(fd, &packet, sizeof(packet), 0,
 1833: 		   (struct sockaddr *)&faddr, &len) == sizeof(packet) &&
 1834: 	  saddr.sin_addr.s_addr == faddr.sin_addr.s_addr &&
 1835: 	  packet.icmp.icmp_type == ICMP_ECHOREPLY &&
 1836: 	  packet.icmp.icmp_seq == 0 &&
 1837: 	  packet.icmp.icmp_id == id)
 1838: 	{
 1839: 	  gotreply = 1;
 1840: 	  break;
 1841: 	}
 1842:     }
 1843:   
 1844: #if defined(HAVE_LINUX_NETWORK) || defined(HAVE_SOLARIS_NETWORK)
 1845:   while (retry_send(close(fd)));
 1846: #else
 1847:   opt = 1;
 1848:   setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
 1849: #endif
 1850: 
 1851:   return gotreply;
 1852: }
 1853: #endif
 1854: 
 1855:  

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