Annotation of embedaddon/dnsmasq/src/dnsmasq.c, revision 1.1

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

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