blob: e6140b7604c43670071c617dd40d3ac4ed55f60a [file] [log] [blame]
Simon Kelleyd1ced3a2018-01-01 22:18:03 +00001/* dnsmasq is Copyright (c) 2000-2018 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 Kelley1a6bca82008-07-11 11:11:42 +010060#endif
Vladislav Grishenko408c3682013-09-24 16:18:49 +010061#if defined(HAVE_DHCP) || defined(HAVE_DHCP6)
Simon Kelley1f776932012-12-16 19:46:08 +000062 struct dhcp_context *context;
Simon Kelleyff7eea22013-09-04 18:01:38 +010063 struct dhcp_relay *relay;
Vladislav Grishenko408c3682013-09-24 16:18:49 +010064#endif
Stefan Tomanek30d08792015-03-31 22:32:11 +010065#ifdef HAVE_TFTP
66 int tftp_prefix_missing = 0;
67#endif
Simon Kelley5aabfc72007-08-29 11:24:47 +010068
Simon Kelley824af852008-02-12 20:43:05 +000069#ifdef LOCALEDIR
Simon Kelleyb8187c82005-11-26 21:46:27 +000070 setlocale(LC_ALL, "");
71 bindtextdomain("dnsmasq", LOCALEDIR);
72 textdomain("dnsmasq");
73#endif
74
Simon Kelley9e4abcb2004-01-22 19:47:41 +000075 sigact.sa_handler = sig_handler;
76 sigact.sa_flags = 0;
77 sigemptyset(&sigact.sa_mask);
78 sigaction(SIGUSR1, &sigact, NULL);
Simon Kelley5aabfc72007-08-29 11:24:47 +010079 sigaction(SIGUSR2, &sigact, NULL);
Simon Kelley9e4abcb2004-01-22 19:47:41 +000080 sigaction(SIGHUP, &sigact, NULL);
81 sigaction(SIGTERM, &sigact, NULL);
Simon Kelley44a2a312004-03-10 20:04:35 +000082 sigaction(SIGALRM, &sigact, NULL);
Simon Kelleyfeba5c12004-07-27 20:28:58 +010083 sigaction(SIGCHLD, &sigact, NULL);
Simon Kelley3c973ad2018-01-14 21:05:37 +000084 sigaction(SIGINT, &sigact, NULL);
85
Simon Kelleyfeba5c12004-07-27 20:28:58 +010086 /* ignore SIGPIPE */
87 sigact.sa_handler = SIG_IGN;
88 sigaction(SIGPIPE, &sigact, NULL);
Simon Kelley9e4abcb2004-01-22 19:47:41 +000089
Simon Kelley5aabfc72007-08-29 11:24:47 +010090 umask(022); /* known umask, create leases and pid files as 0644 */
Simon Kelleyb5ea1cc2014-07-29 16:34:14 +010091
92 rand_init(); /* Must precede read_opts() */
93
Simon Kelley5aabfc72007-08-29 11:24:47 +010094 read_opts(argc, argv, compile_opts);
Simon Kelleyc3e0b9b2013-12-31 13:50:39 +000095
Simon Kelley3be34542004-09-11 19:12:13 +010096 if (daemon->edns_pktsz < PACKETSZ)
Simon Kelley60b68062014-01-08 12:10:28 +000097 daemon->edns_pktsz = PACKETSZ;
Simon Kelley3ddacb82014-01-08 14:32:03 +000098
Simon Kelleyd3a8b392015-12-23 12:27:37 +000099 /* Min buffer size: we check after adding each record, so there must be
100 memory for the largest packet, and the largest record so the
101 min for DNS is PACKETSZ+MAXDNAME+RRFIXEDSZ which is < 1000.
102 This might be increased is EDNS packet size if greater than the minimum. */
103 daemon->packet_buff_sz = daemon->edns_pktsz + MAXDNAME + RRFIXEDSZ;
Simon Kelley0a852542005-03-23 20:28:59 +0000104 daemon->packet = safe_malloc(daemon->packet_buff_sz);
Simon Kelley3ddacb82014-01-08 14:32:03 +0000105
Simon Kelleyc72daea2012-01-05 21:33:27 +0000106 daemon->addrbuff = safe_malloc(ADDRSTRLEN);
Simon Kelley25cf5e32015-01-09 15:53:03 +0000107 if (option_bool(OPT_EXTRALOG))
108 daemon->addrbuff2 = safe_malloc(ADDRSTRLEN);
Simon Kelley3ddacb82014-01-08 14:32:03 +0000109
110#ifdef HAVE_DNSSEC
111 if (option_bool(OPT_DNSSEC_VALID))
Simon Kelley5107ace2014-02-23 10:48:32 +0000112 {
Simon Kelleycbe379a2015-04-21 22:57:06 +0100113 /* Note that both /000 and '.' are allowed within labels. These get
114 represented in presentation format using NAME_ESCAPE as an escape
115 character when in DNSSEC mode.
116 In theory, if all the characters in a name were /000 or
117 '.' or NAME_ESCAPE then all would have to be escaped, so the
118 presentation format would be twice as long as the spec.
119
120 daemon->namebuff was previously allocated by the option-reading
121 code before we knew if we're in DNSSEC mode, so reallocate here. */
122 free(daemon->namebuff);
123 daemon->namebuff = safe_malloc(MAXDNAME * 2);
124 daemon->keyname = safe_malloc(MAXDNAME * 2);
125 daemon->workspacename = safe_malloc(MAXDNAME * 2);
Simon Kelley373e9172017-12-01 22:40:56 +0000126 /* one char flag per possible RR in answer section (may get extended). */
127 daemon->rr_status_sz = 64;
128 daemon->rr_status = safe_malloc(daemon->rr_status_sz);
Simon Kelley5107ace2014-02-23 10:48:32 +0000129 }
Simon Kelley3ddacb82014-01-08 14:32:03 +0000130#endif
Simon Kelley4f7b3042012-11-28 21:27:02 +0000131
Simon Kelley7622fc02009-06-04 20:32:05 +0100132#ifdef HAVE_DHCP
Simon Kelley3be34542004-09-11 19:12:13 +0100133 if (!daemon->lease_file)
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000134 {
Simon Kelley52b92f42012-01-22 16:05:15 +0000135 if (daemon->dhcp || daemon->dhcp6)
Simon Kelley3be34542004-09-11 19:12:13 +0100136 daemon->lease_file = LEASEFILE;
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000137 }
Simon Kelley7622fc02009-06-04 20:32:05 +0100138#endif
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000139
Simon Kelleya2761752012-01-18 16:07:21 +0000140 /* Close any file descriptors we inherited apart from std{in|out|err}
141
142 Ensure that at least stdin, stdout and stderr (fd 0, 1, 2) exist,
143 otherwise file descriptors we create can end up being 0, 1, or 2
144 and then get accidentally closed later when we make 0, 1, and 2
145 open to /dev/null. Normally we'll be started with 0, 1 and 2 open,
146 but it's not guaranteed. By opening /dev/null three times, we
147 ensure that we're not using those fds for real stuff. */
Simon Kelley5aabfc72007-08-29 11:24:47 +0100148 for (i = 0; i < max_fd; i++)
149 if (i != STDOUT_FILENO && i != STDERR_FILENO && i != STDIN_FILENO)
150 close(i);
Simon Kelleya2761752012-01-18 16:07:21 +0000151 else
152 open("/dev/null", O_RDWR);
Simon Kelley5aabfc72007-08-29 11:24:47 +0100153
Simon Kelley801ca9a2012-03-06 19:30:17 +0000154#ifndef HAVE_LINUX_NETWORK
155# if !(defined(IP_RECVDSTADDR) && defined(IP_RECVIF) && defined(IP_SENDSRCADDR))
Simon Kelley28866e92011-02-14 20:19:14 +0000156 if (!option_bool(OPT_NOWILD))
Simon Kelleyde379512004-06-22 20:23:33 +0100157 {
158 bind_fallback = 1;
Simon Kelley28866e92011-02-14 20:19:14 +0000159 set_option_bool(OPT_NOWILD);
Simon Kelleyde379512004-06-22 20:23:33 +0100160 }
Simon Kelley801ca9a2012-03-06 19:30:17 +0000161# endif
Simon Kelley2b5bae92012-06-26 16:55:23 +0100162
163 /* -- bind-dynamic not supported on !Linux, fall back to --bind-interfaces */
Simon Kelley54dd3932012-06-20 11:23:38 +0100164 if (option_bool(OPT_CLEVERBIND))
Simon Kelley2b5bae92012-06-26 16:55:23 +0100165 {
166 bind_fallback = 1;
167 set_option_bool(OPT_NOWILD);
Simon Kelley236e0722012-06-26 21:33:01 +0100168 reset_option_bool(OPT_CLEVERBIND);
Simon Kelley2b5bae92012-06-26 16:55:23 +0100169 }
Simon Kelley04918052015-01-26 11:23:43 +0000170#endif
Simon Kelley5f4dc5c2015-01-20 20:51:02 +0000171
Simon Kelley04918052015-01-26 11:23:43 +0000172#ifndef HAVE_INOTIFY
Simon Kelley70d18732015-01-31 19:59:29 +0000173 if (daemon->dynamic_dirs)
174 die(_("dhcp-hostsdir, dhcp-optsdir and hostsdir are not supported on this platform"), NULL, EC_BADCONF);
Simon Kelley309331f2006-04-22 15:05:01 +0100175#endif
Simon Kelley2b5bae92012-06-26 16:55:23 +0100176
Simon Kelley0744ca62014-01-25 16:40:15 +0000177 if (option_bool(OPT_DNSSEC_VALID))
178 {
Simon Kelley3ddacb82014-01-08 14:32:03 +0000179#ifdef HAVE_DNSSEC
Simon Kelleya63b8b82016-01-12 11:28:58 +0000180 struct ds_config *ds;
181
182 /* Must have at least a root trust anchor, or the DNSSEC code
183 can loop forever. */
184 for (ds = daemon->ds; ds; ds = ds->next)
185 if (ds->name[0] == 0)
186 break;
187
188 if (!ds)
189 die(_("no root trust anchor provided for DNSSEC"), NULL, EC_BADCONF);
Simon Kelley0744ca62014-01-25 16:40:15 +0000190
191 if (daemon->cachesize < CACHESIZ)
Simon Kelley360f2512015-03-07 18:28:06 +0000192 die(_("cannot reduce cache size from default when DNSSEC enabled"), NULL, EC_BADCONF);
Simon Kelley0744ca62014-01-25 16:40:15 +0000193#else
194 die(_("DNSSEC not available: set HAVE_DNSSEC in src/config.h"), NULL, EC_BADCONF);
Simon Kelley3ddacb82014-01-08 14:32:03 +0000195#endif
Simon Kelley0744ca62014-01-25 16:40:15 +0000196 }
Simon Kelley3ddacb82014-01-08 14:32:03 +0000197
Simon Kelley832af0b2007-01-21 20:01:28 +0000198#ifndef HAVE_TFTP
Simon Kelley9b40cbf2012-07-13 19:58:26 +0100199 if (option_bool(OPT_TFTP))
Simon Kelley5aabfc72007-08-29 11:24:47 +0100200 die(_("TFTP server not available: set HAVE_TFTP in src/config.h"), NULL, EC_BADCONF);
Simon Kelley832af0b2007-01-21 20:01:28 +0000201#endif
202
Simon Kelley7de060b2011-08-26 17:24:52 +0100203#ifdef HAVE_CONNTRACK
204 if (option_bool(OPT_CONNTRACK) && (daemon->query_port != 0 || daemon->osport))
Simon Kelley360f2512015-03-07 18:28:06 +0000205 die (_("cannot use --conntrack AND --query-port"), NULL, EC_BADCONF);
Simon Kelley7de060b2011-08-26 17:24:52 +0100206#else
207 if (option_bool(OPT_CONNTRACK))
Simon Kelley360f2512015-03-07 18:28:06 +0000208 die(_("conntrack support not available: set HAVE_CONNTRACK in src/config.h"), NULL, EC_BADCONF);
Simon Kelley7de060b2011-08-26 17:24:52 +0100209#endif
210
Simon Kelley824af852008-02-12 20:43:05 +0000211#ifdef HAVE_SOLARIS_NETWORK
212 if (daemon->max_logs != 0)
Josh Soref730c6742017-02-06 16:14:04 +0000213 die(_("asynchronous logging is not available under Solaris"), NULL, EC_BADCONF);
Simon Kelley824af852008-02-12 20:43:05 +0000214#endif
215
Simon Kelley572b41e2011-02-18 18:11:18 +0000216#ifdef __ANDROID__
217 if (daemon->max_logs != 0)
Josh Soref730c6742017-02-06 16:14:04 +0000218 die(_("asynchronous logging is not available under Android"), NULL, EC_BADCONF);
Simon Kelley572b41e2011-02-18 18:11:18 +0000219#endif
220
Simon Kelley4820dce2012-12-18 18:30:30 +0000221#ifndef HAVE_AUTH
Simon Kelley08933472018-10-05 16:34:35 +0100222 if (daemon->auth_zones)
Simon Kelley4820dce2012-12-18 18:30:30 +0000223 die(_("authoritative DNS not available: set HAVE_AUTH in src/config.h"), NULL, EC_BADCONF);
224#endif
225
Simon Kelleyb5ea1cc2014-07-29 16:34:14 +0100226#ifndef HAVE_LOOP
227 if (option_bool(OPT_LOOP_DETECT))
Simon Kelley360f2512015-03-07 18:28:06 +0000228 die(_("loop detection not available: set HAVE_LOOP in src/config.h"), NULL, EC_BADCONF);
Simon Kelleyb5ea1cc2014-07-29 16:34:14 +0100229#endif
Hans Dedecker926332a2016-01-23 10:48:12 +0000230
Julian Kornberger8dcdb332018-07-21 22:11:08 +0100231#ifndef HAVE_UBUS
232 if (option_bool(OPT_UBUS))
233 die(_("Ubus not available: set HAVE_UBUS in src/config.h"), NULL, EC_BADCONF);
234#endif
235
Hans Dedecker926332a2016-01-23 10:48:12 +0000236 if (daemon->max_port < daemon->min_port)
237 die(_("max_port cannot be smaller than min_port"), NULL, EC_BADCONF);
238
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100239 now = dnsmasq_time();
Simon Kelley4f7b3042012-11-28 21:27:02 +0000240
Simon Kelley08933472018-10-05 16:34:35 +0100241 if (daemon->auth_zones)
242 {
243 if (!daemon->authserver)
244 die(_("--auth-server required when an auth zone is defined."), NULL, EC_BADCONF);
245
246 /* Create a serial at startup if not configured. */
Simon Kelley4f7b3042012-11-28 21:27:02 +0000247#ifdef HAVE_BROKEN_RTC
Martin Schiller53792c92018-10-08 14:55:19 +0200248 if (daemon->soa_sn == 0)
Simon Kelley08933472018-10-05 16:34:35 +0100249 die(_("zone serial must be configured in --auth-soa"), NULL, EC_BADCONF);
Simon Kelley4f7b3042012-11-28 21:27:02 +0000250#else
Simon Kelley08933472018-10-05 16:34:35 +0100251 if (daemon->soa_sn == 0)
252 daemon->soa_sn = now;
Simon Kelley4f7b3042012-11-28 21:27:02 +0000253#endif
Simon Kelley08933472018-10-05 16:34:35 +0100254 }
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000255
Simon Kelleyff7eea22013-09-04 18:01:38 +0100256#ifdef HAVE_DHCP6
257 if (daemon->dhcp6)
258 {
259 daemon->doing_ra = option_bool(OPT_RA);
Simon Kelley1f776932012-12-16 19:46:08 +0000260
Simon Kelleyff7eea22013-09-04 18:01:38 +0100261 for (context = daemon->dhcp6; context; context = context->next)
Simon Kelley1f776932012-12-16 19:46:08 +0000262 {
Simon Kelleyff7eea22013-09-04 18:01:38 +0100263 if (context->flags & CONTEXT_DHCP)
264 daemon->doing_dhcp6 = 1;
265 if (context->flags & CONTEXT_RA)
266 daemon->doing_ra = 1;
Simon Kelley1ee9be42013-12-09 16:50:19 +0000267#if !defined(HAVE_LINUX_NETWORK) && !defined(HAVE_BSD_NETWORK)
Simon Kelleyff7eea22013-09-04 18:01:38 +0100268 if (context->flags & CONTEXT_TEMPLATE)
269 die (_("dhcp-range constructor not available on this platform"), NULL, EC_BADCONF);
Simon Kelleybb86e852012-12-17 22:00:53 +0000270#endif
Simon Kelley1f776932012-12-16 19:46:08 +0000271 }
Simon Kelley1f776932012-12-16 19:46:08 +0000272 }
Simon Kelleyff7eea22013-09-04 18:01:38 +0100273#endif
274
275#ifdef HAVE_DHCP
276 /* Note that order matters here, we must call lease_init before
277 creating any file descriptors which shouldn't be leaked
278 to the lease-script init process. We need to call common_init
Simon Kelley33702ab2015-12-28 23:17:15 +0000279 before lease_init to allocate buffers it uses.
Simon Kelley1e505122016-01-25 21:29:23 +0000280 The script subsystem relies on DHCP buffers, hence the last two
Simon Kelley33702ab2015-12-28 23:17:15 +0000281 conditions below. */
282 if (daemon->dhcp || daemon->doing_dhcp6 || daemon->relay4 ||
Simon Kelley1e505122016-01-25 21:29:23 +0000283 daemon->relay6 || option_bool(OPT_TFTP) || option_bool(OPT_SCRIPT_ARP))
Simon Kelleyff7eea22013-09-04 18:01:38 +0100284 {
285 dhcp_common_init();
286 if (daemon->dhcp || daemon->doing_dhcp6)
287 lease_init(now);
288 }
289
290 if (daemon->dhcp || daemon->relay4)
Simon Kelley305ffb52019-03-16 18:17:17 +0000291 {
292 dhcp_init();
293# ifdef HAVE_LINUX_NETWORK
294 if (!option_bool(OPT_NO_PING))
295 need_cap_net_raw = 1;
296 need_cap_net_admin = 1;
297# endif
298 }
Simon Kelleyff7eea22013-09-04 18:01:38 +0100299
300# ifdef HAVE_DHCP6
Simon Kelley89500e32013-09-20 16:29:20 +0100301 if (daemon->doing_ra || daemon->doing_dhcp6 || daemon->relay6)
Simon Kelley305ffb52019-03-16 18:17:17 +0000302 {
303 ra_init(now);
304# ifdef HAVE_LINUX_NETWORK
305 need_cap_net_raw = 1;
306 need_cap_net_admin = 1;
307# endif
308 }
Simon Kelleyff7eea22013-09-04 18:01:38 +0100309
310 if (daemon->doing_dhcp6 || daemon->relay6)
311 dhcp6_init();
312# endif
Simon Kelley843c96b2012-02-27 17:42:38 +0000313
Simon Kelley7622fc02009-06-04 20:32:05 +0100314#endif
Simon Kelleyfeba5c12004-07-27 20:28:58 +0100315
Jason A. Donenfeld13d86c72013-02-22 18:20:53 +0000316#ifdef HAVE_IPSET
317 if (daemon->ipsets)
Simon Kelley305ffb52019-03-16 18:17:17 +0000318 {
319 ipset_init();
320# ifdef HAVE_LINUX_NETWORK
321 need_cap_net_admin = 1;
322# endif
323 }
Jason A. Donenfeld13d86c72013-02-22 18:20:53 +0000324#endif
325
Simon Kelley1ee9be42013-12-09 16:50:19 +0000326#if defined(HAVE_LINUX_NETWORK)
Simon Kelley801ca9a2012-03-06 19:30:17 +0000327 netlink_init();
Simon Kelley1ee9be42013-12-09 16:50:19 +0000328#elif defined(HAVE_BSD_NETWORK)
329 route_init();
Simon Kelley801ca9a2012-03-06 19:30:17 +0000330#endif
331
Simon Kelley1ee9be42013-12-09 16:50:19 +0000332 if (option_bool(OPT_NOWILD) && option_bool(OPT_CLEVERBIND))
333 die(_("cannot set --bind-interfaces and --bind-dynamic"), NULL, EC_BADCONF);
334
Simon Kelley115ac3e2013-05-20 11:28:32 +0100335 if (!enumerate_interfaces(1) || !enumerate_interfaces(0))
Simon Kelley5aabfc72007-08-29 11:24:47 +0100336 die(_("failed to find list of interfaces: %s"), NULL, EC_MISC);
Simon Kelley843c96b2012-02-27 17:42:38 +0000337
Simon Kelley54dd3932012-06-20 11:23:38 +0100338 if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND))
Simon Kelley5aabfc72007-08-29 11:24:47 +0100339 {
Simon Kelley74c95c22011-10-19 09:33:39 +0100340 create_bound_listeners(1);
Simon Kelley54dd3932012-06-20 11:23:38 +0100341
342 if (!option_bool(OPT_CLEVERBIND))
343 for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
344 if (if_tmp->name && !if_tmp->used)
345 die(_("unknown interface %s"), if_tmp->name, EC_BADNET);
Simon Kelley9380ba72012-04-16 14:41:56 +0100346
347#if defined(HAVE_LINUX_NETWORK) && defined(HAVE_DHCP)
348 /* after enumerate_interfaces() */
Simon Kelley3b3f4412013-10-11 16:33:28 +0100349 bound_device = whichdevice();
350
Simon Kelley9380ba72012-04-16 14:41:56 +0100351 if (daemon->dhcp)
352 {
Simon Kelley3b3f4412013-10-11 16:33:28 +0100353 if (!daemon->relay4 && bound_device)
354 {
355 bindtodevice(bound_device, daemon->dhcpfd);
356 did_bind = 1;
357 }
358 if (daemon->enable_pxe && bound_device)
359 {
360 bindtodevice(bound_device, daemon->pxefd);
361 did_bind = 1;
362 }
Simon Kelley9380ba72012-04-16 14:41:56 +0100363 }
364#endif
365
366#if defined(HAVE_LINUX_NETWORK) && defined(HAVE_DHCP6)
Simon Kelley3b3f4412013-10-11 16:33:28 +0100367 if (daemon->doing_dhcp6 && !daemon->relay6 && bound_device)
368 {
369 bindtodevice(bound_device, daemon->dhcp6fd);
370 did_bind = 1;
371 }
Simon Kelley9380ba72012-04-16 14:41:56 +0100372#endif
Simon Kelley5aabfc72007-08-29 11:24:47 +0100373 }
Simon Kelley28866e92011-02-14 20:19:14 +0000374 else
Simon Kelley74c95c22011-10-19 09:33:39 +0100375 create_wildcard_listeners();
Simon Kelley5d162f22012-12-20 14:55:46 +0000376
377#ifdef HAVE_DHCP6
378 /* after enumerate_interfaces() */
Simon Kelleyff7eea22013-09-04 18:01:38 +0100379 if (daemon->doing_dhcp6 || daemon->relay6 || daemon->doing_ra)
Simon Kelley5d162f22012-12-20 14:55:46 +0000380 join_multicast(1);
Simon Kelley3511a922013-11-07 10:28:11 +0000381
382 /* After netlink_init() and before create_helper() */
383 lease_make_duid(now);
Simon Kelley5d162f22012-12-20 14:55:46 +0000384#endif
Simon Kelley5aabfc72007-08-29 11:24:47 +0100385
Simon Kelley824af852008-02-12 20:43:05 +0000386 if (daemon->port != 0)
Simon Kelley82e3f452014-01-31 21:05:48 +0000387 {
388 cache_init();
Simon Kelley193de4a2014-12-10 17:32:16 +0000389
Simon Kelley82e3f452014-01-31 21:05:48 +0000390 blockdata_init();
Simon Kelley5f4dc5c2015-01-20 20:51:02 +0000391 }
Simon Kelley193de4a2014-12-10 17:32:16 +0000392
Simon Kelley04918052015-01-26 11:23:43 +0000393#ifdef HAVE_INOTIFY
Petr Menšík075366a2017-11-05 16:05:39 +0000394 if ((daemon->port != 0 || daemon->dhcp || daemon->doing_dhcp6)
395 && (!option_bool(OPT_NO_RESOLV) || daemon->dynamic_dirs))
Simon Kelley5f4dc5c2015-01-20 20:51:02 +0000396 inotify_dnsmasq_init();
397 else
398 daemon->inotifyfd = -1;
Simon Kelley193de4a2014-12-10 17:32:16 +0000399#endif
Simon Kelley6b173352018-05-08 18:32:14 +0100400
401 if (daemon->dump_file)
402#ifdef HAVE_DUMPFILE
403 dump_init();
404 else
405 daemon->dumpfd = -1;
406#else
407 die(_("Packet dumps not available: set HAVE_DUMP in src/config.h"), NULL, EC_BADCONF);
408#endif
409
Simon Kelley28866e92011-02-14 20:19:14 +0000410 if (option_bool(OPT_DBUS))
Simon Kelley3d8df262005-08-29 12:19:27 +0100411#ifdef HAVE_DBUS
412 {
413 char *err;
414 daemon->dbus = NULL;
415 daemon->watches = NULL;
Simon Kelley5aabfc72007-08-29 11:24:47 +0100416 if ((err = dbus_init()))
417 die(_("DBus error: %s"), err, EC_MISC);
Simon Kelley3d8df262005-08-29 12:19:27 +0100418 }
419#else
Simon Kelley5aabfc72007-08-29 11:24:47 +0100420 die(_("DBus not available: set HAVE_DBUS in src/config.h"), NULL, EC_BADCONF);
Simon Kelley3d8df262005-08-29 12:19:27 +0100421#endif
Stefan Tomanek7aa970e2015-04-01 17:55:07 +0100422
Jan Willem Janssena2b82202019-03-25 12:42:23 +0100423 if (option_bool(OPT_UBUS))
424#ifdef HAVE_UBUS
425 {
426 daemon->ubus = NULL;
427 ubus_init();
428 }
429#else
430 die(_("UBus not available: set HAVE_UBUS in src/config.h"), NULL, EC_BADCONF);
431#endif
432
Simon Kelley824af852008-02-12 20:43:05 +0000433 if (daemon->port != 0)
434 pre_allocate_sfds();
Simon Kelley1a6bca82008-07-11 11:11:42 +0100435
Simon Kelleyc72daea2012-01-05 21:33:27 +0000436#if defined(HAVE_SCRIPT)
Simon Kelley1a6bca82008-07-11 11:11:42 +0100437 /* Note getpwnam returns static storage */
Simon Kelley843c96b2012-02-27 17:42:38 +0000438 if ((daemon->dhcp || daemon->dhcp6) &&
439 daemon->scriptuser &&
Simon Kelleyc72daea2012-01-05 21:33:27 +0000440 (daemon->lease_change_command || daemon->luascript))
Simon Kelley1a6bca82008-07-11 11:11:42 +0100441 {
Simon Kelley83e4b732018-02-06 16:57:15 +0000442 struct passwd *scr_pw;
443
444 if ((scr_pw = getpwnam(daemon->scriptuser)))
Simon Kelley1a6bca82008-07-11 11:11:42 +0100445 {
Simon Kelley83e4b732018-02-06 16:57:15 +0000446 script_uid = scr_pw->pw_uid;
447 script_gid = scr_pw->pw_gid;
Simon Kelley1a6bca82008-07-11 11:11:42 +0100448 }
449 else
450 baduser = daemon->scriptuser;
451 }
Simon Kelley7622fc02009-06-04 20:32:05 +0100452#endif
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000453
Simon Kelley1a6bca82008-07-11 11:11:42 +0100454 if (daemon->username && !(ent_pw = getpwnam(daemon->username)))
455 baduser = daemon->username;
456 else if (daemon->groupname && !(gp = getgrnam(daemon->groupname)))
457 baduser = daemon->groupname;
458
459 if (baduser)
460 die(_("unknown user or group: %s"), baduser, EC_BADCONF);
Simon Kelleyf6e62e22015-03-01 18:17:54 +0000461
Simon Kelley1a6bca82008-07-11 11:11:42 +0100462 /* implement group defaults, "dip" if available, or group associated with uid */
463 if (!daemon->group_set && !gp)
464 {
465 if (!(gp = getgrnam(CHGRP)) && ent_pw)
466 gp = getgrgid(ent_pw->pw_gid);
467
468 /* for error message */
469 if (gp)
470 daemon->groupname = gp->gr_name;
471 }
472
473#if defined(HAVE_LINUX_NETWORK)
Simon Kelley305ffb52019-03-16 18:17:17 +0000474 /* We keep CAP_NETADMIN (for ARP-injection) and
475 CAP_NET_RAW (for icmp) if we're doing dhcp,
476 if we have yet to bind ports because of DAD,
477 or we're doing it dynamically,
478 we need CAP_NET_BIND_SERVICE. */
479 if ((is_dad_listeners() || option_bool(OPT_CLEVERBIND)) &&
480 (option_bool(OPT_TFTP) || (daemon->port != 0 && daemon->port <= 1024)))
481 need_cap_net_bind_service = 1;
482
Simon Kelley1a6bca82008-07-11 11:11:42 +0100483 /* determine capability API version here, while we can still
484 call safe_malloc */
Simon Kelley305ffb52019-03-16 18:17:17 +0000485 int capsize = 1; /* for header version 1 */
486 char *fail = NULL;
487
488 hdr = safe_malloc(sizeof(*hdr));
489
490 /* find version supported by kernel */
491 memset(hdr, 0, sizeof(*hdr));
492 capget(hdr, NULL);
493
494 if (hdr->version != LINUX_CAPABILITY_VERSION_1)
Simon Kelley1a6bca82008-07-11 11:11:42 +0100495 {
Simon Kelley305ffb52019-03-16 18:17:17 +0000496 /* if unknown version, use largest supported version (3) */
497 if (hdr->version != LINUX_CAPABILITY_VERSION_2)
498 hdr->version = LINUX_CAPABILITY_VERSION_3;
499 capsize = 2;
Simon Kelley1a6bca82008-07-11 11:11:42 +0100500 }
Simon Kelley305ffb52019-03-16 18:17:17 +0000501
502 data = safe_malloc(sizeof(*data) * capsize);
503 capget(hdr, data); /* Get current values, for verification */
504
505 if (need_cap_net_admin && !(data->permitted & (1 << CAP_NET_ADMIN)))
506 fail = "NET_ADMIN";
507 else if (need_cap_net_raw && !(data->permitted & (1 << CAP_NET_RAW)))
508 fail = "NET_RAW";
509 else if (need_cap_net_bind_service && !(data->permitted & (1 << CAP_NET_BIND_SERVICE)))
510 fail = "NET_BIND_SERVICE";
511
512 if (fail)
513 die(_("process is missing required capability %s"), fail, EC_MISC);
514
515 /* Now set bitmaps to set caps after daemonising */
516 memset(data, 0, sizeof(*data) * capsize);
517
518 if (need_cap_net_admin)
519 data->effective |= (1 << CAP_NET_ADMIN);
520 if (need_cap_net_raw)
521 data->effective |= (1 << CAP_NET_RAW);
522 if (need_cap_net_bind_service)
523 data->effective |= (1 << CAP_NET_BIND_SERVICE);
524
525 data->permitted = data->effective;
Simon Kelley1a6bca82008-07-11 11:11:42 +0100526#endif
527
Simon Kelley5aabfc72007-08-29 11:24:47 +0100528 /* Use a pipe to carry signals and other events back to the event loop
Simon Kelley1a6bca82008-07-11 11:11:42 +0100529 in a race-free manner and another to carry errors to daemon-invoking process */
530 safe_pipe(pipefd, 1);
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100531
532 piperead = pipefd[0];
533 pipewrite = pipefd[1];
534 /* prime the pipe to load stuff first time. */
Simon Kelleye98bd522014-03-28 20:41:23 +0000535 send_event(pipewrite, EVENT_INIT, 0, NULL);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100536
537 err_pipe[1] = -1;
Simon Kelley16972692006-10-16 20:04:18 +0100538
Simon Kelley28866e92011-02-14 20:19:14 +0000539 if (!option_bool(OPT_DEBUG))
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000540 {
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000541 /* The following code "daemonizes" the process.
542 See Stevens section 12.4 */
Simon Kelley1a6bca82008-07-11 11:11:42 +0100543
Simon Kelley9e038942008-05-30 20:06:34 +0100544 if (chdir("/") != 0)
545 die(_("cannot chdir to filesystem root: %s"), NULL, EC_MISC);
546
Simon Kelley28866e92011-02-14 20:19:14 +0000547 if (!option_bool(OPT_NO_FORK))
Simon Kelley3be34542004-09-11 19:12:13 +0100548 {
Simon Kelley5aabfc72007-08-29 11:24:47 +0100549 pid_t pid;
550
Simon Kelley1a6bca82008-07-11 11:11:42 +0100551 /* pipe to carry errors back to original process.
552 When startup is complete we close this and the process terminates. */
553 safe_pipe(err_pipe, 0);
554
Simon Kelley7622fc02009-06-04 20:32:05 +0100555 if ((pid = fork()) == -1)
556 /* fd == -1 since we've not forked, never returns. */
Simon Kelleyc72daea2012-01-05 21:33:27 +0000557 send_event(-1, EVENT_FORK_ERR, errno, NULL);
Simon Kelley9e038942008-05-30 20:06:34 +0100558
Simon Kelley5aabfc72007-08-29 11:24:47 +0100559 if (pid != 0)
Simon Kelley1a6bca82008-07-11 11:11:42 +0100560 {
561 struct event_desc ev;
Simon Kelleyc72daea2012-01-05 21:33:27 +0000562 char *msg;
563
Simon Kelley1a6bca82008-07-11 11:11:42 +0100564 /* close our copy of write-end */
Simon Kelley5fc639c2019-03-29 21:29:43 +0000565 close(err_pipe[1]);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100566
567 /* check for errors after the fork */
Simon Kelleyc72daea2012-01-05 21:33:27 +0000568 if (read_event(err_pipe[0], &ev, &msg))
569 fatal_event(&ev, msg);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100570
571 _exit(EC_GOOD);
572 }
573
Simon Kelley5fc639c2019-03-29 21:29:43 +0000574 close(err_pipe[0]);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100575
576 /* NO calls to die() from here on. */
Simon Kelley3be34542004-09-11 19:12:13 +0100577
578 setsid();
Simon Kelley7622fc02009-06-04 20:32:05 +0100579
580 if ((pid = fork()) == -1)
Simon Kelleyc72daea2012-01-05 21:33:27 +0000581 send_event(err_pipe[1], EVENT_FORK_ERR, errno, NULL);
Simon Kelley7622fc02009-06-04 20:32:05 +0100582
583 if (pid != 0)
Simon Kelley7cebd202006-05-06 14:13:33 +0100584 _exit(0);
Simon Kelley3be34542004-09-11 19:12:13 +0100585 }
Simon Kelley9e038942008-05-30 20:06:34 +0100586
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000587 /* write pidfile _after_ forking ! */
Simon Kelley1a6bca82008-07-11 11:11:42 +0100588 if (daemon->runfile)
589 {
Simon Kelley79cfefd2012-09-02 13:29:51 +0100590 int fd, err = 0;
591
592 sprintf(daemon->namebuff, "%d\n", (int) getpid());
593
594 /* Explanation: Some installations of dnsmasq (eg Debian/Ubuntu) locate the pid-file
595 in a directory which is writable by the non-privileged user that dnsmasq runs as. This
596 allows the daemon to delete the file as part of its shutdown. This is a security hole to the
597 extent that an attacker running as the unprivileged user could replace the pidfile with a
598 symlink, and have the target of that symlink overwritten as root next time dnsmasq starts.
599
Josh Soref730c6742017-02-06 16:14:04 +0000600 The following code first deletes any existing file, and then opens it with the O_EXCL flag,
Simon Kelley79cfefd2012-09-02 13:29:51 +0100601 ensuring that the open() fails should there be any existing file (because the unlink() failed,
602 or an attacker exploited the race between unlink() and open()). This ensures that no symlink
603 attack can succeed.
604
605 Any compromise of the non-privileged user still theoretically allows the pid-file to be
606 replaced whilst dnsmasq is running. The worst that could allow is that the usual
607 "shutdown dnsmasq" shell command could be tricked into stopping any other process.
608
609 Note that if dnsmasq is started as non-root (eg for testing) it silently ignores
610 failure to write the pid-file.
611 */
612
613 unlink(daemon->runfile);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100614
Simon Kelley79cfefd2012-09-02 13:29:51 +0100615 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 +0100616 {
Simon Kelley79cfefd2012-09-02 13:29:51 +0100617 /* only complain if started as root */
618 if (getuid() == 0)
619 err = 1;
Simon Kelley1a6bca82008-07-11 11:11:42 +0100620 }
Simon Kelley79cfefd2012-09-02 13:29:51 +0100621 else
622 {
Simon Kelley246a31c2018-02-06 17:27:55 +0000623 /* We're still running as root here. Change the ownership of the PID file
624 to the user we will be running as. Note that this is not to allow
625 us to delete the file, since that depends on the permissions
626 of the directory containing the file. That directory will
627 need to by owned by the dnsmasq user, and the ownership of the
628 file has to match, to keep systemd >273 happy. */
Simon Kelley6b54d692018-02-08 21:23:05 +0000629 if (getuid() == 0 && ent_pw && ent_pw->pw_uid != 0 && fchown(fd, ent_pw->pw_uid, ent_pw->pw_gid) == -1)
630 chown_warn = errno;
631
632 if (!read_write(fd, (unsigned char *)daemon->namebuff, strlen(daemon->namebuff), 0))
Simon Kelley79cfefd2012-09-02 13:29:51 +0100633 err = 1;
Simon Kelley83e4b732018-02-06 16:57:15 +0000634 else
Simon Kelleyff841eb2015-03-11 21:36:30 +0000635 {
Simon Kelley5fc639c2019-03-29 21:29:43 +0000636 if (close(fd) == -1)
Simon Kelleyff841eb2015-03-11 21:36:30 +0000637 err = 1;
638 }
Simon Kelley79cfefd2012-09-02 13:29:51 +0100639 }
640
641 if (err)
Simon Kelley1a6bca82008-07-11 11:11:42 +0100642 {
Simon Kelleyc72daea2012-01-05 21:33:27 +0000643 send_event(err_pipe[1], EVENT_PIDFILE, errno, daemon->runfile);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100644 _exit(0);
645 }
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000646 }
Simon Kelley16972692006-10-16 20:04:18 +0100647 }
648
Simon Kelley8ef5ada2010-06-03 19:42:45 +0100649 log_err = log_start(ent_pw, err_pipe[1]);
650
Simon Kelley28866e92011-02-14 20:19:14 +0000651 if (!option_bool(OPT_DEBUG))
Simon Kelley8ef5ada2010-06-03 19:42:45 +0100652 {
653 /* open stdout etc to /dev/null */
654 int nullfd = open("/dev/null", O_RDWR);
Simon Kelleyf7cf7492016-03-01 16:19:23 +0000655 if (nullfd != -1)
656 {
657 dup2(nullfd, STDOUT_FILENO);
658 dup2(nullfd, STDERR_FILENO);
659 dup2(nullfd, STDIN_FILENO);
660 close(nullfd);
661 }
Simon Kelley8ef5ada2010-06-03 19:42:45 +0100662 }
Simon Kelleyf2621c72007-04-29 19:47:21 +0100663
Simon Kelley1a6bca82008-07-11 11:11:42 +0100664 /* if we are to run scripts, we need to fork a helper before dropping root. */
665 daemon->helperfd = -1;
Simon Kelleyc72daea2012-01-05 21:33:27 +0000666#ifdef HAVE_SCRIPT
Simon Kelley1e505122016-01-25 21:29:23 +0000667 if ((daemon->dhcp || daemon->dhcp6 || option_bool(OPT_TFTP) || option_bool(OPT_SCRIPT_ARP)) &&
Simon Kelley33702ab2015-12-28 23:17:15 +0000668 (daemon->lease_change_command || daemon->luascript))
669 daemon->helperfd = create_helper(pipewrite, err_pipe[1], script_uid, script_gid, max_fd);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100670#endif
Simon Kelley5aabfc72007-08-29 11:24:47 +0100671
Simon Kelley28866e92011-02-14 20:19:14 +0000672 if (!option_bool(OPT_DEBUG) && getuid() == 0)
Simon Kelley16972692006-10-16 20:04:18 +0100673 {
Simon Kelley1a6bca82008-07-11 11:11:42 +0100674 int bad_capabilities = 0;
675 gid_t dummy;
Simon Kelley16972692006-10-16 20:04:18 +0100676
Josh Soref730c6742017-02-06 16:14:04 +0000677 /* remove all supplementary groups */
Simon Kelley1a6bca82008-07-11 11:11:42 +0100678 if (gp &&
679 (setgroups(0, &dummy) == -1 ||
680 setgid(gp->gr_gid) == -1))
681 {
Simon Kelleyc72daea2012-01-05 21:33:27 +0000682 send_event(err_pipe[1], EVENT_GROUP_ERR, errno, daemon->groupname);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100683 _exit(0);
684 }
685
Simon Kelley7cebd202006-05-06 14:13:33 +0100686 if (ent_pw && ent_pw->pw_uid != 0)
Simon Kelley16972692006-10-16 20:04:18 +0100687 {
Simon Kelley74c95c22011-10-19 09:33:39 +0100688#if defined(HAVE_LINUX_NETWORK)
Simon Kelley305ffb52019-03-16 18:17:17 +0000689 /* Need to be able to drop root. */
690 data->effective |= (1 << CAP_SETUID);
691 data->permitted |= (1 << CAP_SETUID);
Simon Kelley16972692006-10-16 20:04:18 +0100692 /* Tell kernel to not clear capabilities when dropping root */
Simon Kelley572b41e2011-02-18 18:11:18 +0000693 if (capset(hdr, data) == -1 || prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1)
Simon Kelley16972692006-10-16 20:04:18 +0100694 bad_capabilities = errno;
Simon Kelley1a6bca82008-07-11 11:11:42 +0100695
Simon Kelley7622fc02009-06-04 20:32:05 +0100696#elif defined(HAVE_SOLARIS_NETWORK)
Simon Kelley824af852008-02-12 20:43:05 +0000697 /* http://developers.sun.com/solaris/articles/program_privileges.html */
698 priv_set_t *priv_set;
699
700 if (!(priv_set = priv_str_to_set("basic", ",", NULL)) ||
701 priv_addset(priv_set, PRIV_NET_ICMPACCESS) == -1 ||
702 priv_addset(priv_set, PRIV_SYS_NET_CONFIG) == -1)
703 bad_capabilities = errno;
704
705 if (priv_set && bad_capabilities == 0)
706 {
707 priv_inverse(priv_set);
708
709 if (setppriv(PRIV_OFF, PRIV_LIMIT, priv_set) == -1)
710 bad_capabilities = errno;
711 }
712
713 if (priv_set)
714 priv_freeset(priv_set);
715
Simon Kelley824af852008-02-12 20:43:05 +0000716#endif
717
Simon Kelley1a6bca82008-07-11 11:11:42 +0100718 if (bad_capabilities != 0)
Simon Kelley16972692006-10-16 20:04:18 +0100719 {
Simon Kelleyc72daea2012-01-05 21:33:27 +0000720 send_event(err_pipe[1], EVENT_CAP_ERR, bad_capabilities, NULL);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100721 _exit(0);
Simon Kelley16972692006-10-16 20:04:18 +0100722 }
Simon Kelley1a6bca82008-07-11 11:11:42 +0100723
724 /* finally drop root */
725 if (setuid(ent_pw->pw_uid) == -1)
726 {
Simon Kelleyc72daea2012-01-05 21:33:27 +0000727 send_event(err_pipe[1], EVENT_USER_ERR, errno, daemon->username);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100728 _exit(0);
729 }
730
731#ifdef HAVE_LINUX_NETWORK
Simon Kelley305ffb52019-03-16 18:17:17 +0000732 data->effective &= ~(1 << CAP_SETUID);
733 data->permitted &= ~(1 << CAP_SETUID);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100734
Simon Kelley305ffb52019-03-16 18:17:17 +0000735 /* lose the setuid capability */
Simon Kelley1a6bca82008-07-11 11:11:42 +0100736 if (capset(hdr, data) == -1)
737 {
Simon Kelleyc72daea2012-01-05 21:33:27 +0000738 send_event(err_pipe[1], EVENT_CAP_ERR, errno, NULL);
Simon Kelley1a6bca82008-07-11 11:11:42 +0100739 _exit(0);
740 }
741#endif
742
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000743 }
Simon Kelley849a8352006-06-09 21:02:31 +0100744 }
Simon Kelley16972692006-10-16 20:04:18 +0100745
Simon Kelley16972692006-10-16 20:04:18 +0100746#ifdef HAVE_LINUX_NETWORK
Chen Wei28b879a2015-02-17 22:07:35 +0000747 free(hdr);
748 free(data);
Simon Kelley28866e92011-02-14 20:19:14 +0000749 if (option_bool(OPT_DEBUG))
Simon Kelley572b41e2011-02-18 18:11:18 +0000750 prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
Simon Kelley16972692006-10-16 20:04:18 +0100751#endif
Simon Kelley849a8352006-06-09 21:02:31 +0100752
Simon Kelley8b3ae2f2012-06-13 13:43:49 +0100753#ifdef HAVE_TFTP
Stefan Tomanek30d08792015-03-31 22:32:11 +0100754 if (option_bool(OPT_TFTP))
Simon Kelley8b3ae2f2012-06-13 13:43:49 +0100755 {
756 DIR *dir;
757 struct tftp_prefix *p;
758
759 if (daemon->tftp_prefix)
760 {
761 if (!((dir = opendir(daemon->tftp_prefix))))
762 {
Stefan Tomanek30d08792015-03-31 22:32:11 +0100763 tftp_prefix_missing = 1;
764 if (!option_bool(OPT_TFTP_NO_FAIL))
765 {
766 send_event(err_pipe[1], EVENT_TFTP_ERR, errno, daemon->tftp_prefix);
767 _exit(0);
768 }
Simon Kelley8b3ae2f2012-06-13 13:43:49 +0100769 }
Stefan Tomanekb4c0f092015-04-16 15:20:59 +0100770 else
771 closedir(dir);
Simon Kelley8b3ae2f2012-06-13 13:43:49 +0100772 }
Stefan Tomanek7aa970e2015-04-01 17:55:07 +0100773
Simon Kelley8b3ae2f2012-06-13 13:43:49 +0100774 for (p = daemon->if_prefix; p; p = p->next)
775 {
Stefan Tomanek30d08792015-03-31 22:32:11 +0100776 p->missing = 0;
Simon Kelley8b3ae2f2012-06-13 13:43:49 +0100777 if (!((dir = opendir(p->prefix))))
Stefan Tomanek30d08792015-03-31 22:32:11 +0100778 {
779 p->missing = 1;
780 if (!option_bool(OPT_TFTP_NO_FAIL))
781 {
782 send_event(err_pipe[1], EVENT_TFTP_ERR, errno, p->prefix);
783 _exit(0);
784 }
Stefan Tomanek7aa970e2015-04-01 17:55:07 +0100785 }
Stefan Tomanekb4c0f092015-04-16 15:20:59 +0100786 else
787 closedir(dir);
Simon Kelley8b3ae2f2012-06-13 13:43:49 +0100788 }
789 }
790#endif
Stefan Tomanek7aa970e2015-04-01 17:55:07 +0100791
Simon Kelley824af852008-02-12 20:43:05 +0000792 if (daemon->port == 0)
793 my_syslog(LOG_INFO, _("started, version %s DNS disabled"), VERSION);
Simon Kelley0ef13342017-01-15 16:42:39 +0000794 else
795 {
796 if (daemon->cachesize != 0)
Simon Kelley1f1873a2018-05-11 23:38:23 +0100797 {
798 my_syslog(LOG_INFO, _("started, version %s cachesize %d"), VERSION, daemon->cachesize);
799 if (daemon->cachesize > 10000)
800 my_syslog(LOG_WARNING, _("cache size greater than 10000 may cause performance issues, and is unlikely to be useful."));
801 }
Simon Kelley0ef13342017-01-15 16:42:39 +0000802 else
803 my_syslog(LOG_INFO, _("started, version %s cache disabled"), VERSION);
804
805 if (option_bool(OPT_LOCAL_SERVICE))
806 my_syslog(LOG_INFO, _("DNS service limited to local subnets"));
807 }
Simon Kelley16972692006-10-16 20:04:18 +0100808
Simon Kelleyf2621c72007-04-29 19:47:21 +0100809 my_syslog(LOG_INFO, _("compile time options: %s"), compile_opts);
Simon Kelley6b54d692018-02-08 21:23:05 +0000810
811 if (chown_warn != 0)
812 my_syslog(LOG_WARNING, "chown of PID file %s failed: %s", daemon->runfile, strerror(chown_warn));
Simon Kelley16972692006-10-16 20:04:18 +0100813
Simon Kelley3d8df262005-08-29 12:19:27 +0100814#ifdef HAVE_DBUS
Simon Kelley28866e92011-02-14 20:19:14 +0000815 if (option_bool(OPT_DBUS))
Simon Kelley3d8df262005-08-29 12:19:27 +0100816 {
817 if (daemon->dbus)
Simon Kelleyf2621c72007-04-29 19:47:21 +0100818 my_syslog(LOG_INFO, _("DBus support enabled: connected to system bus"));
Simon Kelley3d8df262005-08-29 12:19:27 +0100819 else
Simon Kelleyf2621c72007-04-29 19:47:21 +0100820 my_syslog(LOG_INFO, _("DBus support enabled: bus connection pending"));
Simon Kelley3d8df262005-08-29 12:19:27 +0100821 }
822#endif
Simon Kelley1a9a3482014-03-05 15:01:08 +0000823
Jan Willem Janssena2b82202019-03-25 12:42:23 +0100824#ifdef HAVE_UBUS
825 if (option_bool(OPT_UBUS))
826 {
827 if (daemon->ubus)
828 my_syslog(LOG_INFO, _("UBus support enabled: connected to system bus"));
829 else
830 my_syslog(LOG_INFO, _("UBus support enabled: bus connection pending"));
831 }
832#endif
833
Simon Kelley1d97ac42014-01-31 11:12:27 +0000834#ifdef HAVE_DNSSEC
Simon Kelleydb737462014-01-31 10:32:45 +0000835 if (option_bool(OPT_DNSSEC_VALID))
Simon Kelleye98bd522014-03-28 20:41:23 +0000836 {
Simon Kelley360f2512015-03-07 18:28:06 +0000837 int rc;
Simon Kelley3b6eb192018-07-20 21:23:56 +0100838 struct ds_config *ds;
839
Simon Kelley360f2512015-03-07 18:28:06 +0000840 /* Delay creating the timestamp file until here, after we've changed user, so that
841 it has the correct owner to allow updating the mtime later.
842 This means we have to report fatal errors via the pipe. */
843 if ((rc = setup_timestamp()) == -1)
844 {
845 send_event(err_pipe[1], EVENT_TIME_ERR, errno, daemon->timestamp_file);
846 _exit(0);
847 }
848
Simon Kelleya6918532018-04-15 16:20:52 +0100849 if (option_bool(OPT_DNSSEC_IGN_NS))
850 my_syslog(LOG_INFO, _("DNSSEC validation enabled but all unsigned answers are trusted"));
851 else
852 my_syslog(LOG_INFO, _("DNSSEC validation enabled"));
Simon Kelley360f2512015-03-07 18:28:06 +0000853
Kevin Darbyshire-Bryant06093a92016-07-11 21:03:27 +0100854 daemon->dnssec_no_time_check = option_bool(OPT_DNSSEC_TIME);
855 if (option_bool(OPT_DNSSEC_TIME) && !daemon->back_to_the_future)
Simon Kelley3c973ad2018-01-14 21:05:37 +0000856 my_syslog(LOG_INFO, _("DNSSEC signature timestamps not checked until receipt of SIGINT"));
Simon Kelley360f2512015-03-07 18:28:06 +0000857
858 if (rc == 1)
Simon Kelleyf6e62e22015-03-01 18:17:54 +0000859 my_syslog(LOG_INFO, _("DNSSEC signature timestamps not checked until system time valid"));
Simon Kelley3b6eb192018-07-20 21:23:56 +0100860
861 for (ds = daemon->ds; ds; ds = ds->next)
862 my_syslog(LOG_INFO, _("configured with trust anchor for %s keytag %u"),
863 ds->name[0] == 0 ? "<root>" : ds->name, ds->keytag);
Simon Kelleye98bd522014-03-28 20:41:23 +0000864 }
Simon Kelleydb737462014-01-31 10:32:45 +0000865#endif
Simon Kelley3d8df262005-08-29 12:19:27 +0100866
Simon Kelley1a6bca82008-07-11 11:11:42 +0100867 if (log_err != 0)
868 my_syslog(LOG_WARNING, _("warning: failed to change owner of %s: %s"),
869 daemon->log_file, strerror(log_err));
Simon Kelleydb737462014-01-31 10:32:45 +0000870
Simon Kelleyde379512004-06-22 20:23:33 +0100871 if (bind_fallback)
Simon Kelleyf2621c72007-04-29 19:47:21 +0100872 my_syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations"));
Simon Kelleydc27e142013-10-16 13:09:53 +0100873
Simon Kelleyf7029f52013-11-21 15:09:09 +0000874 if (option_bool(OPT_NOWILD))
875 warn_bound_listeners();
Petr Menšíkad59f272017-03-17 17:22:19 +0000876 else if (!option_bool(OPT_CLEVERBIND))
877 warn_wild_labels();
Simon Kelleyf7029f52013-11-21 15:09:09 +0000878
879 warn_int_names();
Simon Kelleyde379512004-06-22 20:23:33 +0100880
Simon Kelley28866e92011-02-14 20:19:14 +0000881 if (!option_bool(OPT_NOWILD))
Simon Kelley26128d22004-11-14 16:43:54 +0000882 for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
883 if (if_tmp->name && !if_tmp->used)
Simon Kelleyf2621c72007-04-29 19:47:21 +0100884 my_syslog(LOG_WARNING, _("warning: interface %s does not currently exist"), if_tmp->name);
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100885
Simon Kelley28866e92011-02-14 20:19:14 +0000886 if (daemon->port != 0 && option_bool(OPT_NO_RESOLV))
Simon Kelley208b65c2006-08-05 21:41:37 +0100887 {
888 if (daemon->resolv_files && !daemon->resolv_files->is_default)
Simon Kelleyf2621c72007-04-29 19:47:21 +0100889 my_syslog(LOG_WARNING, _("warning: ignoring resolv-file flag because no-resolv is set"));
Simon Kelley208b65c2006-08-05 21:41:37 +0100890 daemon->resolv_files = NULL;
Simon Kelley1b7ecd12007-02-05 14:57:57 +0000891 if (!daemon->servers)
Simon Kelleyf2621c72007-04-29 19:47:21 +0100892 my_syslog(LOG_WARNING, _("warning: no upstream servers configured"));
Simon Kelley208b65c2006-08-05 21:41:37 +0100893 }
894
Simon Kelleyf2621c72007-04-29 19:47:21 +0100895 if (daemon->max_logs != 0)
896 my_syslog(LOG_INFO, _("asynchronous logging enabled, queue limit is %d messages"), daemon->max_logs);
Simon Kelley1f776932012-12-16 19:46:08 +0000897
Simon Kelleyf2621c72007-04-29 19:47:21 +0100898
Simon Kelley7622fc02009-06-04 20:32:05 +0100899#ifdef HAVE_DHCP
Simon Kelley1f776932012-12-16 19:46:08 +0000900 for (context = daemon->dhcp; context; context = context->next)
901 log_context(AF_INET, context);
Simon Kelleyc8257542012-03-28 21:15:41 +0100902
Simon Kelleyff7eea22013-09-04 18:01:38 +0100903 for (relay = daemon->relay4; relay; relay = relay->next)
904 log_relay(AF_INET, relay);
905
Simon Kelley1f776932012-12-16 19:46:08 +0000906# ifdef HAVE_DHCP6
907 for (context = daemon->dhcp6; context; context = context->next)
908 log_context(AF_INET6, context);
Simon Kelley52b92f42012-01-22 16:05:15 +0000909
Simon Kelleyff7eea22013-09-04 18:01:38 +0100910 for (relay = daemon->relay6; relay; relay = relay->next)
911 log_relay(AF_INET6, relay);
912
Simon Kelley1f776932012-12-16 19:46:08 +0000913 if (daemon->doing_dhcp6 || daemon->doing_ra)
914 dhcp_construct_contexts(now);
915
916 if (option_bool(OPT_RA))
917 my_syslog(MS_DHCP | LOG_INFO, _("IPv6 router advertisement enabled"));
918# endif
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000919
Simon Kelley3b3f4412013-10-11 16:33:28 +0100920# ifdef HAVE_LINUX_NETWORK
921 if (did_bind)
922 my_syslog(MS_DHCP | LOG_INFO, _("DHCP, sockets bound exclusively to interface %s"), bound_device);
923# endif
924
Josh Soref730c6742017-02-06 16:14:04 +0000925 /* after dhcp_construct_contexts */
Simon Kelley8445f5d2012-12-17 21:54:08 +0000926 if (daemon->dhcp || daemon->doing_dhcp6)
927 lease_find_interfaces(now);
Simon Kelley1f776932012-12-16 19:46:08 +0000928#endif
Simon Kelley52b92f42012-01-22 16:05:15 +0000929
Simon Kelley832af0b2007-01-21 20:01:28 +0000930#ifdef HAVE_TFTP
Simon Kelley5f4dc5c2015-01-20 20:51:02 +0000931 if (option_bool(OPT_TFTP))
Stefan Tomanek7aa970e2015-04-01 17:55:07 +0100932 {
Stefan Tomanek30d08792015-03-31 22:32:11 +0100933 struct tftp_prefix *p;
Simon Kelley832af0b2007-01-21 20:01:28 +0000934
Simon Kelley7622fc02009-06-04 20:32:05 +0100935 my_syslog(MS_TFTP | LOG_INFO, "TFTP %s%s %s",
Simon Kelleyf2621c72007-04-29 19:47:21 +0100936 daemon->tftp_prefix ? _("root is ") : _("enabled"),
937 daemon->tftp_prefix ? daemon->tftp_prefix: "",
Simon Kelley28866e92011-02-14 20:19:14 +0000938 option_bool(OPT_TFTP_SECURE) ? _("secure mode") : "");
Stefan Tomanek7aa970e2015-04-01 17:55:07 +0100939
Stefan Tomanek30d08792015-03-31 22:32:11 +0100940 if (tftp_prefix_missing)
941 my_syslog(MS_TFTP | LOG_WARNING, _("warning: %s inaccessible"), daemon->tftp_prefix);
Stefan Tomanek7aa970e2015-04-01 17:55:07 +0100942
Stefan Tomanek30d08792015-03-31 22:32:11 +0100943 for (p = daemon->if_prefix; p; p = p->next)
944 if (p->missing)
945 my_syslog(MS_TFTP | LOG_WARNING, _("warning: TFTP directory %s inaccessible"), p->prefix);
946
Simon Kelley832af0b2007-01-21 20:01:28 +0000947 /* This is a guess, it assumes that for small limits,
Simon Kelleyf2621c72007-04-29 19:47:21 +0100948 disjoint files might be served, but for large limits,
Simon Kelley832af0b2007-01-21 20:01:28 +0000949 a single file will be sent to may clients (the file only needs
950 one fd). */
951
952 max_fd -= 30; /* use other than TFTP */
953
954 if (max_fd < 0)
955 max_fd = 5;
956 else if (max_fd < 100)
957 max_fd = max_fd/2;
958 else
959 max_fd = max_fd - 20;
Simon Kelley824af852008-02-12 20:43:05 +0000960
961 /* if we have to use a limited range of ports,
962 that will limit the number of transfers */
963 if (daemon->start_tftp_port != 0 &&
964 daemon->end_tftp_port - daemon->start_tftp_port + 1 < max_fd)
965 max_fd = daemon->end_tftp_port - daemon->start_tftp_port + 1;
Simon Kelley832af0b2007-01-21 20:01:28 +0000966
967 if (daemon->tftp_max > max_fd)
968 {
969 daemon->tftp_max = max_fd;
Simon Kelley7622fc02009-06-04 20:32:05 +0100970 my_syslog(MS_TFTP | LOG_WARNING,
Simon Kelleyf2621c72007-04-29 19:47:21 +0100971 _("restricting maximum simultaneous TFTP transfers to %d"),
972 daemon->tftp_max);
Simon Kelley832af0b2007-01-21 20:01:28 +0000973 }
974 }
975#endif
976
Simon Kelley1a6bca82008-07-11 11:11:42 +0100977 /* finished start-up - release original process */
978 if (err_pipe[1] != -1)
Simon Kelley5fc639c2019-03-29 21:29:43 +0000979 close(err_pipe[1]);
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000980
Simon Kelley824af852008-02-12 20:43:05 +0000981 if (daemon->port != 0)
982 check_servers();
983
Simon Kelley7cebd202006-05-06 14:13:33 +0100984 pid = getpid();
Simon Kelleya799ca02018-10-18 19:35:29 +0100985
986 daemon->pipe_to_parent = -1;
987 for (i = 0; i < MAX_PROCS; i++)
988 daemon->tcp_pipes[i] = -1;
Simon Kelley7cebd202006-05-06 14:13:33 +0100989
Simon Kelley04918052015-01-26 11:23:43 +0000990#ifdef HAVE_INOTIFY
Simon Kelley193de4a2014-12-10 17:32:16 +0000991 /* Using inotify, have to select a resolv file at startup */
992 poll_resolv(1, 0, now);
993#endif
994
Simon Kelley5e9e0ef2006-04-17 14:24:29 +0100995 while (1)
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000996 {
Simon Kelleyb842bc92015-07-12 21:09:11 +0100997 int t, timeout = -1;
Simon Kelley9e4abcb2004-01-22 19:47:41 +0000998
Simon Kelleyb842bc92015-07-12 21:09:11 +0100999 poll_reset();
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001000
Simon Kelley16972692006-10-16 20:04:18 +01001001 /* if we are out of resources, find how long we have to wait
1002 for some to come free, we'll loop around then and restart
1003 listening for queries */
Simon Kelleyb842bc92015-07-12 21:09:11 +01001004 if ((t = set_dns_listeners(now)) != 0)
1005 timeout = t * 1000;
Simon Kelley16972692006-10-16 20:04:18 +01001006
Simon Kelley832af0b2007-01-21 20:01:28 +00001007 /* Whilst polling for the dbus, or doing a tftp transfer, wake every quarter second */
1008 if (daemon->tftp_trans ||
Simon Kelley28866e92011-02-14 20:19:14 +00001009 (option_bool(OPT_DBUS) && !daemon->dbus))
Simon Kelleyb842bc92015-07-12 21:09:11 +01001010 timeout = 250;
1011
Simon Kelley74c95c22011-10-19 09:33:39 +01001012 /* Wake every second whilst waiting for DAD to complete */
1013 else if (is_dad_listeners())
Simon Kelleyb842bc92015-07-12 21:09:11 +01001014 timeout = 1000;
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001015
Simon Kelley832af0b2007-01-21 20:01:28 +00001016#ifdef HAVE_DBUS
Simon Kelleyb842bc92015-07-12 21:09:11 +01001017 set_dbus_listeners();
Julian Kornbergercaf4d572018-07-21 21:45:03 +01001018#endif
1019
1020#ifdef HAVE_UBUS
Kevin Darbyshire-Bryant9d6fd172018-07-28 13:26:39 +01001021 if (option_bool(OPT_UBUS))
Jan Willem Janssena2b82202019-03-25 12:42:23 +01001022 set_ubus_listeners();
Julian Kornbergercaf4d572018-07-21 21:45:03 +01001023#endif
Julian Kornberger8dcdb332018-07-21 22:11:08 +01001024
Simon Kelley7622fc02009-06-04 20:32:05 +01001025#ifdef HAVE_DHCP
Simon Kelleyff7eea22013-09-04 18:01:38 +01001026 if (daemon->dhcp || daemon->relay4)
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001027 {
Simon Kelleyb842bc92015-07-12 21:09:11 +01001028 poll_listen(daemon->dhcpfd, POLLIN);
Simon Kelley316e2732010-01-22 20:16:09 +00001029 if (daemon->pxefd != -1)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001030 poll_listen(daemon->pxefd, POLLIN);
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001031 }
Simon Kelley7622fc02009-06-04 20:32:05 +01001032#endif
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001033
Simon Kelley52b92f42012-01-22 16:05:15 +00001034#ifdef HAVE_DHCP6
Simon Kelleyff7eea22013-09-04 18:01:38 +01001035 if (daemon->doing_dhcp6 || daemon->relay6)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001036 poll_listen(daemon->dhcp6fd, POLLIN);
Simon Kelleyf6d69562015-07-08 22:38:13 +01001037
Simon Kelley1f776932012-12-16 19:46:08 +00001038 if (daemon->doing_ra)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001039 poll_listen(daemon->icmp6fd, POLLIN);
Simon Kelley52b92f42012-01-22 16:05:15 +00001040#endif
Simon Kelley04918052015-01-26 11:23:43 +00001041
1042#ifdef HAVE_INOTIFY
Simon Kelley5f4dc5c2015-01-20 20:51:02 +00001043 if (daemon->inotifyfd != -1)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001044 poll_listen(daemon->inotifyfd, POLLIN);
Simon Kelley04918052015-01-26 11:23:43 +00001045#endif
1046
1047#if defined(HAVE_LINUX_NETWORK)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001048 poll_listen(daemon->netlinkfd, POLLIN);
Simon Kelley1ee9be42013-12-09 16:50:19 +00001049#elif defined(HAVE_BSD_NETWORK)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001050 poll_listen(daemon->routefd, POLLIN);
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001051#endif
Simon Kelley193de4a2014-12-10 17:32:16 +00001052
Simon Kelleyb842bc92015-07-12 21:09:11 +01001053 poll_listen(piperead, POLLIN);
Simon Kelley16972692006-10-16 20:04:18 +01001054
Simon Kelley33702ab2015-12-28 23:17:15 +00001055#ifdef HAVE_SCRIPT
Simon Kelley53a91732016-01-06 17:59:13 +00001056# ifdef HAVE_DHCP
Simon Kelley33702ab2015-12-28 23:17:15 +00001057 while (helper_buf_empty() && do_script_run(now));
Simon Kelley53a91732016-01-06 17:59:13 +00001058# endif
1059
Simon Kelley1e505122016-01-25 21:29:23 +00001060 /* Refresh cache */
1061 if (option_bool(OPT_SCRIPT_ARP))
1062 find_mac(NULL, NULL, 0, now);
Simon Kelley33702ab2015-12-28 23:17:15 +00001063 while (helper_buf_empty() && do_arp_script_run());
Simon Kelley16972692006-10-16 20:04:18 +01001064
Simon Kelleya9530962012-03-20 22:07:35 +00001065# ifdef HAVE_TFTP
1066 while (helper_buf_empty() && do_tftp_script_run());
1067# endif
1068
Simon Kelley16972692006-10-16 20:04:18 +01001069 if (!helper_buf_empty())
Simon Kelleyb842bc92015-07-12 21:09:11 +01001070 poll_listen(daemon->helperfd, POLLOUT);
Simon Kelley33702ab2015-12-28 23:17:15 +00001071#else
Simon Kelley5aabfc72007-08-29 11:24:47 +01001072 /* need this for other side-effects */
Simon Kelley53a91732016-01-06 17:59:13 +00001073# ifdef HAVE_DHCP
Simon Kelley5aabfc72007-08-29 11:24:47 +01001074 while (do_script_run(now));
Simon Kelley53a91732016-01-06 17:59:13 +00001075# endif
1076
Simon Kelleyb633de92016-01-06 22:51:17 +00001077 while (do_arp_script_run());
Simon Kelleya9530962012-03-20 22:07:35 +00001078
1079# ifdef HAVE_TFTP
1080 while (do_tftp_script_run());
1081# endif
1082
Simon Kelley5aabfc72007-08-29 11:24:47 +01001083#endif
Simon Kelley33702ab2015-12-28 23:17:15 +00001084
Simon Kelley7622fc02009-06-04 20:32:05 +01001085
Simon Kelleyf2621c72007-04-29 19:47:21 +01001086 /* must do this just before select(), when we know no
1087 more calls to my_syslog() can occur */
Simon Kelleyb842bc92015-07-12 21:09:11 +01001088 set_log_writer();
Simon Kelleyf2621c72007-04-29 19:47:21 +01001089
Simon Kelleyb842bc92015-07-12 21:09:11 +01001090 if (do_poll(timeout) < 0)
1091 continue;
1092
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001093 now = dnsmasq_time();
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001094
Simon Kelleyb842bc92015-07-12 21:09:11 +01001095 check_log_writer(0);
Simon Kelley115ac3e2013-05-20 11:28:32 +01001096
1097 /* prime. */
1098 enumerate_interfaces(1);
1099
Simon Kelley74c95c22011-10-19 09:33:39 +01001100 /* Check the interfaces to see if any have exited DAD state
1101 and if so, bind the address. */
1102 if (is_dad_listeners())
1103 {
Simon Kelley115ac3e2013-05-20 11:28:32 +01001104 enumerate_interfaces(0);
Simon Kelley74c95c22011-10-19 09:33:39 +01001105 /* NB, is_dad_listeners() == 1 --> we're binding interfaces */
1106 create_bound_listeners(0);
Simon Kelleydc27e142013-10-16 13:09:53 +01001107 warn_bound_listeners();
Simon Kelley74c95c22011-10-19 09:33:39 +01001108 }
Simon Kelleyf2621c72007-04-29 19:47:21 +01001109
Simon Kelley1ee9be42013-12-09 16:50:19 +00001110#if defined(HAVE_LINUX_NETWORK)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001111 if (poll_check(daemon->netlinkfd, POLLIN))
Simon Kelleya0358e52014-06-07 13:38:48 +01001112 netlink_multicast();
Simon Kelley1ee9be42013-12-09 16:50:19 +00001113#elif defined(HAVE_BSD_NETWORK)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001114 if (poll_check(daemon->routefd, POLLIN))
Simon Kelleya0358e52014-06-07 13:38:48 +01001115 route_sock();
Simon Kelleyc52e1892010-06-07 22:01:39 +01001116#endif
1117
Simon Kelley04918052015-01-26 11:23:43 +00001118#ifdef HAVE_INOTIFY
Simon Kelleyb842bc92015-07-12 21:09:11 +01001119 if (daemon->inotifyfd != -1 && poll_check(daemon->inotifyfd, POLLIN) && inotify_check(now))
Simon Kelley5f4dc5c2015-01-20 20:51:02 +00001120 {
1121 if (daemon->port != 0 && !option_bool(OPT_NO_POLL))
1122 poll_resolv(1, 1, now);
1123 }
Simon Kelley193de4a2014-12-10 17:32:16 +00001124#else
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001125 /* Check for changes to resolv files once per second max. */
Simon Kelley3d8df262005-08-29 12:19:27 +01001126 /* Don't go silent for long periods if the clock goes backwards. */
Simon Kelley9009d742008-11-14 20:04:27 +00001127 if (daemon->last_resolv == 0 ||
1128 difftime(now, daemon->last_resolv) > 1.0 ||
1129 difftime(now, daemon->last_resolv) < -1.0)
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001130 {
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001131 /* poll_resolv doesn't need to reload first time through, since
1132 that's queued anyway. */
Simon Kelley33820b72004-04-03 21:10:00 +01001133
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001134 poll_resolv(0, daemon->last_resolv != 0, now);
1135 daemon->last_resolv = now;
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001136 }
Simon Kelley193de4a2014-12-10 17:32:16 +00001137#endif
1138
Simon Kelleyb842bc92015-07-12 21:09:11 +01001139 if (poll_check(piperead, POLLIN))
Simon Kelley5aabfc72007-08-29 11:24:47 +01001140 async_event(piperead, now);
Simon Kelley7cebd202006-05-06 14:13:33 +01001141
Simon Kelley3d8df262005-08-29 12:19:27 +01001142#ifdef HAVE_DBUS
1143 /* if we didn't create a DBus connection, retry now. */
Simon Kelley28866e92011-02-14 20:19:14 +00001144 if (option_bool(OPT_DBUS) && !daemon->dbus)
Simon Kelley3d8df262005-08-29 12:19:27 +01001145 {
1146 char *err;
Simon Kelley5aabfc72007-08-29 11:24:47 +01001147 if ((err = dbus_init()))
Simon Kelleyf2621c72007-04-29 19:47:21 +01001148 my_syslog(LOG_WARNING, _("DBus error: %s"), err);
Simon Kelley3d8df262005-08-29 12:19:27 +01001149 if (daemon->dbus)
Simon Kelleyf2621c72007-04-29 19:47:21 +01001150 my_syslog(LOG_INFO, _("connected to system DBus"));
Simon Kelley3d8df262005-08-29 12:19:27 +01001151 }
Simon Kelleyb842bc92015-07-12 21:09:11 +01001152 check_dbus_listeners();
Simon Kelley3d8df262005-08-29 12:19:27 +01001153#endif
Julian Kornbergercaf4d572018-07-21 21:45:03 +01001154
1155#ifdef HAVE_UBUS
Kevin Darbyshire-Bryant9d6fd172018-07-28 13:26:39 +01001156 if (option_bool(OPT_UBUS))
Jan Willem Janssena2b82202019-03-25 12:42:23 +01001157 {
1158 /* if we didn't create a UBus connection, retry now. */
1159 if (!daemon->ubus)
1160 {
1161 ubus_init();
1162 }
1163
1164 check_ubus_listeners();
1165 }
Julian Kornbergercaf4d572018-07-21 21:45:03 +01001166#endif
1167
Simon Kelleyb842bc92015-07-12 21:09:11 +01001168 check_dns_listeners(now);
Simon Kelley832af0b2007-01-21 20:01:28 +00001169
1170#ifdef HAVE_TFTP
Simon Kelleyb842bc92015-07-12 21:09:11 +01001171 check_tftp_listeners(now);
Simon Kelley832af0b2007-01-21 20:01:28 +00001172#endif
1173
Simon Kelley7622fc02009-06-04 20:32:05 +01001174#ifdef HAVE_DHCP
Simon Kelleyff7eea22013-09-04 18:01:38 +01001175 if (daemon->dhcp || daemon->relay4)
Simon Kelley316e2732010-01-22 20:16:09 +00001176 {
Simon Kelleyb842bc92015-07-12 21:09:11 +01001177 if (poll_check(daemon->dhcpfd, POLLIN))
Simon Kelley316e2732010-01-22 20:16:09 +00001178 dhcp_packet(now, 0);
Simon Kelleyb842bc92015-07-12 21:09:11 +01001179 if (daemon->pxefd != -1 && poll_check(daemon->pxefd, POLLIN))
Simon Kelley316e2732010-01-22 20:16:09 +00001180 dhcp_packet(now, 1);
1181 }
Simon Kelley16972692006-10-16 20:04:18 +01001182
Simon Kelley52b92f42012-01-22 16:05:15 +00001183#ifdef HAVE_DHCP6
Simon Kelleyb842bc92015-07-12 21:09:11 +01001184 if ((daemon->doing_dhcp6 || daemon->relay6) && poll_check(daemon->dhcp6fd, POLLIN))
Simon Kelley18c63ef2012-05-21 14:34:15 +01001185 dhcp6_packet(now);
Simon Kelleyc5ad4e72012-02-24 16:06:20 +00001186
Simon Kelleyb842bc92015-07-12 21:09:11 +01001187 if (daemon->doing_ra && poll_check(daemon->icmp6fd, POLLIN))
Simon Kelley1f776932012-12-16 19:46:08 +00001188 icmp6_packet(now);
Simon Kelley52b92f42012-01-22 16:05:15 +00001189#endif
1190
Simon Kelley1f15b812009-10-13 17:49:32 +01001191# ifdef HAVE_SCRIPT
Simon Kelley63ec5d12015-07-30 20:59:07 +01001192 if (daemon->helperfd != -1 && poll_check(daemon->helperfd, POLLOUT))
Simon Kelley5aabfc72007-08-29 11:24:47 +01001193 helper_write();
Simon Kelley7622fc02009-06-04 20:32:05 +01001194# endif
Simon Kelley5aabfc72007-08-29 11:24:47 +01001195#endif
1196
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001197 }
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001198}
1199
Simon Kelley3be34542004-09-11 19:12:13 +01001200static void sig_handler(int sig)
1201{
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001202 if (pid == 0)
1203 {
Simon Kelley16972692006-10-16 20:04:18 +01001204 /* ignore anything other than TERM during startup
1205 and in helper proc. (helper ignore TERM too) */
Simon Kelley3c973ad2018-01-14 21:05:37 +00001206 if (sig == SIGTERM || sig == SIGINT)
Simon Kelley5aabfc72007-08-29 11:24:47 +01001207 exit(EC_MISC);
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001208 }
Simon Kelley5aabfc72007-08-29 11:24:47 +01001209 else if (pid != getpid())
Simon Kelley3be34542004-09-11 19:12:13 +01001210 {
Simon Kelley16972692006-10-16 20:04:18 +01001211 /* alarm is used to kill TCP children after a fixed time. */
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001212 if (sig == SIGALRM)
Simon Kelley7cebd202006-05-06 14:13:33 +01001213 _exit(0);
Simon Kelley3be34542004-09-11 19:12:13 +01001214 }
Simon Kelley5aabfc72007-08-29 11:24:47 +01001215 else
1216 {
1217 /* master process */
1218 int event, errsave = errno;
1219
1220 if (sig == SIGHUP)
1221 event = EVENT_RELOAD;
1222 else if (sig == SIGCHLD)
1223 event = EVENT_CHILD;
1224 else if (sig == SIGALRM)
1225 event = EVENT_ALARM;
1226 else if (sig == SIGTERM)
1227 event = EVENT_TERM;
1228 else if (sig == SIGUSR1)
1229 event = EVENT_DUMP;
1230 else if (sig == SIGUSR2)
1231 event = EVENT_REOPEN;
Simon Kelley3c973ad2018-01-14 21:05:37 +00001232 else if (sig == SIGINT)
1233 {
1234 /* Handle SIGINT normally in debug mode, so
1235 ctrl-c continues to operate. */
1236 if (option_bool(OPT_DEBUG))
1237 exit(EC_MISC);
1238 else
1239 event = EVENT_TIME;
1240 }
Simon Kelley5aabfc72007-08-29 11:24:47 +01001241 else
1242 return;
1243
Simon Kelleyc72daea2012-01-05 21:33:27 +00001244 send_event(pipewrite, event, 0, NULL);
Simon Kelley5aabfc72007-08-29 11:24:47 +01001245 errno = errsave;
1246 }
Simon Kelley3be34542004-09-11 19:12:13 +01001247}
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001248
Simon Kelley353ae4d2012-03-19 20:07:51 +00001249/* now == 0 -> queue immediate callback */
1250void send_alarm(time_t event, time_t now)
Simon Kelley741c2952012-02-25 13:09:18 +00001251{
Simon Kelley884a6df2012-03-20 16:20:22 +00001252 if (now == 0 || event != 0)
Simon Kelley353ae4d2012-03-19 20:07:51 +00001253 {
Simon Kelley884a6df2012-03-20 16:20:22 +00001254 /* alarm(0) or alarm(-ve) doesn't do what we want.... */
1255 if ((now == 0 || difftime(event, now) <= 0.0))
1256 send_event(pipewrite, EVENT_ALARM, 0, NULL);
1257 else
1258 alarm((unsigned)difftime(event, now));
Simon Kelley353ae4d2012-03-19 20:07:51 +00001259 }
Simon Kelley741c2952012-02-25 13:09:18 +00001260}
1261
Simon Kelley47a95162014-07-08 22:22:02 +01001262void queue_event(int event)
Simon Kelleya0358e52014-06-07 13:38:48 +01001263{
Simon Kelley47a95162014-07-08 22:22:02 +01001264 send_event(pipewrite, event, 0, NULL);
Simon Kelleya0358e52014-06-07 13:38:48 +01001265}
1266
Simon Kelleyc72daea2012-01-05 21:33:27 +00001267void send_event(int fd, int event, int data, char *msg)
Simon Kelley5aabfc72007-08-29 11:24:47 +01001268{
1269 struct event_desc ev;
Simon Kelleyc72daea2012-01-05 21:33:27 +00001270 struct iovec iov[2];
1271
Simon Kelley5aabfc72007-08-29 11:24:47 +01001272 ev.event = event;
1273 ev.data = data;
Simon Kelleyc72daea2012-01-05 21:33:27 +00001274 ev.msg_sz = msg ? strlen(msg) : 0;
1275
1276 iov[0].iov_base = &ev;
1277 iov[0].iov_len = sizeof(ev);
1278 iov[1].iov_base = msg;
1279 iov[1].iov_len = ev.msg_sz;
Simon Kelley1a6bca82008-07-11 11:11:42 +01001280
1281 /* error pipe, debug mode. */
1282 if (fd == -1)
Simon Kelleyc72daea2012-01-05 21:33:27 +00001283 fatal_event(&ev, msg);
Simon Kelley1a6bca82008-07-11 11:11:42 +01001284 else
1285 /* pipe is non-blocking and struct event_desc is smaller than
1286 PIPE_BUF, so this either fails or writes everything */
Simon Kelleyc72daea2012-01-05 21:33:27 +00001287 while (writev(fd, iov, msg ? 2 : 1) == -1 && errno == EINTR);
Simon Kelley5aabfc72007-08-29 11:24:47 +01001288}
Simon Kelley3d8df262005-08-29 12:19:27 +01001289
Simon Kelleyc72daea2012-01-05 21:33:27 +00001290/* NOTE: the memory used to return msg is leaked: use msgs in events only
1291 to describe fatal errors. */
1292static int read_event(int fd, struct event_desc *evp, char **msg)
1293{
1294 char *buf;
1295
1296 if (!read_write(fd, (unsigned char *)evp, sizeof(struct event_desc), 1))
1297 return 0;
1298
1299 *msg = NULL;
1300
1301 if (evp->msg_sz != 0 &&
1302 (buf = malloc(evp->msg_sz + 1)) &&
1303 read_write(fd, (unsigned char *)buf, evp->msg_sz, 1))
1304 {
1305 buf[evp->msg_sz] = 0;
1306 *msg = buf;
1307 }
1308
1309 return 1;
1310}
1311
1312static void fatal_event(struct event_desc *ev, char *msg)
Simon Kelley1a6bca82008-07-11 11:11:42 +01001313{
1314 errno = ev->data;
1315
1316 switch (ev->event)
1317 {
1318 case EVENT_DIE:
1319 exit(0);
Simon Kelley7622fc02009-06-04 20:32:05 +01001320
1321 case EVENT_FORK_ERR:
1322 die(_("cannot fork into background: %s"), NULL, EC_MISC);
Simon Kelleye7a4af82018-02-16 21:27:35 +00001323
1324 /* fall through */
Simon Kelley1a6bca82008-07-11 11:11:42 +01001325 case EVENT_PIPE_ERR:
1326 die(_("failed to create helper: %s"), NULL, EC_MISC);
Simon Kelleye7a4af82018-02-16 21:27:35 +00001327
1328 /* fall through */
Simon Kelley1a6bca82008-07-11 11:11:42 +01001329 case EVENT_CAP_ERR:
1330 die(_("setting capabilities failed: %s"), NULL, EC_MISC);
1331
Simon Kelleye7a4af82018-02-16 21:27:35 +00001332 /* fall through */
Simon Kelley1a6bca82008-07-11 11:11:42 +01001333 case EVENT_USER_ERR:
Simon Kelleyc72daea2012-01-05 21:33:27 +00001334 die(_("failed to change user-id to %s: %s"), msg, EC_MISC);
Simon Kelley1a6bca82008-07-11 11:11:42 +01001335
Simon Kelleye7a4af82018-02-16 21:27:35 +00001336 /* fall through */
Simon Kelley1a6bca82008-07-11 11:11:42 +01001337 case EVENT_GROUP_ERR:
Simon Kelleyc72daea2012-01-05 21:33:27 +00001338 die(_("failed to change group-id to %s: %s"), msg, EC_MISC);
Simon Kelleye7a4af82018-02-16 21:27:35 +00001339
1340 /* fall through */
Simon Kelley1a6bca82008-07-11 11:11:42 +01001341 case EVENT_PIDFILE:
Simon Kelleyc72daea2012-01-05 21:33:27 +00001342 die(_("failed to open pidfile %s: %s"), msg, EC_FILE);
Simon Kelley1a6bca82008-07-11 11:11:42 +01001343
Simon Kelleye7a4af82018-02-16 21:27:35 +00001344 /* fall through */
Simon Kelley1a6bca82008-07-11 11:11:42 +01001345 case EVENT_LOG_ERR:
Simon Kelleyc72daea2012-01-05 21:33:27 +00001346 die(_("cannot open log %s: %s"), msg, EC_FILE);
Simon Kelleye7a4af82018-02-16 21:27:35 +00001347
1348 /* fall through */
Simon Kelleyc72daea2012-01-05 21:33:27 +00001349 case EVENT_LUA_ERR:
1350 die(_("failed to load Lua script: %s"), msg, EC_MISC);
Simon Kelley8b3ae2f2012-06-13 13:43:49 +01001351
Simon Kelleye7a4af82018-02-16 21:27:35 +00001352 /* fall through */
Simon Kelley8b3ae2f2012-06-13 13:43:49 +01001353 case EVENT_TFTP_ERR:
1354 die(_("TFTP directory %s inaccessible: %s"), msg, EC_FILE);
Simon Kelleye7a4af82018-02-16 21:27:35 +00001355
1356 /* fall through */
Simon Kelley360f2512015-03-07 18:28:06 +00001357 case EVENT_TIME_ERR:
1358 die(_("cannot create timestamp file %s: %s" ), msg, EC_BADCONF);
Simon Kelley1a6bca82008-07-11 11:11:42 +01001359 }
1360}
1361
Simon Kelley5aabfc72007-08-29 11:24:47 +01001362static void async_event(int pipe, time_t now)
1363{
1364 pid_t p;
1365 struct event_desc ev;
Simon Kelley7b1eae42014-02-20 13:43:28 +00001366 int i, check = 0;
Simon Kelleyc72daea2012-01-05 21:33:27 +00001367 char *msg;
1368
1369 /* NOTE: the memory used to return msg is leaked: use msgs in events only
1370 to describe fatal errors. */
1371
1372 if (read_event(pipe, &ev, &msg))
Simon Kelley5aabfc72007-08-29 11:24:47 +01001373 switch (ev.event)
1374 {
1375 case EVENT_RELOAD:
Simon Kelleyc8328ec2016-08-05 16:54:58 +01001376 daemon->soa_sn++; /* Bump zone serial, as it may have changed. */
Simon Kelley3c973ad2018-01-14 21:05:37 +00001377
Simon Kelleye98bd522014-03-28 20:41:23 +00001378 /* fall through */
1379
1380 case EVENT_INIT:
Simon Kelley5aabfc72007-08-29 11:24:47 +01001381 clear_cache_and_reload(now);
Simon Kelleye98bd522014-03-28 20:41:23 +00001382
Simon Kelley7b1eae42014-02-20 13:43:28 +00001383 if (daemon->port != 0)
Simon Kelley5aabfc72007-08-29 11:24:47 +01001384 {
Simon Kelley7b1eae42014-02-20 13:43:28 +00001385 if (daemon->resolv_files && option_bool(OPT_NO_POLL))
1386 {
1387 reload_servers(daemon->resolv_files->name);
1388 check = 1;
1389 }
1390
1391 if (daemon->servers_file)
1392 {
1393 read_servers_file();
1394 check = 1;
1395 }
1396
1397 if (check)
1398 check_servers();
Simon Kelley5aabfc72007-08-29 11:24:47 +01001399 }
Simon Kelley7b1eae42014-02-20 13:43:28 +00001400
Simon Kelley7622fc02009-06-04 20:32:05 +01001401#ifdef HAVE_DHCP
Simon Kelley5aabfc72007-08-29 11:24:47 +01001402 rerun_scripts();
Simon Kelley7622fc02009-06-04 20:32:05 +01001403#endif
Simon Kelley5aabfc72007-08-29 11:24:47 +01001404 break;
1405
1406 case EVENT_DUMP:
Simon Kelley824af852008-02-12 20:43:05 +00001407 if (daemon->port != 0)
1408 dump_cache(now);
Simon Kelley5aabfc72007-08-29 11:24:47 +01001409 break;
1410
1411 case EVENT_ALARM:
Simon Kelley7622fc02009-06-04 20:32:05 +01001412#ifdef HAVE_DHCP
Simon Kelley1f776932012-12-16 19:46:08 +00001413 if (daemon->dhcp || daemon->doing_dhcp6)
Simon Kelley5aabfc72007-08-29 11:24:47 +01001414 {
1415 lease_prune(NULL, now);
1416 lease_update_file(now);
1417 }
Simon Kelley843c96b2012-02-27 17:42:38 +00001418#ifdef HAVE_DHCP6
Simon Kelley1f776932012-12-16 19:46:08 +00001419 else if (daemon->doing_ra)
Simon Kelley353ae4d2012-03-19 20:07:51 +00001420 /* Not doing DHCP, so no lease system, manage alarms for ra only */
1421 send_alarm(periodic_ra(now), now);
Simon Kelley843c96b2012-02-27 17:42:38 +00001422#endif
Simon Kelley7622fc02009-06-04 20:32:05 +01001423#endif
Simon Kelley5aabfc72007-08-29 11:24:47 +01001424 break;
1425
1426 case EVENT_CHILD:
1427 /* See Stevens 5.10 */
1428 while ((p = waitpid(-1, NULL, WNOHANG)) != 0)
1429 if (p == -1)
1430 {
1431 if (errno != EINTR)
1432 break;
1433 }
1434 else
1435 for (i = 0 ; i < MAX_PROCS; i++)
1436 if (daemon->tcp_pids[i] == p)
1437 daemon->tcp_pids[i] = 0;
1438 break;
1439
Petr Menšíkc77fb9d2017-04-16 20:20:08 +01001440#if defined(HAVE_SCRIPT)
Simon Kelley5aabfc72007-08-29 11:24:47 +01001441 case EVENT_KILLED:
Simon Kelleyc72daea2012-01-05 21:33:27 +00001442 my_syslog(LOG_WARNING, _("script process killed by signal %d"), ev.data);
Simon Kelley5aabfc72007-08-29 11:24:47 +01001443 break;
1444
1445 case EVENT_EXITED:
Simon Kelleyc72daea2012-01-05 21:33:27 +00001446 my_syslog(LOG_WARNING, _("script process exited with status %d"), ev.data);
Simon Kelley5aabfc72007-08-29 11:24:47 +01001447 break;
1448
1449 case EVENT_EXEC_ERR:
Simon Kelley9e038942008-05-30 20:06:34 +01001450 my_syslog(LOG_ERR, _("failed to execute %s: %s"),
1451 daemon->lease_change_command, strerror(ev.data));
Simon Kelley5aabfc72007-08-29 11:24:47 +01001452 break;
1453
Petr Menšíkc77fb9d2017-04-16 20:20:08 +01001454 case EVENT_SCRIPT_LOG:
1455 my_syslog(MS_SCRIPT | LOG_DEBUG, "%s", msg ? msg : "");
1456 free(msg);
1457 msg = NULL;
1458 break;
1459
Simon Kelley1a6bca82008-07-11 11:11:42 +01001460 /* necessary for fatal errors in helper */
Simon Kelleyc72daea2012-01-05 21:33:27 +00001461 case EVENT_USER_ERR:
Simon Kelley1a6bca82008-07-11 11:11:42 +01001462 case EVENT_DIE:
Simon Kelleyc72daea2012-01-05 21:33:27 +00001463 case EVENT_LUA_ERR:
1464 fatal_event(&ev, msg);
Simon Kelley9e038942008-05-30 20:06:34 +01001465 break;
Petr Menšíkc77fb9d2017-04-16 20:20:08 +01001466#endif
Simon Kelley9e038942008-05-30 20:06:34 +01001467
Simon Kelley5aabfc72007-08-29 11:24:47 +01001468 case EVENT_REOPEN:
1469 /* Note: this may leave TCP-handling processes with the old file still open.
1470 Since any such process will die in CHILD_LIFETIME or probably much sooner,
1471 we leave them logging to the old file. */
1472 if (daemon->log_file != NULL)
1473 log_reopen(daemon->log_file);
1474 break;
Simon Kelleya0358e52014-06-07 13:38:48 +01001475
1476 case EVENT_NEWADDR:
1477 newaddress(now);
1478 break;
Simon Kelley47a95162014-07-08 22:22:02 +01001479
1480 case EVENT_NEWROUTE:
1481 resend_query();
1482 /* Force re-reading resolv file right now, for luck. */
1483 poll_resolv(0, 1, now);
1484 break;
1485
Simon Kelley3c973ad2018-01-14 21:05:37 +00001486 case EVENT_TIME:
1487#ifdef HAVE_DNSSEC
1488 if (daemon->dnssec_no_time_check && option_bool(OPT_DNSSEC_VALID) && option_bool(OPT_DNSSEC_TIME))
1489 {
1490 my_syslog(LOG_INFO, _("now checking DNSSEC signature timestamps"));
1491 daemon->dnssec_no_time_check = 0;
1492 clear_cache_and_reload(now);
1493 }
1494#endif
1495 break;
1496
Simon Kelley5aabfc72007-08-29 11:24:47 +01001497 case EVENT_TERM:
1498 /* Knock all our children on the head. */
1499 for (i = 0; i < MAX_PROCS; i++)
1500 if (daemon->tcp_pids[i] != 0)
1501 kill(daemon->tcp_pids[i], SIGALRM);
1502
Simon Kelley53a91732016-01-06 17:59:13 +00001503#if defined(HAVE_SCRIPT) && defined(HAVE_DHCP)
Simon Kelley5aabfc72007-08-29 11:24:47 +01001504 /* handle pending lease transitions */
1505 if (daemon->helperfd != -1)
1506 {
1507 /* block in writes until all done */
1508 if ((i = fcntl(daemon->helperfd, F_GETFL)) != -1)
1509 fcntl(daemon->helperfd, F_SETFL, i & ~O_NONBLOCK);
1510 do {
1511 helper_write();
1512 } while (!helper_buf_empty() || do_script_run(now));
Simon Kelley5fc639c2019-03-29 21:29:43 +00001513 close(daemon->helperfd);
Simon Kelley5aabfc72007-08-29 11:24:47 +01001514 }
1515#endif
1516
1517 if (daemon->lease_stream)
1518 fclose(daemon->lease_stream);
Simon Kelley73a08a22009-02-05 20:28:08 +00001519
Kevin Darbyshire-Bryant34b5d192015-07-27 19:34:23 +01001520#ifdef HAVE_DNSSEC
1521 /* update timestamp file on TERM if time is considered valid */
1522 if (daemon->back_to_the_future)
1523 {
Vladislav Grishenko4583dd92017-05-03 23:16:51 +01001524 if (utimes(daemon->timestamp_file, NULL) == -1)
Kevin Darbyshire-Bryant34b5d192015-07-27 19:34:23 +01001525 my_syslog(LOG_ERR, _("failed to update mtime on %s: %s"), daemon->timestamp_file, strerror(errno));
1526 }
1527#endif
1528
Simon Kelley73a08a22009-02-05 20:28:08 +00001529 if (daemon->runfile)
1530 unlink(daemon->runfile);
Simon Kelley6b173352018-05-08 18:32:14 +01001531
1532#ifdef HAVE_DUMPFILE
1533 if (daemon->dumpfd != -1)
1534 close(daemon->dumpfd);
1535#endif
Simon Kelley5aabfc72007-08-29 11:24:47 +01001536
1537 my_syslog(LOG_INFO, _("exiting on receipt of SIGTERM"));
1538 flush_log();
1539 exit(EC_GOOD);
1540 }
1541}
1542
Simon Kelley47a95162014-07-08 22:22:02 +01001543static void poll_resolv(int force, int do_reload, time_t now)
Simon Kelley5aabfc72007-08-29 11:24:47 +01001544{
1545 struct resolvc *res, *latest;
1546 struct stat statbuf;
1547 time_t last_change = 0;
1548 /* There may be more than one possible file.
1549 Go through and find the one which changed _last_.
1550 Warn of any which can't be read. */
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001551
Simon Kelley28866e92011-02-14 20:19:14 +00001552 if (daemon->port == 0 || option_bool(OPT_NO_POLL))
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001553 return;
1554
Simon Kelley5aabfc72007-08-29 11:24:47 +01001555 for (latest = NULL, res = daemon->resolv_files; res; res = res->next)
1556 if (stat(res->name, &statbuf) == -1)
1557 {
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001558 if (force)
1559 {
1560 res->mtime = 0;
1561 continue;
1562 }
1563
Simon Kelley5aabfc72007-08-29 11:24:47 +01001564 if (!res->logged)
1565 my_syslog(LOG_WARNING, _("failed to access %s: %s"), res->name, strerror(errno));
1566 res->logged = 1;
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001567
1568 if (res->mtime != 0)
1569 {
1570 /* existing file evaporated, force selection of the latest
1571 file even if its mtime hasn't changed since we last looked */
1572 poll_resolv(1, do_reload, now);
1573 return;
1574 }
Simon Kelley5aabfc72007-08-29 11:24:47 +01001575 }
1576 else
1577 {
1578 res->logged = 0;
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001579 if (force || (statbuf.st_mtime != res->mtime))
1580 {
1581 res->mtime = statbuf.st_mtime;
Simon Kelley5aabfc72007-08-29 11:24:47 +01001582 if (difftime(statbuf.st_mtime, last_change) > 0.0)
1583 {
1584 last_change = statbuf.st_mtime;
1585 latest = res;
1586 }
1587 }
1588 }
1589
1590 if (latest)
1591 {
1592 static int warned = 0;
1593 if (reload_servers(latest->name))
1594 {
1595 my_syslog(LOG_INFO, _("reading %s"), latest->name);
1596 warned = 0;
1597 check_servers();
Simon Kelley28866e92011-02-14 20:19:14 +00001598 if (option_bool(OPT_RELOAD) && do_reload)
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001599 clear_cache_and_reload(now);
Simon Kelley5aabfc72007-08-29 11:24:47 +01001600 }
1601 else
1602 {
1603 latest->mtime = 0;
1604 if (!warned)
1605 {
1606 my_syslog(LOG_WARNING, _("no servers found in %s, will retry"), latest->name);
1607 warned = 1;
1608 }
1609 }
1610 }
1611}
1612
1613void clear_cache_and_reload(time_t now)
Simon Kelley3d8df262005-08-29 12:19:27 +01001614{
Vladislav Grishenko408c3682013-09-24 16:18:49 +01001615 (void)now;
1616
Simon Kelley824af852008-02-12 20:43:05 +00001617 if (daemon->port != 0)
Simon Kelley7622fc02009-06-04 20:32:05 +01001618 cache_reload();
Simon Kelley824af852008-02-12 20:43:05 +00001619
Simon Kelley7622fc02009-06-04 20:32:05 +01001620#ifdef HAVE_DHCP
Simon Kelley1f776932012-12-16 19:46:08 +00001621 if (daemon->dhcp || daemon->doing_dhcp6)
Simon Kelley3d8df262005-08-29 12:19:27 +01001622 {
Simon Kelley28866e92011-02-14 20:19:14 +00001623 if (option_bool(OPT_ETHERS))
Simon Kelley5aabfc72007-08-29 11:24:47 +01001624 dhcp_read_ethers();
Simon Kelley824af852008-02-12 20:43:05 +00001625 reread_dhcp();
Simon Kelley3d8df262005-08-29 12:19:27 +01001626 dhcp_update_configs(daemon->dhcp_conf);
Simon Kelley5aabfc72007-08-29 11:24:47 +01001627 lease_update_from_configs();
1628 lease_update_file(now);
Simon Kelley353ae4d2012-03-19 20:07:51 +00001629 lease_update_dns(1);
Simon Kelley3d8df262005-08-29 12:19:27 +01001630 }
Simon Kelley843c96b2012-02-27 17:42:38 +00001631#ifdef HAVE_DHCP6
Simon Kelley1f776932012-12-16 19:46:08 +00001632 else if (daemon->doing_ra)
Simon Kelley2021c662012-05-07 16:43:21 +01001633 /* Not doing DHCP, so no lease system, manage
1634 alarms for ra only */
1635 send_alarm(periodic_ra(now), now);
Simon Kelley843c96b2012-02-27 17:42:38 +00001636#endif
Simon Kelley7622fc02009-06-04 20:32:05 +01001637#endif
Simon Kelley3d8df262005-08-29 12:19:27 +01001638}
1639
Simon Kelleyb842bc92015-07-12 21:09:11 +01001640static int set_dns_listeners(time_t now)
Simon Kelley3be34542004-09-11 19:12:13 +01001641{
1642 struct serverfd *serverfdp;
1643 struct listener *listener;
Simon Kelley824af852008-02-12 20:43:05 +00001644 int wait = 0, i;
Simon Kelley832af0b2007-01-21 20:01:28 +00001645
1646#ifdef HAVE_TFTP
1647 int tftp = 0;
1648 struct tftp_transfer *transfer;
1649 for (transfer = daemon->tftp_trans; transfer; transfer = transfer->next)
1650 {
1651 tftp++;
Simon Kelleyb842bc92015-07-12 21:09:11 +01001652 poll_listen(transfer->sockfd, POLLIN);
Simon Kelley832af0b2007-01-21 20:01:28 +00001653 }
1654#endif
1655
Simon Kelley16972692006-10-16 20:04:18 +01001656 /* will we be able to get memory? */
Simon Kelley824af852008-02-12 20:43:05 +00001657 if (daemon->port != 0)
Simon Kelley3a237152013-12-12 12:15:50 +00001658 get_new_frec(now, &wait, 0);
Simon Kelley16972692006-10-16 20:04:18 +01001659
Simon Kelley3be34542004-09-11 19:12:13 +01001660 for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001661 poll_listen(serverfdp->fd, POLLIN);
Simon Kelleyf6d69562015-07-08 22:38:13 +01001662
Simon Kelley1a6bca82008-07-11 11:11:42 +01001663 if (daemon->port != 0 && !daemon->osport)
1664 for (i = 0; i < RANDOM_SOCKS; i++)
1665 if (daemon->randomsocks[i].refcount != 0)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001666 poll_listen(daemon->randomsocks[i].fd, POLLIN);
Simon Kelleyf6d69562015-07-08 22:38:13 +01001667
Simon Kelley3be34542004-09-11 19:12:13 +01001668 for (listener = daemon->listeners; listener; listener = listener->next)
1669 {
Simon Kelley16972692006-10-16 20:04:18 +01001670 /* only listen for queries if we have resources */
Simon Kelley824af852008-02-12 20:43:05 +00001671 if (listener->fd != -1 && wait == 0)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001672 poll_listen(listener->fd, POLLIN);
Simon Kelleyf6d69562015-07-08 22:38:13 +01001673
Simon Kelley16972692006-10-16 20:04:18 +01001674 /* death of a child goes through the select loop, so
1675 we don't need to explicitly arrange to wake up here */
Simon Kelley824af852008-02-12 20:43:05 +00001676 if (listener->tcpfd != -1)
1677 for (i = 0; i < MAX_PROCS; i++)
Simon Kelleya799ca02018-10-18 19:35:29 +01001678 if (daemon->tcp_pids[i] == 0 && daemon->tcp_pipes[i] == -1)
Simon Kelley824af852008-02-12 20:43:05 +00001679 {
Simon Kelleyb842bc92015-07-12 21:09:11 +01001680 poll_listen(listener->tcpfd, POLLIN);
Simon Kelley824af852008-02-12 20:43:05 +00001681 break;
1682 }
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001683
Simon Kelley832af0b2007-01-21 20:01:28 +00001684#ifdef HAVE_TFTP
1685 if (tftp <= daemon->tftp_max && listener->tftpfd != -1)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001686 poll_listen(listener->tftpfd, POLLIN);
Simon Kelley832af0b2007-01-21 20:01:28 +00001687#endif
1688
1689 }
1690
Simon Kelleya799ca02018-10-18 19:35:29 +01001691 if (!option_bool(OPT_DEBUG))
1692 for (i = 0; i < MAX_PROCS; i++)
1693 if (daemon->tcp_pipes[i] != -1)
1694 poll_listen(daemon->tcp_pipes[i], POLLIN);
Simon Kelleya799ca02018-10-18 19:35:29 +01001695
Simon Kelley16972692006-10-16 20:04:18 +01001696 return wait;
Simon Kelley3be34542004-09-11 19:12:13 +01001697}
Simon Kelley9e4abcb2004-01-22 19:47:41 +00001698
Simon Kelleyb842bc92015-07-12 21:09:11 +01001699static void check_dns_listeners(time_t now)
Simon Kelley3be34542004-09-11 19:12:13 +01001700{
1701 struct serverfd *serverfdp;
Simon Kelley1a6bca82008-07-11 11:11:42 +01001702 struct listener *listener;
1703 int i;
Simon Kelleya799ca02018-10-18 19:35:29 +01001704 int pipefd[2];
Simon Kelleya799ca02018-10-18 19:35:29 +01001705
Simon Kelley832af0b2007-01-21 20:01:28 +00001706 for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
Simon Kelleyb842bc92015-07-12 21:09:11 +01001707 if (poll_check(serverfdp->fd, POLLIN))
Simon Kelley1a6bca82008-07-11 11:11:42 +01001708 reply_query(serverfdp->fd, serverfdp->source_addr.sa.sa_family, now);
1709
1710 if (daemon->port != 0 && !daemon->osport)
1711 for (i = 0; i < RANDOM_SOCKS; i++)
1712 if (daemon->randomsocks[i].refcount != 0 &&
Simon Kelleyb842bc92015-07-12 21:09:11 +01001713 poll_check(daemon->randomsocks[i].fd, POLLIN))
Simon Kelley1a6bca82008-07-11 11:11:42 +01001714 reply_query(daemon->randomsocks[i].fd, daemon->randomsocks[i].family, now);
Simon Kelleya799ca02018-10-18 19:35:29 +01001715
Simon Kelleya799ca02018-10-18 19:35:29 +01001716 /* Races. The child process can die before we read all of the data from the
1717 pipe, or vice versa. Therefore send tcp_pids to zero when we wait() the
1718 process, and tcp_pipes to -1 and close the FD when we read the last
1719 of the data - indicated by cache_recv_insert returning zero.
1720 The order of these events is indeterminate, and both are needed
1721 to free the process slot. Once the child process has gone, poll()
1722 returns POLLHUP, not POLLIN, so have to check for both here. */
1723 if (!option_bool(OPT_DEBUG))
1724 for (i = 0; i < MAX_PROCS; i++)
1725 if (daemon->tcp_pipes[i] != -1 &&
1726 poll_check(daemon->tcp_pipes[i], POLLIN | POLLHUP) &&
1727 !cache_recv_insert(now, daemon->tcp_pipes[i]))
1728 {
1729 close(daemon->tcp_pipes[i]);
1730 daemon->tcp_pipes[i] = -1;
1731 }
Simon Kelleya799ca02018-10-18 19:35:29 +01001732
Simon Kelley832af0b2007-01-21 20:01:28 +00001733 for (listener = daemon->listeners; listener; listener = listener->next)
1734 {
Simon Kelleyb842bc92015-07-12 21:09:11 +01001735 if (listener->fd != -1 && poll_check(listener->fd, POLLIN))
Simon Kelley5aabfc72007-08-29 11:24:47 +01001736 receive_query(listener, now);
Simon Kelley1a6bca82008-07-11 11:11:42 +01001737
Simon Kelley832af0b2007-01-21 20:01:28 +00001738#ifdef HAVE_TFTP
Simon Kelleyb842bc92015-07-12 21:09:11 +01001739 if (listener->tftpfd != -1 && poll_check(listener->tftpfd, POLLIN))
Simon Kelley5aabfc72007-08-29 11:24:47 +01001740 tftp_request(listener, now);
Simon Kelley59353a62004-11-21 19:34:28 +00001741#endif
Simon Kelley832af0b2007-01-21 20:01:28 +00001742
Simon Kelleyb842bc92015-07-12 21:09:11 +01001743 if (listener->tcpfd != -1 && poll_check(listener->tcpfd, POLLIN))
Simon Kelley832af0b2007-01-21 20:01:28 +00001744 {
Simon Kelley22ce5502013-01-22 13:53:04 +00001745 int confd, client_ok = 1;
Simon Kelley832af0b2007-01-21 20:01:28 +00001746 struct irec *iface = NULL;
1747 pid_t p;
Simon Kelley52d4abf2012-03-21 21:39:48 +00001748 union mysockaddr tcp_addr;
1749 socklen_t tcp_len = sizeof(union mysockaddr);
1750
1751 while ((confd = accept(listener->tcpfd, NULL, NULL)) == -1 && errno == EINTR);
Simon Kelley832af0b2007-01-21 20:01:28 +00001752
Simon Kelley46b06652013-02-04 21:47:59 +00001753 if (confd == -1)
Simon Kelley832af0b2007-01-21 20:01:28 +00001754 continue;
Simon Kelley76dd75d2013-05-23 10:04:25 +01001755
Simon Kelley46b06652013-02-04 21:47:59 +00001756 if (getsockname(confd, (struct sockaddr *)&tcp_addr, &tcp_len) == -1)
1757 {
Simon Kelley5fc639c2019-03-29 21:29:43 +00001758 close(confd);
Simon Kelley46b06652013-02-04 21:47:59 +00001759 continue;
1760 }
Simon Kelley76dd75d2013-05-23 10:04:25 +01001761
1762 /* Make sure that the interface list is up-to-date.
1763
1764 We do this here as we may need the results below, and
1765 the DNS code needs them for --interface-name stuff.
Simon Kelley46b06652013-02-04 21:47:59 +00001766
Simon Kelley76dd75d2013-05-23 10:04:25 +01001767 Multiple calls to enumerate_interfaces() per select loop are
1768 inhibited, so calls to it in the child process (which doesn't select())
1769 have no effect. This avoids two processes reading from the same
1770 netlink fd and screwing the pooch entirely.
1771 */
Simon Kelleye25db1f2013-01-29 22:10:26 +00001772
Simon Kelley76dd75d2013-05-23 10:04:25 +01001773 enumerate_interfaces(0);
1774
1775 if (option_bool(OPT_NOWILD))
1776 iface = listener->iface; /* May be NULL */
1777 else
1778 {
1779 int if_index;
1780 char intr_name[IF_NAMESIZE];
1781
1782 /* if we can find the arrival interface, check it's one that's allowed */
1783 if ((if_index = tcp_interface(confd, tcp_addr.sa.sa_family)) != 0 &&
1784 indextoname(listener->tcpfd, if_index, intr_name))
1785 {
Simon Kelleycc921df2019-01-02 22:48:59 +00001786 union all_addr addr;
Simon Kelleyee875042018-10-23 22:10:17 +01001787
Simon Kelley76dd75d2013-05-23 10:04:25 +01001788 if (tcp_addr.sa.sa_family == AF_INET6)
Simon Kelleycc921df2019-01-02 22:48:59 +00001789 addr.addr6 = tcp_addr.in6.sin6_addr;
Simon Kelleyee875042018-10-23 22:10:17 +01001790 else
Simon Kelleycc921df2019-01-02 22:48:59 +00001791 addr.addr4 = tcp_addr.in.sin_addr;
Simon Kelley76dd75d2013-05-23 10:04:25 +01001792
1793 for (iface = daemon->interfaces; iface; iface = iface->next)
1794 if (iface->index == if_index)
1795 break;
1796
1797 if (!iface && !loopback_exception(listener->tcpfd, tcp_addr.sa.sa_family, &addr, intr_name))
1798 client_ok = 0;
1799 }
1800
1801 if (option_bool(OPT_CLEVERBIND))
1802 iface = listener->iface; /* May be NULL */
1803 else
1804 {
1805 /* Check for allowed interfaces when binding the wildcard address:
1806 we do this by looking for an interface with the same address as
1807 the local address of the TCP connection, then looking to see if that's
1808 an allowed interface. As a side effect, we get the netmask of the
1809 interface too, for localisation. */
1810
1811 for (iface = daemon->interfaces; iface; iface = iface->next)
1812 if (sockaddr_isequal(&iface->addr, &tcp_addr))
1813 break;
1814
1815 if (!iface)
1816 client_ok = 0;
1817 }
1818 }
1819
Simon Kelley22ce5502013-01-22 13:53:04 +00001820 if (!client_ok)
Simon Kelley832af0b2007-01-21 20:01:28 +00001821 {
1822 shutdown(confd, SHUT_RDWR);
Simon Kelley5fc639c2019-03-29 21:29:43 +00001823 close(confd);
Simon Kelley832af0b2007-01-21 20:01:28 +00001824 }
Simon Kelleya799ca02018-10-18 19:35:29 +01001825 else if (!option_bool(OPT_DEBUG) && pipe(pipefd) == 0 && (p = fork()) != 0)
Simon Kelley832af0b2007-01-21 20:01:28 +00001826 {
Simon Kelleya799ca02018-10-18 19:35:29 +01001827 close(pipefd[1]); /* parent needs read pipe end. */
1828 if (p == -1)
1829 close(pipefd[0]);
1830 else
Simon Kelley832af0b2007-01-21 20:01:28 +00001831 {
1832 int i;
Simon Kelleya799ca02018-10-18 19:35:29 +01001833
Simon Kelley832af0b2007-01-21 20:01:28 +00001834 for (i = 0; i < MAX_PROCS; i++)
Simon Kelleya799ca02018-10-18 19:35:29 +01001835 if (daemon->tcp_pids[i] == 0 && daemon->tcp_pipes[i] == -1)
Simon Kelley832af0b2007-01-21 20:01:28 +00001836 {
1837 daemon->tcp_pids[i] = p;
Simon Kelleya799ca02018-10-18 19:35:29 +01001838 daemon->tcp_pipes[i] = pipefd[0];
Simon Kelley832af0b2007-01-21 20:01:28 +00001839 break;
1840 }
1841 }
Simon Kelley5fc639c2019-03-29 21:29:43 +00001842 close(confd);
Simon Kelley25cf5e32015-01-09 15:53:03 +00001843
1844 /* The child can use up to TCP_MAX_QUERIES ids, so skip that many. */
1845 daemon->log_id += TCP_MAX_QUERIES;
Simon Kelley832af0b2007-01-21 20:01:28 +00001846 }
Simon Kelley832af0b2007-01-21 20:01:28 +00001847 else
1848 {
1849 unsigned char *buff;
1850 struct server *s;
1851 int flags;
Simon Kelley52d4abf2012-03-21 21:39:48 +00001852 struct in_addr netmask;
Simon Kelley4f7b3042012-11-28 21:27:02 +00001853 int auth_dns;
Simon Kelleya799ca02018-10-18 19:35:29 +01001854
Simon Kelley52d4abf2012-03-21 21:39:48 +00001855 if (iface)
Simon Kelley4f7b3042012-11-28 21:27:02 +00001856 {
1857 netmask = iface->netmask;
1858 auth_dns = iface->dns_auth;
1859 }
Simon Kelley52d4abf2012-03-21 21:39:48 +00001860 else
Simon Kelley4f7b3042012-11-28 21:27:02 +00001861 {
1862 netmask.s_addr = 0;
1863 auth_dns = 0;
1864 }
Simon Kelley52d4abf2012-03-21 21:39:48 +00001865
Josh Soref730c6742017-02-06 16:14:04 +00001866 /* Arrange for SIGALRM after CHILD_LIFETIME seconds to
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001867 terminate the process. */
Simon Kelley28866e92011-02-14 20:19:14 +00001868 if (!option_bool(OPT_DEBUG))
Simon Kelleya799ca02018-10-18 19:35:29 +01001869 {
1870 alarm(CHILD_LIFETIME);
1871 close(pipefd[0]); /* close read end in child. */
1872 daemon->pipe_to_parent = pipefd[1];
1873 }
Simon Kelley8ef5ada2010-06-03 19:42:45 +01001874
Simon Kelley832af0b2007-01-21 20:01:28 +00001875 /* start with no upstream connections. */
1876 for (s = daemon->servers; s; s = s->next)
Simon Kelley7cebd202006-05-06 14:13:33 +01001877 s->tcpfd = -1;
Simon Kelley832af0b2007-01-21 20:01:28 +00001878
1879 /* The connected socket inherits non-blocking
1880 attribute from the listening socket.
1881 Reset that here. */
1882 if ((flags = fcntl(confd, F_GETFL, 0)) != -1)
1883 fcntl(confd, F_SETFL, flags & ~O_NONBLOCK);
1884
Simon Kelley4f7b3042012-11-28 21:27:02 +00001885 buff = tcp_request(confd, now, &tcp_addr, netmask, auth_dns);
Simon Kelley7cebd202006-05-06 14:13:33 +01001886
Simon Kelley832af0b2007-01-21 20:01:28 +00001887 shutdown(confd, SHUT_RDWR);
Simon Kelley5fc639c2019-03-29 21:29:43 +00001888 close(confd);
Simon Kelley832af0b2007-01-21 20:01:28 +00001889
1890 if (buff)
1891 free(buff);
1892
1893 for (s = daemon->servers; s; s = s->next)
1894 if (s->tcpfd != -1)
1895 {
1896 shutdown(s->tcpfd, SHUT_RDWR);
Simon Kelley5fc639c2019-03-29 21:29:43 +00001897 close(s->tcpfd);
Simon Kelley832af0b2007-01-21 20:01:28 +00001898 }
Simon Kelley28866e92011-02-14 20:19:14 +00001899 if (!option_bool(OPT_DEBUG))
Simon Kelley5aabfc72007-08-29 11:24:47 +01001900 {
1901 flush_log();
1902 _exit(0);
1903 }
Simon Kelley832af0b2007-01-21 20:01:28 +00001904 }
1905 }
1906 }
Simon Kelley3be34542004-09-11 19:12:13 +01001907}
1908
Simon Kelley7622fc02009-06-04 20:32:05 +01001909#ifdef HAVE_DHCP
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001910int make_icmp_sock(void)
1911{
Simon Kelley7cebd202006-05-06 14:13:33 +01001912 int fd;
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001913 int zeroopt = 0;
1914
1915 if ((fd = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP)) != -1)
1916 {
Simon Kelley7cebd202006-05-06 14:13:33 +01001917 if (!fix_fd(fd) ||
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001918 setsockopt(fd, SOL_SOCKET, SO_DONTROUTE, &zeroopt, sizeof(zeroopt)) == -1)
1919 {
1920 close(fd);
1921 fd = -1;
1922 }
1923 }
1924
1925 return fd;
1926}
1927
Simon Kelley5aabfc72007-08-29 11:24:47 +01001928int icmp_ping(struct in_addr addr)
Simon Kelley3be34542004-09-11 19:12:13 +01001929{
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001930 /* Try and get an ICMP echo from a machine. */
Simon Kelley3be34542004-09-11 19:12:13 +01001931
Floris Bos503c6092017-04-09 23:07:13 +01001932 int fd;
Simon Kelley3be34542004-09-11 19:12:13 +01001933 struct sockaddr_in saddr;
1934 struct {
1935 struct ip ip;
1936 struct icmp icmp;
1937 } packet;
1938 unsigned short id = rand16();
Floris Bos503c6092017-04-09 23:07:13 +01001939 unsigned int i, j;
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001940 int gotreply = 0;
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001941
Simon Kelley824af852008-02-12 20:43:05 +00001942#if defined(HAVE_LINUX_NETWORK) || defined (HAVE_SOLARIS_NETWORK)
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01001943 if ((fd = make_icmp_sock()) == -1)
1944 return 0;
1945#else
1946 int opt = 2000;
1947 fd = daemon->dhcp_icmp_fd;
1948 setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
1949#endif
1950
Simon Kelley3be34542004-09-11 19:12:13 +01001951 saddr.sin_family = AF_INET;
1952 saddr.sin_port = 0;
1953 saddr.sin_addr = addr;
1954#ifdef HAVE_SOCKADDR_SA_LEN
1955 saddr.sin_len = sizeof(struct sockaddr_in);
1956#endif
1957
1958 memset(&packet.icmp, 0, sizeof(packet.icmp));
1959 packet.icmp.icmp_type = ICMP_ECHO;
1960 packet.icmp.icmp_id = id;
1961 for (j = 0, i = 0; i < sizeof(struct icmp) / 2; i++)
1962 j += ((u16 *)&packet.icmp)[i];
1963 while (j>>16)
1964 j = (j & 0xffff) + (j >> 16);
1965 packet.icmp.icmp_cksum = (j == 0xffff) ? j : ~j;
1966
Simon Kelleyff841eb2015-03-11 21:36:30 +00001967 while (retry_send(sendto(fd, (char *)&packet.icmp, sizeof(struct icmp), 0,
1968 (struct sockaddr *)&saddr, sizeof(saddr))));
Simon Kelleyfd9fa482004-10-21 20:24:00 +01001969
Floris Bos503c6092017-04-09 23:07:13 +01001970 gotreply = delay_dhcp(dnsmasq_time(), PING_WAIT, fd, addr.s_addr, id);
1971
1972#if defined(HAVE_LINUX_NETWORK) || defined(HAVE_SOLARIS_NETWORK)
Simon Kelley5fc639c2019-03-29 21:29:43 +00001973 close(fd);
Floris Bos503c6092017-04-09 23:07:13 +01001974#else
1975 opt = 1;
1976 setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
1977#endif
1978
1979 return gotreply;
1980}
1981
1982int delay_dhcp(time_t start, int sec, int fd, uint32_t addr, unsigned short id)
1983{
1984 /* Delay processing DHCP packets for "sec" seconds counting from "start".
1985 If "fd" is not -1 it will stop waiting if an ICMP echo reply is received
1986 from "addr" with ICMP ID "id" and return 1 */
1987
1988 /* Note that whilst waiting, we check for
1989 (and service) events on the DNS and TFTP sockets, (so doing that
1990 better not use any resources our caller has in use...)
1991 but we remain deaf to signals or further DHCP packets. */
1992
1993 /* There can be a problem using dnsmasq_time() to end the loop, since
1994 it's not monotonic, and can go backwards if the system clock is
1995 tweaked, leading to the code getting stuck in this loop and
1996 ignoring DHCP requests. To fix this, we check to see if select returned
1997 as a result of a timeout rather than a socket becoming available. We
1998 only allow this to happen as many times as it takes to get to the wait time
1999 in quarter-second chunks. This provides a fallback way to end loop. */
2000
2001 int rc, timeout_count;
2002 time_t now;
2003
2004 for (now = dnsmasq_time(), timeout_count = 0;
2005 (difftime(now, start) <= (float)sec) && (timeout_count < sec * 4);)
Simon Kelleyfd9fa482004-10-21 20:24:00 +01002006 {
Simon Kelleyb842bc92015-07-12 21:09:11 +01002007 poll_reset();
Floris Bos503c6092017-04-09 23:07:13 +01002008 if (fd != -1)
2009 poll_listen(fd, POLLIN);
Simon Kelleyb842bc92015-07-12 21:09:11 +01002010 set_dns_listeners(now);
2011 set_log_writer();
Simon Kelleyc5ad4e72012-02-24 16:06:20 +00002012
2013#ifdef HAVE_DHCP6
Simon Kelley1f776932012-12-16 19:46:08 +00002014 if (daemon->doing_ra)
Simon Kelleyb842bc92015-07-12 21:09:11 +01002015 poll_listen(daemon->icmp6fd, POLLIN);
Simon Kelleyc5ad4e72012-02-24 16:06:20 +00002016#endif
2017
Simon Kelleyb842bc92015-07-12 21:09:11 +01002018 rc = do_poll(250);
Simon Kelley5e95a552015-07-05 22:31:30 +01002019
2020 if (rc < 0)
Simon Kelleyb842bc92015-07-12 21:09:11 +01002021 continue;
Simon Kelley5e95a552015-07-05 22:31:30 +01002022 else if (rc == 0)
2023 timeout_count++;
Simon Kelleyf2621c72007-04-29 19:47:21 +01002024
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01002025 now = dnsmasq_time();
Floris Bos503c6092017-04-09 23:07:13 +01002026
Simon Kelleyb842bc92015-07-12 21:09:11 +01002027 check_log_writer(0);
2028 check_dns_listeners(now);
Floris Bos503c6092017-04-09 23:07:13 +01002029
Simon Kelleyc5ad4e72012-02-24 16:06:20 +00002030#ifdef HAVE_DHCP6
Simon Kelleyb842bc92015-07-12 21:09:11 +01002031 if (daemon->doing_ra && poll_check(daemon->icmp6fd, POLLIN))
Simon Kelley1f776932012-12-16 19:46:08 +00002032 icmp6_packet(now);
Simon Kelleyc5ad4e72012-02-24 16:06:20 +00002033#endif
2034
Simon Kelley832af0b2007-01-21 20:01:28 +00002035#ifdef HAVE_TFTP
Simon Kelleyb842bc92015-07-12 21:09:11 +01002036 check_tftp_listeners(now);
Simon Kelley832af0b2007-01-21 20:01:28 +00002037#endif
2038
Floris Bos503c6092017-04-09 23:07:13 +01002039 if (fd != -1)
2040 {
2041 struct {
2042 struct ip ip;
2043 struct icmp icmp;
2044 } packet;
2045 struct sockaddr_in faddr;
2046 socklen_t len = sizeof(faddr);
2047
2048 if (poll_check(fd, POLLIN) &&
2049 recvfrom(fd, &packet, sizeof(packet), 0, (struct sockaddr *)&faddr, &len) == sizeof(packet) &&
2050 addr == faddr.sin_addr.s_addr &&
2051 packet.icmp.icmp_type == ICMP_ECHOREPLY &&
2052 packet.icmp.icmp_seq == 0 &&
2053 packet.icmp.icmp_id == id)
2054 return 1;
Simon Kelleyfd9fa482004-10-21 20:24:00 +01002055 }
2056 }
Simon Kelley5e9e0ef2006-04-17 14:24:29 +01002057
Floris Bos503c6092017-04-09 23:07:13 +01002058 return 0;
Simon Kelley3be34542004-09-11 19:12:13 +01002059}
Simon Kelley7622fc02009-06-04 20:32:05 +01002060#endif
Simon Kelley0a852542005-03-23 20:28:59 +00002061
2062