blob: 2306c4899d3de89da548997fdb25a0462c758cf5 [file] [log] [blame]
Simon Kelley2a8710a2020-01-05 16:40:06 +00001/* dnsmasq is Copyright (c) 2000-2020 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;
Simon Kelley6b54d692018-02-08 21:23:05 +000051 int chown_warn = 0;
Simon Kelley1a6bca82008-07-11 11:11:42 +010052#if defined(HAVE_LINUX_NETWORK)
53 cap_user_header_t hdr = NULL;
54 cap_user_data_t data = NULL;
Simon Kelley305ffb52019-03-16 18:17:17 +000055 int need_cap_net_admin = 0;
56 int need_cap_net_raw = 0;
57 int need_cap_net_bind_service = 0;
Simon Kelley3b3f4412013-10-11 16:33:28 +010058 char *bound_device = NULL;
59 int did_bind = 0;
Simon Kelley90d7c6b2019-09-14 21:13:03 +010060 struct server *serv;
Simon Kelley913fa152020-04-19 23:16:52 +010061 char *netlink_warn;
Simon Kelley1a6bca82008-07-11 11:11:42 +010062#endif
Vladislav Grishenko408c3682013-09-24 16:18:49 +010063#if defined(HAVE_DHCP) || defined(HAVE_DHCP6)
Simon Kelley1f776932012-12-16 19:46:08 +000064 struct dhcp_context *context;
Simon Kelleyff7eea22013-09-04 18:01:38 +010065 struct dhcp_relay *relay;
Vladislav Grishenko408c3682013-09-24 16:18:49 +010066#endif
Stefan Tomanek30d08792015-03-31 22:32:11 +010067#ifdef HAVE_TFTP
68 int tftp_prefix_missing = 0;
69#endif
Simon Kelley5aabfc72007-08-29 11:24:47 +010070
Simon Kelley824af852008-02-12 20:43:05 +000071#ifdef LOCALEDIR
Simon Kelleyb8187c82005-11-26 21:46:27 +000072 setlocale(LC_ALL, "");
73 bindtextdomain("dnsmasq", LOCALEDIR);
74 textdomain("dnsmasq");
75#endif
76
Simon Kelley9e4abcb2004-01-22 19:47:41 +000077 sigact.sa_handler = sig_handler;
78 sigact.sa_flags = 0;
79 sigemptyset(&sigact.sa_mask);
80 sigaction(SIGUSR1, &sigact, NULL);
Simon Kelley5aabfc72007-08-29 11:24:47 +010081 sigaction(SIGUSR2, &sigact, NULL);
Simon Kelley9e4abcb2004-01-22 19:47:41 +000082 sigaction(SIGHUP, &sigact, NULL);
83 sigaction(SIGTERM, &sigact, NULL);
Simon Kelley44a2a312004-03-10 20:04:35 +000084 sigaction(SIGALRM, &sigact, NULL);
Simon Kelleyfeba5c12004-07-27 20:28:58 +010085 sigaction(SIGCHLD, &sigact, NULL);
Simon Kelley3c973ad2018-01-14 21:05:37 +000086 sigaction(SIGINT, &sigact, NULL);
87
Simon Kelleyfeba5c12004-07-27 20:28:58 +010088 /* ignore SIGPIPE */
89 sigact.sa_handler = SIG_IGN;
90 sigaction(SIGPIPE, &sigact, NULL);
Simon Kelley9e4abcb2004-01-22 19:47:41 +000091
Simon Kelley5aabfc72007-08-29 11:24:47 +010092 umask(022); /* known umask, create leases and pid files as 0644 */
Simon Kelley0506a5e2020-03-19 21:56:45 +000093
Simon Kelleyb5ea1cc2014-07-29 16:34:14 +010094 rand_init(); /* Must precede read_opts() */
95
Simon Kelley5aabfc72007-08-29 11:24:47 +010096 read_opts(argc, argv, compile_opts);
Simon Kelleyc3e0b9b2013-12-31 13:50:39 +000097
Simon Kelley0506a5e2020-03-19 21:56:45 +000098#ifdef HAVE_LINUX_NETWORK
99 daemon->kernel_version = kernel_version();
100#endif
101
Simon Kelley3be34542004-09-11 19:12:13 +0100102 if (daemon->edns_pktsz < PACKETSZ)
Simon Kelley60b68062014-01-08 12:10:28 +0000103 daemon->edns_pktsz = PACKETSZ;
Simon Kelley3ddacb82014-01-08 14:32:03 +0000104
Simon Kelleyd3a8b392015-12-23 12:27:37 +0000105 /* Min buffer size: we check after adding each record, so there must be
106 memory for the largest packet, and the largest record so the
107 min for DNS is PACKETSZ+MAXDNAME+RRFIXEDSZ which is < 1000.
108 This might be increased is EDNS packet size if greater than the minimum. */
109 daemon->packet_buff_sz = daemon->edns_pktsz + MAXDNAME + RRFIXEDSZ;
Simon Kelley0a852542005-03-23 20:28:59 +0000110 daemon->packet = safe_malloc(daemon->packet_buff_sz);
Simon Kelley3ddacb82014-01-08 14:32:03 +0000111
Simon Kelleyc72daea2012-01-05 21:33:27 +0000112 daemon->addrbuff = safe_malloc(ADDRSTRLEN);
Simon Kelley25cf5e32015-01-09 15:53:03 +0000113 if (option_bool(OPT_EXTRALOG))
114 daemon->addrbuff2 = safe_malloc(ADDRSTRLEN);
Simon Kelley3ddacb82014-01-08 14:32:03 +0000115
116#ifdef HAVE_DNSSEC
117 if (option_bool(OPT_DNSSEC_VALID))
Simon Kelley5107ace2014-02-23 10:48:32 +0000118 {
Simon Kelleycbe379a2015-04-21 22:57:06 +0100119 /* Note that both /000 and '.' are allowed within labels. These get
120 represented in presentation format using NAME_ESCAPE as an escape
121 character when in DNSSEC mode.
122 In theory, if all the characters in a name were /000 or
123 '.' or NAME_ESCAPE then all would have to be escaped, so the
124 presentation format would be twice as long as the spec.
125
126 daemon->namebuff was previously allocated by the option-reading
127 code before we knew if we're in DNSSEC mode, so reallocate here. */
128 free(daemon->namebuff);
129 daemon->namebuff = safe_malloc(MAXDNAME * 2);
130 daemon->keyname = safe_malloc(MAXDNAME * 2);
131 daemon->workspacename = safe_malloc(MAXDNAME * 2);
Simon Kelley373e9172017-12-01 22:40:56 +0000132 /* one char flag per possible RR in answer section (may get extended). */
133 daemon->rr_status_sz = 64;
Simon Kelleyae7a3b92019-09-03 14:40:47 +0100134 daemon->rr_status = safe_malloc(sizeof(*daemon->rr_status) * daemon->rr_status_sz);
Simon Kelley5107ace2014-02-23 10:48:32 +0000135 }
Simon Kelley3ddacb82014-01-08 14:32:03 +0000136#endif
Simon Kelley4f7b3042012-11-28 21:27:02 +0000137
Simon Kelley7622fc02009-06-04 20:32:05 +0100138#ifdef HAVE_DHCP
Simon Kelley3be34542004-09-11 19:12:13 +0100139 if (!daemon->lease_file)
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000140 {
Simon Kelley52b92f42012-01-22 16:05:15 +0000141 if (daemon->dhcp || daemon->dhcp6)
Simon Kelley3be34542004-09-11 19:12:13 +0100142 daemon->lease_file = LEASEFILE;
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000143 }
Simon Kelley7622fc02009-06-04 20:32:05 +0100144#endif
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000145
Simon Kelley0541a1a2020-03-02 17:10:25 +0000146 /* Ensure that at least stdin, stdout and stderr (fd 0, 1, 2) exist,
Simon Kelleya2761752012-01-18 16:07:21 +0000147 otherwise file descriptors we create can end up being 0, 1, or 2
148 and then get accidentally closed later when we make 0, 1, and 2
149 open to /dev/null. Normally we'll be started with 0, 1 and 2 open,
150 but it's not guaranteed. By opening /dev/null three times, we
151 ensure that we're not using those fds for real stuff. */
Simon Kelley0541a1a2020-03-02 17:10:25 +0000152 for (i = 0; i < 3; i++)
153 open("/dev/null", O_RDWR);
154
155 /* Close any file descriptors we inherited apart from std{in|out|err} */
156 close_fds(max_fd, -1, -1, -1);
157
Simon Kelley801ca9a2012-03-06 19:30:17 +0000158#ifndef HAVE_LINUX_NETWORK
159# if !(defined(IP_RECVDSTADDR) && defined(IP_RECVIF) && defined(IP_SENDSRCADDR))
Simon Kelley28866e92011-02-14 20:19:14 +0000160 if (!option_bool(OPT_NOWILD))
Simon Kelleyde379512004-06-22 20:23:33 +0100161 {
162 bind_fallback = 1;
Simon Kelley28866e92011-02-14 20:19:14 +0000163 set_option_bool(OPT_NOWILD);
Simon Kelleyde379512004-06-22 20:23:33 +0100164 }
Simon Kelley801ca9a2012-03-06 19:30:17 +0000165# endif
Simon Kelley2b5bae92012-06-26 16:55:23 +0100166
167 /* -- bind-dynamic not supported on !Linux, fall back to --bind-interfaces */
Simon Kelley54dd3932012-06-20 11:23:38 +0100168 if (option_bool(OPT_CLEVERBIND))
Simon Kelley2b5bae92012-06-26 16:55:23 +0100169 {
170 bind_fallback = 1;
171 set_option_bool(OPT_NOWILD);
Simon Kelley236e0722012-06-26 21:33:01 +0100172 reset_option_bool(OPT_CLEVERBIND);
Simon Kelley2b5bae92012-06-26 16:55:23 +0100173 }
Simon Kelley04918052015-01-26 11:23:43 +0000174#endif
Simon Kelley5f4dc5c2015-01-20 20:51:02 +0000175
Simon Kelley04918052015-01-26 11:23:43 +0000176#ifndef HAVE_INOTIFY
Simon Kelley70d18732015-01-31 19:59:29 +0000177 if (daemon->dynamic_dirs)
178 die(_("dhcp-hostsdir, dhcp-optsdir and hostsdir are not supported on this platform"), NULL, EC_BADCONF);
Simon Kelley309331f2006-04-22 15:05:01 +0100179#endif
Simon Kelley2b5bae92012-06-26 16:55:23 +0100180
Simon Kelley0744ca62014-01-25 16:40:15 +0000181 if (option_bool(OPT_DNSSEC_VALID))
182 {
Simon Kelley3ddacb82014-01-08 14:32:03 +0000183#ifdef HAVE_DNSSEC
Simon Kelleya63b8b82016-01-12 11:28:58 +0000184 struct ds_config *ds;
185
186 /* Must have at least a root trust anchor, or the DNSSEC code
187 can loop forever. */
188 for (ds = daemon->ds; ds; ds = ds->next)
189 if (ds->name[0] == 0)
190 break;
191
192 if (!ds)
193 die(_("no root trust anchor provided for DNSSEC"), NULL, EC_BADCONF);
Simon Kelley0744ca62014-01-25 16:40:15 +0000194
195 if (daemon->cachesize < CACHESIZ)
Simon Kelley360f2512015-03-07 18:28:06 +0000196 die(_("cannot reduce cache size from default when DNSSEC enabled"), NULL, EC_BADCONF);
Simon Kelley0744ca62014-01-25 16:40:15 +0000197#else
198 die(_("DNSSEC not available: set HAVE_DNSSEC in src/config.h"), NULL, EC_BADCONF);
Simon Kelley3ddacb82014-01-08 14:32:03 +0000199#endif
Simon Kelley0744ca62014-01-25 16:40:15 +0000200 }
Simon Kelley3ddacb82014-01-08 14:32:03 +0000201
Simon Kelley832af0b2007-01-21 20:01:28 +0000202#ifndef HAVE_TFTP
Simon Kelley9b40cbf2012-07-13 19:58:26 +0100203 if (option_bool(OPT_TFTP))
Simon Kelley5aabfc72007-08-29 11:24:47 +0100204 die(_("TFTP server not available: set HAVE_TFTP in src/config.h"), NULL, EC_BADCONF);
Simon Kelley832af0b2007-01-21 20:01:28 +0000205#endif
206
Simon Kelley7de060b2011-08-26 17:24:52 +0100207#ifdef HAVE_CONNTRACK
208 if (option_bool(OPT_CONNTRACK) && (daemon->query_port != 0 || daemon->osport))
Simon Kelley360f2512015-03-07 18:28:06 +0000209 die (_("cannot use --conntrack AND --query-port"), NULL, EC_BADCONF);
Simon Kelley7de060b2011-08-26 17:24:52 +0100210#else
211 if (option_bool(OPT_CONNTRACK))
Simon Kelley360f2512015-03-07 18:28:06 +0000212 die(_("conntrack support not available: set HAVE_CONNTRACK in src/config.h"), NULL, EC_BADCONF);
Simon Kelley7de060b2011-08-26 17:24:52 +0100213#endif
214
Simon Kelley824af852008-02-12 20:43:05 +0000215#ifdef HAVE_SOLARIS_NETWORK
216 if (daemon->max_logs != 0)
Josh Soref730c6742017-02-06 16:14:04 +0000217 die(_("asynchronous logging is not available under Solaris"), NULL, EC_BADCONF);
Simon Kelley824af852008-02-12 20:43:05 +0000218#endif
219
Simon Kelley572b41e2011-02-18 18:11:18 +0000220#ifdef __ANDROID__
221 if (daemon->max_logs != 0)
Josh Soref730c6742017-02-06 16:14:04 +0000222 die(_("asynchronous logging is not available under Android"), NULL, EC_BADCONF);
Simon Kelley572b41e2011-02-18 18:11:18 +0000223#endif
224
Simon Kelley4820dce2012-12-18 18:30:30 +0000225#ifndef HAVE_AUTH
Simon Kelley08933472018-10-05 16:34:35 +0100226 if (daemon->auth_zones)
Simon Kelley4820dce2012-12-18 18:30:30 +0000227 die(_("authoritative DNS not available: set HAVE_AUTH in src/config.h"), NULL, EC_BADCONF);
228#endif
229
Simon Kelleyb5ea1cc2014-07-29 16:34:14 +0100230#ifndef HAVE_LOOP
231 if (option_bool(OPT_LOOP_DETECT))
Simon Kelley360f2512015-03-07 18:28:06 +0000232 die(_("loop detection not available: set HAVE_LOOP in src/config.h"), NULL, EC_BADCONF);
Simon Kelleyb5ea1cc2014-07-29 16:34:14 +0100233#endif
Hans Dedecker926332a2016-01-23 10:48:12 +0000234
Julian Kornberger8dcdb332018-07-21 22:11:08 +0100235#ifndef HAVE_UBUS
236 if (option_bool(OPT_UBUS))
237 die(_("Ubus not available: set HAVE_UBUS in src/config.h"), NULL, EC_BADCONF);
238#endif
239
Hans Dedecker926332a2016-01-23 10:48:12 +0000240 if (daemon->max_port < daemon->min_port)
241 die(_("max_port cannot be smaller than min_port"), NULL, EC_BADCONF);
242
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100243 now = dnsmasq_time();
Simon Kelley4f7b3042012-11-28 21:27:02 +0000244
Simon Kelley08933472018-10-05 16:34:35 +0100245 if (daemon->auth_zones)
246 {
247 if (!daemon->authserver)
248 die(_("--auth-server required when an auth zone is defined."), NULL, EC_BADCONF);
249
250 /* Create a serial at startup if not configured. */
Simon Kelley4f7b3042012-11-28 21:27:02 +0000251#ifdef HAVE_BROKEN_RTC
Martin Schiller53792c92018-10-08 14:55:19 +0200252 if (daemon->soa_sn == 0)
Simon Kelley08933472018-10-05 16:34:35 +0100253 die(_("zone serial must be configured in --auth-soa"), NULL, EC_BADCONF);
Simon Kelley4f7b3042012-11-28 21:27:02 +0000254#else
Simon Kelley08933472018-10-05 16:34:35 +0100255 if (daemon->soa_sn == 0)
256 daemon->soa_sn = now;
Simon Kelley4f7b3042012-11-28 21:27:02 +0000257#endif
Simon Kelley08933472018-10-05 16:34:35 +0100258 }
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000259
Simon Kelleyff7eea22013-09-04 18:01:38 +0100260#ifdef HAVE_DHCP6
261 if (daemon->dhcp6)
262 {
263 daemon->doing_ra = option_bool(OPT_RA);
Simon Kelley1f776932012-12-16 19:46:08 +0000264
Simon Kelleyff7eea22013-09-04 18:01:38 +0100265 for (context = daemon->dhcp6; context; context = context->next)
Simon Kelley1f776932012-12-16 19:46:08 +0000266 {
Simon Kelleyff7eea22013-09-04 18:01:38 +0100267 if (context->flags & CONTEXT_DHCP)
268 daemon->doing_dhcp6 = 1;
269 if (context->flags & CONTEXT_RA)
270 daemon->doing_ra = 1;
Simon Kelley1ee9be42013-12-09 16:50:19 +0000271#if !defined(HAVE_LINUX_NETWORK) && !defined(HAVE_BSD_NETWORK)
Simon Kelleyff7eea22013-09-04 18:01:38 +0100272 if (context->flags & CONTEXT_TEMPLATE)
273 die (_("dhcp-range constructor not available on this platform"), NULL, EC_BADCONF);
Simon Kelleybb86e852012-12-17 22:00:53 +0000274#endif
Simon Kelley1f776932012-12-16 19:46:08 +0000275 }
Simon Kelley1f776932012-12-16 19:46:08 +0000276 }
Simon Kelleyff7eea22013-09-04 18:01:38 +0100277#endif
278
279#ifdef HAVE_DHCP
280 /* Note that order matters here, we must call lease_init before
281 creating any file descriptors which shouldn't be leaked
282 to the lease-script init process. We need to call common_init
Simon Kelley33702ab2015-12-28 23:17:15 +0000283 before lease_init to allocate buffers it uses.
Simon Kelley1e505122016-01-25 21:29:23 +0000284 The script subsystem relies on DHCP buffers, hence the last two
Simon Kelley33702ab2015-12-28 23:17:15 +0000285 conditions below. */
286 if (daemon->dhcp || daemon->doing_dhcp6 || daemon->relay4 ||
Simon Kelley1e505122016-01-25 21:29:23 +0000287 daemon->relay6 || option_bool(OPT_TFTP) || option_bool(OPT_SCRIPT_ARP))
Simon Kelleyff7eea22013-09-04 18:01:38 +0100288 {
289 dhcp_common_init();
290 if (daemon->dhcp || daemon->doing_dhcp6)
291 lease_init(now);
292 }
293
294 if (daemon->dhcp || daemon->relay4)
Simon Kelley305ffb52019-03-16 18:17:17 +0000295 {
296 dhcp_init();
297# ifdef HAVE_LINUX_NETWORK
298 if (!option_bool(OPT_NO_PING))
299 need_cap_net_raw = 1;
300 need_cap_net_admin = 1;
301# endif
302 }
Simon Kelleyff7eea22013-09-04 18:01:38 +0100303
304# ifdef HAVE_DHCP6
Simon Kelley89500e32013-09-20 16:29:20 +0100305 if (daemon->doing_ra || daemon->doing_dhcp6 || daemon->relay6)
Simon Kelley305ffb52019-03-16 18:17:17 +0000306 {
307 ra_init(now);
308# ifdef HAVE_LINUX_NETWORK
309 need_cap_net_raw = 1;
310 need_cap_net_admin = 1;
311# endif
312 }
Simon Kelleyff7eea22013-09-04 18:01:38 +0100313
314 if (daemon->doing_dhcp6 || daemon->relay6)
315 dhcp6_init();
316# endif
Simon Kelley843c96b2012-02-27 17:42:38 +0000317
Simon Kelley7622fc02009-06-04 20:32:05 +0100318#endif
Simon Kelleyfeba5c12004-07-27 20:28:58 +0100319
Jason A. Donenfeld13d86c72013-02-22 18:20:53 +0000320#ifdef HAVE_IPSET
321 if (daemon->ipsets)
Simon Kelley305ffb52019-03-16 18:17:17 +0000322 {
323 ipset_init();
324# ifdef HAVE_LINUX_NETWORK
325 need_cap_net_admin = 1;
326# endif
327 }
Jason A. Donenfeld13d86c72013-02-22 18:20:53 +0000328#endif
329
Simon Kelley1ee9be42013-12-09 16:50:19 +0000330#if defined(HAVE_LINUX_NETWORK)
Simon Kelley913fa152020-04-19 23:16:52 +0100331 netlink_warn = netlink_init();
Simon Kelley1ee9be42013-12-09 16:50:19 +0000332#elif defined(HAVE_BSD_NETWORK)
333 route_init();
Simon Kelley801ca9a2012-03-06 19:30:17 +0000334#endif
335
Simon Kelley1ee9be42013-12-09 16:50:19 +0000336 if (option_bool(OPT_NOWILD) && option_bool(OPT_CLEVERBIND))
337 die(_("cannot set --bind-interfaces and --bind-dynamic"), NULL, EC_BADCONF);
338
Simon Kelley115ac3e2013-05-20 11:28:32 +0100339 if (!enumerate_interfaces(1) || !enumerate_interfaces(0))
Simon Kelley5aabfc72007-08-29 11:24:47 +0100340 die(_("failed to find list of interfaces: %s"), NULL, EC_MISC);
Simon Kelley843c96b2012-02-27 17:42:38 +0000341
Simon Kelley54dd3932012-06-20 11:23:38 +0100342 if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND))
Simon Kelley5aabfc72007-08-29 11:24:47 +0100343 {
Simon Kelley74c95c22011-10-19 09:33:39 +0100344 create_bound_listeners(1);
Simon Kelley54dd3932012-06-20 11:23:38 +0100345
346 if (!option_bool(OPT_CLEVERBIND))
347 for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
348 if (if_tmp->name && !if_tmp->used)
349 die(_("unknown interface %s"), if_tmp->name, EC_BADNET);
Simon Kelley9380ba72012-04-16 14:41:56 +0100350
351#if defined(HAVE_LINUX_NETWORK) && defined(HAVE_DHCP)
352 /* after enumerate_interfaces() */
Simon Kelley3b3f4412013-10-11 16:33:28 +0100353 bound_device = whichdevice();
354
Simon Kelley9380ba72012-04-16 14:41:56 +0100355 if (daemon->dhcp)
356 {
Simon Kelley3b3f4412013-10-11 16:33:28 +0100357 if (!daemon->relay4 && bound_device)
358 {
359 bindtodevice(bound_device, daemon->dhcpfd);
360 did_bind = 1;
361 }
362 if (daemon->enable_pxe && bound_device)
363 {
364 bindtodevice(bound_device, daemon->pxefd);
365 did_bind = 1;
366 }
Simon Kelley9380ba72012-04-16 14:41:56 +0100367 }
368#endif
369
370#if defined(HAVE_LINUX_NETWORK) && defined(HAVE_DHCP6)
Simon Kelley3b3f4412013-10-11 16:33:28 +0100371 if (daemon->doing_dhcp6 && !daemon->relay6 && bound_device)
372 {
373 bindtodevice(bound_device, daemon->dhcp6fd);
374 did_bind = 1;
375 }
Simon Kelley9380ba72012-04-16 14:41:56 +0100376#endif
Simon Kelley5aabfc72007-08-29 11:24:47 +0100377 }
Simon Kelley28866e92011-02-14 20:19:14 +0000378 else
Simon Kelley74c95c22011-10-19 09:33:39 +0100379 create_wildcard_listeners();
Simon Kelley5d162f22012-12-20 14:55:46 +0000380
381#ifdef HAVE_DHCP6
382 /* after enumerate_interfaces() */
Simon Kelleyff7eea22013-09-04 18:01:38 +0100383 if (daemon->doing_dhcp6 || daemon->relay6 || daemon->doing_ra)
Simon Kelley5d162f22012-12-20 14:55:46 +0000384 join_multicast(1);
Simon Kelley3511a922013-11-07 10:28:11 +0000385
386 /* After netlink_init() and before create_helper() */
387 lease_make_duid(now);
Simon Kelley5d162f22012-12-20 14:55:46 +0000388#endif
Simon Kelley5aabfc72007-08-29 11:24:47 +0100389
Simon Kelley824af852008-02-12 20:43:05 +0000390 if (daemon->port != 0)
Simon Kelley82e3f452014-01-31 21:05:48 +0000391 {
392 cache_init();
Simon Kelley193de4a2014-12-10 17:32:16 +0000393
Simon Kelley82e3f452014-01-31 21:05:48 +0000394 blockdata_init();
Simon Kelley5f4dc5c2015-01-20 20:51:02 +0000395 }
Simon Kelley193de4a2014-12-10 17:32:16 +0000396
Simon Kelley04918052015-01-26 11:23:43 +0000397#ifdef HAVE_INOTIFY
Petr Menšík075366a2017-11-05 16:05:39 +0000398 if ((daemon->port != 0 || daemon->dhcp || daemon->doing_dhcp6)
399 && (!option_bool(OPT_NO_RESOLV) || daemon->dynamic_dirs))
Simon Kelley5f4dc5c2015-01-20 20:51:02 +0000400 inotify_dnsmasq_init();
401 else
402 daemon->inotifyfd = -1;
Simon Kelley193de4a2014-12-10 17:32:16 +0000403#endif
Simon Kelley6b173352018-05-08 18:32:14 +0100404
405 if (daemon->dump_file)
406#ifdef HAVE_DUMPFILE
407 dump_init();
408 else
409 daemon->dumpfd = -1;
410#else
411 die(_("Packet dumps not available: set HAVE_DUMP in src/config.h"), NULL, EC_BADCONF);
412#endif
413
Simon Kelley28866e92011-02-14 20:19:14 +0000414 if (option_bool(OPT_DBUS))
Simon Kelley3d8df262005-08-29 12:19:27 +0100415#ifdef HAVE_DBUS
416 {
417 char *err;
418 daemon->dbus = NULL;
419 daemon->watches = NULL;
Simon Kelley5aabfc72007-08-29 11:24:47 +0100420 if ((err = dbus_init()))
421 die(_("DBus error: %s"), err, EC_MISC);
Simon Kelley3d8df262005-08-29 12:19:27 +0100422 }
423#else
Simon Kelley5aabfc72007-08-29 11:24:47 +0100424 die(_("DBus not available: set HAVE_DBUS in src/config.h"), NULL, EC_BADCONF);
Simon Kelley3d8df262005-08-29 12:19:27 +0100425#endif
Stefan Tomanek7aa970e2015-04-01 17:55:07 +0100426
Jan Willem Janssena2b82202019-03-25 12:42:23 +0100427 if (option_bool(OPT_UBUS))
428#ifdef HAVE_UBUS
429 {
430 daemon->ubus = NULL;
431 ubus_init();
432 }
433#else
434 die(_("UBus not available: set HAVE_UBUS in src/config.h"), NULL, EC_BADCONF);
435#endif
436
Simon Kelley824af852008-02-12 20:43:05 +0000437 if (daemon->port != 0)
438 pre_allocate_sfds();
Simon Kelley1a6bca82008-07-11 11:11:42 +0100439
Simon Kelleyc72daea2012-01-05 21:33:27 +0000440#if defined(HAVE_SCRIPT)
Simon Kelley1a6bca82008-07-11 11:11:42 +0100441 /* Note getpwnam returns static storage */
Simon Kelley843c96b2012-02-27 17:42:38 +0000442 if ((daemon->dhcp || daemon->dhcp6) &&
443 daemon->scriptuser &&
Simon Kelleyc72daea2012-01-05 21:33:27 +0000444 (daemon->lease_change_command || daemon->luascript))
Simon Kelley1a6bca82008-07-11 11:11:42 +0100445 {
Simon Kelley83e4b732018-02-06 16:57:15 +0000446 struct passwd *scr_pw;
447
448 if ((scr_pw = getpwnam(daemon->scriptuser)))
Simon Kelley1a6bca82008-07-11 11:11:42 +0100449 {
Simon Kelley83e4b732018-02-06 16:57:15 +0000450 script_uid = scr_pw->pw_uid;
451 script_gid = scr_pw->pw_gid;
Simon Kelley1a6bca82008-07-11 11:11:42 +0100452 }
453 else
454 baduser = daemon->scriptuser;
455 }
Simon Kelley7622fc02009-06-04 20:32:05 +0100456#endif
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000457
Simon Kelley1a6bca82008-07-11 11:11:42 +0100458 if (daemon->username && !(ent_pw = getpwnam(daemon->username)))
459 baduser = daemon->username;
460 else if (daemon->groupname && !(gp = getgrnam(daemon->groupname)))
461 baduser = daemon->groupname;
462
463 if (baduser)
464 die(_("unknown user or group: %s"), baduser, EC_BADCONF);
Simon Kelleyf6e62e22015-03-01 18:17:54 +0000465
Simon Kelley1a6bca82008-07-11 11:11:42 +0100466 /* implement group defaults, "dip" if available, or group associated with uid */
467 if (!daemon->group_set && !gp)
468 {
469 if (!(gp = getgrnam(CHGRP)) && ent_pw)
470 gp = getgrgid(ent_pw->pw_gid);
471
472 /* for error message */
473 if (gp)
474 daemon->groupname = gp->gr_name;
475 }
476
477#if defined(HAVE_LINUX_NETWORK)
Simon Kelley305ffb52019-03-16 18:17:17 +0000478 /* We keep CAP_NETADMIN (for ARP-injection) and
479 CAP_NET_RAW (for icmp) if we're doing dhcp,
480 if we have yet to bind ports because of DAD,
Simon Kelley90d7c6b2019-09-14 21:13:03 +0100481 or we're doing it dynamically, we need CAP_NET_BIND_SERVICE. */
Simon Kelley305ffb52019-03-16 18:17:17 +0000482 if ((is_dad_listeners() || option_bool(OPT_CLEVERBIND)) &&
483 (option_bool(OPT_TFTP) || (daemon->port != 0 && daemon->port <= 1024)))
484 need_cap_net_bind_service = 1;
485
Simon Kelley90d7c6b2019-09-14 21:13:03 +0100486 /* usptream servers which bind to an interface call SO_BINDTODEVICE
Simon Kelleydefd6b12019-09-16 23:02:12 +0100487 for each TCP connection, so need CAP_NET_RAW */
Simon Kelley90d7c6b2019-09-14 21:13:03 +0100488 for (serv = daemon->servers; serv; serv = serv->next)
489 if (serv->interface[0] != 0)
Simon Kelleydefd6b12019-09-16 23:02:12 +0100490 need_cap_net_raw = 1;
Simon Kelley90d7c6b2019-09-14 21:13:03 +0100491
492 /* If we're doing Dbus or UBus, the above can be set dynamically,
493 (as can ports) so always (potentially) needed. */
494#ifdef HAVE_DBUS
495 if (option_bool(OPT_DBUS))
496 {
497 need_cap_net_bind_service = 1;
Simon Kelleydefd6b12019-09-16 23:02:12 +0100498 need_cap_net_raw = 1;
Simon Kelley90d7c6b2019-09-14 21:13:03 +0100499 }
500#endif
501
502#ifdef HAVE_UBUS
503 if (option_bool(OPT_UBUS))
504 {
505 need_cap_net_bind_service = 1;
Simon Kelleydefd6b12019-09-16 23:02:12 +0100506 need_cap_net_raw = 1;
Simon Kelley90d7c6b2019-09-14 21:13:03 +0100507 }
508#endif
509
Simon Kelley1a6bca82008-07-11 11:11:42 +0100510 /* determine capability API version here, while we can still
511 call safe_malloc */
Simon Kelley305ffb52019-03-16 18:17:17 +0000512 int capsize = 1; /* for header version 1 */
513 char *fail = NULL;
514
515 hdr = safe_malloc(sizeof(*hdr));
516
517 /* find version supported by kernel */
518 memset(hdr, 0, sizeof(*hdr));
519 capget(hdr, NULL);
520
521 if (hdr->version != LINUX_CAPABILITY_VERSION_1)
Simon Kelley1a6bca82008-07-11 11:11:42 +0100522 {
Simon Kelley305ffb52019-03-16 18:17:17 +0000523 /* if unknown version, use largest supported version (3) */
524 if (hdr->version != LINUX_CAPABILITY_VERSION_2)
525 hdr->version = LINUX_CAPABILITY_VERSION_3;
526 capsize = 2;
Simon Kelley1a6bca82008-07-11 11:11:42 +0100527 }
Simon Kelley305ffb52019-03-16 18:17:17 +0000528
529 data = safe_malloc(sizeof(*data) * capsize);
530 capget(hdr, data); /* Get current values, for verification */
531
532 if (need_cap_net_admin && !(data->permitted & (1 << CAP_NET_ADMIN)))
533 fail = "NET_ADMIN";
534 else if (need_cap_net_raw && !(data->permitted & (1 << CAP_NET_RAW)))
535 fail = "NET_RAW";
536 else if (need_cap_net_bind_service && !(data->permitted & (1 << CAP_NET_BIND_SERVICE)))
537 fail = "NET_BIND_SERVICE";
538
539 if (fail)
540 die(_("process is missing required capability %s"), fail, EC_MISC);
541
542 /* Now set bitmaps to set caps after daemonising */
543 memset(data, 0, sizeof(*data) * capsize);
544
545 if (need_cap_net_admin)
546 data->effective |= (1 << CAP_NET_ADMIN);
547 if (need_cap_net_raw)
548 data->effective |= (1 << CAP_NET_RAW);
549 if (need_cap_net_bind_service)
550 data->effective |= (1 << CAP_NET_BIND_SERVICE);
551
552 data->permitted = data->effective;
Simon Kelley1a6bca82008-07-11 11:11:42 +0100553#endif
554
Simon Kelley5aabfc72007-08-29 11:24:47 +0100555 /* Use a pipe to carry signals and other events back to the event loop
Simon Kelley1a6bca82008-07-11 11:11:42 +0100556 in a race-free manner and another to carry errors to daemon-invoking process */
557 safe_pipe(pipefd, 1);
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100558
559 piperead = pipefd[0];
560 pipewrite = pipefd[1];
561 /* prime the pipe to load stuff first time. */
Simon Kelleye98bd522014-03-28 20:41:23 +0000562 send_event(pipewrite, EVENT_INIT, 0, NULL);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100563
564 err_pipe[1] = -1;
Simon Kelley16972692006-10-16 20:04:18 +0100565
Simon Kelley28866e92011-02-14 20:19:14 +0000566 if (!option_bool(OPT_DEBUG))
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000567 {
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000568 /* The following code "daemonizes" the process.
569 See Stevens section 12.4 */
Simon Kelley1a6bca82008-07-11 11:11:42 +0100570
Simon Kelley9e038942008-05-30 20:06:34 +0100571 if (chdir("/") != 0)
572 die(_("cannot chdir to filesystem root: %s"), NULL, EC_MISC);
573
Simon Kelley28866e92011-02-14 20:19:14 +0000574 if (!option_bool(OPT_NO_FORK))
Simon Kelley3be34542004-09-11 19:12:13 +0100575 {
Simon Kelley5aabfc72007-08-29 11:24:47 +0100576 pid_t pid;
577
Simon Kelley1a6bca82008-07-11 11:11:42 +0100578 /* pipe to carry errors back to original process.
579 When startup is complete we close this and the process terminates. */
580 safe_pipe(err_pipe, 0);
581
Simon Kelley7622fc02009-06-04 20:32:05 +0100582 if ((pid = fork()) == -1)
583 /* fd == -1 since we've not forked, never returns. */
Simon Kelleyc72daea2012-01-05 21:33:27 +0000584 send_event(-1, EVENT_FORK_ERR, errno, NULL);
Simon Kelley9e038942008-05-30 20:06:34 +0100585
Simon Kelley5aabfc72007-08-29 11:24:47 +0100586 if (pid != 0)
Simon Kelley1a6bca82008-07-11 11:11:42 +0100587 {
588 struct event_desc ev;
Simon Kelleyc72daea2012-01-05 21:33:27 +0000589 char *msg;
590
Simon Kelley1a6bca82008-07-11 11:11:42 +0100591 /* close our copy of write-end */
Simon Kelley5fc639c2019-03-29 21:29:43 +0000592 close(err_pipe[1]);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100593
594 /* check for errors after the fork */
Simon Kelleyc72daea2012-01-05 21:33:27 +0000595 if (read_event(err_pipe[0], &ev, &msg))
596 fatal_event(&ev, msg);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100597
598 _exit(EC_GOOD);
599 }
600
Simon Kelley5fc639c2019-03-29 21:29:43 +0000601 close(err_pipe[0]);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100602
603 /* NO calls to die() from here on. */
Simon Kelley3be34542004-09-11 19:12:13 +0100604
605 setsid();
Simon Kelley7622fc02009-06-04 20:32:05 +0100606
607 if ((pid = fork()) == -1)
Simon Kelleyc72daea2012-01-05 21:33:27 +0000608 send_event(err_pipe[1], EVENT_FORK_ERR, errno, NULL);
Simon Kelley7622fc02009-06-04 20:32:05 +0100609
610 if (pid != 0)
Simon Kelley7cebd202006-05-06 14:13:33 +0100611 _exit(0);
Simon Kelley3be34542004-09-11 19:12:13 +0100612 }
Simon Kelley9e038942008-05-30 20:06:34 +0100613
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000614 /* write pidfile _after_ forking ! */
Simon Kelley1a6bca82008-07-11 11:11:42 +0100615 if (daemon->runfile)
616 {
Simon Kelley79cfefd2012-09-02 13:29:51 +0100617 int fd, err = 0;
618
619 sprintf(daemon->namebuff, "%d\n", (int) getpid());
620
621 /* Explanation: Some installations of dnsmasq (eg Debian/Ubuntu) locate the pid-file
622 in a directory which is writable by the non-privileged user that dnsmasq runs as. This
623 allows the daemon to delete the file as part of its shutdown. This is a security hole to the
624 extent that an attacker running as the unprivileged user could replace the pidfile with a
625 symlink, and have the target of that symlink overwritten as root next time dnsmasq starts.
626
Josh Soref730c6742017-02-06 16:14:04 +0000627 The following code first deletes any existing file, and then opens it with the O_EXCL flag,
Simon Kelley79cfefd2012-09-02 13:29:51 +0100628 ensuring that the open() fails should there be any existing file (because the unlink() failed,
629 or an attacker exploited the race between unlink() and open()). This ensures that no symlink
630 attack can succeed.
631
632 Any compromise of the non-privileged user still theoretically allows the pid-file to be
633 replaced whilst dnsmasq is running. The worst that could allow is that the usual
634 "shutdown dnsmasq" shell command could be tricked into stopping any other process.
635
636 Note that if dnsmasq is started as non-root (eg for testing) it silently ignores
637 failure to write the pid-file.
638 */
639
640 unlink(daemon->runfile);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100641
Simon Kelley79cfefd2012-09-02 13:29:51 +0100642 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 +0100643 {
Simon Kelley79cfefd2012-09-02 13:29:51 +0100644 /* only complain if started as root */
645 if (getuid() == 0)
646 err = 1;
Simon Kelley1a6bca82008-07-11 11:11:42 +0100647 }
Simon Kelley79cfefd2012-09-02 13:29:51 +0100648 else
649 {
Simon Kelley246a31c2018-02-06 17:27:55 +0000650 /* We're still running as root here. Change the ownership of the PID file
651 to the user we will be running as. Note that this is not to allow
652 us to delete the file, since that depends on the permissions
653 of the directory containing the file. That directory will
654 need to by owned by the dnsmasq user, and the ownership of the
655 file has to match, to keep systemd >273 happy. */
Simon Kelley6b54d692018-02-08 21:23:05 +0000656 if (getuid() == 0 && ent_pw && ent_pw->pw_uid != 0 && fchown(fd, ent_pw->pw_uid, ent_pw->pw_gid) == -1)
657 chown_warn = errno;
658
659 if (!read_write(fd, (unsigned char *)daemon->namebuff, strlen(daemon->namebuff), 0))
Simon Kelley79cfefd2012-09-02 13:29:51 +0100660 err = 1;
Simon Kelley83e4b732018-02-06 16:57:15 +0000661 else
Simon Kelleyff841eb2015-03-11 21:36:30 +0000662 {
Simon Kelley5fc639c2019-03-29 21:29:43 +0000663 if (close(fd) == -1)
Simon Kelleyff841eb2015-03-11 21:36:30 +0000664 err = 1;
665 }
Simon Kelley79cfefd2012-09-02 13:29:51 +0100666 }
667
668 if (err)
Simon Kelley1a6bca82008-07-11 11:11:42 +0100669 {
Simon Kelleyc72daea2012-01-05 21:33:27 +0000670 send_event(err_pipe[1], EVENT_PIDFILE, errno, daemon->runfile);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100671 _exit(0);
672 }
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000673 }
Simon Kelley16972692006-10-16 20:04:18 +0100674 }
675
Simon Kelley8ef5ada2010-06-03 19:42:45 +0100676 log_err = log_start(ent_pw, err_pipe[1]);
677
Simon Kelley28866e92011-02-14 20:19:14 +0000678 if (!option_bool(OPT_DEBUG))
Simon Kelley8ef5ada2010-06-03 19:42:45 +0100679 {
680 /* open stdout etc to /dev/null */
681 int nullfd = open("/dev/null", O_RDWR);
Simon Kelleyf7cf7492016-03-01 16:19:23 +0000682 if (nullfd != -1)
683 {
684 dup2(nullfd, STDOUT_FILENO);
685 dup2(nullfd, STDERR_FILENO);
686 dup2(nullfd, STDIN_FILENO);
687 close(nullfd);
688 }
Simon Kelley8ef5ada2010-06-03 19:42:45 +0100689 }
Simon Kelleyf2621c72007-04-29 19:47:21 +0100690
Simon Kelley1a6bca82008-07-11 11:11:42 +0100691 /* if we are to run scripts, we need to fork a helper before dropping root. */
692 daemon->helperfd = -1;
Simon Kelleyc72daea2012-01-05 21:33:27 +0000693#ifdef HAVE_SCRIPT
Simon Kelley1e505122016-01-25 21:29:23 +0000694 if ((daemon->dhcp || daemon->dhcp6 || option_bool(OPT_TFTP) || option_bool(OPT_SCRIPT_ARP)) &&
Simon Kelley33702ab2015-12-28 23:17:15 +0000695 (daemon->lease_change_command || daemon->luascript))
696 daemon->helperfd = create_helper(pipewrite, err_pipe[1], script_uid, script_gid, max_fd);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100697#endif
Simon Kelley5aabfc72007-08-29 11:24:47 +0100698
Simon Kelley28866e92011-02-14 20:19:14 +0000699 if (!option_bool(OPT_DEBUG) && getuid() == 0)
Simon Kelley16972692006-10-16 20:04:18 +0100700 {
Simon Kelley1a6bca82008-07-11 11:11:42 +0100701 int bad_capabilities = 0;
702 gid_t dummy;
Simon Kelley16972692006-10-16 20:04:18 +0100703
Josh Soref730c6742017-02-06 16:14:04 +0000704 /* remove all supplementary groups */
Simon Kelley1a6bca82008-07-11 11:11:42 +0100705 if (gp &&
706 (setgroups(0, &dummy) == -1 ||
707 setgid(gp->gr_gid) == -1))
708 {
Simon Kelleyc72daea2012-01-05 21:33:27 +0000709 send_event(err_pipe[1], EVENT_GROUP_ERR, errno, daemon->groupname);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100710 _exit(0);
711 }
712
Simon Kelley7cebd202006-05-06 14:13:33 +0100713 if (ent_pw && ent_pw->pw_uid != 0)
Simon Kelley16972692006-10-16 20:04:18 +0100714 {
Simon Kelley74c95c22011-10-19 09:33:39 +0100715#if defined(HAVE_LINUX_NETWORK)
Simon Kelley305ffb52019-03-16 18:17:17 +0000716 /* Need to be able to drop root. */
717 data->effective |= (1 << CAP_SETUID);
718 data->permitted |= (1 << CAP_SETUID);
Simon Kelley16972692006-10-16 20:04:18 +0100719 /* Tell kernel to not clear capabilities when dropping root */
Simon Kelley572b41e2011-02-18 18:11:18 +0000720 if (capset(hdr, data) == -1 || prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1)
Simon Kelley16972692006-10-16 20:04:18 +0100721 bad_capabilities = errno;
Simon Kelley1a6bca82008-07-11 11:11:42 +0100722
Simon Kelley7622fc02009-06-04 20:32:05 +0100723#elif defined(HAVE_SOLARIS_NETWORK)
Simon Kelley824af852008-02-12 20:43:05 +0000724 /* http://developers.sun.com/solaris/articles/program_privileges.html */
725 priv_set_t *priv_set;
726
727 if (!(priv_set = priv_str_to_set("basic", ",", NULL)) ||
728 priv_addset(priv_set, PRIV_NET_ICMPACCESS) == -1 ||
729 priv_addset(priv_set, PRIV_SYS_NET_CONFIG) == -1)
730 bad_capabilities = errno;
731
732 if (priv_set && bad_capabilities == 0)
733 {
734 priv_inverse(priv_set);
735
736 if (setppriv(PRIV_OFF, PRIV_LIMIT, priv_set) == -1)
737 bad_capabilities = errno;
738 }
739
740 if (priv_set)
741 priv_freeset(priv_set);
742
Simon Kelley824af852008-02-12 20:43:05 +0000743#endif
744
Simon Kelley1a6bca82008-07-11 11:11:42 +0100745 if (bad_capabilities != 0)
Simon Kelley16972692006-10-16 20:04:18 +0100746 {
Simon Kelleyc72daea2012-01-05 21:33:27 +0000747 send_event(err_pipe[1], EVENT_CAP_ERR, bad_capabilities, NULL);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100748 _exit(0);
Simon Kelley16972692006-10-16 20:04:18 +0100749 }
Simon Kelley1a6bca82008-07-11 11:11:42 +0100750
751 /* finally drop root */
752 if (setuid(ent_pw->pw_uid) == -1)
753 {
Simon Kelleyc72daea2012-01-05 21:33:27 +0000754 send_event(err_pipe[1], EVENT_USER_ERR, errno, daemon->username);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100755 _exit(0);
756 }
757
758#ifdef HAVE_LINUX_NETWORK
Simon Kelley305ffb52019-03-16 18:17:17 +0000759 data->effective &= ~(1 << CAP_SETUID);
760 data->permitted &= ~(1 << CAP_SETUID);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100761
Simon Kelley305ffb52019-03-16 18:17:17 +0000762 /* lose the setuid capability */
Simon Kelley1a6bca82008-07-11 11:11:42 +0100763 if (capset(hdr, data) == -1)
764 {
Simon Kelleyc72daea2012-01-05 21:33:27 +0000765 send_event(err_pipe[1], EVENT_CAP_ERR, errno, NULL);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100766 _exit(0);
767 }
768#endif
769
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000770 }
Simon Kelley849a8352006-06-09 21:02:31 +0100771 }
Simon Kelley16972692006-10-16 20:04:18 +0100772
Simon Kelley16972692006-10-16 20:04:18 +0100773#ifdef HAVE_LINUX_NETWORK
Chen Wei28b879a2015-02-17 22:07:35 +0000774 free(hdr);
775 free(data);
Simon Kelley28866e92011-02-14 20:19:14 +0000776 if (option_bool(OPT_DEBUG))
Simon Kelley572b41e2011-02-18 18:11:18 +0000777 prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
Simon Kelley16972692006-10-16 20:04:18 +0100778#endif
Simon Kelley849a8352006-06-09 21:02:31 +0100779
Simon Kelley8b3ae2f2012-06-13 13:43:49 +0100780#ifdef HAVE_TFTP
Stefan Tomanek30d08792015-03-31 22:32:11 +0100781 if (option_bool(OPT_TFTP))
Simon Kelley8b3ae2f2012-06-13 13:43:49 +0100782 {
783 DIR *dir;
784 struct tftp_prefix *p;
785
786 if (daemon->tftp_prefix)
787 {
788 if (!((dir = opendir(daemon->tftp_prefix))))
789 {
Stefan Tomanek30d08792015-03-31 22:32:11 +0100790 tftp_prefix_missing = 1;
791 if (!option_bool(OPT_TFTP_NO_FAIL))
792 {
793 send_event(err_pipe[1], EVENT_TFTP_ERR, errno, daemon->tftp_prefix);
794 _exit(0);
795 }
Simon Kelley8b3ae2f2012-06-13 13:43:49 +0100796 }
Stefan Tomanekb4c0f092015-04-16 15:20:59 +0100797 else
798 closedir(dir);
Simon Kelley8b3ae2f2012-06-13 13:43:49 +0100799 }
Stefan Tomanek7aa970e2015-04-01 17:55:07 +0100800
Simon Kelley8b3ae2f2012-06-13 13:43:49 +0100801 for (p = daemon->if_prefix; p; p = p->next)
802 {
Stefan Tomanek30d08792015-03-31 22:32:11 +0100803 p->missing = 0;
Simon Kelley8b3ae2f2012-06-13 13:43:49 +0100804 if (!((dir = opendir(p->prefix))))
Stefan Tomanek30d08792015-03-31 22:32:11 +0100805 {
806 p->missing = 1;
807 if (!option_bool(OPT_TFTP_NO_FAIL))
808 {
809 send_event(err_pipe[1], EVENT_TFTP_ERR, errno, p->prefix);
810 _exit(0);
811 }
Stefan Tomanek7aa970e2015-04-01 17:55:07 +0100812 }
Stefan Tomanekb4c0f092015-04-16 15:20:59 +0100813 else
814 closedir(dir);
Simon Kelley8b3ae2f2012-06-13 13:43:49 +0100815 }
816 }
817#endif
Stefan Tomanek7aa970e2015-04-01 17:55:07 +0100818
Simon Kelley824af852008-02-12 20:43:05 +0000819 if (daemon->port == 0)
820 my_syslog(LOG_INFO, _("started, version %s DNS disabled"), VERSION);
Simon Kelley0ef13342017-01-15 16:42:39 +0000821 else
822 {
823 if (daemon->cachesize != 0)
Simon Kelley1f1873a2018-05-11 23:38:23 +0100824 {
825 my_syslog(LOG_INFO, _("started, version %s cachesize %d"), VERSION, daemon->cachesize);
826 if (daemon->cachesize > 10000)
827 my_syslog(LOG_WARNING, _("cache size greater than 10000 may cause performance issues, and is unlikely to be useful."));
828 }
Simon Kelley0ef13342017-01-15 16:42:39 +0000829 else
830 my_syslog(LOG_INFO, _("started, version %s cache disabled"), VERSION);
831
832 if (option_bool(OPT_LOCAL_SERVICE))
833 my_syslog(LOG_INFO, _("DNS service limited to local subnets"));
834 }
Simon Kelley16972692006-10-16 20:04:18 +0100835
Simon Kelleyf2621c72007-04-29 19:47:21 +0100836 my_syslog(LOG_INFO, _("compile time options: %s"), compile_opts);
Simon Kelley6b54d692018-02-08 21:23:05 +0000837
838 if (chown_warn != 0)
839 my_syslog(LOG_WARNING, "chown of PID file %s failed: %s", daemon->runfile, strerror(chown_warn));
Simon Kelley16972692006-10-16 20:04:18 +0100840
Simon Kelley3d8df262005-08-29 12:19:27 +0100841#ifdef HAVE_DBUS
Simon Kelley28866e92011-02-14 20:19:14 +0000842 if (option_bool(OPT_DBUS))
Simon Kelley3d8df262005-08-29 12:19:27 +0100843 {
844 if (daemon->dbus)
Simon Kelleyf2621c72007-04-29 19:47:21 +0100845 my_syslog(LOG_INFO, _("DBus support enabled: connected to system bus"));
Simon Kelley3d8df262005-08-29 12:19:27 +0100846 else
Simon Kelleyf2621c72007-04-29 19:47:21 +0100847 my_syslog(LOG_INFO, _("DBus support enabled: bus connection pending"));
Simon Kelley3d8df262005-08-29 12:19:27 +0100848 }
849#endif
Simon Kelley1a9a3482014-03-05 15:01:08 +0000850
Jan Willem Janssena2b82202019-03-25 12:42:23 +0100851#ifdef HAVE_UBUS
852 if (option_bool(OPT_UBUS))
853 {
854 if (daemon->ubus)
855 my_syslog(LOG_INFO, _("UBus support enabled: connected to system bus"));
856 else
857 my_syslog(LOG_INFO, _("UBus support enabled: bus connection pending"));
858 }
859#endif
860
Simon Kelley1d97ac42014-01-31 11:12:27 +0000861#ifdef HAVE_DNSSEC
Simon Kelleydb737462014-01-31 10:32:45 +0000862 if (option_bool(OPT_DNSSEC_VALID))
Simon Kelleye98bd522014-03-28 20:41:23 +0000863 {
Simon Kelley360f2512015-03-07 18:28:06 +0000864 int rc;
Simon Kelley3b6eb192018-07-20 21:23:56 +0100865 struct ds_config *ds;
866
Simon Kelley360f2512015-03-07 18:28:06 +0000867 /* Delay creating the timestamp file until here, after we've changed user, so that
868 it has the correct owner to allow updating the mtime later.
869 This means we have to report fatal errors via the pipe. */
870 if ((rc = setup_timestamp()) == -1)
871 {
872 send_event(err_pipe[1], EVENT_TIME_ERR, errno, daemon->timestamp_file);
873 _exit(0);
874 }
875
Simon Kelleya6918532018-04-15 16:20:52 +0100876 if (option_bool(OPT_DNSSEC_IGN_NS))
877 my_syslog(LOG_INFO, _("DNSSEC validation enabled but all unsigned answers are trusted"));
878 else
879 my_syslog(LOG_INFO, _("DNSSEC validation enabled"));
Simon Kelley360f2512015-03-07 18:28:06 +0000880
Kevin Darbyshire-Bryant06093a92016-07-11 21:03:27 +0100881 daemon->dnssec_no_time_check = option_bool(OPT_DNSSEC_TIME);
882 if (option_bool(OPT_DNSSEC_TIME) && !daemon->back_to_the_future)
Simon Kelley3c973ad2018-01-14 21:05:37 +0000883 my_syslog(LOG_INFO, _("DNSSEC signature timestamps not checked until receipt of SIGINT"));
Simon Kelley360f2512015-03-07 18:28:06 +0000884
885 if (rc == 1)
Simon Kelleyf6e62e22015-03-01 18:17:54 +0000886 my_syslog(LOG_INFO, _("DNSSEC signature timestamps not checked until system time valid"));
Simon Kelley3b6eb192018-07-20 21:23:56 +0100887
888 for (ds = daemon->ds; ds; ds = ds->next)
889 my_syslog(LOG_INFO, _("configured with trust anchor for %s keytag %u"),
890 ds->name[0] == 0 ? "<root>" : ds->name, ds->keytag);
Simon Kelleye98bd522014-03-28 20:41:23 +0000891 }
Simon Kelleydb737462014-01-31 10:32:45 +0000892#endif
Simon Kelley3d8df262005-08-29 12:19:27 +0100893
Simon Kelley1a6bca82008-07-11 11:11:42 +0100894 if (log_err != 0)
895 my_syslog(LOG_WARNING, _("warning: failed to change owner of %s: %s"),
896 daemon->log_file, strerror(log_err));
Simon Kelleydb737462014-01-31 10:32:45 +0000897
Simon Kelleyde379512004-06-22 20:23:33 +0100898 if (bind_fallback)
Simon Kelleyf2621c72007-04-29 19:47:21 +0100899 my_syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations"));
Simon Kelleydc27e142013-10-16 13:09:53 +0100900
Simon Kelleyf7029f52013-11-21 15:09:09 +0000901 if (option_bool(OPT_NOWILD))
902 warn_bound_listeners();
Petr Menšíkad59f272017-03-17 17:22:19 +0000903 else if (!option_bool(OPT_CLEVERBIND))
904 warn_wild_labels();
Simon Kelleyf7029f52013-11-21 15:09:09 +0000905
906 warn_int_names();
Simon Kelleyde379512004-06-22 20:23:33 +0100907
Simon Kelley28866e92011-02-14 20:19:14 +0000908 if (!option_bool(OPT_NOWILD))
Simon Kelley26128d22004-11-14 16:43:54 +0000909 for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
910 if (if_tmp->name && !if_tmp->used)
Simon Kelleyf2621c72007-04-29 19:47:21 +0100911 my_syslog(LOG_WARNING, _("warning: interface %s does not currently exist"), if_tmp->name);
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100912
Simon Kelley28866e92011-02-14 20:19:14 +0000913 if (daemon->port != 0 && option_bool(OPT_NO_RESOLV))
Simon Kelley208b65c2006-08-05 21:41:37 +0100914 {
915 if (daemon->resolv_files && !daemon->resolv_files->is_default)
Simon Kelleyf2621c72007-04-29 19:47:21 +0100916 my_syslog(LOG_WARNING, _("warning: ignoring resolv-file flag because no-resolv is set"));
Simon Kelley208b65c2006-08-05 21:41:37 +0100917 daemon->resolv_files = NULL;
Simon Kelley1b7ecd12007-02-05 14:57:57 +0000918 if (!daemon->servers)
Simon Kelleyf2621c72007-04-29 19:47:21 +0100919 my_syslog(LOG_WARNING, _("warning: no upstream servers configured"));
Simon Kelley208b65c2006-08-05 21:41:37 +0100920 }
921
Simon Kelleyf2621c72007-04-29 19:47:21 +0100922 if (daemon->max_logs != 0)
923 my_syslog(LOG_INFO, _("asynchronous logging enabled, queue limit is %d messages"), daemon->max_logs);
Simon Kelley1f776932012-12-16 19:46:08 +0000924
Simon Kelleyf2621c72007-04-29 19:47:21 +0100925
Simon Kelley7622fc02009-06-04 20:32:05 +0100926#ifdef HAVE_DHCP
Simon Kelley1f776932012-12-16 19:46:08 +0000927 for (context = daemon->dhcp; context; context = context->next)
928 log_context(AF_INET, context);
Simon Kelleyc8257542012-03-28 21:15:41 +0100929
Simon Kelleyff7eea22013-09-04 18:01:38 +0100930 for (relay = daemon->relay4; relay; relay = relay->next)
931 log_relay(AF_INET, relay);
932
Simon Kelley1f776932012-12-16 19:46:08 +0000933# ifdef HAVE_DHCP6
934 for (context = daemon->dhcp6; context; context = context->next)
935 log_context(AF_INET6, context);
Simon Kelley52b92f42012-01-22 16:05:15 +0000936
Simon Kelleyff7eea22013-09-04 18:01:38 +0100937 for (relay = daemon->relay6; relay; relay = relay->next)
938 log_relay(AF_INET6, relay);
939
Simon Kelley1f776932012-12-16 19:46:08 +0000940 if (daemon->doing_dhcp6 || daemon->doing_ra)
941 dhcp_construct_contexts(now);
942
943 if (option_bool(OPT_RA))
944 my_syslog(MS_DHCP | LOG_INFO, _("IPv6 router advertisement enabled"));
945# endif
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000946
Simon Kelley3b3f4412013-10-11 16:33:28 +0100947# ifdef HAVE_LINUX_NETWORK
948 if (did_bind)
949 my_syslog(MS_DHCP | LOG_INFO, _("DHCP, sockets bound exclusively to interface %s"), bound_device);
Simon Kelley913fa152020-04-19 23:16:52 +0100950
951 if (netlink_warn)
952 my_syslog(LOG_WARNING, netlink_warn);
Simon Kelley3b3f4412013-10-11 16:33:28 +0100953# endif
954
Josh Soref730c6742017-02-06 16:14:04 +0000955 /* after dhcp_construct_contexts */
Simon Kelley8445f5d2012-12-17 21:54:08 +0000956 if (daemon->dhcp || daemon->doing_dhcp6)
957 lease_find_interfaces(now);
Simon Kelley1f776932012-12-16 19:46:08 +0000958#endif
Simon Kelley52b92f42012-01-22 16:05:15 +0000959
Simon Kelley832af0b2007-01-21 20:01:28 +0000960#ifdef HAVE_TFTP
Simon Kelley5f4dc5c2015-01-20 20:51:02 +0000961 if (option_bool(OPT_TFTP))
Stefan Tomanek7aa970e2015-04-01 17:55:07 +0100962 {
Stefan Tomanek30d08792015-03-31 22:32:11 +0100963 struct tftp_prefix *p;
Simon Kelley832af0b2007-01-21 20:01:28 +0000964
Simon Kelley2ac4cf02020-01-06 23:39:33 +0000965 my_syslog(MS_TFTP | LOG_INFO, "TFTP %s%s %s %s",
Simon Kelleyf2621c72007-04-29 19:47:21 +0100966 daemon->tftp_prefix ? _("root is ") : _("enabled"),
Simon Kelley2ac4cf02020-01-06 23:39:33 +0000967 daemon->tftp_prefix ? daemon->tftp_prefix : "",
968 option_bool(OPT_TFTP_SECURE) ? _("secure mode") : "",
969 option_bool(OPT_SINGLE_PORT) ? _("single port mode") : "");
Stefan Tomanek7aa970e2015-04-01 17:55:07 +0100970
Stefan Tomanek30d08792015-03-31 22:32:11 +0100971 if (tftp_prefix_missing)
972 my_syslog(MS_TFTP | LOG_WARNING, _("warning: %s inaccessible"), daemon->tftp_prefix);
Stefan Tomanek7aa970e2015-04-01 17:55:07 +0100973
Stefan Tomanek30d08792015-03-31 22:32:11 +0100974 for (p = daemon->if_prefix; p; p = p->next)
975 if (p->missing)
976 my_syslog(MS_TFTP | LOG_WARNING, _("warning: TFTP directory %s inaccessible"), p->prefix);
977
Simon Kelley832af0b2007-01-21 20:01:28 +0000978 /* This is a guess, it assumes that for small limits,
Simon Kelleyf2621c72007-04-29 19:47:21 +0100979 disjoint files might be served, but for large limits,
Simon Kelley832af0b2007-01-21 20:01:28 +0000980 a single file will be sent to may clients (the file only needs
981 one fd). */
982
983 max_fd -= 30; /* use other than TFTP */
984
985 if (max_fd < 0)
986 max_fd = 5;
Simon Kelley2ac4cf02020-01-06 23:39:33 +0000987 else if (max_fd < 100 && !option_bool(OPT_SINGLE_PORT))
Simon Kelley832af0b2007-01-21 20:01:28 +0000988 max_fd = max_fd/2;
989 else
990 max_fd = max_fd - 20;
Simon Kelley824af852008-02-12 20:43:05 +0000991
992 /* if we have to use a limited range of ports,
993 that will limit the number of transfers */
994 if (daemon->start_tftp_port != 0 &&
995 daemon->end_tftp_port - daemon->start_tftp_port + 1 < max_fd)
996 max_fd = daemon->end_tftp_port - daemon->start_tftp_port + 1;
Simon Kelley832af0b2007-01-21 20:01:28 +0000997
998 if (daemon->tftp_max > max_fd)
999 {
1000 daemon->tftp_max = max_fd;
Simon Kelley7622fc02009-06-04 20:32:05 +01001001 my_syslog(MS_TFTP | LOG_WARNING,
Simon Kelleyf2621c72007-04-29 19:47:21 +01001002 _("restricting maximum simultaneous TFTP transfers to %d"),
1003 daemon->tftp_max);
Simon Kelley832af0b2007-01-21 20:01:28 +00001004 }
1005 }
1006#endif
1007
Simon Kelley1a6bca82008-07-11 11:11:42 +01001008 /* finished start-up - release original process */
1009 if (err_pipe[1] != -1)
Simon Kelley5fc639c2019-03-29 21:29:43 +00001010 close(err_pipe[1]);
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001011
Simon Kelley824af852008-02-12 20:43:05 +00001012 if (daemon->port != 0)
1013 check_servers();
1014
Simon Kelley7cebd202006-05-06 14:13:33 +01001015 pid = getpid();
Simon Kelleya799ca02018-10-18 19:35:29 +01001016
1017 daemon->pipe_to_parent = -1;
1018 for (i = 0; i < MAX_PROCS; i++)
1019 daemon->tcp_pipes[i] = -1;
Simon Kelley7cebd202006-05-06 14:13:33 +01001020
Simon Kelley04918052015-01-26 11:23:43 +00001021#ifdef HAVE_INOTIFY
Simon Kelley193de4a2014-12-10 17:32:16 +00001022 /* Using inotify, have to select a resolv file at startup */
1023 poll_resolv(1, 0, now);
1024#endif
1025
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001026 while (1)
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001027 {
Simon Kelleyb842bc92015-07-12 21:09:11 +01001028 int t, timeout = -1;
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001029
Simon Kelleyb842bc92015-07-12 21:09:11 +01001030 poll_reset();
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001031
Simon Kelley16972692006-10-16 20:04:18 +01001032 /* if we are out of resources, find how long we have to wait
1033 for some to come free, we'll loop around then and restart
1034 listening for queries */
Simon Kelleyb842bc92015-07-12 21:09:11 +01001035 if ((t = set_dns_listeners(now)) != 0)
1036 timeout = t * 1000;
Simon Kelley16972692006-10-16 20:04:18 +01001037
Simon Kelley832af0b2007-01-21 20:01:28 +00001038 /* Whilst polling for the dbus, or doing a tftp transfer, wake every quarter second */
1039 if (daemon->tftp_trans ||
Simon Kelley28866e92011-02-14 20:19:14 +00001040 (option_bool(OPT_DBUS) && !daemon->dbus))
Simon Kelleyb842bc92015-07-12 21:09:11 +01001041 timeout = 250;
1042
Simon Kelley74c95c22011-10-19 09:33:39 +01001043 /* Wake every second whilst waiting for DAD to complete */
1044 else if (is_dad_listeners())
Simon Kelleyb842bc92015-07-12 21:09:11 +01001045 timeout = 1000;
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001046
Simon Kelley832af0b2007-01-21 20:01:28 +00001047#ifdef HAVE_DBUS
Simon Kelleyb842bc92015-07-12 21:09:11 +01001048 set_dbus_listeners();
Julian Kornbergercaf4d572018-07-21 21:45:03 +01001049#endif
1050
1051#ifdef HAVE_UBUS
Kevin Darbyshire-Bryant9d6fd172018-07-28 13:26:39 +01001052 if (option_bool(OPT_UBUS))
Jan Willem Janssena2b82202019-03-25 12:42:23 +01001053 set_ubus_listeners();
Julian Kornbergercaf4d572018-07-21 21:45:03 +01001054#endif
Julian Kornberger8dcdb332018-07-21 22:11:08 +01001055
Simon Kelley7622fc02009-06-04 20:32:05 +01001056#ifdef HAVE_DHCP
Simon Kelleyff7eea22013-09-04 18:01:38 +01001057 if (daemon->dhcp || daemon->relay4)
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001058 {
Simon Kelleyb842bc92015-07-12 21:09:11 +01001059 poll_listen(daemon->dhcpfd, POLLIN);
Simon Kelley316e2732010-01-22 20:16:09 +00001060 if (daemon->pxefd != -1)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001061 poll_listen(daemon->pxefd, POLLIN);
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001062 }
Simon Kelley7622fc02009-06-04 20:32:05 +01001063#endif
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001064
Simon Kelley52b92f42012-01-22 16:05:15 +00001065#ifdef HAVE_DHCP6
Simon Kelleyff7eea22013-09-04 18:01:38 +01001066 if (daemon->doing_dhcp6 || daemon->relay6)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001067 poll_listen(daemon->dhcp6fd, POLLIN);
Simon Kelleyf6d69562015-07-08 22:38:13 +01001068
Simon Kelley1f776932012-12-16 19:46:08 +00001069 if (daemon->doing_ra)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001070 poll_listen(daemon->icmp6fd, POLLIN);
Simon Kelley52b92f42012-01-22 16:05:15 +00001071#endif
Simon Kelley04918052015-01-26 11:23:43 +00001072
1073#ifdef HAVE_INOTIFY
Simon Kelley5f4dc5c2015-01-20 20:51:02 +00001074 if (daemon->inotifyfd != -1)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001075 poll_listen(daemon->inotifyfd, POLLIN);
Simon Kelley04918052015-01-26 11:23:43 +00001076#endif
1077
1078#if defined(HAVE_LINUX_NETWORK)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001079 poll_listen(daemon->netlinkfd, POLLIN);
Simon Kelley1ee9be42013-12-09 16:50:19 +00001080#elif defined(HAVE_BSD_NETWORK)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001081 poll_listen(daemon->routefd, POLLIN);
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001082#endif
Simon Kelley193de4a2014-12-10 17:32:16 +00001083
Simon Kelleyb842bc92015-07-12 21:09:11 +01001084 poll_listen(piperead, POLLIN);
Simon Kelley16972692006-10-16 20:04:18 +01001085
Simon Kelley33702ab2015-12-28 23:17:15 +00001086#ifdef HAVE_SCRIPT
Simon Kelley53a91732016-01-06 17:59:13 +00001087# ifdef HAVE_DHCP
Simon Kelley33702ab2015-12-28 23:17:15 +00001088 while (helper_buf_empty() && do_script_run(now));
Simon Kelley53a91732016-01-06 17:59:13 +00001089# endif
1090
Simon Kelley1e505122016-01-25 21:29:23 +00001091 /* Refresh cache */
1092 if (option_bool(OPT_SCRIPT_ARP))
1093 find_mac(NULL, NULL, 0, now);
Simon Kelley33702ab2015-12-28 23:17:15 +00001094 while (helper_buf_empty() && do_arp_script_run());
Simon Kelley16972692006-10-16 20:04:18 +01001095
Simon Kelleya9530962012-03-20 22:07:35 +00001096# ifdef HAVE_TFTP
1097 while (helper_buf_empty() && do_tftp_script_run());
1098# endif
1099
Simon Kelley16972692006-10-16 20:04:18 +01001100 if (!helper_buf_empty())
Simon Kelleyb842bc92015-07-12 21:09:11 +01001101 poll_listen(daemon->helperfd, POLLOUT);
Simon Kelley33702ab2015-12-28 23:17:15 +00001102#else
Simon Kelley5aabfc72007-08-29 11:24:47 +01001103 /* need this for other side-effects */
Simon Kelley53a91732016-01-06 17:59:13 +00001104# ifdef HAVE_DHCP
Simon Kelley5aabfc72007-08-29 11:24:47 +01001105 while (do_script_run(now));
Simon Kelley53a91732016-01-06 17:59:13 +00001106# endif
1107
Simon Kelleyb633de92016-01-06 22:51:17 +00001108 while (do_arp_script_run());
Simon Kelleya9530962012-03-20 22:07:35 +00001109
1110# ifdef HAVE_TFTP
1111 while (do_tftp_script_run());
1112# endif
1113
Simon Kelley5aabfc72007-08-29 11:24:47 +01001114#endif
Simon Kelley33702ab2015-12-28 23:17:15 +00001115
Simon Kelley7622fc02009-06-04 20:32:05 +01001116
Simon Kelley66f62652020-01-05 16:21:24 +00001117 /* must do this just before do_poll(), when we know no
Simon Kelleyf2621c72007-04-29 19:47:21 +01001118 more calls to my_syslog() can occur */
Simon Kelleyb842bc92015-07-12 21:09:11 +01001119 set_log_writer();
Simon Kelleyf2621c72007-04-29 19:47:21 +01001120
Simon Kelleyb842bc92015-07-12 21:09:11 +01001121 if (do_poll(timeout) < 0)
1122 continue;
1123
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001124 now = dnsmasq_time();
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001125
Simon Kelleyb842bc92015-07-12 21:09:11 +01001126 check_log_writer(0);
Simon Kelley115ac3e2013-05-20 11:28:32 +01001127
1128 /* prime. */
1129 enumerate_interfaces(1);
1130
Simon Kelley74c95c22011-10-19 09:33:39 +01001131 /* Check the interfaces to see if any have exited DAD state
1132 and if so, bind the address. */
1133 if (is_dad_listeners())
1134 {
Simon Kelley115ac3e2013-05-20 11:28:32 +01001135 enumerate_interfaces(0);
Simon Kelley74c95c22011-10-19 09:33:39 +01001136 /* NB, is_dad_listeners() == 1 --> we're binding interfaces */
1137 create_bound_listeners(0);
Simon Kelleydc27e142013-10-16 13:09:53 +01001138 warn_bound_listeners();
Simon Kelley74c95c22011-10-19 09:33:39 +01001139 }
Simon Kelleyf2621c72007-04-29 19:47:21 +01001140
Simon Kelley1ee9be42013-12-09 16:50:19 +00001141#if defined(HAVE_LINUX_NETWORK)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001142 if (poll_check(daemon->netlinkfd, POLLIN))
Simon Kelleya0358e52014-06-07 13:38:48 +01001143 netlink_multicast();
Simon Kelley1ee9be42013-12-09 16:50:19 +00001144#elif defined(HAVE_BSD_NETWORK)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001145 if (poll_check(daemon->routefd, POLLIN))
Simon Kelleya0358e52014-06-07 13:38:48 +01001146 route_sock();
Simon Kelleyc52e1892010-06-07 22:01:39 +01001147#endif
1148
Simon Kelley04918052015-01-26 11:23:43 +00001149#ifdef HAVE_INOTIFY
Simon Kelleyb842bc92015-07-12 21:09:11 +01001150 if (daemon->inotifyfd != -1 && poll_check(daemon->inotifyfd, POLLIN) && inotify_check(now))
Simon Kelley5f4dc5c2015-01-20 20:51:02 +00001151 {
1152 if (daemon->port != 0 && !option_bool(OPT_NO_POLL))
1153 poll_resolv(1, 1, now);
1154 }
Simon Kelley193de4a2014-12-10 17:32:16 +00001155#else
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001156 /* Check for changes to resolv files once per second max. */
Simon Kelley3d8df262005-08-29 12:19:27 +01001157 /* Don't go silent for long periods if the clock goes backwards. */
Simon Kelley9009d742008-11-14 20:04:27 +00001158 if (daemon->last_resolv == 0 ||
1159 difftime(now, daemon->last_resolv) > 1.0 ||
1160 difftime(now, daemon->last_resolv) < -1.0)
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001161 {
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001162 /* poll_resolv doesn't need to reload first time through, since
1163 that's queued anyway. */
Simon Kelley33820b72004-04-03 21:10:00 +01001164
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001165 poll_resolv(0, daemon->last_resolv != 0, now);
1166 daemon->last_resolv = now;
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001167 }
Simon Kelley193de4a2014-12-10 17:32:16 +00001168#endif
1169
Simon Kelleyb842bc92015-07-12 21:09:11 +01001170 if (poll_check(piperead, POLLIN))
Simon Kelley5aabfc72007-08-29 11:24:47 +01001171 async_event(piperead, now);
Simon Kelley7cebd202006-05-06 14:13:33 +01001172
Simon Kelley3d8df262005-08-29 12:19:27 +01001173#ifdef HAVE_DBUS
1174 /* if we didn't create a DBus connection, retry now. */
Simon Kelley28866e92011-02-14 20:19:14 +00001175 if (option_bool(OPT_DBUS) && !daemon->dbus)
Simon Kelley3d8df262005-08-29 12:19:27 +01001176 {
1177 char *err;
Simon Kelley5aabfc72007-08-29 11:24:47 +01001178 if ((err = dbus_init()))
Simon Kelleyf2621c72007-04-29 19:47:21 +01001179 my_syslog(LOG_WARNING, _("DBus error: %s"), err);
Simon Kelley3d8df262005-08-29 12:19:27 +01001180 if (daemon->dbus)
Simon Kelleyf2621c72007-04-29 19:47:21 +01001181 my_syslog(LOG_INFO, _("connected to system DBus"));
Simon Kelley3d8df262005-08-29 12:19:27 +01001182 }
Simon Kelleyb842bc92015-07-12 21:09:11 +01001183 check_dbus_listeners();
Simon Kelley3d8df262005-08-29 12:19:27 +01001184#endif
Julian Kornbergercaf4d572018-07-21 21:45:03 +01001185
1186#ifdef HAVE_UBUS
Kevin Darbyshire-Bryant9d6fd172018-07-28 13:26:39 +01001187 if (option_bool(OPT_UBUS))
Jan Willem Janssena2b82202019-03-25 12:42:23 +01001188 {
1189 /* if we didn't create a UBus connection, retry now. */
1190 if (!daemon->ubus)
1191 {
1192 ubus_init();
1193 }
1194
1195 check_ubus_listeners();
1196 }
Julian Kornbergercaf4d572018-07-21 21:45:03 +01001197#endif
1198
Simon Kelleyb842bc92015-07-12 21:09:11 +01001199 check_dns_listeners(now);
Simon Kelley832af0b2007-01-21 20:01:28 +00001200
1201#ifdef HAVE_TFTP
Simon Kelleyb842bc92015-07-12 21:09:11 +01001202 check_tftp_listeners(now);
Simon Kelley832af0b2007-01-21 20:01:28 +00001203#endif
1204
Simon Kelley7622fc02009-06-04 20:32:05 +01001205#ifdef HAVE_DHCP
Simon Kelleyff7eea22013-09-04 18:01:38 +01001206 if (daemon->dhcp || daemon->relay4)
Simon Kelley316e2732010-01-22 20:16:09 +00001207 {
Simon Kelleyb842bc92015-07-12 21:09:11 +01001208 if (poll_check(daemon->dhcpfd, POLLIN))
Simon Kelley316e2732010-01-22 20:16:09 +00001209 dhcp_packet(now, 0);
Simon Kelleyb842bc92015-07-12 21:09:11 +01001210 if (daemon->pxefd != -1 && poll_check(daemon->pxefd, POLLIN))
Simon Kelley316e2732010-01-22 20:16:09 +00001211 dhcp_packet(now, 1);
1212 }
Simon Kelley16972692006-10-16 20:04:18 +01001213
Simon Kelley52b92f42012-01-22 16:05:15 +00001214#ifdef HAVE_DHCP6
Simon Kelleyb842bc92015-07-12 21:09:11 +01001215 if ((daemon->doing_dhcp6 || daemon->relay6) && poll_check(daemon->dhcp6fd, POLLIN))
Simon Kelley18c63ef2012-05-21 14:34:15 +01001216 dhcp6_packet(now);
Simon Kelleyc5ad4e72012-02-24 16:06:20 +00001217
Simon Kelleyb842bc92015-07-12 21:09:11 +01001218 if (daemon->doing_ra && poll_check(daemon->icmp6fd, POLLIN))
Simon Kelley1f776932012-12-16 19:46:08 +00001219 icmp6_packet(now);
Simon Kelley52b92f42012-01-22 16:05:15 +00001220#endif
1221
Simon Kelley1f15b812009-10-13 17:49:32 +01001222# ifdef HAVE_SCRIPT
Simon Kelley63ec5d12015-07-30 20:59:07 +01001223 if (daemon->helperfd != -1 && poll_check(daemon->helperfd, POLLOUT))
Simon Kelley5aabfc72007-08-29 11:24:47 +01001224 helper_write();
Simon Kelley7622fc02009-06-04 20:32:05 +01001225# endif
Simon Kelley5aabfc72007-08-29 11:24:47 +01001226#endif
1227
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001228 }
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001229}
1230
Simon Kelley3be34542004-09-11 19:12:13 +01001231static void sig_handler(int sig)
1232{
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001233 if (pid == 0)
1234 {
Simon Kelley16972692006-10-16 20:04:18 +01001235 /* ignore anything other than TERM during startup
1236 and in helper proc. (helper ignore TERM too) */
Simon Kelley3c973ad2018-01-14 21:05:37 +00001237 if (sig == SIGTERM || sig == SIGINT)
Simon Kelley5aabfc72007-08-29 11:24:47 +01001238 exit(EC_MISC);
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001239 }
Simon Kelley5aabfc72007-08-29 11:24:47 +01001240 else if (pid != getpid())
Simon Kelley3be34542004-09-11 19:12:13 +01001241 {
Simon Kelley16972692006-10-16 20:04:18 +01001242 /* alarm is used to kill TCP children after a fixed time. */
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001243 if (sig == SIGALRM)
Simon Kelley7cebd202006-05-06 14:13:33 +01001244 _exit(0);
Simon Kelley3be34542004-09-11 19:12:13 +01001245 }
Simon Kelley5aabfc72007-08-29 11:24:47 +01001246 else
1247 {
1248 /* master process */
1249 int event, errsave = errno;
1250
1251 if (sig == SIGHUP)
1252 event = EVENT_RELOAD;
1253 else if (sig == SIGCHLD)
1254 event = EVENT_CHILD;
1255 else if (sig == SIGALRM)
1256 event = EVENT_ALARM;
1257 else if (sig == SIGTERM)
1258 event = EVENT_TERM;
1259 else if (sig == SIGUSR1)
1260 event = EVENT_DUMP;
1261 else if (sig == SIGUSR2)
1262 event = EVENT_REOPEN;
Simon Kelley3c973ad2018-01-14 21:05:37 +00001263 else if (sig == SIGINT)
1264 {
1265 /* Handle SIGINT normally in debug mode, so
1266 ctrl-c continues to operate. */
1267 if (option_bool(OPT_DEBUG))
1268 exit(EC_MISC);
1269 else
1270 event = EVENT_TIME;
1271 }
Simon Kelley5aabfc72007-08-29 11:24:47 +01001272 else
1273 return;
1274
Simon Kelleyc72daea2012-01-05 21:33:27 +00001275 send_event(pipewrite, event, 0, NULL);
Simon Kelley5aabfc72007-08-29 11:24:47 +01001276 errno = errsave;
1277 }
Simon Kelley3be34542004-09-11 19:12:13 +01001278}
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001279
Simon Kelley353ae4d2012-03-19 20:07:51 +00001280/* now == 0 -> queue immediate callback */
1281void send_alarm(time_t event, time_t now)
Simon Kelley741c2952012-02-25 13:09:18 +00001282{
Simon Kelley884a6df2012-03-20 16:20:22 +00001283 if (now == 0 || event != 0)
Simon Kelley353ae4d2012-03-19 20:07:51 +00001284 {
Simon Kelley884a6df2012-03-20 16:20:22 +00001285 /* alarm(0) or alarm(-ve) doesn't do what we want.... */
1286 if ((now == 0 || difftime(event, now) <= 0.0))
1287 send_event(pipewrite, EVENT_ALARM, 0, NULL);
1288 else
1289 alarm((unsigned)difftime(event, now));
Simon Kelley353ae4d2012-03-19 20:07:51 +00001290 }
Simon Kelley741c2952012-02-25 13:09:18 +00001291}
1292
Simon Kelley47a95162014-07-08 22:22:02 +01001293void queue_event(int event)
Simon Kelleya0358e52014-06-07 13:38:48 +01001294{
Simon Kelley47a95162014-07-08 22:22:02 +01001295 send_event(pipewrite, event, 0, NULL);
Simon Kelleya0358e52014-06-07 13:38:48 +01001296}
1297
Simon Kelleyc72daea2012-01-05 21:33:27 +00001298void send_event(int fd, int event, int data, char *msg)
Simon Kelley5aabfc72007-08-29 11:24:47 +01001299{
1300 struct event_desc ev;
Simon Kelleyc72daea2012-01-05 21:33:27 +00001301 struct iovec iov[2];
1302
Simon Kelley5aabfc72007-08-29 11:24:47 +01001303 ev.event = event;
1304 ev.data = data;
Simon Kelleyc72daea2012-01-05 21:33:27 +00001305 ev.msg_sz = msg ? strlen(msg) : 0;
1306
1307 iov[0].iov_base = &ev;
1308 iov[0].iov_len = sizeof(ev);
1309 iov[1].iov_base = msg;
1310 iov[1].iov_len = ev.msg_sz;
Simon Kelley1a6bca82008-07-11 11:11:42 +01001311
1312 /* error pipe, debug mode. */
1313 if (fd == -1)
Simon Kelleyc72daea2012-01-05 21:33:27 +00001314 fatal_event(&ev, msg);
Simon Kelley1a6bca82008-07-11 11:11:42 +01001315 else
1316 /* pipe is non-blocking and struct event_desc is smaller than
1317 PIPE_BUF, so this either fails or writes everything */
Simon Kelleyc72daea2012-01-05 21:33:27 +00001318 while (writev(fd, iov, msg ? 2 : 1) == -1 && errno == EINTR);
Simon Kelley5aabfc72007-08-29 11:24:47 +01001319}
Simon Kelley3d8df262005-08-29 12:19:27 +01001320
Simon Kelleyc72daea2012-01-05 21:33:27 +00001321/* NOTE: the memory used to return msg is leaked: use msgs in events only
1322 to describe fatal errors. */
1323static int read_event(int fd, struct event_desc *evp, char **msg)
1324{
1325 char *buf;
1326
1327 if (!read_write(fd, (unsigned char *)evp, sizeof(struct event_desc), 1))
1328 return 0;
1329
1330 *msg = NULL;
1331
1332 if (evp->msg_sz != 0 &&
1333 (buf = malloc(evp->msg_sz + 1)) &&
1334 read_write(fd, (unsigned char *)buf, evp->msg_sz, 1))
1335 {
1336 buf[evp->msg_sz] = 0;
1337 *msg = buf;
1338 }
1339
1340 return 1;
1341}
1342
1343static void fatal_event(struct event_desc *ev, char *msg)
Simon Kelley1a6bca82008-07-11 11:11:42 +01001344{
1345 errno = ev->data;
1346
1347 switch (ev->event)
1348 {
1349 case EVENT_DIE:
1350 exit(0);
Simon Kelley7622fc02009-06-04 20:32:05 +01001351
1352 case EVENT_FORK_ERR:
1353 die(_("cannot fork into background: %s"), NULL, EC_MISC);
Simon Kelleye7a4af82018-02-16 21:27:35 +00001354
1355 /* fall through */
Simon Kelley1a6bca82008-07-11 11:11:42 +01001356 case EVENT_PIPE_ERR:
1357 die(_("failed to create helper: %s"), NULL, EC_MISC);
Simon Kelleye7a4af82018-02-16 21:27:35 +00001358
1359 /* fall through */
Simon Kelley1a6bca82008-07-11 11:11:42 +01001360 case EVENT_CAP_ERR:
1361 die(_("setting capabilities failed: %s"), NULL, EC_MISC);
1362
Simon Kelleye7a4af82018-02-16 21:27:35 +00001363 /* fall through */
Simon Kelley1a6bca82008-07-11 11:11:42 +01001364 case EVENT_USER_ERR:
Simon Kelleyc72daea2012-01-05 21:33:27 +00001365 die(_("failed to change user-id to %s: %s"), msg, EC_MISC);
Simon Kelley1a6bca82008-07-11 11:11:42 +01001366
Simon Kelleye7a4af82018-02-16 21:27:35 +00001367 /* fall through */
Simon Kelley1a6bca82008-07-11 11:11:42 +01001368 case EVENT_GROUP_ERR:
Simon Kelleyc72daea2012-01-05 21:33:27 +00001369 die(_("failed to change group-id to %s: %s"), msg, EC_MISC);
Simon Kelleye7a4af82018-02-16 21:27:35 +00001370
1371 /* fall through */
Simon Kelley1a6bca82008-07-11 11:11:42 +01001372 case EVENT_PIDFILE:
Simon Kelleyc72daea2012-01-05 21:33:27 +00001373 die(_("failed to open pidfile %s: %s"), msg, EC_FILE);
Simon Kelley1a6bca82008-07-11 11:11:42 +01001374
Simon Kelleye7a4af82018-02-16 21:27:35 +00001375 /* fall through */
Simon Kelley1a6bca82008-07-11 11:11:42 +01001376 case EVENT_LOG_ERR:
Simon Kelleyc72daea2012-01-05 21:33:27 +00001377 die(_("cannot open log %s: %s"), msg, EC_FILE);
Simon Kelleye7a4af82018-02-16 21:27:35 +00001378
1379 /* fall through */
Simon Kelleyc72daea2012-01-05 21:33:27 +00001380 case EVENT_LUA_ERR:
1381 die(_("failed to load Lua script: %s"), msg, EC_MISC);
Simon Kelley8b3ae2f2012-06-13 13:43:49 +01001382
Simon Kelleye7a4af82018-02-16 21:27:35 +00001383 /* fall through */
Simon Kelley8b3ae2f2012-06-13 13:43:49 +01001384 case EVENT_TFTP_ERR:
1385 die(_("TFTP directory %s inaccessible: %s"), msg, EC_FILE);
Simon Kelleye7a4af82018-02-16 21:27:35 +00001386
1387 /* fall through */
Simon Kelley360f2512015-03-07 18:28:06 +00001388 case EVENT_TIME_ERR:
1389 die(_("cannot create timestamp file %s: %s" ), msg, EC_BADCONF);
Simon Kelley1a6bca82008-07-11 11:11:42 +01001390 }
1391}
1392
Simon Kelley5aabfc72007-08-29 11:24:47 +01001393static void async_event(int pipe, time_t now)
1394{
1395 pid_t p;
1396 struct event_desc ev;
Simon Kelley7b1eae42014-02-20 13:43:28 +00001397 int i, check = 0;
Simon Kelleyc72daea2012-01-05 21:33:27 +00001398 char *msg;
1399
1400 /* NOTE: the memory used to return msg is leaked: use msgs in events only
1401 to describe fatal errors. */
1402
1403 if (read_event(pipe, &ev, &msg))
Simon Kelley5aabfc72007-08-29 11:24:47 +01001404 switch (ev.event)
1405 {
1406 case EVENT_RELOAD:
Simon Kelleyc8328ec2016-08-05 16:54:58 +01001407 daemon->soa_sn++; /* Bump zone serial, as it may have changed. */
Simon Kelley3c973ad2018-01-14 21:05:37 +00001408
Simon Kelleye98bd522014-03-28 20:41:23 +00001409 /* fall through */
1410
1411 case EVENT_INIT:
Simon Kelley5aabfc72007-08-29 11:24:47 +01001412 clear_cache_and_reload(now);
Simon Kelleye98bd522014-03-28 20:41:23 +00001413
Simon Kelley7b1eae42014-02-20 13:43:28 +00001414 if (daemon->port != 0)
Simon Kelley5aabfc72007-08-29 11:24:47 +01001415 {
Simon Kelley7b1eae42014-02-20 13:43:28 +00001416 if (daemon->resolv_files && option_bool(OPT_NO_POLL))
1417 {
1418 reload_servers(daemon->resolv_files->name);
1419 check = 1;
1420 }
1421
1422 if (daemon->servers_file)
1423 {
1424 read_servers_file();
1425 check = 1;
1426 }
1427
1428 if (check)
1429 check_servers();
Simon Kelley5aabfc72007-08-29 11:24:47 +01001430 }
Simon Kelley7b1eae42014-02-20 13:43:28 +00001431
Simon Kelley7622fc02009-06-04 20:32:05 +01001432#ifdef HAVE_DHCP
Simon Kelley5aabfc72007-08-29 11:24:47 +01001433 rerun_scripts();
Simon Kelley7622fc02009-06-04 20:32:05 +01001434#endif
Simon Kelley5aabfc72007-08-29 11:24:47 +01001435 break;
1436
1437 case EVENT_DUMP:
Simon Kelley824af852008-02-12 20:43:05 +00001438 if (daemon->port != 0)
1439 dump_cache(now);
Simon Kelley5aabfc72007-08-29 11:24:47 +01001440 break;
1441
1442 case EVENT_ALARM:
Simon Kelley7622fc02009-06-04 20:32:05 +01001443#ifdef HAVE_DHCP
Simon Kelley1f776932012-12-16 19:46:08 +00001444 if (daemon->dhcp || daemon->doing_dhcp6)
Simon Kelley5aabfc72007-08-29 11:24:47 +01001445 {
1446 lease_prune(NULL, now);
1447 lease_update_file(now);
1448 }
Simon Kelley843c96b2012-02-27 17:42:38 +00001449#ifdef HAVE_DHCP6
Simon Kelley1f776932012-12-16 19:46:08 +00001450 else if (daemon->doing_ra)
Simon Kelley353ae4d2012-03-19 20:07:51 +00001451 /* Not doing DHCP, so no lease system, manage alarms for ra only */
1452 send_alarm(periodic_ra(now), now);
Simon Kelley843c96b2012-02-27 17:42:38 +00001453#endif
Simon Kelley7622fc02009-06-04 20:32:05 +01001454#endif
Simon Kelley5aabfc72007-08-29 11:24:47 +01001455 break;
1456
1457 case EVENT_CHILD:
1458 /* See Stevens 5.10 */
1459 while ((p = waitpid(-1, NULL, WNOHANG)) != 0)
1460 if (p == -1)
1461 {
1462 if (errno != EINTR)
1463 break;
1464 }
1465 else
1466 for (i = 0 ; i < MAX_PROCS; i++)
1467 if (daemon->tcp_pids[i] == p)
1468 daemon->tcp_pids[i] = 0;
1469 break;
1470
Petr Menšíkc77fb9d2017-04-16 20:20:08 +01001471#if defined(HAVE_SCRIPT)
Simon Kelley5aabfc72007-08-29 11:24:47 +01001472 case EVENT_KILLED:
Simon Kelleyc72daea2012-01-05 21:33:27 +00001473 my_syslog(LOG_WARNING, _("script process killed by signal %d"), ev.data);
Simon Kelley5aabfc72007-08-29 11:24:47 +01001474 break;
1475
1476 case EVENT_EXITED:
Simon Kelleyc72daea2012-01-05 21:33:27 +00001477 my_syslog(LOG_WARNING, _("script process exited with status %d"), ev.data);
Simon Kelley5aabfc72007-08-29 11:24:47 +01001478 break;
1479
1480 case EVENT_EXEC_ERR:
Simon Kelley9e038942008-05-30 20:06:34 +01001481 my_syslog(LOG_ERR, _("failed to execute %s: %s"),
1482 daemon->lease_change_command, strerror(ev.data));
Simon Kelley5aabfc72007-08-29 11:24:47 +01001483 break;
1484
Petr Menšíkc77fb9d2017-04-16 20:20:08 +01001485 case EVENT_SCRIPT_LOG:
1486 my_syslog(MS_SCRIPT | LOG_DEBUG, "%s", msg ? msg : "");
1487 free(msg);
1488 msg = NULL;
1489 break;
1490
Simon Kelley1a6bca82008-07-11 11:11:42 +01001491 /* necessary for fatal errors in helper */
Simon Kelleyc72daea2012-01-05 21:33:27 +00001492 case EVENT_USER_ERR:
Simon Kelley1a6bca82008-07-11 11:11:42 +01001493 case EVENT_DIE:
Simon Kelleyc72daea2012-01-05 21:33:27 +00001494 case EVENT_LUA_ERR:
1495 fatal_event(&ev, msg);
Simon Kelley9e038942008-05-30 20:06:34 +01001496 break;
Petr Menšíkc77fb9d2017-04-16 20:20:08 +01001497#endif
Simon Kelley9e038942008-05-30 20:06:34 +01001498
Simon Kelley5aabfc72007-08-29 11:24:47 +01001499 case EVENT_REOPEN:
1500 /* Note: this may leave TCP-handling processes with the old file still open.
1501 Since any such process will die in CHILD_LIFETIME or probably much sooner,
1502 we leave them logging to the old file. */
1503 if (daemon->log_file != NULL)
1504 log_reopen(daemon->log_file);
1505 break;
Simon Kelleya0358e52014-06-07 13:38:48 +01001506
1507 case EVENT_NEWADDR:
1508 newaddress(now);
1509 break;
Simon Kelley47a95162014-07-08 22:22:02 +01001510
1511 case EVENT_NEWROUTE:
1512 resend_query();
1513 /* Force re-reading resolv file right now, for luck. */
1514 poll_resolv(0, 1, now);
1515 break;
1516
Simon Kelley3c973ad2018-01-14 21:05:37 +00001517 case EVENT_TIME:
1518#ifdef HAVE_DNSSEC
1519 if (daemon->dnssec_no_time_check && option_bool(OPT_DNSSEC_VALID) && option_bool(OPT_DNSSEC_TIME))
1520 {
1521 my_syslog(LOG_INFO, _("now checking DNSSEC signature timestamps"));
1522 daemon->dnssec_no_time_check = 0;
1523 clear_cache_and_reload(now);
1524 }
1525#endif
1526 break;
1527
Simon Kelley5aabfc72007-08-29 11:24:47 +01001528 case EVENT_TERM:
1529 /* Knock all our children on the head. */
1530 for (i = 0; i < MAX_PROCS; i++)
1531 if (daemon->tcp_pids[i] != 0)
1532 kill(daemon->tcp_pids[i], SIGALRM);
1533
Simon Kelley53a91732016-01-06 17:59:13 +00001534#if defined(HAVE_SCRIPT) && defined(HAVE_DHCP)
Simon Kelley5aabfc72007-08-29 11:24:47 +01001535 /* handle pending lease transitions */
1536 if (daemon->helperfd != -1)
1537 {
1538 /* block in writes until all done */
1539 if ((i = fcntl(daemon->helperfd, F_GETFL)) != -1)
1540 fcntl(daemon->helperfd, F_SETFL, i & ~O_NONBLOCK);
1541 do {
1542 helper_write();
1543 } while (!helper_buf_empty() || do_script_run(now));
Simon Kelley5fc639c2019-03-29 21:29:43 +00001544 close(daemon->helperfd);
Simon Kelley5aabfc72007-08-29 11:24:47 +01001545 }
1546#endif
1547
1548 if (daemon->lease_stream)
1549 fclose(daemon->lease_stream);
Simon Kelley73a08a22009-02-05 20:28:08 +00001550
Kevin Darbyshire-Bryant34b5d192015-07-27 19:34:23 +01001551#ifdef HAVE_DNSSEC
1552 /* update timestamp file on TERM if time is considered valid */
1553 if (daemon->back_to_the_future)
1554 {
Vladislav Grishenko4583dd92017-05-03 23:16:51 +01001555 if (utimes(daemon->timestamp_file, NULL) == -1)
Kevin Darbyshire-Bryant34b5d192015-07-27 19:34:23 +01001556 my_syslog(LOG_ERR, _("failed to update mtime on %s: %s"), daemon->timestamp_file, strerror(errno));
1557 }
1558#endif
1559
Simon Kelley73a08a22009-02-05 20:28:08 +00001560 if (daemon->runfile)
1561 unlink(daemon->runfile);
Simon Kelley6b173352018-05-08 18:32:14 +01001562
1563#ifdef HAVE_DUMPFILE
1564 if (daemon->dumpfd != -1)
1565 close(daemon->dumpfd);
1566#endif
Simon Kelley5aabfc72007-08-29 11:24:47 +01001567
1568 my_syslog(LOG_INFO, _("exiting on receipt of SIGTERM"));
1569 flush_log();
1570 exit(EC_GOOD);
1571 }
1572}
1573
Simon Kelley47a95162014-07-08 22:22:02 +01001574static void poll_resolv(int force, int do_reload, time_t now)
Simon Kelley5aabfc72007-08-29 11:24:47 +01001575{
1576 struct resolvc *res, *latest;
1577 struct stat statbuf;
1578 time_t last_change = 0;
1579 /* There may be more than one possible file.
1580 Go through and find the one which changed _last_.
1581 Warn of any which can't be read. */
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001582
Simon Kelley28866e92011-02-14 20:19:14 +00001583 if (daemon->port == 0 || option_bool(OPT_NO_POLL))
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001584 return;
1585
Simon Kelley5aabfc72007-08-29 11:24:47 +01001586 for (latest = NULL, res = daemon->resolv_files; res; res = res->next)
1587 if (stat(res->name, &statbuf) == -1)
1588 {
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001589 if (force)
1590 {
1591 res->mtime = 0;
1592 continue;
1593 }
1594
Simon Kelley5aabfc72007-08-29 11:24:47 +01001595 if (!res->logged)
1596 my_syslog(LOG_WARNING, _("failed to access %s: %s"), res->name, strerror(errno));
1597 res->logged = 1;
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001598
1599 if (res->mtime != 0)
1600 {
1601 /* existing file evaporated, force selection of the latest
1602 file even if its mtime hasn't changed since we last looked */
1603 poll_resolv(1, do_reload, now);
1604 return;
1605 }
Simon Kelley5aabfc72007-08-29 11:24:47 +01001606 }
1607 else
1608 {
1609 res->logged = 0;
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001610 if (force || (statbuf.st_mtime != res->mtime))
1611 {
1612 res->mtime = statbuf.st_mtime;
Simon Kelley5aabfc72007-08-29 11:24:47 +01001613 if (difftime(statbuf.st_mtime, last_change) > 0.0)
1614 {
1615 last_change = statbuf.st_mtime;
1616 latest = res;
1617 }
1618 }
1619 }
1620
1621 if (latest)
1622 {
1623 static int warned = 0;
1624 if (reload_servers(latest->name))
1625 {
1626 my_syslog(LOG_INFO, _("reading %s"), latest->name);
1627 warned = 0;
1628 check_servers();
Simon Kelley28866e92011-02-14 20:19:14 +00001629 if (option_bool(OPT_RELOAD) && do_reload)
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001630 clear_cache_and_reload(now);
Simon Kelley5aabfc72007-08-29 11:24:47 +01001631 }
1632 else
1633 {
1634 latest->mtime = 0;
1635 if (!warned)
1636 {
1637 my_syslog(LOG_WARNING, _("no servers found in %s, will retry"), latest->name);
1638 warned = 1;
1639 }
1640 }
1641 }
1642}
1643
1644void clear_cache_and_reload(time_t now)
Simon Kelley3d8df262005-08-29 12:19:27 +01001645{
Vladislav Grishenko408c3682013-09-24 16:18:49 +01001646 (void)now;
1647
Simon Kelley824af852008-02-12 20:43:05 +00001648 if (daemon->port != 0)
Simon Kelley7622fc02009-06-04 20:32:05 +01001649 cache_reload();
Simon Kelley824af852008-02-12 20:43:05 +00001650
Simon Kelley7622fc02009-06-04 20:32:05 +01001651#ifdef HAVE_DHCP
Simon Kelley1f776932012-12-16 19:46:08 +00001652 if (daemon->dhcp || daemon->doing_dhcp6)
Simon Kelley3d8df262005-08-29 12:19:27 +01001653 {
Simon Kelley28866e92011-02-14 20:19:14 +00001654 if (option_bool(OPT_ETHERS))
Simon Kelley5aabfc72007-08-29 11:24:47 +01001655 dhcp_read_ethers();
Simon Kelley824af852008-02-12 20:43:05 +00001656 reread_dhcp();
Simon Kelley3d8df262005-08-29 12:19:27 +01001657 dhcp_update_configs(daemon->dhcp_conf);
Simon Kelley5aabfc72007-08-29 11:24:47 +01001658 lease_update_from_configs();
1659 lease_update_file(now);
Simon Kelley353ae4d2012-03-19 20:07:51 +00001660 lease_update_dns(1);
Simon Kelley3d8df262005-08-29 12:19:27 +01001661 }
Simon Kelley843c96b2012-02-27 17:42:38 +00001662#ifdef HAVE_DHCP6
Simon Kelley1f776932012-12-16 19:46:08 +00001663 else if (daemon->doing_ra)
Simon Kelley2021c662012-05-07 16:43:21 +01001664 /* Not doing DHCP, so no lease system, manage
1665 alarms for ra only */
1666 send_alarm(periodic_ra(now), now);
Simon Kelley843c96b2012-02-27 17:42:38 +00001667#endif
Simon Kelley7622fc02009-06-04 20:32:05 +01001668#endif
Simon Kelley3d8df262005-08-29 12:19:27 +01001669}
1670
Simon Kelleyb842bc92015-07-12 21:09:11 +01001671static int set_dns_listeners(time_t now)
Simon Kelley3be34542004-09-11 19:12:13 +01001672{
1673 struct serverfd *serverfdp;
1674 struct listener *listener;
Simon Kelley824af852008-02-12 20:43:05 +00001675 int wait = 0, i;
Simon Kelley832af0b2007-01-21 20:01:28 +00001676
1677#ifdef HAVE_TFTP
1678 int tftp = 0;
1679 struct tftp_transfer *transfer;
Simon Kelley66f62652020-01-05 16:21:24 +00001680 if (!option_bool(OPT_SINGLE_PORT))
1681 for (transfer = daemon->tftp_trans; transfer; transfer = transfer->next)
1682 {
1683 tftp++;
1684 poll_listen(transfer->sockfd, POLLIN);
1685 }
Simon Kelley832af0b2007-01-21 20:01:28 +00001686#endif
1687
Simon Kelley16972692006-10-16 20:04:18 +01001688 /* will we be able to get memory? */
Simon Kelley824af852008-02-12 20:43:05 +00001689 if (daemon->port != 0)
Simon Kelley8caf3d72020-04-04 17:00:32 +01001690 get_new_frec(now, &wait, NULL);
Simon Kelley16972692006-10-16 20:04:18 +01001691
Simon Kelley3be34542004-09-11 19:12:13 +01001692 for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001693 poll_listen(serverfdp->fd, POLLIN);
Simon Kelleyf6d69562015-07-08 22:38:13 +01001694
Simon Kelley1a6bca82008-07-11 11:11:42 +01001695 if (daemon->port != 0 && !daemon->osport)
1696 for (i = 0; i < RANDOM_SOCKS; i++)
1697 if (daemon->randomsocks[i].refcount != 0)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001698 poll_listen(daemon->randomsocks[i].fd, POLLIN);
Simon Kelleyf6d69562015-07-08 22:38:13 +01001699
Simon Kelley3be34542004-09-11 19:12:13 +01001700 for (listener = daemon->listeners; listener; listener = listener->next)
1701 {
Simon Kelley16972692006-10-16 20:04:18 +01001702 /* only listen for queries if we have resources */
Simon Kelley824af852008-02-12 20:43:05 +00001703 if (listener->fd != -1 && wait == 0)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001704 poll_listen(listener->fd, POLLIN);
Simon Kelleyf6d69562015-07-08 22:38:13 +01001705
Simon Kelley16972692006-10-16 20:04:18 +01001706 /* death of a child goes through the select loop, so
1707 we don't need to explicitly arrange to wake up here */
Simon Kelley824af852008-02-12 20:43:05 +00001708 if (listener->tcpfd != -1)
1709 for (i = 0; i < MAX_PROCS; i++)
Simon Kelleya799ca02018-10-18 19:35:29 +01001710 if (daemon->tcp_pids[i] == 0 && daemon->tcp_pipes[i] == -1)
Simon Kelley824af852008-02-12 20:43:05 +00001711 {
Simon Kelleyb842bc92015-07-12 21:09:11 +01001712 poll_listen(listener->tcpfd, POLLIN);
Simon Kelley824af852008-02-12 20:43:05 +00001713 break;
1714 }
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001715
Simon Kelley832af0b2007-01-21 20:01:28 +00001716#ifdef HAVE_TFTP
Simon Kelley2ac4cf02020-01-06 23:39:33 +00001717 /* tftp == 0 in single-port mode. */
Simon Kelley832af0b2007-01-21 20:01:28 +00001718 if (tftp <= daemon->tftp_max && listener->tftpfd != -1)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001719 poll_listen(listener->tftpfd, POLLIN);
Simon Kelley832af0b2007-01-21 20:01:28 +00001720#endif
1721
1722 }
1723
Simon Kelleya799ca02018-10-18 19:35:29 +01001724 if (!option_bool(OPT_DEBUG))
1725 for (i = 0; i < MAX_PROCS; i++)
1726 if (daemon->tcp_pipes[i] != -1)
1727 poll_listen(daemon->tcp_pipes[i], POLLIN);
Simon Kelleya799ca02018-10-18 19:35:29 +01001728
Simon Kelley16972692006-10-16 20:04:18 +01001729 return wait;
Simon Kelley3be34542004-09-11 19:12:13 +01001730}
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001731
Simon Kelleyb842bc92015-07-12 21:09:11 +01001732static void check_dns_listeners(time_t now)
Simon Kelley3be34542004-09-11 19:12:13 +01001733{
1734 struct serverfd *serverfdp;
Simon Kelley1a6bca82008-07-11 11:11:42 +01001735 struct listener *listener;
1736 int i;
Simon Kelleya799ca02018-10-18 19:35:29 +01001737 int pipefd[2];
Simon Kelleya799ca02018-10-18 19:35:29 +01001738
Simon Kelley832af0b2007-01-21 20:01:28 +00001739 for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001740 if (poll_check(serverfdp->fd, POLLIN))
Simon Kelley1a6bca82008-07-11 11:11:42 +01001741 reply_query(serverfdp->fd, serverfdp->source_addr.sa.sa_family, now);
1742
1743 if (daemon->port != 0 && !daemon->osport)
1744 for (i = 0; i < RANDOM_SOCKS; i++)
1745 if (daemon->randomsocks[i].refcount != 0 &&
Simon Kelleyb842bc92015-07-12 21:09:11 +01001746 poll_check(daemon->randomsocks[i].fd, POLLIN))
Simon Kelley1a6bca82008-07-11 11:11:42 +01001747 reply_query(daemon->randomsocks[i].fd, daemon->randomsocks[i].family, now);
Simon Kelleya799ca02018-10-18 19:35:29 +01001748
Simon Kelleya799ca02018-10-18 19:35:29 +01001749 /* Races. The child process can die before we read all of the data from the
1750 pipe, or vice versa. Therefore send tcp_pids to zero when we wait() the
1751 process, and tcp_pipes to -1 and close the FD when we read the last
1752 of the data - indicated by cache_recv_insert returning zero.
1753 The order of these events is indeterminate, and both are needed
1754 to free the process slot. Once the child process has gone, poll()
1755 returns POLLHUP, not POLLIN, so have to check for both here. */
1756 if (!option_bool(OPT_DEBUG))
1757 for (i = 0; i < MAX_PROCS; i++)
1758 if (daemon->tcp_pipes[i] != -1 &&
1759 poll_check(daemon->tcp_pipes[i], POLLIN | POLLHUP) &&
1760 !cache_recv_insert(now, daemon->tcp_pipes[i]))
1761 {
1762 close(daemon->tcp_pipes[i]);
1763 daemon->tcp_pipes[i] = -1;
1764 }
Simon Kelleya799ca02018-10-18 19:35:29 +01001765
Simon Kelley832af0b2007-01-21 20:01:28 +00001766 for (listener = daemon->listeners; listener; listener = listener->next)
1767 {
Simon Kelleyb842bc92015-07-12 21:09:11 +01001768 if (listener->fd != -1 && poll_check(listener->fd, POLLIN))
Simon Kelley5aabfc72007-08-29 11:24:47 +01001769 receive_query(listener, now);
Simon Kelley1a6bca82008-07-11 11:11:42 +01001770
Simon Kelley832af0b2007-01-21 20:01:28 +00001771#ifdef HAVE_TFTP
Simon Kelleyb842bc92015-07-12 21:09:11 +01001772 if (listener->tftpfd != -1 && poll_check(listener->tftpfd, POLLIN))
Simon Kelley5aabfc72007-08-29 11:24:47 +01001773 tftp_request(listener, now);
Simon Kelley59353a62004-11-21 19:34:28 +00001774#endif
Simon Kelley832af0b2007-01-21 20:01:28 +00001775
Simon Kelleyb842bc92015-07-12 21:09:11 +01001776 if (listener->tcpfd != -1 && poll_check(listener->tcpfd, POLLIN))
Simon Kelley832af0b2007-01-21 20:01:28 +00001777 {
Simon Kelley22ce5502013-01-22 13:53:04 +00001778 int confd, client_ok = 1;
Simon Kelley832af0b2007-01-21 20:01:28 +00001779 struct irec *iface = NULL;
1780 pid_t p;
Simon Kelley52d4abf2012-03-21 21:39:48 +00001781 union mysockaddr tcp_addr;
1782 socklen_t tcp_len = sizeof(union mysockaddr);
1783
1784 while ((confd = accept(listener->tcpfd, NULL, NULL)) == -1 && errno == EINTR);
Simon Kelley832af0b2007-01-21 20:01:28 +00001785
Simon Kelley46b06652013-02-04 21:47:59 +00001786 if (confd == -1)
Simon Kelley832af0b2007-01-21 20:01:28 +00001787 continue;
Simon Kelley76dd75d2013-05-23 10:04:25 +01001788
Simon Kelley46b06652013-02-04 21:47:59 +00001789 if (getsockname(confd, (struct sockaddr *)&tcp_addr, &tcp_len) == -1)
1790 {
Simon Kelley5fc639c2019-03-29 21:29:43 +00001791 close(confd);
Simon Kelley46b06652013-02-04 21:47:59 +00001792 continue;
1793 }
Simon Kelley76dd75d2013-05-23 10:04:25 +01001794
1795 /* Make sure that the interface list is up-to-date.
1796
1797 We do this here as we may need the results below, and
1798 the DNS code needs them for --interface-name stuff.
Simon Kelley46b06652013-02-04 21:47:59 +00001799
Simon Kelley76dd75d2013-05-23 10:04:25 +01001800 Multiple calls to enumerate_interfaces() per select loop are
1801 inhibited, so calls to it in the child process (which doesn't select())
1802 have no effect. This avoids two processes reading from the same
1803 netlink fd and screwing the pooch entirely.
1804 */
Simon Kelleye25db1f2013-01-29 22:10:26 +00001805
Simon Kelley76dd75d2013-05-23 10:04:25 +01001806 enumerate_interfaces(0);
1807
1808 if (option_bool(OPT_NOWILD))
1809 iface = listener->iface; /* May be NULL */
1810 else
1811 {
1812 int if_index;
1813 char intr_name[IF_NAMESIZE];
1814
1815 /* if we can find the arrival interface, check it's one that's allowed */
1816 if ((if_index = tcp_interface(confd, tcp_addr.sa.sa_family)) != 0 &&
1817 indextoname(listener->tcpfd, if_index, intr_name))
1818 {
Simon Kelleycc921df2019-01-02 22:48:59 +00001819 union all_addr addr;
Simon Kelleyee875042018-10-23 22:10:17 +01001820
Simon Kelley76dd75d2013-05-23 10:04:25 +01001821 if (tcp_addr.sa.sa_family == AF_INET6)
Simon Kelleycc921df2019-01-02 22:48:59 +00001822 addr.addr6 = tcp_addr.in6.sin6_addr;
Simon Kelleyee875042018-10-23 22:10:17 +01001823 else
Simon Kelleycc921df2019-01-02 22:48:59 +00001824 addr.addr4 = tcp_addr.in.sin_addr;
Simon Kelley76dd75d2013-05-23 10:04:25 +01001825
1826 for (iface = daemon->interfaces; iface; iface = iface->next)
Petr Mensik951a2212019-07-03 17:02:16 +02001827 if (iface->index == if_index &&
1828 iface->addr.sa.sa_family == tcp_addr.sa.sa_family)
Simon Kelley76dd75d2013-05-23 10:04:25 +01001829 break;
1830
1831 if (!iface && !loopback_exception(listener->tcpfd, tcp_addr.sa.sa_family, &addr, intr_name))
1832 client_ok = 0;
1833 }
1834
1835 if (option_bool(OPT_CLEVERBIND))
1836 iface = listener->iface; /* May be NULL */
1837 else
1838 {
1839 /* Check for allowed interfaces when binding the wildcard address:
1840 we do this by looking for an interface with the same address as
1841 the local address of the TCP connection, then looking to see if that's
1842 an allowed interface. As a side effect, we get the netmask of the
1843 interface too, for localisation. */
1844
1845 for (iface = daemon->interfaces; iface; iface = iface->next)
1846 if (sockaddr_isequal(&iface->addr, &tcp_addr))
1847 break;
1848
1849 if (!iface)
1850 client_ok = 0;
1851 }
1852 }
1853
Simon Kelley22ce5502013-01-22 13:53:04 +00001854 if (!client_ok)
Simon Kelley832af0b2007-01-21 20:01:28 +00001855 {
1856 shutdown(confd, SHUT_RDWR);
Simon Kelley5fc639c2019-03-29 21:29:43 +00001857 close(confd);
Simon Kelley832af0b2007-01-21 20:01:28 +00001858 }
Simon Kelleya799ca02018-10-18 19:35:29 +01001859 else if (!option_bool(OPT_DEBUG) && pipe(pipefd) == 0 && (p = fork()) != 0)
Simon Kelley832af0b2007-01-21 20:01:28 +00001860 {
Simon Kelleya799ca02018-10-18 19:35:29 +01001861 close(pipefd[1]); /* parent needs read pipe end. */
1862 if (p == -1)
1863 close(pipefd[0]);
1864 else
Simon Kelley832af0b2007-01-21 20:01:28 +00001865 {
1866 int i;
Simon Kelleye2cb6552020-06-20 22:30:12 +01001867#ifdef HAVE_LINUX_NETWORK
1868 /* The child process inherits the netlink socket,
1869 which it never uses, but when the parent (us)
1870 uses it in the future, the answer may go to the
1871 child, resulting in the parent blocking
1872 forever awaiting the result. To avoid this
1873 the child closes the netlink socket, but there's
1874 a nasty race, since the parent may use netlink
1875 before the child has done the close.
1876
1877 To avoid this, the parent blocks here until a
1878 single byte comes back up the pipe, which
1879 is sent by the child after it has closed the
1880 netlink socket. */
1881
1882 unsigned char a;
1883 read_write(pipefd[0], &a, 1, 1);
1884#endif
Simon Kelleya799ca02018-10-18 19:35:29 +01001885
Simon Kelley832af0b2007-01-21 20:01:28 +00001886 for (i = 0; i < MAX_PROCS; i++)
Simon Kelleya799ca02018-10-18 19:35:29 +01001887 if (daemon->tcp_pids[i] == 0 && daemon->tcp_pipes[i] == -1)
Simon Kelley832af0b2007-01-21 20:01:28 +00001888 {
1889 daemon->tcp_pids[i] = p;
Simon Kelleya799ca02018-10-18 19:35:29 +01001890 daemon->tcp_pipes[i] = pipefd[0];
Simon Kelley832af0b2007-01-21 20:01:28 +00001891 break;
1892 }
1893 }
Simon Kelley5fc639c2019-03-29 21:29:43 +00001894 close(confd);
Simon Kelley25cf5e32015-01-09 15:53:03 +00001895
1896 /* The child can use up to TCP_MAX_QUERIES ids, so skip that many. */
1897 daemon->log_id += TCP_MAX_QUERIES;
Simon Kelley832af0b2007-01-21 20:01:28 +00001898 }
Simon Kelley832af0b2007-01-21 20:01:28 +00001899 else
1900 {
1901 unsigned char *buff;
1902 struct server *s;
1903 int flags;
Simon Kelley52d4abf2012-03-21 21:39:48 +00001904 struct in_addr netmask;
Simon Kelley4f7b3042012-11-28 21:27:02 +00001905 int auth_dns;
Simon Kelleya799ca02018-10-18 19:35:29 +01001906
Simon Kelley52d4abf2012-03-21 21:39:48 +00001907 if (iface)
Simon Kelley4f7b3042012-11-28 21:27:02 +00001908 {
1909 netmask = iface->netmask;
1910 auth_dns = iface->dns_auth;
1911 }
Simon Kelley52d4abf2012-03-21 21:39:48 +00001912 else
Simon Kelley4f7b3042012-11-28 21:27:02 +00001913 {
1914 netmask.s_addr = 0;
1915 auth_dns = 0;
1916 }
Simon Kelley52d4abf2012-03-21 21:39:48 +00001917
Josh Soref730c6742017-02-06 16:14:04 +00001918 /* Arrange for SIGALRM after CHILD_LIFETIME seconds to
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001919 terminate the process. */
Simon Kelley28866e92011-02-14 20:19:14 +00001920 if (!option_bool(OPT_DEBUG))
Simon Kelleya799ca02018-10-18 19:35:29 +01001921 {
Simon Kelleye2cb6552020-06-20 22:30:12 +01001922#ifdef HAVE_LINUX_NETWORK
1923 /* See comment above re: netlink socket. */
1924 unsigned char a = 0;
1925
1926 close(daemon->netlinkfd);
1927 read_write(pipefd[1], &a, 1, 0);
1928#endif
Simon Kelleya799ca02018-10-18 19:35:29 +01001929 alarm(CHILD_LIFETIME);
1930 close(pipefd[0]); /* close read end in child. */
1931 daemon->pipe_to_parent = pipefd[1];
1932 }
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001933
Simon Kelley832af0b2007-01-21 20:01:28 +00001934 /* start with no upstream connections. */
1935 for (s = daemon->servers; s; s = s->next)
Simon Kelley7cebd202006-05-06 14:13:33 +01001936 s->tcpfd = -1;
Simon Kelley832af0b2007-01-21 20:01:28 +00001937
1938 /* The connected socket inherits non-blocking
1939 attribute from the listening socket.
1940 Reset that here. */
1941 if ((flags = fcntl(confd, F_GETFL, 0)) != -1)
1942 fcntl(confd, F_SETFL, flags & ~O_NONBLOCK);
1943
Simon Kelley4f7b3042012-11-28 21:27:02 +00001944 buff = tcp_request(confd, now, &tcp_addr, netmask, auth_dns);
Simon Kelley7cebd202006-05-06 14:13:33 +01001945
Simon Kelley832af0b2007-01-21 20:01:28 +00001946 shutdown(confd, SHUT_RDWR);
Simon Kelley5fc639c2019-03-29 21:29:43 +00001947 close(confd);
Simon Kelley832af0b2007-01-21 20:01:28 +00001948
1949 if (buff)
1950 free(buff);
1951
1952 for (s = daemon->servers; s; s = s->next)
1953 if (s->tcpfd != -1)
1954 {
1955 shutdown(s->tcpfd, SHUT_RDWR);
Simon Kelley5fc639c2019-03-29 21:29:43 +00001956 close(s->tcpfd);
Simon Kelley832af0b2007-01-21 20:01:28 +00001957 }
Simon Kelleye2cb6552020-06-20 22:30:12 +01001958
Simon Kelley28866e92011-02-14 20:19:14 +00001959 if (!option_bool(OPT_DEBUG))
Simon Kelley5aabfc72007-08-29 11:24:47 +01001960 {
Simon Kelleye2cb6552020-06-20 22:30:12 +01001961 close(daemon->pipe_to_parent);
Simon Kelley5aabfc72007-08-29 11:24:47 +01001962 flush_log();
1963 _exit(0);
1964 }
Simon Kelley832af0b2007-01-21 20:01:28 +00001965 }
1966 }
1967 }
Simon Kelley3be34542004-09-11 19:12:13 +01001968}
1969
Simon Kelley7622fc02009-06-04 20:32:05 +01001970#ifdef HAVE_DHCP
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001971int make_icmp_sock(void)
1972{
Simon Kelley7cebd202006-05-06 14:13:33 +01001973 int fd;
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001974 int zeroopt = 0;
1975
1976 if ((fd = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP)) != -1)
1977 {
Simon Kelley7cebd202006-05-06 14:13:33 +01001978 if (!fix_fd(fd) ||
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001979 setsockopt(fd, SOL_SOCKET, SO_DONTROUTE, &zeroopt, sizeof(zeroopt)) == -1)
1980 {
1981 close(fd);
1982 fd = -1;
1983 }
1984 }
1985
1986 return fd;
1987}
1988
Simon Kelley5aabfc72007-08-29 11:24:47 +01001989int icmp_ping(struct in_addr addr)
Simon Kelley3be34542004-09-11 19:12:13 +01001990{
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001991 /* Try and get an ICMP echo from a machine. */
Simon Kelley3be34542004-09-11 19:12:13 +01001992
Floris Bos503c6092017-04-09 23:07:13 +01001993 int fd;
Simon Kelley3be34542004-09-11 19:12:13 +01001994 struct sockaddr_in saddr;
1995 struct {
1996 struct ip ip;
1997 struct icmp icmp;
1998 } packet;
1999 unsigned short id = rand16();
Floris Bos503c6092017-04-09 23:07:13 +01002000 unsigned int i, j;
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01002001 int gotreply = 0;
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01002002
Simon Kelley824af852008-02-12 20:43:05 +00002003#if defined(HAVE_LINUX_NETWORK) || defined (HAVE_SOLARIS_NETWORK)
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01002004 if ((fd = make_icmp_sock()) == -1)
2005 return 0;
2006#else
2007 int opt = 2000;
2008 fd = daemon->dhcp_icmp_fd;
2009 setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
2010#endif
2011
Simon Kelley3be34542004-09-11 19:12:13 +01002012 saddr.sin_family = AF_INET;
2013 saddr.sin_port = 0;
2014 saddr.sin_addr = addr;
2015#ifdef HAVE_SOCKADDR_SA_LEN
2016 saddr.sin_len = sizeof(struct sockaddr_in);
2017#endif
2018
2019 memset(&packet.icmp, 0, sizeof(packet.icmp));
2020 packet.icmp.icmp_type = ICMP_ECHO;
2021 packet.icmp.icmp_id = id;
2022 for (j = 0, i = 0; i < sizeof(struct icmp) / 2; i++)
2023 j += ((u16 *)&packet.icmp)[i];
2024 while (j>>16)
2025 j = (j & 0xffff) + (j >> 16);
2026 packet.icmp.icmp_cksum = (j == 0xffff) ? j : ~j;
2027
Simon Kelleyff841eb2015-03-11 21:36:30 +00002028 while (retry_send(sendto(fd, (char *)&packet.icmp, sizeof(struct icmp), 0,
2029 (struct sockaddr *)&saddr, sizeof(saddr))));
Simon Kelleyfd9fa482004-10-21 20:24:00 +01002030
Floris Bos503c6092017-04-09 23:07:13 +01002031 gotreply = delay_dhcp(dnsmasq_time(), PING_WAIT, fd, addr.s_addr, id);
2032
2033#if defined(HAVE_LINUX_NETWORK) || defined(HAVE_SOLARIS_NETWORK)
Simon Kelley5fc639c2019-03-29 21:29:43 +00002034 close(fd);
Floris Bos503c6092017-04-09 23:07:13 +01002035#else
2036 opt = 1;
2037 setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
2038#endif
2039
2040 return gotreply;
2041}
2042
2043int delay_dhcp(time_t start, int sec, int fd, uint32_t addr, unsigned short id)
2044{
2045 /* Delay processing DHCP packets for "sec" seconds counting from "start".
2046 If "fd" is not -1 it will stop waiting if an ICMP echo reply is received
2047 from "addr" with ICMP ID "id" and return 1 */
2048
2049 /* Note that whilst waiting, we check for
2050 (and service) events on the DNS and TFTP sockets, (so doing that
2051 better not use any resources our caller has in use...)
2052 but we remain deaf to signals or further DHCP packets. */
2053
2054 /* There can be a problem using dnsmasq_time() to end the loop, since
2055 it's not monotonic, and can go backwards if the system clock is
2056 tweaked, leading to the code getting stuck in this loop and
2057 ignoring DHCP requests. To fix this, we check to see if select returned
2058 as a result of a timeout rather than a socket becoming available. We
2059 only allow this to happen as many times as it takes to get to the wait time
2060 in quarter-second chunks. This provides a fallback way to end loop. */
2061
2062 int rc, timeout_count;
2063 time_t now;
2064
2065 for (now = dnsmasq_time(), timeout_count = 0;
2066 (difftime(now, start) <= (float)sec) && (timeout_count < sec * 4);)
Simon Kelleyfd9fa482004-10-21 20:24:00 +01002067 {
Simon Kelleyb842bc92015-07-12 21:09:11 +01002068 poll_reset();
Floris Bos503c6092017-04-09 23:07:13 +01002069 if (fd != -1)
2070 poll_listen(fd, POLLIN);
Simon Kelleyb842bc92015-07-12 21:09:11 +01002071 set_dns_listeners(now);
2072 set_log_writer();
Simon Kelleyc5ad4e72012-02-24 16:06:20 +00002073
2074#ifdef HAVE_DHCP6
Simon Kelley1f776932012-12-16 19:46:08 +00002075 if (daemon->doing_ra)
Simon Kelleyb842bc92015-07-12 21:09:11 +01002076 poll_listen(daemon->icmp6fd, POLLIN);
Simon Kelleyc5ad4e72012-02-24 16:06:20 +00002077#endif
2078
Simon Kelleyb842bc92015-07-12 21:09:11 +01002079 rc = do_poll(250);
Simon Kelley5e95a552015-07-05 22:31:30 +01002080
2081 if (rc < 0)
Simon Kelleyb842bc92015-07-12 21:09:11 +01002082 continue;
Simon Kelley5e95a552015-07-05 22:31:30 +01002083 else if (rc == 0)
2084 timeout_count++;
Simon Kelleyf2621c72007-04-29 19:47:21 +01002085
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01002086 now = dnsmasq_time();
Floris Bos503c6092017-04-09 23:07:13 +01002087
Simon Kelleyb842bc92015-07-12 21:09:11 +01002088 check_log_writer(0);
2089 check_dns_listeners(now);
Floris Bos503c6092017-04-09 23:07:13 +01002090
Simon Kelleyc5ad4e72012-02-24 16:06:20 +00002091#ifdef HAVE_DHCP6
Simon Kelleyb842bc92015-07-12 21:09:11 +01002092 if (daemon->doing_ra && poll_check(daemon->icmp6fd, POLLIN))
Simon Kelley1f776932012-12-16 19:46:08 +00002093 icmp6_packet(now);
Simon Kelleyc5ad4e72012-02-24 16:06:20 +00002094#endif
2095
Simon Kelley832af0b2007-01-21 20:01:28 +00002096#ifdef HAVE_TFTP
Simon Kelleyb842bc92015-07-12 21:09:11 +01002097 check_tftp_listeners(now);
Simon Kelley832af0b2007-01-21 20:01:28 +00002098#endif
2099
Floris Bos503c6092017-04-09 23:07:13 +01002100 if (fd != -1)
2101 {
2102 struct {
2103 struct ip ip;
2104 struct icmp icmp;
2105 } packet;
2106 struct sockaddr_in faddr;
2107 socklen_t len = sizeof(faddr);
2108
2109 if (poll_check(fd, POLLIN) &&
2110 recvfrom(fd, &packet, sizeof(packet), 0, (struct sockaddr *)&faddr, &len) == sizeof(packet) &&
2111 addr == faddr.sin_addr.s_addr &&
2112 packet.icmp.icmp_type == ICMP_ECHOREPLY &&
2113 packet.icmp.icmp_seq == 0 &&
2114 packet.icmp.icmp_id == id)
2115 return 1;
Simon Kelleyfd9fa482004-10-21 20:24:00 +01002116 }
2117 }
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01002118
Floris Bos503c6092017-04-09 23:07:13 +01002119 return 0;
Simon Kelley3be34542004-09-11 19:12:13 +01002120}
Geert Stappersba26d342020-04-06 15:42:39 +01002121#endif /* HAVE_DHCP */