blob: 45761ccd89bec1bf5039b337219ff4f2e9001822 [file] [log] [blame]
Simon Kelleyaff33962015-01-31 20:13:40 +00001/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley
Simon Kelley9e4abcb2004-01-22 19:47:41 +00002
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
Simon Kelley824af852008-02-12 20:43:05 +00005 the Free Software Foundation; version 2 dated June, 1991, or
6 (at your option) version 3 dated 29 June, 2007.
7
Simon Kelley9e4abcb2004-01-22 19:47:41 +00008 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.
Simon Kelley824af852008-02-12 20:43:05 +000012
Simon Kelley73a08a22009-02-05 20:28:08 +000013 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/>.
Simon Kelley9e4abcb2004-01-22 19:47:41 +000015*/
16
Simon Kelleyc72daea2012-01-05 21:33:27 +000017/* Declare static char *compiler_opts in config.h */
18#define DNSMASQ_COMPILE_OPTS
19
Simon Kelley9e4abcb2004-01-22 19:47:41 +000020#include "dnsmasq.h"
21
Simon Kelley5aabfc72007-08-29 11:24:47 +010022struct daemon *daemon;
23
Simon Kelley5aabfc72007-08-29 11:24:47 +010024static volatile pid_t pid = 0;
25static volatile int pipewrite;
Simon Kelley9e4abcb2004-01-22 19:47:41 +000026
Simon Kelleyb842bc92015-07-12 21:09:11 +010027static int set_dns_listeners(time_t now);
28static void check_dns_listeners(time_t now);
Simon Kelley3be34542004-09-11 19:12:13 +010029static void sig_handler(int sig);
Simon Kelley5aabfc72007-08-29 11:24:47 +010030static void async_event(int pipe, time_t now);
Simon Kelleyc72daea2012-01-05 21:33:27 +000031static void fatal_event(struct event_desc *ev, char *msg);
32static int read_event(int fd, struct event_desc *evp, char **msg);
Simon Kelley47a95162014-07-08 22:22:02 +010033static void poll_resolv(int force, int do_reload, time_t now);
Simon Kelley9e4abcb2004-01-22 19:47:41 +000034
35int main (int argc, char **argv)
36{
Simon Kelleyde379512004-06-22 20:23:33 +010037 int bind_fallback = 0;
Simon Kelley9009d742008-11-14 20:04:27 +000038 time_t now;
Simon Kelley9e4abcb2004-01-22 19:47:41 +000039 struct sigaction sigact;
Simon Kelley26128d22004-11-14 16:43:54 +000040 struct iname *if_tmp;
Simon Kelley1a6bca82008-07-11 11:11:42 +010041 int piperead, pipefd[2], err_pipe[2];
42 struct passwd *ent_pw = NULL;
Simon Kelleyc72daea2012-01-05 21:33:27 +000043#if defined(HAVE_SCRIPT)
Simon Kelley1a6bca82008-07-11 11:11:42 +010044 uid_t script_uid = 0;
45 gid_t script_gid = 0;
Simon Kelley7622fc02009-06-04 20:32:05 +010046#endif
47 struct group *gp = NULL;
Simon Kelley5aabfc72007-08-29 11:24:47 +010048 long i, max_fd = sysconf(_SC_OPEN_MAX);
Simon Kelley1a6bca82008-07-11 11:11:42 +010049 char *baduser = NULL;
50 int log_err;
51#if defined(HAVE_LINUX_NETWORK)
52 cap_user_header_t hdr = NULL;
53 cap_user_data_t data = NULL;
Simon Kelley3b3f4412013-10-11 16:33:28 +010054 char *bound_device = NULL;
55 int did_bind = 0;
Simon Kelley1a6bca82008-07-11 11:11:42 +010056#endif
Vladislav Grishenko408c3682013-09-24 16:18:49 +010057#if defined(HAVE_DHCP) || defined(HAVE_DHCP6)
Simon Kelley1f776932012-12-16 19:46:08 +000058 struct dhcp_context *context;
Simon Kelleyff7eea22013-09-04 18:01:38 +010059 struct dhcp_relay *relay;
Vladislav Grishenko408c3682013-09-24 16:18:49 +010060#endif
Stefan Tomanek30d08792015-03-31 22:32:11 +010061#ifdef HAVE_TFTP
62 int tftp_prefix_missing = 0;
63#endif
Simon Kelley5aabfc72007-08-29 11:24:47 +010064
Simon Kelley824af852008-02-12 20:43:05 +000065#ifdef LOCALEDIR
Simon Kelleyb8187c82005-11-26 21:46:27 +000066 setlocale(LC_ALL, "");
67 bindtextdomain("dnsmasq", LOCALEDIR);
68 textdomain("dnsmasq");
69#endif
70
Simon Kelley9e4abcb2004-01-22 19:47:41 +000071 sigact.sa_handler = sig_handler;
72 sigact.sa_flags = 0;
73 sigemptyset(&sigact.sa_mask);
74 sigaction(SIGUSR1, &sigact, NULL);
Simon Kelley5aabfc72007-08-29 11:24:47 +010075 sigaction(SIGUSR2, &sigact, NULL);
Simon Kelley9e4abcb2004-01-22 19:47:41 +000076 sigaction(SIGHUP, &sigact, NULL);
77 sigaction(SIGTERM, &sigact, NULL);
Simon Kelley44a2a312004-03-10 20:04:35 +000078 sigaction(SIGALRM, &sigact, NULL);
Simon Kelleyfeba5c12004-07-27 20:28:58 +010079 sigaction(SIGCHLD, &sigact, NULL);
80
81 /* ignore SIGPIPE */
82 sigact.sa_handler = SIG_IGN;
83 sigaction(SIGPIPE, &sigact, NULL);
Simon Kelley9e4abcb2004-01-22 19:47:41 +000084
Simon Kelley5aabfc72007-08-29 11:24:47 +010085 umask(022); /* known umask, create leases and pid files as 0644 */
Simon Kelleyb5ea1cc2014-07-29 16:34:14 +010086
87 rand_init(); /* Must precede read_opts() */
88
Simon Kelley5aabfc72007-08-29 11:24:47 +010089 read_opts(argc, argv, compile_opts);
Simon Kelleyc3e0b9b2013-12-31 13:50:39 +000090
Simon Kelley3be34542004-09-11 19:12:13 +010091 if (daemon->edns_pktsz < PACKETSZ)
Simon Kelley60b68062014-01-08 12:10:28 +000092 daemon->edns_pktsz = PACKETSZ;
Simon Kelley3ddacb82014-01-08 14:32:03 +000093
Simon Kelleyd3a8b392015-12-23 12:27:37 +000094 /* Min buffer size: we check after adding each record, so there must be
95 memory for the largest packet, and the largest record so the
96 min for DNS is PACKETSZ+MAXDNAME+RRFIXEDSZ which is < 1000.
97 This might be increased is EDNS packet size if greater than the minimum. */
98 daemon->packet_buff_sz = daemon->edns_pktsz + MAXDNAME + RRFIXEDSZ;
Simon Kelley0a852542005-03-23 20:28:59 +000099 daemon->packet = safe_malloc(daemon->packet_buff_sz);
Simon Kelley3ddacb82014-01-08 14:32:03 +0000100
Simon Kelleyc72daea2012-01-05 21:33:27 +0000101 daemon->addrbuff = safe_malloc(ADDRSTRLEN);
Simon Kelley25cf5e32015-01-09 15:53:03 +0000102 if (option_bool(OPT_EXTRALOG))
103 daemon->addrbuff2 = safe_malloc(ADDRSTRLEN);
Simon Kelley3ddacb82014-01-08 14:32:03 +0000104
105#ifdef HAVE_DNSSEC
106 if (option_bool(OPT_DNSSEC_VALID))
Simon Kelley5107ace2014-02-23 10:48:32 +0000107 {
Simon Kelleycbe379a2015-04-21 22:57:06 +0100108 /* Note that both /000 and '.' are allowed within labels. These get
109 represented in presentation format using NAME_ESCAPE as an escape
110 character when in DNSSEC mode.
111 In theory, if all the characters in a name were /000 or
112 '.' or NAME_ESCAPE then all would have to be escaped, so the
113 presentation format would be twice as long as the spec.
114
115 daemon->namebuff was previously allocated by the option-reading
116 code before we knew if we're in DNSSEC mode, so reallocate here. */
117 free(daemon->namebuff);
118 daemon->namebuff = safe_malloc(MAXDNAME * 2);
119 daemon->keyname = safe_malloc(MAXDNAME * 2);
120 daemon->workspacename = safe_malloc(MAXDNAME * 2);
Simon Kelley5107ace2014-02-23 10:48:32 +0000121 }
Simon Kelley3ddacb82014-01-08 14:32:03 +0000122#endif
Simon Kelley4f7b3042012-11-28 21:27:02 +0000123
Simon Kelley7622fc02009-06-04 20:32:05 +0100124#ifdef HAVE_DHCP
Simon Kelley3be34542004-09-11 19:12:13 +0100125 if (!daemon->lease_file)
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000126 {
Simon Kelley52b92f42012-01-22 16:05:15 +0000127 if (daemon->dhcp || daemon->dhcp6)
Simon Kelley3be34542004-09-11 19:12:13 +0100128 daemon->lease_file = LEASEFILE;
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000129 }
Simon Kelley7622fc02009-06-04 20:32:05 +0100130#endif
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000131
Simon Kelleya2761752012-01-18 16:07:21 +0000132 /* Close any file descriptors we inherited apart from std{in|out|err}
133
134 Ensure that at least stdin, stdout and stderr (fd 0, 1, 2) exist,
135 otherwise file descriptors we create can end up being 0, 1, or 2
136 and then get accidentally closed later when we make 0, 1, and 2
137 open to /dev/null. Normally we'll be started with 0, 1 and 2 open,
138 but it's not guaranteed. By opening /dev/null three times, we
139 ensure that we're not using those fds for real stuff. */
Simon Kelley5aabfc72007-08-29 11:24:47 +0100140 for (i = 0; i < max_fd; i++)
141 if (i != STDOUT_FILENO && i != STDERR_FILENO && i != STDIN_FILENO)
142 close(i);
Simon Kelleya2761752012-01-18 16:07:21 +0000143 else
144 open("/dev/null", O_RDWR);
Simon Kelley5aabfc72007-08-29 11:24:47 +0100145
Simon Kelley801ca9a2012-03-06 19:30:17 +0000146#ifndef HAVE_LINUX_NETWORK
147# if !(defined(IP_RECVDSTADDR) && defined(IP_RECVIF) && defined(IP_SENDSRCADDR))
Simon Kelley28866e92011-02-14 20:19:14 +0000148 if (!option_bool(OPT_NOWILD))
Simon Kelleyde379512004-06-22 20:23:33 +0100149 {
150 bind_fallback = 1;
Simon Kelley28866e92011-02-14 20:19:14 +0000151 set_option_bool(OPT_NOWILD);
Simon Kelleyde379512004-06-22 20:23:33 +0100152 }
Simon Kelley801ca9a2012-03-06 19:30:17 +0000153# endif
Simon Kelley2b5bae92012-06-26 16:55:23 +0100154
155 /* -- bind-dynamic not supported on !Linux, fall back to --bind-interfaces */
Simon Kelley54dd3932012-06-20 11:23:38 +0100156 if (option_bool(OPT_CLEVERBIND))
Simon Kelley2b5bae92012-06-26 16:55:23 +0100157 {
158 bind_fallback = 1;
159 set_option_bool(OPT_NOWILD);
Simon Kelley236e0722012-06-26 21:33:01 +0100160 reset_option_bool(OPT_CLEVERBIND);
Simon Kelley2b5bae92012-06-26 16:55:23 +0100161 }
Simon Kelley04918052015-01-26 11:23:43 +0000162#endif
Simon Kelley5f4dc5c2015-01-20 20:51:02 +0000163
Simon Kelley04918052015-01-26 11:23:43 +0000164#ifndef HAVE_INOTIFY
Simon Kelley70d18732015-01-31 19:59:29 +0000165 if (daemon->dynamic_dirs)
166 die(_("dhcp-hostsdir, dhcp-optsdir and hostsdir are not supported on this platform"), NULL, EC_BADCONF);
Simon Kelley309331f2006-04-22 15:05:01 +0100167#endif
Simon Kelley2b5bae92012-06-26 16:55:23 +0100168
Simon Kelley0744ca62014-01-25 16:40:15 +0000169 if (option_bool(OPT_DNSSEC_VALID))
170 {
Simon Kelley3ddacb82014-01-08 14:32:03 +0000171#ifdef HAVE_DNSSEC
Simon Kelleyee415862014-02-11 11:07:22 +0000172 if (!daemon->ds)
Simon Kelley360f2512015-03-07 18:28:06 +0000173 die(_("no trust anchors provided for DNSSEC"), NULL, EC_BADCONF);
Simon Kelley0744ca62014-01-25 16:40:15 +0000174
175 if (daemon->cachesize < CACHESIZ)
Simon Kelley360f2512015-03-07 18:28:06 +0000176 die(_("cannot reduce cache size from default when DNSSEC enabled"), NULL, EC_BADCONF);
Simon Kelley0744ca62014-01-25 16:40:15 +0000177#else
178 die(_("DNSSEC not available: set HAVE_DNSSEC in src/config.h"), NULL, EC_BADCONF);
Simon Kelley3ddacb82014-01-08 14:32:03 +0000179#endif
Simon Kelley0744ca62014-01-25 16:40:15 +0000180 }
Simon Kelley3ddacb82014-01-08 14:32:03 +0000181
Simon Kelley832af0b2007-01-21 20:01:28 +0000182#ifndef HAVE_TFTP
Simon Kelley9b40cbf2012-07-13 19:58:26 +0100183 if (option_bool(OPT_TFTP))
Simon Kelley5aabfc72007-08-29 11:24:47 +0100184 die(_("TFTP server not available: set HAVE_TFTP in src/config.h"), NULL, EC_BADCONF);
Simon Kelley832af0b2007-01-21 20:01:28 +0000185#endif
186
Simon Kelley7de060b2011-08-26 17:24:52 +0100187#ifdef HAVE_CONNTRACK
188 if (option_bool(OPT_CONNTRACK) && (daemon->query_port != 0 || daemon->osport))
Simon Kelley360f2512015-03-07 18:28:06 +0000189 die (_("cannot use --conntrack AND --query-port"), NULL, EC_BADCONF);
Simon Kelley7de060b2011-08-26 17:24:52 +0100190#else
191 if (option_bool(OPT_CONNTRACK))
Simon Kelley360f2512015-03-07 18:28:06 +0000192 die(_("conntrack support not available: set HAVE_CONNTRACK in src/config.h"), NULL, EC_BADCONF);
Simon Kelley7de060b2011-08-26 17:24:52 +0100193#endif
194
Simon Kelley824af852008-02-12 20:43:05 +0000195#ifdef HAVE_SOLARIS_NETWORK
196 if (daemon->max_logs != 0)
197 die(_("asychronous logging is not available under Solaris"), NULL, EC_BADCONF);
198#endif
199
Simon Kelley572b41e2011-02-18 18:11:18 +0000200#ifdef __ANDROID__
201 if (daemon->max_logs != 0)
202 die(_("asychronous logging is not available under Android"), NULL, EC_BADCONF);
203#endif
204
Simon Kelley4820dce2012-12-18 18:30:30 +0000205#ifndef HAVE_AUTH
206 if (daemon->authserver)
207 die(_("authoritative DNS not available: set HAVE_AUTH in src/config.h"), NULL, EC_BADCONF);
208#endif
209
Simon Kelleyb5ea1cc2014-07-29 16:34:14 +0100210#ifndef HAVE_LOOP
211 if (option_bool(OPT_LOOP_DETECT))
Simon Kelley360f2512015-03-07 18:28:06 +0000212 die(_("loop detection not available: set HAVE_LOOP in src/config.h"), NULL, EC_BADCONF);
Simon Kelleyb5ea1cc2014-07-29 16:34:14 +0100213#endif
Simon Kelley1a6bca82008-07-11 11:11:42 +0100214
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100215 now = dnsmasq_time();
Simon Kelley4f7b3042012-11-28 21:27:02 +0000216
Simon Kelleyb0ff8582013-02-06 09:57:47 +0000217 /* Create a serial at startup if not configured. */
Simon Kelley4f7b3042012-11-28 21:27:02 +0000218 if (daemon->authinterface && daemon->soa_sn == 0)
219#ifdef HAVE_BROKEN_RTC
Simon Kelleyb0ff8582013-02-06 09:57:47 +0000220 die(_("zone serial must be configured in --auth-soa"), NULL, EC_BADCONF);
Simon Kelley4f7b3042012-11-28 21:27:02 +0000221#else
222 daemon->soa_sn = now;
223#endif
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000224
Simon Kelleyff7eea22013-09-04 18:01:38 +0100225#ifdef HAVE_DHCP6
226 if (daemon->dhcp6)
227 {
228 daemon->doing_ra = option_bool(OPT_RA);
Simon Kelley1f776932012-12-16 19:46:08 +0000229
Simon Kelleyff7eea22013-09-04 18:01:38 +0100230 for (context = daemon->dhcp6; context; context = context->next)
Simon Kelley1f776932012-12-16 19:46:08 +0000231 {
Simon Kelleyff7eea22013-09-04 18:01:38 +0100232 if (context->flags & CONTEXT_DHCP)
233 daemon->doing_dhcp6 = 1;
234 if (context->flags & CONTEXT_RA)
235 daemon->doing_ra = 1;
Simon Kelley1ee9be42013-12-09 16:50:19 +0000236#if !defined(HAVE_LINUX_NETWORK) && !defined(HAVE_BSD_NETWORK)
Simon Kelleyff7eea22013-09-04 18:01:38 +0100237 if (context->flags & CONTEXT_TEMPLATE)
238 die (_("dhcp-range constructor not available on this platform"), NULL, EC_BADCONF);
Simon Kelleybb86e852012-12-17 22:00:53 +0000239#endif
Simon Kelley1f776932012-12-16 19:46:08 +0000240 }
Simon Kelley1f776932012-12-16 19:46:08 +0000241 }
Simon Kelleyff7eea22013-09-04 18:01:38 +0100242#endif
243
244#ifdef HAVE_DHCP
245 /* Note that order matters here, we must call lease_init before
246 creating any file descriptors which shouldn't be leaked
247 to the lease-script init process. We need to call common_init
248 before lease_init to allocate buffers it uses.*/
249 if (daemon->dhcp || daemon->doing_dhcp6 || daemon->relay4 || daemon->relay6)
250 {
251 dhcp_common_init();
252 if (daemon->dhcp || daemon->doing_dhcp6)
253 lease_init(now);
254 }
255
256 if (daemon->dhcp || daemon->relay4)
257 dhcp_init();
258
259# ifdef HAVE_DHCP6
Simon Kelley89500e32013-09-20 16:29:20 +0100260 if (daemon->doing_ra || daemon->doing_dhcp6 || daemon->relay6)
Simon Kelleyff7eea22013-09-04 18:01:38 +0100261 ra_init(now);
262
263 if (daemon->doing_dhcp6 || daemon->relay6)
264 dhcp6_init();
265# endif
Simon Kelley843c96b2012-02-27 17:42:38 +0000266
Simon Kelley7622fc02009-06-04 20:32:05 +0100267#endif
Simon Kelleyfeba5c12004-07-27 20:28:58 +0100268
Jason A. Donenfeld13d86c72013-02-22 18:20:53 +0000269#ifdef HAVE_IPSET
270 if (daemon->ipsets)
271 ipset_init();
272#endif
273
Simon Kelley1ee9be42013-12-09 16:50:19 +0000274#if defined(HAVE_LINUX_NETWORK)
Simon Kelley801ca9a2012-03-06 19:30:17 +0000275 netlink_init();
Simon Kelley1ee9be42013-12-09 16:50:19 +0000276#elif defined(HAVE_BSD_NETWORK)
277 route_init();
Simon Kelley801ca9a2012-03-06 19:30:17 +0000278#endif
279
Simon Kelley1ee9be42013-12-09 16:50:19 +0000280 if (option_bool(OPT_NOWILD) && option_bool(OPT_CLEVERBIND))
281 die(_("cannot set --bind-interfaces and --bind-dynamic"), NULL, EC_BADCONF);
282
Simon Kelley115ac3e2013-05-20 11:28:32 +0100283 if (!enumerate_interfaces(1) || !enumerate_interfaces(0))
Simon Kelley5aabfc72007-08-29 11:24:47 +0100284 die(_("failed to find list of interfaces: %s"), NULL, EC_MISC);
Simon Kelley843c96b2012-02-27 17:42:38 +0000285
Simon Kelley54dd3932012-06-20 11:23:38 +0100286 if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND))
Simon Kelley5aabfc72007-08-29 11:24:47 +0100287 {
Simon Kelley74c95c22011-10-19 09:33:39 +0100288 create_bound_listeners(1);
Simon Kelley54dd3932012-06-20 11:23:38 +0100289
290 if (!option_bool(OPT_CLEVERBIND))
291 for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
292 if (if_tmp->name && !if_tmp->used)
293 die(_("unknown interface %s"), if_tmp->name, EC_BADNET);
Simon Kelley9380ba72012-04-16 14:41:56 +0100294
295#if defined(HAVE_LINUX_NETWORK) && defined(HAVE_DHCP)
296 /* after enumerate_interfaces() */
Simon Kelley3b3f4412013-10-11 16:33:28 +0100297 bound_device = whichdevice();
298
Simon Kelley9380ba72012-04-16 14:41:56 +0100299 if (daemon->dhcp)
300 {
Simon Kelley3b3f4412013-10-11 16:33:28 +0100301 if (!daemon->relay4 && bound_device)
302 {
303 bindtodevice(bound_device, daemon->dhcpfd);
304 did_bind = 1;
305 }
306 if (daemon->enable_pxe && bound_device)
307 {
308 bindtodevice(bound_device, daemon->pxefd);
309 did_bind = 1;
310 }
Simon Kelley9380ba72012-04-16 14:41:56 +0100311 }
312#endif
313
314#if defined(HAVE_LINUX_NETWORK) && defined(HAVE_DHCP6)
Simon Kelley3b3f4412013-10-11 16:33:28 +0100315 if (daemon->doing_dhcp6 && !daemon->relay6 && bound_device)
316 {
317 bindtodevice(bound_device, daemon->dhcp6fd);
318 did_bind = 1;
319 }
Simon Kelley9380ba72012-04-16 14:41:56 +0100320#endif
Simon Kelley5aabfc72007-08-29 11:24:47 +0100321 }
Simon Kelley28866e92011-02-14 20:19:14 +0000322 else
Simon Kelley74c95c22011-10-19 09:33:39 +0100323 create_wildcard_listeners();
Simon Kelley5d162f22012-12-20 14:55:46 +0000324
325#ifdef HAVE_DHCP6
326 /* after enumerate_interfaces() */
Simon Kelleyff7eea22013-09-04 18:01:38 +0100327 if (daemon->doing_dhcp6 || daemon->relay6 || daemon->doing_ra)
Simon Kelley5d162f22012-12-20 14:55:46 +0000328 join_multicast(1);
Simon Kelley3511a922013-11-07 10:28:11 +0000329
330 /* After netlink_init() and before create_helper() */
331 lease_make_duid(now);
Simon Kelley5d162f22012-12-20 14:55:46 +0000332#endif
Simon Kelley5aabfc72007-08-29 11:24:47 +0100333
Simon Kelley824af852008-02-12 20:43:05 +0000334 if (daemon->port != 0)
Simon Kelley82e3f452014-01-31 21:05:48 +0000335 {
336 cache_init();
Simon Kelley193de4a2014-12-10 17:32:16 +0000337
Simon Kelley82e3f452014-01-31 21:05:48 +0000338#ifdef HAVE_DNSSEC
339 blockdata_init();
340#endif
Simon Kelley5f4dc5c2015-01-20 20:51:02 +0000341 }
Simon Kelley193de4a2014-12-10 17:32:16 +0000342
Simon Kelley04918052015-01-26 11:23:43 +0000343#ifdef HAVE_INOTIFY
Simon Kelley70d18732015-01-31 19:59:29 +0000344 if (daemon->port != 0 || daemon->dhcp || daemon->doing_dhcp6)
Simon Kelley5f4dc5c2015-01-20 20:51:02 +0000345 inotify_dnsmasq_init();
346 else
347 daemon->inotifyfd = -1;
Simon Kelley193de4a2014-12-10 17:32:16 +0000348#endif
Simon Kelley5f4dc5c2015-01-20 20:51:02 +0000349
Simon Kelley28866e92011-02-14 20:19:14 +0000350 if (option_bool(OPT_DBUS))
Simon Kelley3d8df262005-08-29 12:19:27 +0100351#ifdef HAVE_DBUS
352 {
353 char *err;
354 daemon->dbus = NULL;
355 daemon->watches = NULL;
Simon Kelley5aabfc72007-08-29 11:24:47 +0100356 if ((err = dbus_init()))
357 die(_("DBus error: %s"), err, EC_MISC);
Simon Kelley3d8df262005-08-29 12:19:27 +0100358 }
359#else
Simon Kelley5aabfc72007-08-29 11:24:47 +0100360 die(_("DBus not available: set HAVE_DBUS in src/config.h"), NULL, EC_BADCONF);
Simon Kelley3d8df262005-08-29 12:19:27 +0100361#endif
Stefan Tomanek7aa970e2015-04-01 17:55:07 +0100362
Simon Kelley824af852008-02-12 20:43:05 +0000363 if (daemon->port != 0)
364 pre_allocate_sfds();
Simon Kelley1a6bca82008-07-11 11:11:42 +0100365
Simon Kelleyc72daea2012-01-05 21:33:27 +0000366#if defined(HAVE_SCRIPT)
Simon Kelley1a6bca82008-07-11 11:11:42 +0100367 /* Note getpwnam returns static storage */
Simon Kelley843c96b2012-02-27 17:42:38 +0000368 if ((daemon->dhcp || daemon->dhcp6) &&
369 daemon->scriptuser &&
Simon Kelleyc72daea2012-01-05 21:33:27 +0000370 (daemon->lease_change_command || daemon->luascript))
Simon Kelley1a6bca82008-07-11 11:11:42 +0100371 {
372 if ((ent_pw = getpwnam(daemon->scriptuser)))
373 {
374 script_uid = ent_pw->pw_uid;
375 script_gid = ent_pw->pw_gid;
376 }
377 else
378 baduser = daemon->scriptuser;
379 }
Simon Kelley7622fc02009-06-04 20:32:05 +0100380#endif
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000381
Simon Kelley1a6bca82008-07-11 11:11:42 +0100382 if (daemon->username && !(ent_pw = getpwnam(daemon->username)))
383 baduser = daemon->username;
384 else if (daemon->groupname && !(gp = getgrnam(daemon->groupname)))
385 baduser = daemon->groupname;
386
387 if (baduser)
388 die(_("unknown user or group: %s"), baduser, EC_BADCONF);
Simon Kelleyf6e62e22015-03-01 18:17:54 +0000389
Simon Kelley1a6bca82008-07-11 11:11:42 +0100390 /* implement group defaults, "dip" if available, or group associated with uid */
391 if (!daemon->group_set && !gp)
392 {
393 if (!(gp = getgrnam(CHGRP)) && ent_pw)
394 gp = getgrgid(ent_pw->pw_gid);
395
396 /* for error message */
397 if (gp)
398 daemon->groupname = gp->gr_name;
399 }
400
401#if defined(HAVE_LINUX_NETWORK)
402 /* determine capability API version here, while we can still
403 call safe_malloc */
404 if (ent_pw && ent_pw->pw_uid != 0)
405 {
Simon Kelley1a6bca82008-07-11 11:11:42 +0100406 int capsize = 1; /* for header version 1 */
Simon Kelley3927da42008-07-20 15:10:39 +0100407 hdr = safe_malloc(sizeof(*hdr));
408
Simon Kelley1a6bca82008-07-11 11:11:42 +0100409 /* find version supported by kernel */
410 memset(hdr, 0, sizeof(*hdr));
411 capget(hdr, NULL);
412
413 if (hdr->version != LINUX_CAPABILITY_VERSION_1)
414 {
415 /* if unknown version, use largest supported version (3) */
416 if (hdr->version != LINUX_CAPABILITY_VERSION_2)
417 hdr->version = LINUX_CAPABILITY_VERSION_3;
418 capsize = 2;
419 }
420
421 data = safe_malloc(sizeof(*data) * capsize);
422 memset(data, 0, sizeof(*data) * capsize);
423 }
424#endif
425
Simon Kelley5aabfc72007-08-29 11:24:47 +0100426 /* Use a pipe to carry signals and other events back to the event loop
Simon Kelley1a6bca82008-07-11 11:11:42 +0100427 in a race-free manner and another to carry errors to daemon-invoking process */
428 safe_pipe(pipefd, 1);
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100429
430 piperead = pipefd[0];
431 pipewrite = pipefd[1];
432 /* prime the pipe to load stuff first time. */
Simon Kelleye98bd522014-03-28 20:41:23 +0000433 send_event(pipewrite, EVENT_INIT, 0, NULL);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100434
435 err_pipe[1] = -1;
Simon Kelley16972692006-10-16 20:04:18 +0100436
Simon Kelley28866e92011-02-14 20:19:14 +0000437 if (!option_bool(OPT_DEBUG))
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000438 {
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000439 /* The following code "daemonizes" the process.
440 See Stevens section 12.4 */
Simon Kelley1a6bca82008-07-11 11:11:42 +0100441
Simon Kelley9e038942008-05-30 20:06:34 +0100442 if (chdir("/") != 0)
443 die(_("cannot chdir to filesystem root: %s"), NULL, EC_MISC);
444
Simon Kelley16972692006-10-16 20:04:18 +0100445#ifndef NO_FORK
Simon Kelley28866e92011-02-14 20:19:14 +0000446 if (!option_bool(OPT_NO_FORK))
Simon Kelley3be34542004-09-11 19:12:13 +0100447 {
Simon Kelley5aabfc72007-08-29 11:24:47 +0100448 pid_t pid;
449
Simon Kelley1a6bca82008-07-11 11:11:42 +0100450 /* pipe to carry errors back to original process.
451 When startup is complete we close this and the process terminates. */
452 safe_pipe(err_pipe, 0);
453
Simon Kelley7622fc02009-06-04 20:32:05 +0100454 if ((pid = fork()) == -1)
455 /* fd == -1 since we've not forked, never returns. */
Simon Kelleyc72daea2012-01-05 21:33:27 +0000456 send_event(-1, EVENT_FORK_ERR, errno, NULL);
Simon Kelley9e038942008-05-30 20:06:34 +0100457
Simon Kelley5aabfc72007-08-29 11:24:47 +0100458 if (pid != 0)
Simon Kelley1a6bca82008-07-11 11:11:42 +0100459 {
460 struct event_desc ev;
Simon Kelleyc72daea2012-01-05 21:33:27 +0000461 char *msg;
462
Simon Kelley1a6bca82008-07-11 11:11:42 +0100463 /* close our copy of write-end */
Simon Kelleyff841eb2015-03-11 21:36:30 +0000464 while (retry_send(close(err_pipe[1])));
Simon Kelley1a6bca82008-07-11 11:11:42 +0100465
466 /* check for errors after the fork */
Simon Kelleyc72daea2012-01-05 21:33:27 +0000467 if (read_event(err_pipe[0], &ev, &msg))
468 fatal_event(&ev, msg);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100469
470 _exit(EC_GOOD);
471 }
472
Simon Kelleyff841eb2015-03-11 21:36:30 +0000473 while (retry_send(close(err_pipe[0])));
Simon Kelley1a6bca82008-07-11 11:11:42 +0100474
475 /* NO calls to die() from here on. */
Simon Kelley3be34542004-09-11 19:12:13 +0100476
477 setsid();
Simon Kelley7622fc02009-06-04 20:32:05 +0100478
479 if ((pid = fork()) == -1)
Simon Kelleyc72daea2012-01-05 21:33:27 +0000480 send_event(err_pipe[1], EVENT_FORK_ERR, errno, NULL);
Simon Kelley7622fc02009-06-04 20:32:05 +0100481
482 if (pid != 0)
Simon Kelley7cebd202006-05-06 14:13:33 +0100483 _exit(0);
Simon Kelley3be34542004-09-11 19:12:13 +0100484 }
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000485#endif
Simon Kelley9e038942008-05-30 20:06:34 +0100486
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000487 /* write pidfile _after_ forking ! */
Simon Kelley1a6bca82008-07-11 11:11:42 +0100488 if (daemon->runfile)
489 {
Simon Kelley79cfefd2012-09-02 13:29:51 +0100490 int fd, err = 0;
491
492 sprintf(daemon->namebuff, "%d\n", (int) getpid());
493
494 /* Explanation: Some installations of dnsmasq (eg Debian/Ubuntu) locate the pid-file
495 in a directory which is writable by the non-privileged user that dnsmasq runs as. This
496 allows the daemon to delete the file as part of its shutdown. This is a security hole to the
497 extent that an attacker running as the unprivileged user could replace the pidfile with a
498 symlink, and have the target of that symlink overwritten as root next time dnsmasq starts.
499
500 The folowing code first deletes any existing file, and then opens it with the O_EXCL flag,
501 ensuring that the open() fails should there be any existing file (because the unlink() failed,
502 or an attacker exploited the race between unlink() and open()). This ensures that no symlink
503 attack can succeed.
504
505 Any compromise of the non-privileged user still theoretically allows the pid-file to be
506 replaced whilst dnsmasq is running. The worst that could allow is that the usual
507 "shutdown dnsmasq" shell command could be tricked into stopping any other process.
508
509 Note that if dnsmasq is started as non-root (eg for testing) it silently ignores
510 failure to write the pid-file.
511 */
512
513 unlink(daemon->runfile);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100514
Simon Kelley79cfefd2012-09-02 13:29:51 +0100515 if ((fd = open(daemon->runfile, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH)) == -1)
Simon Kelley1a6bca82008-07-11 11:11:42 +0100516 {
Simon Kelley79cfefd2012-09-02 13:29:51 +0100517 /* only complain if started as root */
518 if (getuid() == 0)
519 err = 1;
Simon Kelley1a6bca82008-07-11 11:11:42 +0100520 }
Simon Kelley79cfefd2012-09-02 13:29:51 +0100521 else
522 {
523 if (!read_write(fd, (unsigned char *)daemon->namebuff, strlen(daemon->namebuff), 0))
524 err = 1;
Simon Kelleyff841eb2015-03-11 21:36:30 +0000525 else
526 {
527 while (retry_send(close(fd)));
528 if (errno != 0)
529 err = 1;
530 }
Simon Kelley79cfefd2012-09-02 13:29:51 +0100531 }
532
533 if (err)
Simon Kelley1a6bca82008-07-11 11:11:42 +0100534 {
Simon Kelleyc72daea2012-01-05 21:33:27 +0000535 send_event(err_pipe[1], EVENT_PIDFILE, errno, daemon->runfile);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100536 _exit(0);
537 }
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000538 }
Simon Kelley16972692006-10-16 20:04:18 +0100539 }
540
Simon Kelley8ef5ada2010-06-03 19:42:45 +0100541 log_err = log_start(ent_pw, err_pipe[1]);
542
Simon Kelley28866e92011-02-14 20:19:14 +0000543 if (!option_bool(OPT_DEBUG))
Simon Kelley8ef5ada2010-06-03 19:42:45 +0100544 {
545 /* open stdout etc to /dev/null */
546 int nullfd = open("/dev/null", O_RDWR);
547 dup2(nullfd, STDOUT_FILENO);
548 dup2(nullfd, STDERR_FILENO);
549 dup2(nullfd, STDIN_FILENO);
550 close(nullfd);
551 }
Simon Kelleyf2621c72007-04-29 19:47:21 +0100552
Simon Kelley1a6bca82008-07-11 11:11:42 +0100553 /* if we are to run scripts, we need to fork a helper before dropping root. */
554 daemon->helperfd = -1;
Simon Kelleyc72daea2012-01-05 21:33:27 +0000555#ifdef HAVE_SCRIPT
Simon Kelley52b92f42012-01-22 16:05:15 +0000556 if ((daemon->dhcp || daemon->dhcp6) && (daemon->lease_change_command || daemon->luascript))
Simon Kelley1a6bca82008-07-11 11:11:42 +0100557 daemon->helperfd = create_helper(pipewrite, err_pipe[1], script_uid, script_gid, max_fd);
558#endif
Simon Kelley5aabfc72007-08-29 11:24:47 +0100559
Simon Kelley28866e92011-02-14 20:19:14 +0000560 if (!option_bool(OPT_DEBUG) && getuid() == 0)
Simon Kelley16972692006-10-16 20:04:18 +0100561 {
Simon Kelley1a6bca82008-07-11 11:11:42 +0100562 int bad_capabilities = 0;
563 gid_t dummy;
Simon Kelley16972692006-10-16 20:04:18 +0100564
Simon Kelley1a6bca82008-07-11 11:11:42 +0100565 /* remove all supplimentary groups */
566 if (gp &&
567 (setgroups(0, &dummy) == -1 ||
568 setgid(gp->gr_gid) == -1))
569 {
Simon Kelleyc72daea2012-01-05 21:33:27 +0000570 send_event(err_pipe[1], EVENT_GROUP_ERR, errno, daemon->groupname);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100571 _exit(0);
572 }
573
Simon Kelley7cebd202006-05-06 14:13:33 +0100574 if (ent_pw && ent_pw->pw_uid != 0)
Simon Kelley16972692006-10-16 20:04:18 +0100575 {
Simon Kelley74c95c22011-10-19 09:33:39 +0100576#if defined(HAVE_LINUX_NETWORK)
Simon Kelley16972692006-10-16 20:04:18 +0100577 /* On linux, we keep CAP_NETADMIN (for ARP-injection) and
Simon Kelley74c95c22011-10-19 09:33:39 +0100578 CAP_NET_RAW (for icmp) if we're doing dhcp. If we have yet to bind
Simon Kelley54dd3932012-06-20 11:23:38 +0100579 ports because of DAD, or we're doing it dynamically,
580 we need CAP_NET_BIND_SERVICE too. */
581 if (is_dad_listeners() || option_bool(OPT_CLEVERBIND))
Simon Kelley74c95c22011-10-19 09:33:39 +0100582 data->effective = data->permitted = data->inheritable =
583 (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW) |
584 (1 << CAP_SETUID) | (1 << CAP_NET_BIND_SERVICE);
585 else
586 data->effective = data->permitted = data->inheritable =
587 (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW) | (1 << CAP_SETUID);
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100588
Simon Kelley16972692006-10-16 20:04:18 +0100589 /* Tell kernel to not clear capabilities when dropping root */
Simon Kelley572b41e2011-02-18 18:11:18 +0000590 if (capset(hdr, data) == -1 || prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1)
Simon Kelley16972692006-10-16 20:04:18 +0100591 bad_capabilities = errno;
Simon Kelley1a6bca82008-07-11 11:11:42 +0100592
Simon Kelley7622fc02009-06-04 20:32:05 +0100593#elif defined(HAVE_SOLARIS_NETWORK)
Simon Kelley824af852008-02-12 20:43:05 +0000594 /* http://developers.sun.com/solaris/articles/program_privileges.html */
595 priv_set_t *priv_set;
596
597 if (!(priv_set = priv_str_to_set("basic", ",", NULL)) ||
598 priv_addset(priv_set, PRIV_NET_ICMPACCESS) == -1 ||
599 priv_addset(priv_set, PRIV_SYS_NET_CONFIG) == -1)
600 bad_capabilities = errno;
601
602 if (priv_set && bad_capabilities == 0)
603 {
604 priv_inverse(priv_set);
605
606 if (setppriv(PRIV_OFF, PRIV_LIMIT, priv_set) == -1)
607 bad_capabilities = errno;
608 }
609
610 if (priv_set)
611 priv_freeset(priv_set);
612
Simon Kelley824af852008-02-12 20:43:05 +0000613#endif
614
Simon Kelley1a6bca82008-07-11 11:11:42 +0100615 if (bad_capabilities != 0)
Simon Kelley16972692006-10-16 20:04:18 +0100616 {
Simon Kelleyc72daea2012-01-05 21:33:27 +0000617 send_event(err_pipe[1], EVENT_CAP_ERR, bad_capabilities, NULL);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100618 _exit(0);
Simon Kelley16972692006-10-16 20:04:18 +0100619 }
Simon Kelley1a6bca82008-07-11 11:11:42 +0100620
621 /* finally drop root */
622 if (setuid(ent_pw->pw_uid) == -1)
623 {
Simon Kelleyc72daea2012-01-05 21:33:27 +0000624 send_event(err_pipe[1], EVENT_USER_ERR, errno, daemon->username);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100625 _exit(0);
626 }
627
628#ifdef HAVE_LINUX_NETWORK
Simon Kelley54dd3932012-06-20 11:23:38 +0100629 if (is_dad_listeners() || option_bool(OPT_CLEVERBIND))
Simon Kelley74c95c22011-10-19 09:33:39 +0100630 data->effective = data->permitted =
631 (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW) | (1 << CAP_NET_BIND_SERVICE);
632 else
633 data->effective = data->permitted =
634 (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100635 data->inheritable = 0;
636
637 /* lose the setuid and setgid capbilities */
638 if (capset(hdr, data) == -1)
639 {
Simon Kelleyc72daea2012-01-05 21:33:27 +0000640 send_event(err_pipe[1], EVENT_CAP_ERR, errno, NULL);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100641 _exit(0);
642 }
643#endif
644
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000645 }
Simon Kelley849a8352006-06-09 21:02:31 +0100646 }
Simon Kelley16972692006-10-16 20:04:18 +0100647
Simon Kelley16972692006-10-16 20:04:18 +0100648#ifdef HAVE_LINUX_NETWORK
Chen Wei28b879a2015-02-17 22:07:35 +0000649 free(hdr);
650 free(data);
Simon Kelley28866e92011-02-14 20:19:14 +0000651 if (option_bool(OPT_DEBUG))
Simon Kelley572b41e2011-02-18 18:11:18 +0000652 prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
Simon Kelley16972692006-10-16 20:04:18 +0100653#endif
Simon Kelley849a8352006-06-09 21:02:31 +0100654
Simon Kelley8b3ae2f2012-06-13 13:43:49 +0100655#ifdef HAVE_TFTP
Stefan Tomanek30d08792015-03-31 22:32:11 +0100656 if (option_bool(OPT_TFTP))
Simon Kelley8b3ae2f2012-06-13 13:43:49 +0100657 {
658 DIR *dir;
659 struct tftp_prefix *p;
660
661 if (daemon->tftp_prefix)
662 {
663 if (!((dir = opendir(daemon->tftp_prefix))))
664 {
Stefan Tomanek30d08792015-03-31 22:32:11 +0100665 tftp_prefix_missing = 1;
666 if (!option_bool(OPT_TFTP_NO_FAIL))
667 {
668 send_event(err_pipe[1], EVENT_TFTP_ERR, errno, daemon->tftp_prefix);
669 _exit(0);
670 }
Simon Kelley8b3ae2f2012-06-13 13:43:49 +0100671 }
Stefan Tomanekb4c0f092015-04-16 15:20:59 +0100672 else
673 closedir(dir);
Simon Kelley8b3ae2f2012-06-13 13:43:49 +0100674 }
Stefan Tomanek7aa970e2015-04-01 17:55:07 +0100675
Simon Kelley8b3ae2f2012-06-13 13:43:49 +0100676 for (p = daemon->if_prefix; p; p = p->next)
677 {
Stefan Tomanek30d08792015-03-31 22:32:11 +0100678 p->missing = 0;
Simon Kelley8b3ae2f2012-06-13 13:43:49 +0100679 if (!((dir = opendir(p->prefix))))
Stefan Tomanek30d08792015-03-31 22:32:11 +0100680 {
681 p->missing = 1;
682 if (!option_bool(OPT_TFTP_NO_FAIL))
683 {
684 send_event(err_pipe[1], EVENT_TFTP_ERR, errno, p->prefix);
685 _exit(0);
686 }
Stefan Tomanek7aa970e2015-04-01 17:55:07 +0100687 }
Stefan Tomanekb4c0f092015-04-16 15:20:59 +0100688 else
689 closedir(dir);
Simon Kelley8b3ae2f2012-06-13 13:43:49 +0100690 }
691 }
692#endif
Stefan Tomanek7aa970e2015-04-01 17:55:07 +0100693
Simon Kelley824af852008-02-12 20:43:05 +0000694 if (daemon->port == 0)
695 my_syslog(LOG_INFO, _("started, version %s DNS disabled"), VERSION);
696 else if (daemon->cachesize != 0)
Simon Kelleyf2621c72007-04-29 19:47:21 +0100697 my_syslog(LOG_INFO, _("started, version %s cachesize %d"), VERSION, daemon->cachesize);
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000698 else
Simon Kelleyf2621c72007-04-29 19:47:21 +0100699 my_syslog(LOG_INFO, _("started, version %s cache disabled"), VERSION);
Simon Kelley16972692006-10-16 20:04:18 +0100700
Simon Kelleyf2621c72007-04-29 19:47:21 +0100701 my_syslog(LOG_INFO, _("compile time options: %s"), compile_opts);
Simon Kelley16972692006-10-16 20:04:18 +0100702
Simon Kelley3d8df262005-08-29 12:19:27 +0100703#ifdef HAVE_DBUS
Simon Kelley28866e92011-02-14 20:19:14 +0000704 if (option_bool(OPT_DBUS))
Simon Kelley3d8df262005-08-29 12:19:27 +0100705 {
706 if (daemon->dbus)
Simon Kelleyf2621c72007-04-29 19:47:21 +0100707 my_syslog(LOG_INFO, _("DBus support enabled: connected to system bus"));
Simon Kelley3d8df262005-08-29 12:19:27 +0100708 else
Simon Kelleyf2621c72007-04-29 19:47:21 +0100709 my_syslog(LOG_INFO, _("DBus support enabled: bus connection pending"));
Simon Kelley3d8df262005-08-29 12:19:27 +0100710 }
711#endif
Simon Kelley1a9a3482014-03-05 15:01:08 +0000712
713 if (option_bool(OPT_LOCAL_SERVICE))
714 my_syslog(LOG_INFO, _("DNS service limited to local subnets"));
Simon Kelleydb737462014-01-31 10:32:45 +0000715
Simon Kelley1d97ac42014-01-31 11:12:27 +0000716#ifdef HAVE_DNSSEC
Simon Kelleydb737462014-01-31 10:32:45 +0000717 if (option_bool(OPT_DNSSEC_VALID))
Simon Kelleye98bd522014-03-28 20:41:23 +0000718 {
Simon Kelley360f2512015-03-07 18:28:06 +0000719 int rc;
720
721 /* Delay creating the timestamp file until here, after we've changed user, so that
722 it has the correct owner to allow updating the mtime later.
723 This means we have to report fatal errors via the pipe. */
724 if ((rc = setup_timestamp()) == -1)
725 {
726 send_event(err_pipe[1], EVENT_TIME_ERR, errno, daemon->timestamp_file);
727 _exit(0);
728 }
729
Simon Kelleye98bd522014-03-28 20:41:23 +0000730 my_syslog(LOG_INFO, _("DNSSEC validation enabled"));
Simon Kelley360f2512015-03-07 18:28:06 +0000731
Simon Kelleye98bd522014-03-28 20:41:23 +0000732 if (option_bool(OPT_DNSSEC_TIME))
733 my_syslog(LOG_INFO, _("DNSSEC signature timestamps not checked until first cache reload"));
Simon Kelley360f2512015-03-07 18:28:06 +0000734
735 if (rc == 1)
Simon Kelleyf6e62e22015-03-01 18:17:54 +0000736 my_syslog(LOG_INFO, _("DNSSEC signature timestamps not checked until system time valid"));
Simon Kelleye98bd522014-03-28 20:41:23 +0000737 }
Simon Kelleydb737462014-01-31 10:32:45 +0000738#endif
Simon Kelley3d8df262005-08-29 12:19:27 +0100739
Simon Kelley1a6bca82008-07-11 11:11:42 +0100740 if (log_err != 0)
741 my_syslog(LOG_WARNING, _("warning: failed to change owner of %s: %s"),
742 daemon->log_file, strerror(log_err));
Simon Kelleydb737462014-01-31 10:32:45 +0000743
Simon Kelleyde379512004-06-22 20:23:33 +0100744 if (bind_fallback)
Simon Kelleyf2621c72007-04-29 19:47:21 +0100745 my_syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations"));
Simon Kelleydc27e142013-10-16 13:09:53 +0100746
Simon Kelleyf7029f52013-11-21 15:09:09 +0000747 if (option_bool(OPT_NOWILD))
748 warn_bound_listeners();
749
750 warn_int_names();
Simon Kelleyde379512004-06-22 20:23:33 +0100751
Simon Kelley28866e92011-02-14 20:19:14 +0000752 if (!option_bool(OPT_NOWILD))
Simon Kelley26128d22004-11-14 16:43:54 +0000753 for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
754 if (if_tmp->name && !if_tmp->used)
Simon Kelleyf2621c72007-04-29 19:47:21 +0100755 my_syslog(LOG_WARNING, _("warning: interface %s does not currently exist"), if_tmp->name);
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100756
Simon Kelley28866e92011-02-14 20:19:14 +0000757 if (daemon->port != 0 && option_bool(OPT_NO_RESOLV))
Simon Kelley208b65c2006-08-05 21:41:37 +0100758 {
759 if (daemon->resolv_files && !daemon->resolv_files->is_default)
Simon Kelleyf2621c72007-04-29 19:47:21 +0100760 my_syslog(LOG_WARNING, _("warning: ignoring resolv-file flag because no-resolv is set"));
Simon Kelley208b65c2006-08-05 21:41:37 +0100761 daemon->resolv_files = NULL;
Simon Kelley1b7ecd12007-02-05 14:57:57 +0000762 if (!daemon->servers)
Simon Kelleyf2621c72007-04-29 19:47:21 +0100763 my_syslog(LOG_WARNING, _("warning: no upstream servers configured"));
Simon Kelley208b65c2006-08-05 21:41:37 +0100764 }
765
Simon Kelleyf2621c72007-04-29 19:47:21 +0100766 if (daemon->max_logs != 0)
767 my_syslog(LOG_INFO, _("asynchronous logging enabled, queue limit is %d messages"), daemon->max_logs);
Simon Kelley1f776932012-12-16 19:46:08 +0000768
Simon Kelleyf2621c72007-04-29 19:47:21 +0100769
Simon Kelley7622fc02009-06-04 20:32:05 +0100770#ifdef HAVE_DHCP
Simon Kelley1f776932012-12-16 19:46:08 +0000771 for (context = daemon->dhcp; context; context = context->next)
772 log_context(AF_INET, context);
Simon Kelleyc8257542012-03-28 21:15:41 +0100773
Simon Kelleyff7eea22013-09-04 18:01:38 +0100774 for (relay = daemon->relay4; relay; relay = relay->next)
775 log_relay(AF_INET, relay);
776
Simon Kelley1f776932012-12-16 19:46:08 +0000777# ifdef HAVE_DHCP6
778 for (context = daemon->dhcp6; context; context = context->next)
779 log_context(AF_INET6, context);
Simon Kelley52b92f42012-01-22 16:05:15 +0000780
Simon Kelleyff7eea22013-09-04 18:01:38 +0100781 for (relay = daemon->relay6; relay; relay = relay->next)
782 log_relay(AF_INET6, relay);
783
Simon Kelley1f776932012-12-16 19:46:08 +0000784 if (daemon->doing_dhcp6 || daemon->doing_ra)
785 dhcp_construct_contexts(now);
786
787 if (option_bool(OPT_RA))
788 my_syslog(MS_DHCP | LOG_INFO, _("IPv6 router advertisement enabled"));
789# endif
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000790
Simon Kelley3b3f4412013-10-11 16:33:28 +0100791# ifdef HAVE_LINUX_NETWORK
792 if (did_bind)
793 my_syslog(MS_DHCP | LOG_INFO, _("DHCP, sockets bound exclusively to interface %s"), bound_device);
794# endif
795
Simon Kelley8445f5d2012-12-17 21:54:08 +0000796 /* after dhcp_contruct_contexts */
797 if (daemon->dhcp || daemon->doing_dhcp6)
798 lease_find_interfaces(now);
Simon Kelley1f776932012-12-16 19:46:08 +0000799#endif
Simon Kelley52b92f42012-01-22 16:05:15 +0000800
Simon Kelley832af0b2007-01-21 20:01:28 +0000801#ifdef HAVE_TFTP
Simon Kelley5f4dc5c2015-01-20 20:51:02 +0000802 if (option_bool(OPT_TFTP))
Stefan Tomanek7aa970e2015-04-01 17:55:07 +0100803 {
Stefan Tomanek30d08792015-03-31 22:32:11 +0100804 struct tftp_prefix *p;
Simon Kelley832af0b2007-01-21 20:01:28 +0000805
Simon Kelley7622fc02009-06-04 20:32:05 +0100806 my_syslog(MS_TFTP | LOG_INFO, "TFTP %s%s %s",
Simon Kelleyf2621c72007-04-29 19:47:21 +0100807 daemon->tftp_prefix ? _("root is ") : _("enabled"),
808 daemon->tftp_prefix ? daemon->tftp_prefix: "",
Simon Kelley28866e92011-02-14 20:19:14 +0000809 option_bool(OPT_TFTP_SECURE) ? _("secure mode") : "");
Stefan Tomanek7aa970e2015-04-01 17:55:07 +0100810
Stefan Tomanek30d08792015-03-31 22:32:11 +0100811 if (tftp_prefix_missing)
812 my_syslog(MS_TFTP | LOG_WARNING, _("warning: %s inaccessible"), daemon->tftp_prefix);
Stefan Tomanek7aa970e2015-04-01 17:55:07 +0100813
Stefan Tomanek30d08792015-03-31 22:32:11 +0100814 for (p = daemon->if_prefix; p; p = p->next)
815 if (p->missing)
816 my_syslog(MS_TFTP | LOG_WARNING, _("warning: TFTP directory %s inaccessible"), p->prefix);
817
Simon Kelley832af0b2007-01-21 20:01:28 +0000818 /* This is a guess, it assumes that for small limits,
Simon Kelleyf2621c72007-04-29 19:47:21 +0100819 disjoint files might be served, but for large limits,
Simon Kelley832af0b2007-01-21 20:01:28 +0000820 a single file will be sent to may clients (the file only needs
821 one fd). */
822
823 max_fd -= 30; /* use other than TFTP */
824
825 if (max_fd < 0)
826 max_fd = 5;
827 else if (max_fd < 100)
828 max_fd = max_fd/2;
829 else
830 max_fd = max_fd - 20;
Simon Kelley824af852008-02-12 20:43:05 +0000831
832 /* if we have to use a limited range of ports,
833 that will limit the number of transfers */
834 if (daemon->start_tftp_port != 0 &&
835 daemon->end_tftp_port - daemon->start_tftp_port + 1 < max_fd)
836 max_fd = daemon->end_tftp_port - daemon->start_tftp_port + 1;
Simon Kelley832af0b2007-01-21 20:01:28 +0000837
838 if (daemon->tftp_max > max_fd)
839 {
840 daemon->tftp_max = max_fd;
Simon Kelley7622fc02009-06-04 20:32:05 +0100841 my_syslog(MS_TFTP | LOG_WARNING,
Simon Kelleyf2621c72007-04-29 19:47:21 +0100842 _("restricting maximum simultaneous TFTP transfers to %d"),
843 daemon->tftp_max);
Simon Kelley832af0b2007-01-21 20:01:28 +0000844 }
845 }
846#endif
847
Simon Kelley1a6bca82008-07-11 11:11:42 +0100848 /* finished start-up - release original process */
849 if (err_pipe[1] != -1)
Simon Kelleyff841eb2015-03-11 21:36:30 +0000850 while (retry_send(close(err_pipe[1])));
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000851
Simon Kelley824af852008-02-12 20:43:05 +0000852 if (daemon->port != 0)
853 check_servers();
854
Simon Kelley7cebd202006-05-06 14:13:33 +0100855 pid = getpid();
856
Simon Kelley04918052015-01-26 11:23:43 +0000857#ifdef HAVE_INOTIFY
Simon Kelley193de4a2014-12-10 17:32:16 +0000858 /* Using inotify, have to select a resolv file at startup */
859 poll_resolv(1, 0, now);
860#endif
861
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100862 while (1)
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000863 {
Simon Kelleyb842bc92015-07-12 21:09:11 +0100864 int t, timeout = -1;
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000865
Simon Kelleyb842bc92015-07-12 21:09:11 +0100866 poll_reset();
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000867
Simon Kelley16972692006-10-16 20:04:18 +0100868 /* if we are out of resources, find how long we have to wait
869 for some to come free, we'll loop around then and restart
870 listening for queries */
Simon Kelleyb842bc92015-07-12 21:09:11 +0100871 if ((t = set_dns_listeners(now)) != 0)
872 timeout = t * 1000;
Simon Kelley16972692006-10-16 20:04:18 +0100873
Simon Kelley832af0b2007-01-21 20:01:28 +0000874 /* Whilst polling for the dbus, or doing a tftp transfer, wake every quarter second */
875 if (daemon->tftp_trans ||
Simon Kelley28866e92011-02-14 20:19:14 +0000876 (option_bool(OPT_DBUS) && !daemon->dbus))
Simon Kelleyb842bc92015-07-12 21:09:11 +0100877 timeout = 250;
878
Simon Kelley74c95c22011-10-19 09:33:39 +0100879 /* Wake every second whilst waiting for DAD to complete */
880 else if (is_dad_listeners())
Simon Kelleyb842bc92015-07-12 21:09:11 +0100881 timeout = 1000;
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100882
Simon Kelley832af0b2007-01-21 20:01:28 +0000883#ifdef HAVE_DBUS
Simon Kelleyb842bc92015-07-12 21:09:11 +0100884 set_dbus_listeners();
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100885#endif
886
Simon Kelley7622fc02009-06-04 20:32:05 +0100887#ifdef HAVE_DHCP
Simon Kelleyff7eea22013-09-04 18:01:38 +0100888 if (daemon->dhcp || daemon->relay4)
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100889 {
Simon Kelleyb842bc92015-07-12 21:09:11 +0100890 poll_listen(daemon->dhcpfd, POLLIN);
Simon Kelley316e2732010-01-22 20:16:09 +0000891 if (daemon->pxefd != -1)
Simon Kelleyb842bc92015-07-12 21:09:11 +0100892 poll_listen(daemon->pxefd, POLLIN);
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100893 }
Simon Kelley7622fc02009-06-04 20:32:05 +0100894#endif
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100895
Simon Kelley52b92f42012-01-22 16:05:15 +0000896#ifdef HAVE_DHCP6
Simon Kelleyff7eea22013-09-04 18:01:38 +0100897 if (daemon->doing_dhcp6 || daemon->relay6)
Simon Kelleyb842bc92015-07-12 21:09:11 +0100898 poll_listen(daemon->dhcp6fd, POLLIN);
Simon Kelleyf6d69562015-07-08 22:38:13 +0100899
Simon Kelley1f776932012-12-16 19:46:08 +0000900 if (daemon->doing_ra)
Simon Kelleyb842bc92015-07-12 21:09:11 +0100901 poll_listen(daemon->icmp6fd, POLLIN);
Simon Kelley52b92f42012-01-22 16:05:15 +0000902#endif
Simon Kelley04918052015-01-26 11:23:43 +0000903
904#ifdef HAVE_INOTIFY
Simon Kelley5f4dc5c2015-01-20 20:51:02 +0000905 if (daemon->inotifyfd != -1)
Simon Kelleyb842bc92015-07-12 21:09:11 +0100906 poll_listen(daemon->inotifyfd, POLLIN);
Simon Kelley04918052015-01-26 11:23:43 +0000907#endif
908
909#if defined(HAVE_LINUX_NETWORK)
Simon Kelleyb842bc92015-07-12 21:09:11 +0100910 poll_listen(daemon->netlinkfd, POLLIN);
Simon Kelley1ee9be42013-12-09 16:50:19 +0000911#elif defined(HAVE_BSD_NETWORK)
Simon Kelleyb842bc92015-07-12 21:09:11 +0100912 poll_listen(daemon->routefd, POLLIN);
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100913#endif
Simon Kelley193de4a2014-12-10 17:32:16 +0000914
Simon Kelleyb842bc92015-07-12 21:09:11 +0100915 poll_listen(piperead, POLLIN);
Simon Kelley16972692006-10-16 20:04:18 +0100916
Simon Kelley7622fc02009-06-04 20:32:05 +0100917#ifdef HAVE_DHCP
Simon Kelley1f15b812009-10-13 17:49:32 +0100918# ifdef HAVE_SCRIPT
Simon Kelley5aabfc72007-08-29 11:24:47 +0100919 while (helper_buf_empty() && do_script_run(now));
Simon Kelley16972692006-10-16 20:04:18 +0100920
Simon Kelleya9530962012-03-20 22:07:35 +0000921# ifdef HAVE_TFTP
922 while (helper_buf_empty() && do_tftp_script_run());
923# endif
924
Simon Kelley16972692006-10-16 20:04:18 +0100925 if (!helper_buf_empty())
Simon Kelleyb842bc92015-07-12 21:09:11 +0100926 poll_listen(daemon->helperfd, POLLOUT);
Simon Kelley7622fc02009-06-04 20:32:05 +0100927# else
Simon Kelley5aabfc72007-08-29 11:24:47 +0100928 /* need this for other side-effects */
929 while (do_script_run(now));
Simon Kelleya9530962012-03-20 22:07:35 +0000930
931# ifdef HAVE_TFTP
932 while (do_tftp_script_run());
933# endif
934
Simon Kelley7622fc02009-06-04 20:32:05 +0100935# endif
Simon Kelley5aabfc72007-08-29 11:24:47 +0100936#endif
Simon Kelley7622fc02009-06-04 20:32:05 +0100937
Simon Kelleyf2621c72007-04-29 19:47:21 +0100938 /* must do this just before select(), when we know no
939 more calls to my_syslog() can occur */
Simon Kelleyb842bc92015-07-12 21:09:11 +0100940 set_log_writer();
Simon Kelleyf2621c72007-04-29 19:47:21 +0100941
Simon Kelleyb842bc92015-07-12 21:09:11 +0100942 if (do_poll(timeout) < 0)
943 continue;
944
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100945 now = dnsmasq_time();
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000946
Simon Kelleyb842bc92015-07-12 21:09:11 +0100947 check_log_writer(0);
Simon Kelley115ac3e2013-05-20 11:28:32 +0100948
949 /* prime. */
950 enumerate_interfaces(1);
951
Simon Kelley74c95c22011-10-19 09:33:39 +0100952 /* Check the interfaces to see if any have exited DAD state
953 and if so, bind the address. */
954 if (is_dad_listeners())
955 {
Simon Kelley115ac3e2013-05-20 11:28:32 +0100956 enumerate_interfaces(0);
Simon Kelley74c95c22011-10-19 09:33:39 +0100957 /* NB, is_dad_listeners() == 1 --> we're binding interfaces */
958 create_bound_listeners(0);
Simon Kelleydc27e142013-10-16 13:09:53 +0100959 warn_bound_listeners();
Simon Kelley74c95c22011-10-19 09:33:39 +0100960 }
Simon Kelleyf2621c72007-04-29 19:47:21 +0100961
Simon Kelley1ee9be42013-12-09 16:50:19 +0000962#if defined(HAVE_LINUX_NETWORK)
Simon Kelleyb842bc92015-07-12 21:09:11 +0100963 if (poll_check(daemon->netlinkfd, POLLIN))
Simon Kelleya0358e52014-06-07 13:38:48 +0100964 netlink_multicast();
Simon Kelley1ee9be42013-12-09 16:50:19 +0000965#elif defined(HAVE_BSD_NETWORK)
Simon Kelleyb842bc92015-07-12 21:09:11 +0100966 if (poll_check(daemon->routefd, POLLIN))
Simon Kelleya0358e52014-06-07 13:38:48 +0100967 route_sock();
Simon Kelleyc52e1892010-06-07 22:01:39 +0100968#endif
969
Simon Kelley04918052015-01-26 11:23:43 +0000970#ifdef HAVE_INOTIFY
Simon Kelleyb842bc92015-07-12 21:09:11 +0100971 if (daemon->inotifyfd != -1 && poll_check(daemon->inotifyfd, POLLIN) && inotify_check(now))
Simon Kelley5f4dc5c2015-01-20 20:51:02 +0000972 {
973 if (daemon->port != 0 && !option_bool(OPT_NO_POLL))
974 poll_resolv(1, 1, now);
975 }
Simon Kelley193de4a2014-12-10 17:32:16 +0000976#else
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000977 /* Check for changes to resolv files once per second max. */
Simon Kelley3d8df262005-08-29 12:19:27 +0100978 /* Don't go silent for long periods if the clock goes backwards. */
Simon Kelley9009d742008-11-14 20:04:27 +0000979 if (daemon->last_resolv == 0 ||
980 difftime(now, daemon->last_resolv) > 1.0 ||
981 difftime(now, daemon->last_resolv) < -1.0)
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000982 {
Simon Kelley8ef5ada2010-06-03 19:42:45 +0100983 /* poll_resolv doesn't need to reload first time through, since
984 that's queued anyway. */
Simon Kelley33820b72004-04-03 21:10:00 +0100985
Simon Kelley8ef5ada2010-06-03 19:42:45 +0100986 poll_resolv(0, daemon->last_resolv != 0, now);
987 daemon->last_resolv = now;
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000988 }
Simon Kelley193de4a2014-12-10 17:32:16 +0000989#endif
990
Simon Kelleyb842bc92015-07-12 21:09:11 +0100991 if (poll_check(piperead, POLLIN))
Simon Kelley5aabfc72007-08-29 11:24:47 +0100992 async_event(piperead, now);
Simon Kelley7cebd202006-05-06 14:13:33 +0100993
Simon Kelley3d8df262005-08-29 12:19:27 +0100994#ifdef HAVE_DBUS
995 /* if we didn't create a DBus connection, retry now. */
Simon Kelley28866e92011-02-14 20:19:14 +0000996 if (option_bool(OPT_DBUS) && !daemon->dbus)
Simon Kelley3d8df262005-08-29 12:19:27 +0100997 {
998 char *err;
Simon Kelley5aabfc72007-08-29 11:24:47 +0100999 if ((err = dbus_init()))
Simon Kelleyf2621c72007-04-29 19:47:21 +01001000 my_syslog(LOG_WARNING, _("DBus error: %s"), err);
Simon Kelley3d8df262005-08-29 12:19:27 +01001001 if (daemon->dbus)
Simon Kelleyf2621c72007-04-29 19:47:21 +01001002 my_syslog(LOG_INFO, _("connected to system DBus"));
Simon Kelley3d8df262005-08-29 12:19:27 +01001003 }
Simon Kelleyb842bc92015-07-12 21:09:11 +01001004 check_dbus_listeners();
Simon Kelley3d8df262005-08-29 12:19:27 +01001005#endif
Simon Kelley824af852008-02-12 20:43:05 +00001006
Simon Kelleyb842bc92015-07-12 21:09:11 +01001007 check_dns_listeners(now);
Simon Kelley832af0b2007-01-21 20:01:28 +00001008
1009#ifdef HAVE_TFTP
Simon Kelleyb842bc92015-07-12 21:09:11 +01001010 check_tftp_listeners(now);
Simon Kelley832af0b2007-01-21 20:01:28 +00001011#endif
1012
Simon Kelley7622fc02009-06-04 20:32:05 +01001013#ifdef HAVE_DHCP
Simon Kelleyff7eea22013-09-04 18:01:38 +01001014 if (daemon->dhcp || daemon->relay4)
Simon Kelley316e2732010-01-22 20:16:09 +00001015 {
Simon Kelleyb842bc92015-07-12 21:09:11 +01001016 if (poll_check(daemon->dhcpfd, POLLIN))
Simon Kelley316e2732010-01-22 20:16:09 +00001017 dhcp_packet(now, 0);
Simon Kelleyb842bc92015-07-12 21:09:11 +01001018 if (daemon->pxefd != -1 && poll_check(daemon->pxefd, POLLIN))
Simon Kelley316e2732010-01-22 20:16:09 +00001019 dhcp_packet(now, 1);
1020 }
Simon Kelley16972692006-10-16 20:04:18 +01001021
Simon Kelley52b92f42012-01-22 16:05:15 +00001022#ifdef HAVE_DHCP6
Simon Kelleyb842bc92015-07-12 21:09:11 +01001023 if ((daemon->doing_dhcp6 || daemon->relay6) && poll_check(daemon->dhcp6fd, POLLIN))
Simon Kelley18c63ef2012-05-21 14:34:15 +01001024 dhcp6_packet(now);
Simon Kelleyc5ad4e72012-02-24 16:06:20 +00001025
Simon Kelleyb842bc92015-07-12 21:09:11 +01001026 if (daemon->doing_ra && poll_check(daemon->icmp6fd, POLLIN))
Simon Kelley1f776932012-12-16 19:46:08 +00001027 icmp6_packet(now);
Simon Kelley52b92f42012-01-22 16:05:15 +00001028#endif
1029
Simon Kelley1f15b812009-10-13 17:49:32 +01001030# ifdef HAVE_SCRIPT
Simon Kelley63ec5d12015-07-30 20:59:07 +01001031 if (daemon->helperfd != -1 && poll_check(daemon->helperfd, POLLOUT))
Simon Kelley5aabfc72007-08-29 11:24:47 +01001032 helper_write();
Simon Kelley7622fc02009-06-04 20:32:05 +01001033# endif
Simon Kelley5aabfc72007-08-29 11:24:47 +01001034#endif
1035
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001036 }
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001037}
1038
Simon Kelley3be34542004-09-11 19:12:13 +01001039static void sig_handler(int sig)
1040{
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001041 if (pid == 0)
1042 {
Simon Kelley16972692006-10-16 20:04:18 +01001043 /* ignore anything other than TERM during startup
1044 and in helper proc. (helper ignore TERM too) */
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001045 if (sig == SIGTERM)
Simon Kelley5aabfc72007-08-29 11:24:47 +01001046 exit(EC_MISC);
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001047 }
Simon Kelley5aabfc72007-08-29 11:24:47 +01001048 else if (pid != getpid())
Simon Kelley3be34542004-09-11 19:12:13 +01001049 {
Simon Kelley16972692006-10-16 20:04:18 +01001050 /* alarm is used to kill TCP children after a fixed time. */
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001051 if (sig == SIGALRM)
Simon Kelley7cebd202006-05-06 14:13:33 +01001052 _exit(0);
Simon Kelley3be34542004-09-11 19:12:13 +01001053 }
Simon Kelley5aabfc72007-08-29 11:24:47 +01001054 else
1055 {
1056 /* master process */
1057 int event, errsave = errno;
1058
1059 if (sig == SIGHUP)
1060 event = EVENT_RELOAD;
1061 else if (sig == SIGCHLD)
1062 event = EVENT_CHILD;
1063 else if (sig == SIGALRM)
1064 event = EVENT_ALARM;
1065 else if (sig == SIGTERM)
1066 event = EVENT_TERM;
1067 else if (sig == SIGUSR1)
1068 event = EVENT_DUMP;
1069 else if (sig == SIGUSR2)
1070 event = EVENT_REOPEN;
1071 else
1072 return;
1073
Simon Kelleyc72daea2012-01-05 21:33:27 +00001074 send_event(pipewrite, event, 0, NULL);
Simon Kelley5aabfc72007-08-29 11:24:47 +01001075 errno = errsave;
1076 }
Simon Kelley3be34542004-09-11 19:12:13 +01001077}
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001078
Simon Kelley353ae4d2012-03-19 20:07:51 +00001079/* now == 0 -> queue immediate callback */
1080void send_alarm(time_t event, time_t now)
Simon Kelley741c2952012-02-25 13:09:18 +00001081{
Simon Kelley884a6df2012-03-20 16:20:22 +00001082 if (now == 0 || event != 0)
Simon Kelley353ae4d2012-03-19 20:07:51 +00001083 {
Simon Kelley884a6df2012-03-20 16:20:22 +00001084 /* alarm(0) or alarm(-ve) doesn't do what we want.... */
1085 if ((now == 0 || difftime(event, now) <= 0.0))
1086 send_event(pipewrite, EVENT_ALARM, 0, NULL);
1087 else
1088 alarm((unsigned)difftime(event, now));
Simon Kelley353ae4d2012-03-19 20:07:51 +00001089 }
Simon Kelley741c2952012-02-25 13:09:18 +00001090}
1091
Simon Kelley47a95162014-07-08 22:22:02 +01001092void queue_event(int event)
Simon Kelleya0358e52014-06-07 13:38:48 +01001093{
Simon Kelley47a95162014-07-08 22:22:02 +01001094 send_event(pipewrite, event, 0, NULL);
Simon Kelleya0358e52014-06-07 13:38:48 +01001095}
1096
Simon Kelleyc72daea2012-01-05 21:33:27 +00001097void send_event(int fd, int event, int data, char *msg)
Simon Kelley5aabfc72007-08-29 11:24:47 +01001098{
1099 struct event_desc ev;
Simon Kelleyc72daea2012-01-05 21:33:27 +00001100 struct iovec iov[2];
1101
Simon Kelley5aabfc72007-08-29 11:24:47 +01001102 ev.event = event;
1103 ev.data = data;
Simon Kelleyc72daea2012-01-05 21:33:27 +00001104 ev.msg_sz = msg ? strlen(msg) : 0;
1105
1106 iov[0].iov_base = &ev;
1107 iov[0].iov_len = sizeof(ev);
1108 iov[1].iov_base = msg;
1109 iov[1].iov_len = ev.msg_sz;
Simon Kelley1a6bca82008-07-11 11:11:42 +01001110
1111 /* error pipe, debug mode. */
1112 if (fd == -1)
Simon Kelleyc72daea2012-01-05 21:33:27 +00001113 fatal_event(&ev, msg);
Simon Kelley1a6bca82008-07-11 11:11:42 +01001114 else
1115 /* pipe is non-blocking and struct event_desc is smaller than
1116 PIPE_BUF, so this either fails or writes everything */
Simon Kelleyc72daea2012-01-05 21:33:27 +00001117 while (writev(fd, iov, msg ? 2 : 1) == -1 && errno == EINTR);
Simon Kelley5aabfc72007-08-29 11:24:47 +01001118}
Simon Kelley3d8df262005-08-29 12:19:27 +01001119
Simon Kelleyc72daea2012-01-05 21:33:27 +00001120/* NOTE: the memory used to return msg is leaked: use msgs in events only
1121 to describe fatal errors. */
1122static int read_event(int fd, struct event_desc *evp, char **msg)
1123{
1124 char *buf;
1125
1126 if (!read_write(fd, (unsigned char *)evp, sizeof(struct event_desc), 1))
1127 return 0;
1128
1129 *msg = NULL;
1130
1131 if (evp->msg_sz != 0 &&
1132 (buf = malloc(evp->msg_sz + 1)) &&
1133 read_write(fd, (unsigned char *)buf, evp->msg_sz, 1))
1134 {
1135 buf[evp->msg_sz] = 0;
1136 *msg = buf;
1137 }
1138
1139 return 1;
1140}
1141
1142static void fatal_event(struct event_desc *ev, char *msg)
Simon Kelley1a6bca82008-07-11 11:11:42 +01001143{
1144 errno = ev->data;
1145
1146 switch (ev->event)
1147 {
1148 case EVENT_DIE:
1149 exit(0);
Simon Kelley7622fc02009-06-04 20:32:05 +01001150
1151 case EVENT_FORK_ERR:
1152 die(_("cannot fork into background: %s"), NULL, EC_MISC);
Simon Kelley1a6bca82008-07-11 11:11:42 +01001153
1154 case EVENT_PIPE_ERR:
1155 die(_("failed to create helper: %s"), NULL, EC_MISC);
1156
1157 case EVENT_CAP_ERR:
1158 die(_("setting capabilities failed: %s"), NULL, EC_MISC);
1159
1160 case EVENT_USER_ERR:
Simon Kelleyc72daea2012-01-05 21:33:27 +00001161 die(_("failed to change user-id to %s: %s"), msg, EC_MISC);
Simon Kelley1a6bca82008-07-11 11:11:42 +01001162
1163 case EVENT_GROUP_ERR:
Simon Kelleyc72daea2012-01-05 21:33:27 +00001164 die(_("failed to change group-id to %s: %s"), msg, EC_MISC);
Simon Kelley1a6bca82008-07-11 11:11:42 +01001165
1166 case EVENT_PIDFILE:
Simon Kelleyc72daea2012-01-05 21:33:27 +00001167 die(_("failed to open pidfile %s: %s"), msg, EC_FILE);
Simon Kelley1a6bca82008-07-11 11:11:42 +01001168
1169 case EVENT_LOG_ERR:
Simon Kelleyc72daea2012-01-05 21:33:27 +00001170 die(_("cannot open log %s: %s"), msg, EC_FILE);
1171
1172 case EVENT_LUA_ERR:
1173 die(_("failed to load Lua script: %s"), msg, EC_MISC);
Simon Kelley8b3ae2f2012-06-13 13:43:49 +01001174
1175 case EVENT_TFTP_ERR:
1176 die(_("TFTP directory %s inaccessible: %s"), msg, EC_FILE);
Simon Kelley360f2512015-03-07 18:28:06 +00001177
1178 case EVENT_TIME_ERR:
1179 die(_("cannot create timestamp file %s: %s" ), msg, EC_BADCONF);
Simon Kelley1a6bca82008-07-11 11:11:42 +01001180 }
1181}
1182
Simon Kelley5aabfc72007-08-29 11:24:47 +01001183static void async_event(int pipe, time_t now)
1184{
1185 pid_t p;
1186 struct event_desc ev;
Simon Kelley7b1eae42014-02-20 13:43:28 +00001187 int i, check = 0;
Simon Kelleyc72daea2012-01-05 21:33:27 +00001188 char *msg;
1189
1190 /* NOTE: the memory used to return msg is leaked: use msgs in events only
1191 to describe fatal errors. */
1192
1193 if (read_event(pipe, &ev, &msg))
Simon Kelley5aabfc72007-08-29 11:24:47 +01001194 switch (ev.event)
1195 {
1196 case EVENT_RELOAD:
Simon Kelleye98bd522014-03-28 20:41:23 +00001197#ifdef HAVE_DNSSEC
1198 if (option_bool(OPT_DNSSEC_VALID) && option_bool(OPT_DNSSEC_TIME))
1199 {
1200 my_syslog(LOG_INFO, _("now checking DNSSEC signature timestamps"));
1201 reset_option_bool(OPT_DNSSEC_TIME);
1202 }
1203#endif
1204 /* fall through */
1205
1206 case EVENT_INIT:
Simon Kelley5aabfc72007-08-29 11:24:47 +01001207 clear_cache_and_reload(now);
Simon Kelleye98bd522014-03-28 20:41:23 +00001208
Simon Kelley7b1eae42014-02-20 13:43:28 +00001209 if (daemon->port != 0)
Simon Kelley5aabfc72007-08-29 11:24:47 +01001210 {
Simon Kelley7b1eae42014-02-20 13:43:28 +00001211 if (daemon->resolv_files && option_bool(OPT_NO_POLL))
1212 {
1213 reload_servers(daemon->resolv_files->name);
1214 check = 1;
1215 }
1216
1217 if (daemon->servers_file)
1218 {
1219 read_servers_file();
1220 check = 1;
1221 }
1222
1223 if (check)
1224 check_servers();
Simon Kelley5aabfc72007-08-29 11:24:47 +01001225 }
Simon Kelley7b1eae42014-02-20 13:43:28 +00001226
Simon Kelley7622fc02009-06-04 20:32:05 +01001227#ifdef HAVE_DHCP
Simon Kelley5aabfc72007-08-29 11:24:47 +01001228 rerun_scripts();
Simon Kelley7622fc02009-06-04 20:32:05 +01001229#endif
Simon Kelley5aabfc72007-08-29 11:24:47 +01001230 break;
1231
1232 case EVENT_DUMP:
Simon Kelley824af852008-02-12 20:43:05 +00001233 if (daemon->port != 0)
1234 dump_cache(now);
Simon Kelley5aabfc72007-08-29 11:24:47 +01001235 break;
1236
1237 case EVENT_ALARM:
Simon Kelley7622fc02009-06-04 20:32:05 +01001238#ifdef HAVE_DHCP
Simon Kelley1f776932012-12-16 19:46:08 +00001239 if (daemon->dhcp || daemon->doing_dhcp6)
Simon Kelley5aabfc72007-08-29 11:24:47 +01001240 {
1241 lease_prune(NULL, now);
1242 lease_update_file(now);
1243 }
Simon Kelley843c96b2012-02-27 17:42:38 +00001244#ifdef HAVE_DHCP6
Simon Kelley1f776932012-12-16 19:46:08 +00001245 else if (daemon->doing_ra)
Simon Kelley353ae4d2012-03-19 20:07:51 +00001246 /* Not doing DHCP, so no lease system, manage alarms for ra only */
1247 send_alarm(periodic_ra(now), now);
Simon Kelley843c96b2012-02-27 17:42:38 +00001248#endif
Simon Kelley7622fc02009-06-04 20:32:05 +01001249#endif
Simon Kelley5aabfc72007-08-29 11:24:47 +01001250 break;
1251
1252 case EVENT_CHILD:
1253 /* See Stevens 5.10 */
1254 while ((p = waitpid(-1, NULL, WNOHANG)) != 0)
1255 if (p == -1)
1256 {
1257 if (errno != EINTR)
1258 break;
1259 }
1260 else
1261 for (i = 0 ; i < MAX_PROCS; i++)
1262 if (daemon->tcp_pids[i] == p)
1263 daemon->tcp_pids[i] = 0;
1264 break;
1265
1266 case EVENT_KILLED:
Simon Kelleyc72daea2012-01-05 21:33:27 +00001267 my_syslog(LOG_WARNING, _("script process killed by signal %d"), ev.data);
Simon Kelley5aabfc72007-08-29 11:24:47 +01001268 break;
1269
1270 case EVENT_EXITED:
Simon Kelleyc72daea2012-01-05 21:33:27 +00001271 my_syslog(LOG_WARNING, _("script process exited with status %d"), ev.data);
Simon Kelley5aabfc72007-08-29 11:24:47 +01001272 break;
1273
1274 case EVENT_EXEC_ERR:
Simon Kelley9e038942008-05-30 20:06:34 +01001275 my_syslog(LOG_ERR, _("failed to execute %s: %s"),
1276 daemon->lease_change_command, strerror(ev.data));
Simon Kelley5aabfc72007-08-29 11:24:47 +01001277 break;
1278
Simon Kelley1a6bca82008-07-11 11:11:42 +01001279 /* necessary for fatal errors in helper */
Simon Kelleyc72daea2012-01-05 21:33:27 +00001280 case EVENT_USER_ERR:
Simon Kelley1a6bca82008-07-11 11:11:42 +01001281 case EVENT_DIE:
Simon Kelleyc72daea2012-01-05 21:33:27 +00001282 case EVENT_LUA_ERR:
1283 fatal_event(&ev, msg);
Simon Kelley9e038942008-05-30 20:06:34 +01001284 break;
1285
Simon Kelley5aabfc72007-08-29 11:24:47 +01001286 case EVENT_REOPEN:
1287 /* Note: this may leave TCP-handling processes with the old file still open.
1288 Since any such process will die in CHILD_LIFETIME or probably much sooner,
1289 we leave them logging to the old file. */
1290 if (daemon->log_file != NULL)
1291 log_reopen(daemon->log_file);
1292 break;
Simon Kelleya0358e52014-06-07 13:38:48 +01001293
1294 case EVENT_NEWADDR:
1295 newaddress(now);
1296 break;
Simon Kelley47a95162014-07-08 22:22:02 +01001297
1298 case EVENT_NEWROUTE:
1299 resend_query();
1300 /* Force re-reading resolv file right now, for luck. */
1301 poll_resolv(0, 1, now);
1302 break;
1303
Simon Kelley5aabfc72007-08-29 11:24:47 +01001304 case EVENT_TERM:
1305 /* Knock all our children on the head. */
1306 for (i = 0; i < MAX_PROCS; i++)
1307 if (daemon->tcp_pids[i] != 0)
1308 kill(daemon->tcp_pids[i], SIGALRM);
1309
Simon Kelleyc72daea2012-01-05 21:33:27 +00001310#if defined(HAVE_SCRIPT)
Simon Kelley5aabfc72007-08-29 11:24:47 +01001311 /* handle pending lease transitions */
1312 if (daemon->helperfd != -1)
1313 {
1314 /* block in writes until all done */
1315 if ((i = fcntl(daemon->helperfd, F_GETFL)) != -1)
1316 fcntl(daemon->helperfd, F_SETFL, i & ~O_NONBLOCK);
1317 do {
1318 helper_write();
1319 } while (!helper_buf_empty() || do_script_run(now));
Simon Kelleyff841eb2015-03-11 21:36:30 +00001320 while (retry_send(close(daemon->helperfd)));
Simon Kelley5aabfc72007-08-29 11:24:47 +01001321 }
1322#endif
1323
1324 if (daemon->lease_stream)
1325 fclose(daemon->lease_stream);
Simon Kelley73a08a22009-02-05 20:28:08 +00001326
Kevin Darbyshire-Bryant34b5d192015-07-27 19:34:23 +01001327#ifdef HAVE_DNSSEC
1328 /* update timestamp file on TERM if time is considered valid */
1329 if (daemon->back_to_the_future)
1330 {
1331 if (utime(daemon->timestamp_file, NULL) == -1)
1332 my_syslog(LOG_ERR, _("failed to update mtime on %s: %s"), daemon->timestamp_file, strerror(errno));
1333 }
1334#endif
1335
Simon Kelley73a08a22009-02-05 20:28:08 +00001336 if (daemon->runfile)
1337 unlink(daemon->runfile);
Simon Kelley5aabfc72007-08-29 11:24:47 +01001338
1339 my_syslog(LOG_INFO, _("exiting on receipt of SIGTERM"));
1340 flush_log();
1341 exit(EC_GOOD);
1342 }
1343}
1344
Simon Kelley47a95162014-07-08 22:22:02 +01001345static void poll_resolv(int force, int do_reload, time_t now)
Simon Kelley5aabfc72007-08-29 11:24:47 +01001346{
1347 struct resolvc *res, *latest;
1348 struct stat statbuf;
1349 time_t last_change = 0;
1350 /* There may be more than one possible file.
1351 Go through and find the one which changed _last_.
1352 Warn of any which can't be read. */
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001353
Simon Kelley28866e92011-02-14 20:19:14 +00001354 if (daemon->port == 0 || option_bool(OPT_NO_POLL))
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001355 return;
1356
Simon Kelley5aabfc72007-08-29 11:24:47 +01001357 for (latest = NULL, res = daemon->resolv_files; res; res = res->next)
1358 if (stat(res->name, &statbuf) == -1)
1359 {
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001360 if (force)
1361 {
1362 res->mtime = 0;
1363 continue;
1364 }
1365
Simon Kelley5aabfc72007-08-29 11:24:47 +01001366 if (!res->logged)
1367 my_syslog(LOG_WARNING, _("failed to access %s: %s"), res->name, strerror(errno));
1368 res->logged = 1;
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001369
1370 if (res->mtime != 0)
1371 {
1372 /* existing file evaporated, force selection of the latest
1373 file even if its mtime hasn't changed since we last looked */
1374 poll_resolv(1, do_reload, now);
1375 return;
1376 }
Simon Kelley5aabfc72007-08-29 11:24:47 +01001377 }
1378 else
1379 {
1380 res->logged = 0;
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001381 if (force || (statbuf.st_mtime != res->mtime))
1382 {
1383 res->mtime = statbuf.st_mtime;
Simon Kelley5aabfc72007-08-29 11:24:47 +01001384 if (difftime(statbuf.st_mtime, last_change) > 0.0)
1385 {
1386 last_change = statbuf.st_mtime;
1387 latest = res;
1388 }
1389 }
1390 }
1391
1392 if (latest)
1393 {
1394 static int warned = 0;
1395 if (reload_servers(latest->name))
1396 {
1397 my_syslog(LOG_INFO, _("reading %s"), latest->name);
1398 warned = 0;
1399 check_servers();
Simon Kelley28866e92011-02-14 20:19:14 +00001400 if (option_bool(OPT_RELOAD) && do_reload)
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001401 clear_cache_and_reload(now);
Simon Kelley5aabfc72007-08-29 11:24:47 +01001402 }
1403 else
1404 {
1405 latest->mtime = 0;
1406 if (!warned)
1407 {
1408 my_syslog(LOG_WARNING, _("no servers found in %s, will retry"), latest->name);
1409 warned = 1;
1410 }
1411 }
1412 }
1413}
1414
1415void clear_cache_and_reload(time_t now)
Simon Kelley3d8df262005-08-29 12:19:27 +01001416{
Vladislav Grishenko408c3682013-09-24 16:18:49 +01001417 (void)now;
1418
Simon Kelley824af852008-02-12 20:43:05 +00001419 if (daemon->port != 0)
Simon Kelley7622fc02009-06-04 20:32:05 +01001420 cache_reload();
Simon Kelley824af852008-02-12 20:43:05 +00001421
Simon Kelley7622fc02009-06-04 20:32:05 +01001422#ifdef HAVE_DHCP
Simon Kelley1f776932012-12-16 19:46:08 +00001423 if (daemon->dhcp || daemon->doing_dhcp6)
Simon Kelley3d8df262005-08-29 12:19:27 +01001424 {
Simon Kelley28866e92011-02-14 20:19:14 +00001425 if (option_bool(OPT_ETHERS))
Simon Kelley5aabfc72007-08-29 11:24:47 +01001426 dhcp_read_ethers();
Simon Kelley824af852008-02-12 20:43:05 +00001427 reread_dhcp();
Simon Kelley04918052015-01-26 11:23:43 +00001428#ifdef HAVE_INOTIFY
Simon Kelley70d18732015-01-31 19:59:29 +00001429 set_dynamic_inotify(AH_DHCP_HST | AH_DHCP_OPT, 0, NULL, 0);
Simon Kelley5f4dc5c2015-01-20 20:51:02 +00001430#endif
Simon Kelley3d8df262005-08-29 12:19:27 +01001431 dhcp_update_configs(daemon->dhcp_conf);
Simon Kelley5aabfc72007-08-29 11:24:47 +01001432 lease_update_from_configs();
1433 lease_update_file(now);
Simon Kelley353ae4d2012-03-19 20:07:51 +00001434 lease_update_dns(1);
Simon Kelley3d8df262005-08-29 12:19:27 +01001435 }
Simon Kelley843c96b2012-02-27 17:42:38 +00001436#ifdef HAVE_DHCP6
Simon Kelley1f776932012-12-16 19:46:08 +00001437 else if (daemon->doing_ra)
Simon Kelley2021c662012-05-07 16:43:21 +01001438 /* Not doing DHCP, so no lease system, manage
1439 alarms for ra only */
1440 send_alarm(periodic_ra(now), now);
Simon Kelley843c96b2012-02-27 17:42:38 +00001441#endif
Simon Kelley7622fc02009-06-04 20:32:05 +01001442#endif
Simon Kelley3d8df262005-08-29 12:19:27 +01001443}
1444
Simon Kelleyb842bc92015-07-12 21:09:11 +01001445static int set_dns_listeners(time_t now)
Simon Kelley3be34542004-09-11 19:12:13 +01001446{
1447 struct serverfd *serverfdp;
1448 struct listener *listener;
Simon Kelley824af852008-02-12 20:43:05 +00001449 int wait = 0, i;
Simon Kelley832af0b2007-01-21 20:01:28 +00001450
1451#ifdef HAVE_TFTP
1452 int tftp = 0;
1453 struct tftp_transfer *transfer;
1454 for (transfer = daemon->tftp_trans; transfer; transfer = transfer->next)
1455 {
1456 tftp++;
Simon Kelleyb842bc92015-07-12 21:09:11 +01001457 poll_listen(transfer->sockfd, POLLIN);
Simon Kelley832af0b2007-01-21 20:01:28 +00001458 }
1459#endif
1460
Simon Kelley16972692006-10-16 20:04:18 +01001461 /* will we be able to get memory? */
Simon Kelley824af852008-02-12 20:43:05 +00001462 if (daemon->port != 0)
Simon Kelley3a237152013-12-12 12:15:50 +00001463 get_new_frec(now, &wait, 0);
Simon Kelley16972692006-10-16 20:04:18 +01001464
Simon Kelley3be34542004-09-11 19:12:13 +01001465 for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001466 poll_listen(serverfdp->fd, POLLIN);
Simon Kelleyf6d69562015-07-08 22:38:13 +01001467
Simon Kelley1a6bca82008-07-11 11:11:42 +01001468 if (daemon->port != 0 && !daemon->osport)
1469 for (i = 0; i < RANDOM_SOCKS; i++)
1470 if (daemon->randomsocks[i].refcount != 0)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001471 poll_listen(daemon->randomsocks[i].fd, POLLIN);
Simon Kelleyf6d69562015-07-08 22:38:13 +01001472
Simon Kelley3be34542004-09-11 19:12:13 +01001473 for (listener = daemon->listeners; listener; listener = listener->next)
1474 {
Simon Kelley16972692006-10-16 20:04:18 +01001475 /* only listen for queries if we have resources */
Simon Kelley824af852008-02-12 20:43:05 +00001476 if (listener->fd != -1 && wait == 0)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001477 poll_listen(listener->fd, POLLIN);
Simon Kelleyf6d69562015-07-08 22:38:13 +01001478
Simon Kelley16972692006-10-16 20:04:18 +01001479 /* death of a child goes through the select loop, so
1480 we don't need to explicitly arrange to wake up here */
Simon Kelley824af852008-02-12 20:43:05 +00001481 if (listener->tcpfd != -1)
1482 for (i = 0; i < MAX_PROCS; i++)
1483 if (daemon->tcp_pids[i] == 0)
1484 {
Simon Kelleyb842bc92015-07-12 21:09:11 +01001485 poll_listen(listener->tcpfd, POLLIN);
Simon Kelley824af852008-02-12 20:43:05 +00001486 break;
1487 }
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001488
Simon Kelley832af0b2007-01-21 20:01:28 +00001489#ifdef HAVE_TFTP
1490 if (tftp <= daemon->tftp_max && listener->tftpfd != -1)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001491 poll_listen(listener->tftpfd, POLLIN);
Simon Kelley832af0b2007-01-21 20:01:28 +00001492#endif
1493
1494 }
1495
Simon Kelley16972692006-10-16 20:04:18 +01001496 return wait;
Simon Kelley3be34542004-09-11 19:12:13 +01001497}
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001498
Simon Kelleyb842bc92015-07-12 21:09:11 +01001499static void check_dns_listeners(time_t now)
Simon Kelley3be34542004-09-11 19:12:13 +01001500{
1501 struct serverfd *serverfdp;
Simon Kelley1a6bca82008-07-11 11:11:42 +01001502 struct listener *listener;
1503 int i;
1504
Simon Kelley832af0b2007-01-21 20:01:28 +00001505 for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001506 if (poll_check(serverfdp->fd, POLLIN))
Simon Kelley1a6bca82008-07-11 11:11:42 +01001507 reply_query(serverfdp->fd, serverfdp->source_addr.sa.sa_family, now);
1508
1509 if (daemon->port != 0 && !daemon->osport)
1510 for (i = 0; i < RANDOM_SOCKS; i++)
1511 if (daemon->randomsocks[i].refcount != 0 &&
Simon Kelleyb842bc92015-07-12 21:09:11 +01001512 poll_check(daemon->randomsocks[i].fd, POLLIN))
Simon Kelley1a6bca82008-07-11 11:11:42 +01001513 reply_query(daemon->randomsocks[i].fd, daemon->randomsocks[i].family, now);
Simon Kelley832af0b2007-01-21 20:01:28 +00001514
1515 for (listener = daemon->listeners; listener; listener = listener->next)
1516 {
Simon Kelleyb842bc92015-07-12 21:09:11 +01001517 if (listener->fd != -1 && poll_check(listener->fd, POLLIN))
Simon Kelley5aabfc72007-08-29 11:24:47 +01001518 receive_query(listener, now);
Simon Kelley1a6bca82008-07-11 11:11:42 +01001519
Simon Kelley832af0b2007-01-21 20:01:28 +00001520#ifdef HAVE_TFTP
Simon Kelleyb842bc92015-07-12 21:09:11 +01001521 if (listener->tftpfd != -1 && poll_check(listener->tftpfd, POLLIN))
Simon Kelley5aabfc72007-08-29 11:24:47 +01001522 tftp_request(listener, now);
Simon Kelley59353a62004-11-21 19:34:28 +00001523#endif
Simon Kelley832af0b2007-01-21 20:01:28 +00001524
Simon Kelleyb842bc92015-07-12 21:09:11 +01001525 if (listener->tcpfd != -1 && poll_check(listener->tcpfd, POLLIN))
Simon Kelley832af0b2007-01-21 20:01:28 +00001526 {
Simon Kelley22ce5502013-01-22 13:53:04 +00001527 int confd, client_ok = 1;
Simon Kelley832af0b2007-01-21 20:01:28 +00001528 struct irec *iface = NULL;
1529 pid_t p;
Simon Kelley52d4abf2012-03-21 21:39:48 +00001530 union mysockaddr tcp_addr;
1531 socklen_t tcp_len = sizeof(union mysockaddr);
1532
1533 while ((confd = accept(listener->tcpfd, NULL, NULL)) == -1 && errno == EINTR);
Simon Kelley832af0b2007-01-21 20:01:28 +00001534
Simon Kelley46b06652013-02-04 21:47:59 +00001535 if (confd == -1)
Simon Kelley832af0b2007-01-21 20:01:28 +00001536 continue;
Simon Kelley76dd75d2013-05-23 10:04:25 +01001537
Simon Kelley46b06652013-02-04 21:47:59 +00001538 if (getsockname(confd, (struct sockaddr *)&tcp_addr, &tcp_len) == -1)
1539 {
Simon Kelleyff841eb2015-03-11 21:36:30 +00001540 while (retry_send(close(confd)));
Simon Kelley46b06652013-02-04 21:47:59 +00001541 continue;
1542 }
Simon Kelley76dd75d2013-05-23 10:04:25 +01001543
1544 /* Make sure that the interface list is up-to-date.
1545
1546 We do this here as we may need the results below, and
1547 the DNS code needs them for --interface-name stuff.
Simon Kelley46b06652013-02-04 21:47:59 +00001548
Simon Kelley76dd75d2013-05-23 10:04:25 +01001549 Multiple calls to enumerate_interfaces() per select loop are
1550 inhibited, so calls to it in the child process (which doesn't select())
1551 have no effect. This avoids two processes reading from the same
1552 netlink fd and screwing the pooch entirely.
1553 */
Simon Kelleye25db1f2013-01-29 22:10:26 +00001554
Simon Kelley76dd75d2013-05-23 10:04:25 +01001555 enumerate_interfaces(0);
1556
1557 if (option_bool(OPT_NOWILD))
1558 iface = listener->iface; /* May be NULL */
1559 else
1560 {
1561 int if_index;
1562 char intr_name[IF_NAMESIZE];
1563
1564 /* if we can find the arrival interface, check it's one that's allowed */
1565 if ((if_index = tcp_interface(confd, tcp_addr.sa.sa_family)) != 0 &&
1566 indextoname(listener->tcpfd, if_index, intr_name))
1567 {
1568 struct all_addr addr;
1569 addr.addr.addr4 = tcp_addr.in.sin_addr;
Simon Kelleye25db1f2013-01-29 22:10:26 +00001570#ifdef HAVE_IPV6
Simon Kelley76dd75d2013-05-23 10:04:25 +01001571 if (tcp_addr.sa.sa_family == AF_INET6)
1572 addr.addr.addr6 = tcp_addr.in6.sin6_addr;
Simon Kelleye25db1f2013-01-29 22:10:26 +00001573#endif
Simon Kelley76dd75d2013-05-23 10:04:25 +01001574
1575 for (iface = daemon->interfaces; iface; iface = iface->next)
1576 if (iface->index == if_index)
1577 break;
1578
1579 if (!iface && !loopback_exception(listener->tcpfd, tcp_addr.sa.sa_family, &addr, intr_name))
1580 client_ok = 0;
1581 }
1582
1583 if (option_bool(OPT_CLEVERBIND))
1584 iface = listener->iface; /* May be NULL */
1585 else
1586 {
1587 /* Check for allowed interfaces when binding the wildcard address:
1588 we do this by looking for an interface with the same address as
1589 the local address of the TCP connection, then looking to see if that's
1590 an allowed interface. As a side effect, we get the netmask of the
1591 interface too, for localisation. */
1592
1593 for (iface = daemon->interfaces; iface; iface = iface->next)
1594 if (sockaddr_isequal(&iface->addr, &tcp_addr))
1595 break;
1596
1597 if (!iface)
1598 client_ok = 0;
1599 }
1600 }
1601
Simon Kelley22ce5502013-01-22 13:53:04 +00001602 if (!client_ok)
Simon Kelley832af0b2007-01-21 20:01:28 +00001603 {
1604 shutdown(confd, SHUT_RDWR);
Simon Kelleyff841eb2015-03-11 21:36:30 +00001605 while (retry_send(close(confd)));
Simon Kelley832af0b2007-01-21 20:01:28 +00001606 }
1607#ifndef NO_FORK
Simon Kelley28866e92011-02-14 20:19:14 +00001608 else if (!option_bool(OPT_DEBUG) && (p = fork()) != 0)
Simon Kelley832af0b2007-01-21 20:01:28 +00001609 {
1610 if (p != -1)
1611 {
1612 int i;
1613 for (i = 0; i < MAX_PROCS; i++)
1614 if (daemon->tcp_pids[i] == 0)
1615 {
1616 daemon->tcp_pids[i] = p;
1617 break;
1618 }
1619 }
Simon Kelleyff841eb2015-03-11 21:36:30 +00001620 while (retry_send(close(confd)));
Simon Kelley25cf5e32015-01-09 15:53:03 +00001621
1622 /* The child can use up to TCP_MAX_QUERIES ids, so skip that many. */
1623 daemon->log_id += TCP_MAX_QUERIES;
Simon Kelley832af0b2007-01-21 20:01:28 +00001624 }
1625#endif
1626 else
1627 {
1628 unsigned char *buff;
1629 struct server *s;
1630 int flags;
Simon Kelley52d4abf2012-03-21 21:39:48 +00001631 struct in_addr netmask;
Simon Kelley4f7b3042012-11-28 21:27:02 +00001632 int auth_dns;
Simon Kelley52d4abf2012-03-21 21:39:48 +00001633
1634 if (iface)
Simon Kelley4f7b3042012-11-28 21:27:02 +00001635 {
1636 netmask = iface->netmask;
1637 auth_dns = iface->dns_auth;
1638 }
Simon Kelley52d4abf2012-03-21 21:39:48 +00001639 else
Simon Kelley4f7b3042012-11-28 21:27:02 +00001640 {
1641 netmask.s_addr = 0;
1642 auth_dns = 0;
1643 }
Simon Kelley52d4abf2012-03-21 21:39:48 +00001644
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001645#ifndef NO_FORK
1646 /* Arrange for SIGALARM after CHILD_LIFETIME seconds to
1647 terminate the process. */
Simon Kelley28866e92011-02-14 20:19:14 +00001648 if (!option_bool(OPT_DEBUG))
Simon Kelley832af0b2007-01-21 20:01:28 +00001649 alarm(CHILD_LIFETIME);
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001650#endif
1651
Simon Kelley832af0b2007-01-21 20:01:28 +00001652 /* start with no upstream connections. */
1653 for (s = daemon->servers; s; s = s->next)
Simon Kelley7cebd202006-05-06 14:13:33 +01001654 s->tcpfd = -1;
Simon Kelley832af0b2007-01-21 20:01:28 +00001655
1656 /* The connected socket inherits non-blocking
1657 attribute from the listening socket.
1658 Reset that here. */
1659 if ((flags = fcntl(confd, F_GETFL, 0)) != -1)
1660 fcntl(confd, F_SETFL, flags & ~O_NONBLOCK);
1661
Simon Kelley4f7b3042012-11-28 21:27:02 +00001662 buff = tcp_request(confd, now, &tcp_addr, netmask, auth_dns);
Simon Kelley7cebd202006-05-06 14:13:33 +01001663
Simon Kelley832af0b2007-01-21 20:01:28 +00001664 shutdown(confd, SHUT_RDWR);
Simon Kelleyff841eb2015-03-11 21:36:30 +00001665 while (retry_send(close(confd)));
Simon Kelley832af0b2007-01-21 20:01:28 +00001666
1667 if (buff)
1668 free(buff);
1669
1670 for (s = daemon->servers; s; s = s->next)
1671 if (s->tcpfd != -1)
1672 {
1673 shutdown(s->tcpfd, SHUT_RDWR);
Simon Kelleyff841eb2015-03-11 21:36:30 +00001674 while (retry_send(close(s->tcpfd)));
Simon Kelley832af0b2007-01-21 20:01:28 +00001675 }
Simon Kelley7cebd202006-05-06 14:13:33 +01001676#ifndef NO_FORK
Simon Kelley28866e92011-02-14 20:19:14 +00001677 if (!option_bool(OPT_DEBUG))
Simon Kelley5aabfc72007-08-29 11:24:47 +01001678 {
1679 flush_log();
1680 _exit(0);
1681 }
Simon Kelley7cebd202006-05-06 14:13:33 +01001682#endif
Simon Kelley832af0b2007-01-21 20:01:28 +00001683 }
1684 }
1685 }
Simon Kelley3be34542004-09-11 19:12:13 +01001686}
1687
Simon Kelley7622fc02009-06-04 20:32:05 +01001688#ifdef HAVE_DHCP
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001689int make_icmp_sock(void)
1690{
Simon Kelley7cebd202006-05-06 14:13:33 +01001691 int fd;
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001692 int zeroopt = 0;
1693
1694 if ((fd = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP)) != -1)
1695 {
Simon Kelley7cebd202006-05-06 14:13:33 +01001696 if (!fix_fd(fd) ||
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001697 setsockopt(fd, SOL_SOCKET, SO_DONTROUTE, &zeroopt, sizeof(zeroopt)) == -1)
1698 {
1699 close(fd);
1700 fd = -1;
1701 }
1702 }
1703
1704 return fd;
1705}
1706
Simon Kelley5aabfc72007-08-29 11:24:47 +01001707int icmp_ping(struct in_addr addr)
Simon Kelley3be34542004-09-11 19:12:13 +01001708{
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001709 /* Try and get an ICMP echo from a machine. */
Simon Kelley3be34542004-09-11 19:12:13 +01001710
1711 /* Note that whilst in the three second wait, we check for
Simon Kelley832af0b2007-01-21 20:01:28 +00001712 (and service) events on the DNS and TFTP sockets, (so doing that
Simon Kelley3be34542004-09-11 19:12:13 +01001713 better not use any resources our caller has in use...)
1714 but we remain deaf to signals or further DHCP packets. */
1715
Simon Kelley5e95a552015-07-05 22:31:30 +01001716 /* There can be a problem using dnsmasq_time() to end the loop, since
1717 it's not monotonic, and can go backwards if the system clock is
1718 tweaked, leading to the code getting stuck in this loop and
1719 ignoring DHCP requests. To fix this, we check to see if select returned
1720 as a result of a timeout rather than a socket becoming available. We
1721 only allow this to happen as many times as it takes to get to the wait time
1722 in quarter-second chunks. This provides a fallback way to end loop. */
1723
1724 int fd, rc;
Simon Kelley3be34542004-09-11 19:12:13 +01001725 struct sockaddr_in saddr;
1726 struct {
1727 struct ip ip;
1728 struct icmp icmp;
1729 } packet;
1730 unsigned short id = rand16();
Simon Kelley5e95a552015-07-05 22:31:30 +01001731 unsigned int i, j, timeout_count;
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001732 int gotreply = 0;
Simon Kelley3be34542004-09-11 19:12:13 +01001733 time_t start, now;
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001734
Simon Kelley824af852008-02-12 20:43:05 +00001735#if defined(HAVE_LINUX_NETWORK) || defined (HAVE_SOLARIS_NETWORK)
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001736 if ((fd = make_icmp_sock()) == -1)
1737 return 0;
1738#else
1739 int opt = 2000;
1740 fd = daemon->dhcp_icmp_fd;
1741 setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
1742#endif
1743
Simon Kelley3be34542004-09-11 19:12:13 +01001744 saddr.sin_family = AF_INET;
1745 saddr.sin_port = 0;
1746 saddr.sin_addr = addr;
1747#ifdef HAVE_SOCKADDR_SA_LEN
1748 saddr.sin_len = sizeof(struct sockaddr_in);
1749#endif
1750
1751 memset(&packet.icmp, 0, sizeof(packet.icmp));
1752 packet.icmp.icmp_type = ICMP_ECHO;
1753 packet.icmp.icmp_id = id;
1754 for (j = 0, i = 0; i < sizeof(struct icmp) / 2; i++)
1755 j += ((u16 *)&packet.icmp)[i];
1756 while (j>>16)
1757 j = (j & 0xffff) + (j >> 16);
1758 packet.icmp.icmp_cksum = (j == 0xffff) ? j : ~j;
1759
Simon Kelleyff841eb2015-03-11 21:36:30 +00001760 while (retry_send(sendto(fd, (char *)&packet.icmp, sizeof(struct icmp), 0,
1761 (struct sockaddr *)&saddr, sizeof(saddr))));
Simon Kelleyfd9fa482004-10-21 20:24:00 +01001762
Simon Kelley5e95a552015-07-05 22:31:30 +01001763 for (now = start = dnsmasq_time(), timeout_count = 0;
1764 (difftime(now, start) < (float)PING_WAIT) && (timeout_count < PING_WAIT * 4);)
Simon Kelleyfd9fa482004-10-21 20:24:00 +01001765 {
Simon Kelleyfd9fa482004-10-21 20:24:00 +01001766 struct sockaddr_in faddr;
Simon Kelley3d8df262005-08-29 12:19:27 +01001767 socklen_t len = sizeof(faddr);
Simon Kelleyfd9fa482004-10-21 20:24:00 +01001768
Simon Kelleyb842bc92015-07-12 21:09:11 +01001769 poll_reset();
1770 poll_listen(fd, POLLIN);
1771 set_dns_listeners(now);
1772 set_log_writer();
Simon Kelleyc5ad4e72012-02-24 16:06:20 +00001773
1774#ifdef HAVE_DHCP6
Simon Kelley1f776932012-12-16 19:46:08 +00001775 if (daemon->doing_ra)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001776 poll_listen(daemon->icmp6fd, POLLIN);
Simon Kelleyc5ad4e72012-02-24 16:06:20 +00001777#endif
1778
Simon Kelleyb842bc92015-07-12 21:09:11 +01001779 rc = do_poll(250);
Simon Kelley5e95a552015-07-05 22:31:30 +01001780
1781 if (rc < 0)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001782 continue;
Simon Kelley5e95a552015-07-05 22:31:30 +01001783 else if (rc == 0)
1784 timeout_count++;
Simon Kelleyf2621c72007-04-29 19:47:21 +01001785
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001786 now = dnsmasq_time();
Simon Kelleyf2621c72007-04-29 19:47:21 +01001787
Simon Kelleyb842bc92015-07-12 21:09:11 +01001788 check_log_writer(0);
1789 check_dns_listeners(now);
Simon Kelley832af0b2007-01-21 20:01:28 +00001790
Simon Kelleyc5ad4e72012-02-24 16:06:20 +00001791#ifdef HAVE_DHCP6
Simon Kelleyb842bc92015-07-12 21:09:11 +01001792 if (daemon->doing_ra && poll_check(daemon->icmp6fd, POLLIN))
Simon Kelley1f776932012-12-16 19:46:08 +00001793 icmp6_packet(now);
Simon Kelleyc5ad4e72012-02-24 16:06:20 +00001794#endif
1795
Simon Kelley832af0b2007-01-21 20:01:28 +00001796#ifdef HAVE_TFTP
Simon Kelleyb842bc92015-07-12 21:09:11 +01001797 check_tftp_listeners(now);
Simon Kelley832af0b2007-01-21 20:01:28 +00001798#endif
1799
Simon Kelleyb842bc92015-07-12 21:09:11 +01001800 if (poll_check(fd, POLLIN) &&
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001801 recvfrom(fd, &packet, sizeof(packet), 0,
Simon Kelleyfd9fa482004-10-21 20:24:00 +01001802 (struct sockaddr *)&faddr, &len) == sizeof(packet) &&
1803 saddr.sin_addr.s_addr == faddr.sin_addr.s_addr &&
1804 packet.icmp.icmp_type == ICMP_ECHOREPLY &&
1805 packet.icmp.icmp_seq == 0 &&
1806 packet.icmp.icmp_id == id)
1807 {
1808 gotreply = 1;
1809 break;
1810 }
1811 }
1812
Simon Kelley824af852008-02-12 20:43:05 +00001813#if defined(HAVE_LINUX_NETWORK) || defined(HAVE_SOLARIS_NETWORK)
Simon Kelleyff841eb2015-03-11 21:36:30 +00001814 while (retry_send(close(fd)));
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001815#else
Simon Kelley3be34542004-09-11 19:12:13 +01001816 opt = 1;
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001817 setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
1818#endif
1819
Simon Kelley3be34542004-09-11 19:12:13 +01001820 return gotreply;
1821}
Simon Kelley7622fc02009-06-04 20:32:05 +01001822#endif
Simon Kelley0a852542005-03-23 20:28:59 +00001823
1824