]> git.ipfire.org Git - people/ms/dnsmasq.git/blame - src/dnsmasq.c
import of dnsmasq-2.36.tar.gz
[people/ms/dnsmasq.git] / src / dnsmasq.c
CommitLineData
cdeda28f 1/* dnsmasq is Copyright (c) 2000-2006 Simon Kelley
9e4abcb5
SK
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.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11*/
12
9e4abcb5
SK
13#include "dnsmasq.h"
14
3d8df260
SK
15static char *compile_opts =
16#ifndef HAVE_IPV6
17"no-"
18#endif
19"IPv6 "
20#ifndef HAVE_GETOPT_LONG
21"no-"
22#endif
23"GNU-getopt "
24#ifdef HAVE_BROKEN_RTC
25"no-RTC "
26#endif
1697269c
SK
27#ifdef NO_FORK
28"no-MMU "
29#endif
3d8df260
SK
30#ifndef HAVE_ISC_READER
31"no-"
32#endif
33"ISC-leasefile "
34#ifndef HAVE_DBUS
35"no-"
36#endif
b8187c80
SK
37"DBus "
38#ifdef NO_GETTEXT
39"no-"
40#endif
e17fb629 41"I18N ";
3d8df260 42
5e9e0efb
SK
43static pid_t pid;
44static int pipewrite;
9e4abcb5 45
1697269c 46static int set_dns_listeners(struct daemon *daemon, time_t now, fd_set *set, int *maxfdp);
3be34541
SK
47static void check_dns_listeners(struct daemon *daemon, fd_set *set, time_t now);
48static void sig_handler(int sig);
9e4abcb5
SK
49
50int main (int argc, char **argv)
51{
3be34541 52 struct daemon *daemon;
de37951c 53 int bind_fallback = 0;
309331f5 54 int bad_capabilities = 0;
9e4abcb5 55 time_t now, last = 0;
9e4abcb5 56 struct sigaction sigact;
26128d27 57 struct iname *if_tmp;
7cebd20f 58 int piperead, pipefd[2];
5e9e0efb 59 unsigned char sig;
7cebd20f 60
b8187c80
SK
61#ifndef NO_GETTEXT
62 setlocale(LC_ALL, "");
63 bindtextdomain("dnsmasq", LOCALEDIR);
64 textdomain("dnsmasq");
65#endif
66
5e9e0efb 67 pid = 0;
9e4abcb5
SK
68
69 sigact.sa_handler = sig_handler;
70 sigact.sa_flags = 0;
71 sigemptyset(&sigact.sa_mask);
72 sigaction(SIGUSR1, &sigact, NULL);
9e4abcb5
SK
73 sigaction(SIGHUP, &sigact, NULL);
74 sigaction(SIGTERM, &sigact, NULL);
44a2a316 75 sigaction(SIGALRM, &sigact, NULL);
feba5c1d
SK
76 sigaction(SIGCHLD, &sigact, NULL);
77
78 /* ignore SIGPIPE */
79 sigact.sa_handler = SIG_IGN;
80 sigaction(SIGPIPE, &sigact, NULL);
9e4abcb5 81
3d8df260 82 daemon = read_opts(argc, argv, compile_opts);
3be34541
SK
83
84 if (daemon->edns_pktsz < PACKETSZ)
85 daemon->edns_pktsz = PACKETSZ;
0a852541
SK
86 daemon->packet_buff_sz = daemon->edns_pktsz > DNSMASQ_PACKETSZ ?
87 daemon->edns_pktsz : DNSMASQ_PACKETSZ;
88 daemon->packet = safe_malloc(daemon->packet_buff_sz);
9e4abcb5 89
3be34541 90 if (!daemon->lease_file)
9e4abcb5 91 {
3be34541
SK
92 if (daemon->dhcp)
93 daemon->lease_file = LEASEFILE;
9e4abcb5 94 }
33820b7e 95#ifndef HAVE_ISC_READER
3be34541 96 else if (!daemon->dhcp)
b8187c80 97 die(_("ISC dhcpd integration not available: set HAVE_ISC_READER in src/config.h"), NULL);
33820b7e 98#endif
9e4abcb5 99
5e9e0efb
SK
100#ifdef HAVE_LINUX_NETWORK
101 netlink_init(daemon);
309331f5
SK
102#elif !(defined(IP_RECVDSTADDR) && \
103 defined(IP_RECVIF) && \
104 defined(IP_SENDSRCADDR))
105 if (!(daemon->options & OPT_NOWILD))
de37951c
SK
106 {
107 bind_fallback = 1;
3be34541 108 daemon->options |= OPT_NOWILD;
de37951c 109 }
309331f5
SK
110#endif
111
832af0ba
SK
112#ifndef HAVE_TFTP
113 if (daemon->options & OPT_TFTP)
114 die(_("TFTP server not available: set HAVE_TFTP in src/config.h"), NULL);
115#endif
116
309331f5
SK
117 daemon->interfaces = NULL;
118 if (!enumerate_interfaces(daemon))
119 die(_("failed to find list of interfaces: %s"), NULL);
9e4abcb5 120
3be34541 121 if (daemon->options & OPT_NOWILD)
de37951c 122 {
5e9e0efb 123 daemon->listeners = create_bound_listeners(daemon);
de37951c 124
3be34541 125 for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
de37951c 126 if (if_tmp->name && !if_tmp->used)
b8187c80 127 die(_("unknown interface %s"), if_tmp->name);
de37951c 128
3be34541 129 for (if_tmp = daemon->if_addrs; if_tmp; if_tmp = if_tmp->next)
de37951c
SK
130 if (!if_tmp->used)
131 {
3d8df260 132 prettyprint_addr(&if_tmp->addr, daemon->namebuff);
b8187c80 133 die(_("no interface with address %s"), daemon->namebuff);
de37951c
SK
134 }
135 }
832af0ba 136 else if (!(daemon->listeners = create_wildcard_listeners(daemon->port, daemon->options & OPT_TFTP)))
309331f5 137 die(_("failed to create listening socket: %s"), NULL);
de37951c 138
3be34541 139 cache_init(daemon->cachesize, daemon->options & OPT_LOG);
44a2a316 140
5e9e0efb 141 now = dnsmasq_time();
9e4abcb5 142
3be34541 143 if (daemon->dhcp)
9e4abcb5 144 {
5e9e0efb 145#if !defined(HAVE_LINUX_NETWORK) && !defined(IP_RECVIF)
de37951c
SK
146 int c;
147 struct iname *tmp;
3be34541 148 for (c = 0, tmp = daemon->if_names; tmp; tmp = tmp->next)
de37951c
SK
149 if (!tmp->isloop)
150 c++;
151 if (c != 1)
b8187c80 152 die(_("must set exactly one interface on broken systems without IP_RECVIF"), NULL);
de37951c 153#endif
3be34541
SK
154 dhcp_init(daemon);
155 lease_init(daemon, now);
9e4abcb5 156 }
feba5c1d 157
3d8df260
SK
158 if (daemon->options & OPT_DBUS)
159#ifdef HAVE_DBUS
160 {
161 char *err;
162 daemon->dbus = NULL;
163 daemon->watches = NULL;
164 if ((err = dbus_init(daemon)))
b8187c80 165 die(_("DBus error: %s"), err);
3d8df260
SK
166 }
167#else
cdeda28f 168 die(_("DBus not available: set HAVE_DBUS in src/config.h"), NULL);
3d8df260
SK
169#endif
170
feba5c1d
SK
171 /* If query_port is set then create a socket now, before dumping root
172 for use to access nameservers without more specific source addresses.
173 This allows query_port to be a low port */
3be34541 174 if (daemon->query_port)
feba5c1d
SK
175 {
176 union mysockaddr addr;
849a8357 177 memset(&addr, 0, sizeof(addr));
feba5c1d
SK
178 addr.in.sin_family = AF_INET;
179 addr.in.sin_addr.s_addr = INADDR_ANY;
3be34541 180 addr.in.sin_port = htons(daemon->query_port);
feba5c1d
SK
181#ifdef HAVE_SOCKADDR_SA_LEN
182 addr.in.sin_len = sizeof(struct sockaddr_in);
183#endif
3be34541 184 allocate_sfd(&addr, &daemon->sfds);
feba5c1d 185#ifdef HAVE_IPV6
849a8357 186 memset(&addr, 0, sizeof(addr));
feba5c1d
SK
187 addr.in6.sin6_family = AF_INET6;
188 addr.in6.sin6_addr = in6addr_any;
3be34541 189 addr.in6.sin6_port = htons(daemon->query_port);
feba5c1d
SK
190#ifdef HAVE_SOCKADDR_SA_LEN
191 addr.in6.sin6_len = sizeof(struct sockaddr_in6);
192#endif
3be34541 193 allocate_sfd(&addr, &daemon->sfds);
feba5c1d
SK
194#endif
195 }
9e4abcb5 196
5e9e0efb 197 /* Use a pipe to carry signals back to the event loop in a race-free manner */
7cebd20f 198 if (pipe(pipefd) == -1 || !fix_fd(pipefd[0]) || !fix_fd(pipefd[1]))
5e9e0efb
SK
199 die(_("cannot create pipe: %s"), NULL);
200
201 piperead = pipefd[0];
202 pipewrite = pipefd[1];
203 /* prime the pipe to load stuff first time. */
204 sig = SIGHUP;
205 write(pipewrite, &sig, 1);
1697269c
SK
206
207 if (!(daemon->options & OPT_DEBUG))
9e4abcb5
SK
208 {
209 FILE *pidfile;
3d8df260 210 fd_set test_set;
1697269c 211 int maxfd = -1, i;
7cebd20f 212 int nullfd = open("/dev/null", O_RDWR);
5e9e0efb 213
9e4abcb5
SK
214 /* The following code "daemonizes" the process.
215 See Stevens section 12.4 */
1697269c
SK
216
217#ifndef NO_FORK
3be34541
SK
218 if (!(daemon->options & OPT_NO_FORK))
219 {
220 if (fork() != 0 )
7cebd20f 221 _exit(0);
3be34541
SK
222
223 setsid();
224
225 if (fork() != 0)
7cebd20f 226 _exit(0);
3be34541 227 }
9e4abcb5
SK
228#endif
229
230 chdir("/");
231 umask(022); /* make pidfile 0644 */
232
233 /* write pidfile _after_ forking ! */
3be34541 234 if (daemon->runfile && (pidfile = fopen(daemon->runfile, "w")))
9e4abcb5
SK
235 {
236 fprintf(pidfile, "%d\n", (int) getpid());
237 fclose(pidfile);
238 }
239
240 umask(0);
1697269c
SK
241
242 FD_ZERO(&test_set);
243 set_dns_listeners(daemon, now, &test_set, &maxfd);
244#ifdef HAVE_DBUS
245 set_dbus_listeners(daemon, &maxfd, &test_set, &test_set, &test_set);
246#endif
9e4abcb5
SK
247 for (i=0; i<64; i++)
248 {
5e9e0efb
SK
249 if (i == piperead || i == pipewrite)
250 continue;
251
252#ifdef HAVE_LINUX_NETWORK
253 if (i == daemon->netlinkfd)
9e4abcb5 254 continue;
3be34541 255#endif
3d8df260 256
3be34541 257 if (daemon->dhcp &&
208b65c5 258 ((daemon->lease_stream && i == fileno(daemon->lease_stream)) ||
5e9e0efb 259#ifndef HAVE_LINUX_NETWORK
3be34541 260 i == daemon->dhcp_raw_fd ||
5e9e0efb
SK
261 i == daemon->dhcp_icmp_fd ||
262#endif
263 i == daemon->dhcpfd))
3be34541 264 continue;
3d8df260
SK
265
266 if (i <= maxfd && FD_ISSET(i, &test_set))
feba5c1d
SK
267 continue;
268
7cebd20f
SK
269 /* open stdout etc to /dev/null */
270 if (i == STDOUT_FILENO || i == STDERR_FILENO || i == STDIN_FILENO)
271 dup2(nullfd, i);
272 else
273 close(i);
9e4abcb5 274 }
1697269c
SK
275 }
276
277 /* if we are to run scripts, we need to fork a helper before dropping root. */
832af0ba 278 daemon->helperfd = create_helper(daemon);
1697269c
SK
279
280 if (!(daemon->options & OPT_DEBUG))
281 {
282 /* UID changing, etc */
283 struct passwd *ent_pw = daemon->username ? getpwnam(daemon->username) : NULL;
284
7cebd20f 285 if (daemon->groupname || ent_pw)
9e4abcb5
SK
286 {
287 gid_t dummy;
288 struct group *gp;
7cebd20f
SK
289
290 /* change group for /etc/ppp/resolv.conf otherwise get the group for "nobody" */
3be34541 291 if ((daemon->groupname && (gp = getgrnam(daemon->groupname))) ||
7cebd20f
SK
292 (ent_pw && (gp = getgrgid(ent_pw->pw_gid))))
293 {
294 /* remove all supplimentary groups */
295 setgroups(0, &dummy);
296 setgid(gp->gr_gid);
297 }
298 }
1697269c 299
7cebd20f 300 if (ent_pw && ent_pw->pw_uid != 0)
1697269c 301 {
5e9e0efb 302#ifdef HAVE_LINUX_NETWORK
1697269c
SK
303 /* On linux, we keep CAP_NETADMIN (for ARP-injection) and
304 CAP_NET_RAW (for icmp) if we're doing dhcp */
305 cap_user_header_t hdr = safe_malloc(sizeof(*hdr));
306 cap_user_data_t data = safe_malloc(sizeof(*data));
307 hdr->version = _LINUX_CAPABILITY_VERSION;
308 hdr->pid = 0; /* this process */
309 data->effective = data->permitted = data->inheritable =
310 (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW) |
311 (1 << CAP_SETGID) | (1 << CAP_SETUID);
5e9e0efb 312
1697269c
SK
313 /* Tell kernel to not clear capabilities when dropping root */
314 if (capset(hdr, data) == -1 || prctl(PR_SET_KEEPCAPS, 1) == -1)
315 bad_capabilities = errno;
316 else
5e9e0efb 317#endif
1697269c
SK
318 {
319 /* finally drop root */
320 setuid(ent_pw->pw_uid);
321
322#ifdef HAVE_LINUX_NETWORK
323 data->effective = data->permitted =
324 (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW);
325 data->inheritable = 0;
326
327 /* lose the setuid and setgid capbilities */
328 capset(hdr, data);
329#endif
330 }
9e4abcb5
SK
331 }
332 }
1697269c
SK
333
334 log_start(daemon);
335
336#ifdef HAVE_LINUX_NETWORK
337 if (daemon->options & OPT_DEBUG)
338 prctl(PR_SET_DUMPABLE, 1);
339#endif
9e4abcb5 340
3be34541 341 if (daemon->cachesize != 0)
b8187c80 342 syslog(LOG_INFO, _("started, version %s cachesize %d"), VERSION, daemon->cachesize);
9e4abcb5 343 else
b8187c80 344 syslog(LOG_INFO, _("started, version %s cache disabled"), VERSION);
1697269c 345
b8187c80 346 syslog(LOG_INFO, _("compile time options: %s"), compile_opts);
1697269c 347
3d8df260
SK
348#ifdef HAVE_DBUS
349 if (daemon->options & OPT_DBUS)
350 {
351 if (daemon->dbus)
b8187c80 352 syslog(LOG_INFO, _("DBus support enabled: connected to system bus"));
3d8df260 353 else
b8187c80 354 syslog(LOG_INFO, _("DBus support enabled: bus connection pending"));
3d8df260
SK
355 }
356#endif
357
de37951c 358 if (bind_fallback)
b8187c80 359 syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations"));
de37951c 360
26128d27
SK
361 if (!(daemon->options & OPT_NOWILD))
362 for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
363 if (if_tmp->name && !if_tmp->used)
b8187c80 364 syslog(LOG_WARNING, _("warning: interface %s does not currently exist"), if_tmp->name);
5e9e0efb 365
208b65c5
SK
366 if (daemon->options & OPT_NO_RESOLV)
367 {
368 if (daemon->resolv_files && !daemon->resolv_files->is_default)
369 syslog(LOG_WARNING, _("warning: ignoring resolv-file flag because no-resolv is set"));
370 daemon->resolv_files = NULL;
371 }
372
3be34541 373 if (daemon->dhcp)
9e4abcb5 374 {
3be34541 375 struct dhcp_context *dhcp_tmp;
0a852541 376
3be34541 377 for (dhcp_tmp = daemon->dhcp; dhcp_tmp; dhcp_tmp = dhcp_tmp->next)
feba5c1d 378 {
0a852541 379 prettyprint_time(daemon->dhcp_buff2, dhcp_tmp->lease_time);
3be34541 380 strcpy(daemon->dhcp_buff, inet_ntoa(dhcp_tmp->start));
3be34541 381 syslog(LOG_INFO,
0a852541 382 (dhcp_tmp->flags & CONTEXT_STATIC) ?
b8187c80
SK
383 _("DHCP, static leases only on %.0s%s, lease time %s") :
384 _("DHCP, IP range %s -- %s, lease time %s"),
0a852541 385 daemon->dhcp_buff, inet_ntoa(dhcp_tmp->end), daemon->dhcp_buff2);
feba5c1d 386 }
26128d27
SK
387 }
388
832af0ba
SK
389#ifdef HAVE_TFTP
390 if (daemon->options & OPT_TFTP)
391 {
392 long max_fd = sysconf(_SC_OPEN_MAX);
393
394#ifdef FD_SETSIZE
395 if (FD_SETSIZE < max_fd)
396 max_fd = FD_SETSIZE;
397#endif
398
399 syslog(LOG_INFO, "TFTP %s%s %s",
400 daemon->tftp_prefix ? _("root is ") : _("enabled"),
401 daemon->tftp_prefix ? daemon->tftp_prefix: "",
402 daemon->options & OPT_TFTP_SECURE ? _("secure mode") : "");
403
404 /* This is a guess, it assumes that for small limits,
405 disjoint files might be servered, but for large limits,
406 a single file will be sent to may clients (the file only needs
407 one fd). */
408
409 max_fd -= 30; /* use other than TFTP */
410
411 if (max_fd < 0)
412 max_fd = 5;
413 else if (max_fd < 100)
414 max_fd = max_fd/2;
415 else
416 max_fd = max_fd - 20;
417
418 if (daemon->tftp_max > max_fd)
419 {
420 daemon->tftp_max = max_fd;
421 syslog(LOG_WARNING,
422 _("restricting maximum simultaneous TFTP transfers to %d"),
423 daemon->tftp_max);
424 }
425 }
426#endif
427
3be34541 428 if (!(daemon->options & OPT_DEBUG) && (getuid() == 0 || geteuid() == 0))
309331f5
SK
429 {
430 if (bad_capabilities)
431 {
432 errno = bad_capabilities;
433 syslog(LOG_WARNING, _("warning: setting capabilities failed: %m"));
434 }
435 syslog(LOG_WARNING, _("running as root"));
436 }
9e4abcb5 437
3d8df260 438 check_servers(daemon);
5e9e0efb 439
7cebd20f
SK
440 pid = getpid();
441
5e9e0efb 442 while (1)
9e4abcb5 443 {
1697269c 444 int maxfd = -1;
5e9e0efb 445 struct timeval t, *tp = NULL;
3d8df260 446 fd_set rset, wset, eset;
9e4abcb5
SK
447
448 FD_ZERO(&rset);
3d8df260
SK
449 FD_ZERO(&wset);
450 FD_ZERO(&eset);
9e4abcb5 451
1697269c
SK
452 /* if we are out of resources, find how long we have to wait
453 for some to come free, we'll loop around then and restart
454 listening for queries */
455 if ((t.tv_sec = set_dns_listeners(daemon, now, &rset, &maxfd)) != 0)
456 {
457 t.tv_usec = 0;
458 tp = &t;
459 }
460
832af0ba
SK
461 /* Whilst polling for the dbus, or doing a tftp transfer, wake every quarter second */
462 if (daemon->tftp_trans ||
463 ((daemon->options & OPT_DBUS) && !daemon->dbus))
5e9e0efb 464 {
1697269c
SK
465 t.tv_sec = 0;
466 t.tv_usec = 250000;
5e9e0efb 467 tp = &t;
5e9e0efb 468 }
44a2a316 469
832af0ba 470#ifdef HAVE_DBUS
1697269c 471 set_dbus_listeners(daemon, &maxfd, &rset, &wset, &eset);
5e9e0efb
SK
472#endif
473
474 if (daemon->dhcp)
475 {
476 FD_SET(daemon->dhcpfd, &rset);
1697269c 477 bump_maxfd(daemon->dhcpfd, &maxfd);
5e9e0efb 478 }
cdeda28f 479
5e9e0efb
SK
480#ifdef HAVE_LINUX_NETWORK
481 FD_SET(daemon->netlinkfd, &rset);
1697269c 482 bump_maxfd(daemon->netlinkfd, &maxfd);
3d8df260 483#endif
3d8df260 484
5e9e0efb 485 FD_SET(piperead, &rset);
1697269c
SK
486 bump_maxfd(piperead, &maxfd);
487
488 while (helper_buf_empty() && do_script_run(daemon));
489
490 if (!helper_buf_empty())
491 {
492 FD_SET(daemon->helperfd, &wset);
493 bump_maxfd(daemon->helperfd, &maxfd);
494 }
495
5e9e0efb
SK
496 if (select(maxfd+1, &rset, &wset, &eset, tp) < 0)
497 {
498 /* otherwise undefined after error */
499 FD_ZERO(&rset); FD_ZERO(&wset); FD_ZERO(&eset);
500 }
501
502 now = dnsmasq_time();
9e4abcb5
SK
503
504 /* Check for changes to resolv files once per second max. */
3d8df260 505 /* Don't go silent for long periods if the clock goes backwards. */
849a8357 506 if (last == 0 || difftime(now, last) > 1.0 || difftime(now, last) < -1.0)
9e4abcb5
SK
507 {
508 last = now;
33820b7e
SK
509
510#ifdef HAVE_ISC_READER
3be34541 511 if (daemon->lease_file && !daemon->dhcp)
fd9fa481 512 load_dhcp(daemon, now);
33820b7e
SK
513#endif
514
3be34541 515 if (!(daemon->options & OPT_NO_POLL))
9e4abcb5 516 {
208b65c5 517 struct resolvc *res, *latest;
9e4abcb5 518 struct stat statbuf;
33820b7e 519 time_t last_change = 0;
9e4abcb5
SK
520 /* There may be more than one possible file.
521 Go through and find the one which changed _last_.
522 Warn of any which can't be read. */
208b65c5
SK
523 for (latest = NULL, res = daemon->resolv_files; res; res = res->next)
524 if (stat(res->name, &statbuf) == -1)
525 {
526 if (!res->logged)
527 syslog(LOG_WARNING, _("failed to access %s: %m"), res->name);
528 res->logged = 1;
529 }
530 else
531 {
532 res->logged = 0;
533 if (statbuf.st_mtime != res->mtime)
534 {
535 res->mtime = statbuf.st_mtime;
536 if (difftime(statbuf.st_mtime, last_change) > 0.0)
537 {
538 last_change = statbuf.st_mtime;
539 latest = res;
540 }
541 }
542 }
543
3d8df260 544 if (latest)
9e4abcb5 545 {
849a8357
SK
546 static int warned = 0;
547 if (reload_servers(latest->name, daemon))
548 {
549 syslog(LOG_INFO, _("reading %s"), latest->name);
849a8357
SK
550 warned = 0;
551 check_servers(daemon);
1697269c
SK
552 if (daemon->options & OPT_RELOAD)
553 cache_reload(daemon->options, daemon->namebuff, daemon->domain_suffix, daemon->addn_hosts);
849a8357 554 }
208b65c5 555 else
849a8357 556 {
208b65c5
SK
557 latest->mtime = 0;
558 if (!warned)
559 {
560 syslog(LOG_WARNING, _("no servers found in %s, will retry"), latest->name);
561 warned = 1;
562 }
849a8357 563 }
9e4abcb5
SK
564 }
565 }
566 }
cdeda28f 567
5e9e0efb
SK
568 if (FD_ISSET(piperead, &rset))
569 {
7cebd20f
SK
570 pid_t p;
571
5e9e0efb
SK
572 if (read(piperead, &sig, 1) == 1)
573 switch (sig)
574 {
575 case SIGHUP:
7cebd20f 576 clear_cache_and_reload(daemon, now);
5e9e0efb
SK
577 if (daemon->resolv_files && (daemon->options & OPT_NO_POLL))
578 {
579 reload_servers(daemon->resolv_files->name, daemon);
580 check_servers(daemon);
581 }
582 break;
583
584 case SIGUSR1:
585 dump_cache(daemon, now);
586 break;
587
588 case SIGALRM:
589 if (daemon->dhcp)
7cebd20f
SK
590 {
591 lease_prune(NULL, now);
592 lease_update_file(daemon, now);
7cebd20f 593 }
5e9e0efb
SK
594 break;
595
596 case SIGTERM:
7cebd20f
SK
597 {
598 int i;
7cebd20f
SK
599 /* Knock all our children on the head. */
600 for (i = 0; i < MAX_PROCS; i++)
601 if (daemon->tcp_pids[i] != 0)
849a8357 602 kill(daemon->tcp_pids[i], SIGALRM);
7cebd20f 603
1697269c
SK
604 /* handle pending lease transitions */
605 if (daemon->helperfd != -1)
606 {
607 /* block in writes until all done */
608 if ((i = fcntl(daemon->helperfd, F_GETFL)) != -1)
609 fcntl(daemon->helperfd, F_SETFL, i & ~O_NONBLOCK);
610 do {
611 helper_write(daemon);
612 } while (!helper_buf_empty() || do_script_run(daemon));
613 close(daemon->helperfd);
614 }
615
208b65c5 616 if (daemon->lease_stream)
849a8357 617 fclose(daemon->lease_stream);
1697269c
SK
618
619 syslog(LOG_INFO, _("exiting on receipt of SIGTERM"));
7cebd20f
SK
620 exit(0);
621 }
5e9e0efb
SK
622
623 case SIGCHLD:
624 /* See Stevens 5.10 */
7cebd20f
SK
625 /* Note that if a script process forks and then exits
626 without waiting for its child, we will reap that child.
627 It is not therefore safe to assume that any dieing children
628 whose pid != script_pid are TCP server threads. */
629 while ((p = waitpid(-1, NULL, WNOHANG)) > 0)
630 {
1697269c
SK
631 int i;
632 for (i = 0 ; i < MAX_PROCS; i++)
633 if (daemon->tcp_pids[i] == p)
634 {
635 daemon->tcp_pids[i] = 0;
636 break;
637 }
7cebd20f 638 }
5e9e0efb 639 break;
5e9e0efb
SK
640 }
641 }
7cebd20f 642
5e9e0efb
SK
643#ifdef HAVE_LINUX_NETWORK
644 if (FD_ISSET(daemon->netlinkfd, &rset))
cdeda28f
SK
645 netlink_multicast(daemon);
646#endif
3d8df260
SK
647
648#ifdef HAVE_DBUS
649 /* if we didn't create a DBus connection, retry now. */
7cebd20f 650 if ((daemon->options & OPT_DBUS) && !daemon->dbus)
3d8df260
SK
651 {
652 char *err;
653 if ((err = dbus_init(daemon)))
b8187c80 654 syslog(LOG_WARNING, _("DBus error: %s"), err);
3d8df260 655 if (daemon->dbus)
b8187c80 656 syslog(LOG_INFO, _("connected to system DBus"));
3d8df260
SK
657 }
658 check_dbus_listeners(daemon, &rset, &wset, &eset);
659#endif
660
3be34541 661 check_dns_listeners(daemon, &rset, now);
832af0ba
SK
662
663#ifdef HAVE_TFTP
664 check_tftp_listeners(daemon, &rset, now);
665#endif
666
3be34541
SK
667 if (daemon->dhcp && FD_ISSET(daemon->dhcpfd, &rset))
668 dhcp_packet(daemon, now);
1697269c
SK
669
670 if (daemon->helperfd != -1 && FD_ISSET(daemon->helperfd, &wset))
671 helper_write(daemon);
9e4abcb5 672 }
9e4abcb5
SK
673}
674
3be34541
SK
675static void sig_handler(int sig)
676{
5e9e0efb 677 if (pid == 0)
3be34541 678 {
1697269c
SK
679 /* ignore anything other than TERM during startup
680 and in helper proc. (helper ignore TERM too) */
5e9e0efb 681 if (sig == SIGTERM)
3be34541 682 exit(0);
3be34541 683 }
5e9e0efb 684 else if (pid == getpid())
3be34541 685 {
5e9e0efb
SK
686 /* master process */
687 unsigned char sigchr = sig;
688 int errsave = errno;
689 write(pipewrite, &sigchr, 1);
690 errno = errsave;
691 }
692 else
693 {
1697269c 694 /* alarm is used to kill TCP children after a fixed time. */
5e9e0efb 695 if (sig == SIGALRM)
7cebd20f 696 _exit(0);
3be34541
SK
697 }
698}
699
3d8df260 700
7cebd20f 701void clear_cache_and_reload(struct daemon *daemon, time_t now)
3d8df260
SK
702{
703 cache_reload(daemon->options, daemon->namebuff, daemon->domain_suffix, daemon->addn_hosts);
704 if (daemon->dhcp)
705 {
706 if (daemon->options & OPT_ETHERS)
707 dhcp_read_ethers(daemon);
708 dhcp_update_configs(daemon->dhcp_conf);
b8187c80 709 lease_update_from_configs(daemon);
7cebd20f 710 lease_update_file(daemon, now);
3d8df260
SK
711 lease_update_dns(daemon);
712 }
713}
714
1697269c 715static int set_dns_listeners(struct daemon *daemon, time_t now, fd_set *set, int *maxfdp)
3be34541
SK
716{
717 struct serverfd *serverfdp;
718 struct listener *listener;
1697269c 719 int wait, i;
832af0ba
SK
720
721#ifdef HAVE_TFTP
722 int tftp = 0;
723 struct tftp_transfer *transfer;
724 for (transfer = daemon->tftp_trans; transfer; transfer = transfer->next)
725 {
726 tftp++;
727 FD_SET(transfer->sockfd, set);
728 bump_maxfd(transfer->sockfd, maxfdp);
729 }
730#endif
731
1697269c
SK
732 /* will we be able to get memory? */
733 get_new_frec(daemon, now, &wait);
734
3be34541
SK
735 for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
736 {
737 FD_SET(serverfdp->fd, set);
1697269c 738 bump_maxfd(serverfdp->fd, maxfdp);
3be34541
SK
739 }
740
741 for (listener = daemon->listeners; listener; listener = listener->next)
742 {
1697269c
SK
743 /* only listen for queries if we have resources */
744 if (wait == 0)
745 {
746 FD_SET(listener->fd, set);
747 bump_maxfd(listener->fd, maxfdp);
748 }
749
750 /* death of a child goes through the select loop, so
751 we don't need to explicitly arrange to wake up here */
752 for (i = 0; i < MAX_PROCS; i++)
753 if (daemon->tcp_pids[i] == 0)
754 {
755 FD_SET(listener->tcpfd, set);
756 bump_maxfd(listener->tcpfd, maxfdp);
757 break;
758 }
9e4abcb5 759
832af0ba
SK
760#ifdef HAVE_TFTP
761 if (tftp <= daemon->tftp_max && listener->tftpfd != -1)
762 {
763 FD_SET(listener->tftpfd, set);
764 bump_maxfd(listener->tftpfd, maxfdp);
765 }
766#endif
767
768 }
769
1697269c 770 return wait;
3be34541 771}
9e4abcb5 772
3be34541
SK
773static void check_dns_listeners(struct daemon *daemon, fd_set *set, time_t now)
774{
775 struct serverfd *serverfdp;
776 struct listener *listener;
832af0ba
SK
777
778 for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
779 if (FD_ISSET(serverfdp->fd, set))
780 reply_query(serverfdp, daemon, now);
781
782 for (listener = daemon->listeners; listener; listener = listener->next)
783 {
784 if (FD_ISSET(listener->fd, set))
785 receive_query(listener, daemon, now);
786
787#ifdef HAVE_TFTP
788 if (listener->tftpfd != -1 && FD_ISSET(listener->tftpfd, set))
789 tftp_request(listener, daemon, now);
790#endif
3be34541 791
832af0ba
SK
792 if (FD_ISSET(listener->tcpfd, set))
793 {
794 int confd;
795 struct irec *iface = NULL;
796 pid_t p;
797
798 while((confd = accept(listener->tcpfd, NULL, NULL)) == -1 && errno == EINTR);
799
800 if (confd == -1)
801 continue;
802
803 if (daemon->options & OPT_NOWILD)
804 iface = listener->iface;
805 else
806 {
807 union mysockaddr tcp_addr;
808 socklen_t tcp_len = sizeof(union mysockaddr);
809 /* Check for allowed interfaces when binding the wildcard address:
810 we do this by looking for an interface with the same address as
811 the local address of the TCP connection, then looking to see if that's
812 an allowed interface. As a side effect, we get the netmask of the
813 interface too, for localisation. */
3be34541 814
832af0ba
SK
815 /* interface may be new since startup */
816 if (enumerate_interfaces(daemon) &&
817 getsockname(confd, (struct sockaddr *)&tcp_addr, &tcp_len) != -1)
818 for (iface = daemon->interfaces; iface; iface = iface->next)
819 if (sockaddr_isequal(&iface->addr, &tcp_addr))
820 break;
821 }
822
823 if (!iface)
824 {
825 shutdown(confd, SHUT_RDWR);
826 close(confd);
827 }
59353a6b 828#ifndef NO_FORK
832af0ba
SK
829 else if (!(daemon->options & OPT_DEBUG) && (p = fork()) != 0)
830 {
831 if (p != -1)
832 {
833 int i;
834 for (i = 0; i < MAX_PROCS; i++)
835 if (daemon->tcp_pids[i] == 0)
836 {
837 daemon->tcp_pids[i] = p;
838 break;
839 }
840 }
841 close(confd);
842 }
843#endif
844 else
845 {
846 unsigned char *buff;
847 struct server *s;
848 int flags;
849 struct in_addr dst_addr_4;
850
851 dst_addr_4.s_addr = 0;
852
7cebd20f
SK
853 /* Arrange for SIGALARM after CHILD_LIFETIME seconds to
854 terminate the process. */
832af0ba
SK
855 if (!(daemon->options & OPT_DEBUG))
856 alarm(CHILD_LIFETIME);
857
858 /* start with no upstream connections. */
859 for (s = daemon->servers; s; s = s->next)
7cebd20f 860 s->tcpfd = -1;
832af0ba
SK
861
862 /* The connected socket inherits non-blocking
863 attribute from the listening socket.
864 Reset that here. */
865 if ((flags = fcntl(confd, F_GETFL, 0)) != -1)
866 fcntl(confd, F_SETFL, flags & ~O_NONBLOCK);
867
868 if (listener->family == AF_INET)
869 dst_addr_4 = iface->addr.in.sin_addr;
870
871 buff = tcp_request(daemon, confd, now, dst_addr_4, iface->netmask);
7cebd20f 872
832af0ba
SK
873 shutdown(confd, SHUT_RDWR);
874 close(confd);
875
876 if (buff)
877 free(buff);
878
879 for (s = daemon->servers; s; s = s->next)
880 if (s->tcpfd != -1)
881 {
882 shutdown(s->tcpfd, SHUT_RDWR);
883 close(s->tcpfd);
884 }
7cebd20f 885#ifndef NO_FORK
832af0ba
SK
886 if (!(daemon->options & OPT_DEBUG))
887 _exit(0);
59353a6b 888#endif
832af0ba
SK
889 }
890 }
891 }
3be34541
SK
892}
893
7cebd20f 894
5e9e0efb
SK
895int make_icmp_sock(void)
896{
7cebd20f 897 int fd;
5e9e0efb
SK
898 int zeroopt = 0;
899
900 if ((fd = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP)) != -1)
901 {
7cebd20f 902 if (!fix_fd(fd) ||
5e9e0efb
SK
903 setsockopt(fd, SOL_SOCKET, SO_DONTROUTE, &zeroopt, sizeof(zeroopt)) == -1)
904 {
905 close(fd);
906 fd = -1;
907 }
908 }
909
910 return fd;
911}
912
3be34541
SK
913int icmp_ping(struct daemon *daemon, struct in_addr addr)
914{
5e9e0efb 915 /* Try and get an ICMP echo from a machine. */
3be34541
SK
916
917 /* Note that whilst in the three second wait, we check for
832af0ba 918 (and service) events on the DNS and TFTP sockets, (so doing that
3be34541
SK
919 better not use any resources our caller has in use...)
920 but we remain deaf to signals or further DHCP packets. */
921
5e9e0efb 922 int fd;
3be34541
SK
923 struct sockaddr_in saddr;
924 struct {
925 struct ip ip;
926 struct icmp icmp;
927 } packet;
928 unsigned short id = rand16();
929 unsigned int i, j;
5e9e0efb 930 int gotreply = 0;
3be34541 931 time_t start, now;
5e9e0efb
SK
932
933#ifdef HAVE_LINUX_NETWORK
934 if ((fd = make_icmp_sock()) == -1)
935 return 0;
936#else
937 int opt = 2000;
938 fd = daemon->dhcp_icmp_fd;
939 setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
940#endif
941
3be34541
SK
942 saddr.sin_family = AF_INET;
943 saddr.sin_port = 0;
944 saddr.sin_addr = addr;
945#ifdef HAVE_SOCKADDR_SA_LEN
946 saddr.sin_len = sizeof(struct sockaddr_in);
947#endif
948
949 memset(&packet.icmp, 0, sizeof(packet.icmp));
950 packet.icmp.icmp_type = ICMP_ECHO;
951 packet.icmp.icmp_id = id;
952 for (j = 0, i = 0; i < sizeof(struct icmp) / 2; i++)
953 j += ((u16 *)&packet.icmp)[i];
954 while (j>>16)
955 j = (j & 0xffff) + (j >> 16);
956 packet.icmp.icmp_cksum = (j == 0xffff) ? j : ~j;
957
5e9e0efb 958 while (sendto(fd, (char *)&packet.icmp, sizeof(struct icmp), 0,
fd9fa481
SK
959 (struct sockaddr *)&saddr, sizeof(saddr)) == -1 &&
960 retry_send());
961
5e9e0efb
SK
962 for (now = start = dnsmasq_time();
963 difftime(now, start) < (float)PING_WAIT;)
fd9fa481
SK
964 {
965 struct timeval tv;
966 fd_set rset;
967 struct sockaddr_in faddr;
1697269c 968 int maxfd = fd;
3d8df260 969 socklen_t len = sizeof(faddr);
fd9fa481
SK
970
971 tv.tv_usec = 250000;
972 tv.tv_sec = 0;
973
974 FD_ZERO(&rset);
5e9e0efb 975 FD_SET(fd, &rset);
1697269c 976 set_dns_listeners(daemon, now, &rset, &maxfd);
832af0ba 977
fd9fa481
SK
978 if (select(maxfd+1, &rset, NULL, NULL, &tv) < 0)
979 FD_ZERO(&rset);
980
5e9e0efb 981 now = dnsmasq_time();
fd9fa481 982 check_dns_listeners(daemon, &rset, now);
832af0ba
SK
983
984#ifdef HAVE_TFTP
985 check_tftp_listeners(daemon, &rset, now);
986#endif
987
5e9e0efb
SK
988 if (FD_ISSET(fd, &rset) &&
989 recvfrom(fd, &packet, sizeof(packet), 0,
fd9fa481
SK
990 (struct sockaddr *)&faddr, &len) == sizeof(packet) &&
991 saddr.sin_addr.s_addr == faddr.sin_addr.s_addr &&
992 packet.icmp.icmp_type == ICMP_ECHOREPLY &&
993 packet.icmp.icmp_seq == 0 &&
994 packet.icmp.icmp_id == id)
995 {
996 gotreply = 1;
997 break;
998 }
999 }
1000
5e9e0efb
SK
1001#ifdef HAVE_LINUX_NETWORK
1002 close(fd);
1003#else
3be34541 1004 opt = 1;
5e9e0efb
SK
1005 setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
1006#endif
1007
3be34541
SK
1008 return gotreply;
1009}
0a852541
SK
1010
1011