xref: /aosp_15_r20/external/dnsmasq/src/dnsmasq.c (revision c2c26c8b25cb2c9c4fe49a734c2305a522f5635e)
1*c2c26c8bSAndroid Build Coastguard Worker /* dnsmasq is Copyright (c) 2000-2009 Simon Kelley
2*c2c26c8bSAndroid Build Coastguard Worker 
3*c2c26c8bSAndroid Build Coastguard Worker    This program is free software; you can redistribute it and/or modify
4*c2c26c8bSAndroid Build Coastguard Worker    it under the terms of the GNU General Public License as published by
5*c2c26c8bSAndroid Build Coastguard Worker    the Free Software Foundation; version 2 dated June, 1991, or
6*c2c26c8bSAndroid Build Coastguard Worker    (at your option) version 3 dated 29 June, 2007.
7*c2c26c8bSAndroid Build Coastguard Worker 
8*c2c26c8bSAndroid Build Coastguard Worker    This program is distributed in the hope that it will be useful,
9*c2c26c8bSAndroid Build Coastguard Worker    but WITHOUT ANY WARRANTY; without even the implied warranty of
10*c2c26c8bSAndroid Build Coastguard Worker    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11*c2c26c8bSAndroid Build Coastguard Worker    GNU General Public License for more details.
12*c2c26c8bSAndroid Build Coastguard Worker 
13*c2c26c8bSAndroid Build Coastguard Worker    You should have received a copy of the GNU General Public License
14*c2c26c8bSAndroid Build Coastguard Worker    along with this program.  If not, see <http://www.gnu.org/licenses/>.
15*c2c26c8bSAndroid Build Coastguard Worker */
16*c2c26c8bSAndroid Build Coastguard Worker 
17*c2c26c8bSAndroid Build Coastguard Worker #include "dnsmasq.h"
18*c2c26c8bSAndroid Build Coastguard Worker 
19*c2c26c8bSAndroid Build Coastguard Worker #include <sys/stat.h>
20*c2c26c8bSAndroid Build Coastguard Worker 
21*c2c26c8bSAndroid Build Coastguard Worker #if defined(HAVE_BSD_NETWORK)
22*c2c26c8bSAndroid Build Coastguard Worker #error Should not HAVE_BSD_NETWORK
23*c2c26c8bSAndroid Build Coastguard Worker #endif
24*c2c26c8bSAndroid Build Coastguard Worker 
25*c2c26c8bSAndroid Build Coastguard Worker #if defined(HAVE_SOCKADDR_SA_LEN)
26*c2c26c8bSAndroid Build Coastguard Worker #error Should not HAVE_SOCKADDR_SA_LEN
27*c2c26c8bSAndroid Build Coastguard Worker #endif
28*c2c26c8bSAndroid Build Coastguard Worker 
29*c2c26c8bSAndroid Build Coastguard Worker #if defined(HAVE_SOLARIS_NETWORK)
30*c2c26c8bSAndroid Build Coastguard Worker #error Should not HAVE_SOLARIS_NETWORK
31*c2c26c8bSAndroid Build Coastguard Worker #endif
32*c2c26c8bSAndroid Build Coastguard Worker 
33*c2c26c8bSAndroid Build Coastguard Worker #if !defined(HAVE_LINUX_NETWORK)
34*c2c26c8bSAndroid Build Coastguard Worker #error Should HAVE_LINUX_NETWORK
35*c2c26c8bSAndroid Build Coastguard Worker #endif
36*c2c26c8bSAndroid Build Coastguard Worker 
37*c2c26c8bSAndroid Build Coastguard Worker struct daemon* daemon;
38*c2c26c8bSAndroid Build Coastguard Worker 
39*c2c26c8bSAndroid Build Coastguard Worker static char* compile_opts =
40*c2c26c8bSAndroid Build Coastguard Worker #ifndef HAVE_IPV6
41*c2c26c8bSAndroid Build Coastguard Worker     "no-"
42*c2c26c8bSAndroid Build Coastguard Worker #endif
43*c2c26c8bSAndroid Build Coastguard Worker     "IPv6 "
44*c2c26c8bSAndroid Build Coastguard Worker #ifndef HAVE_GETOPT_LONG
45*c2c26c8bSAndroid Build Coastguard Worker     "no-"
46*c2c26c8bSAndroid Build Coastguard Worker #endif
47*c2c26c8bSAndroid Build Coastguard Worker     "GNU-getopt "
48*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_BROKEN_RTC
49*c2c26c8bSAndroid Build Coastguard Worker     "no-RTC "
50*c2c26c8bSAndroid Build Coastguard Worker #endif
51*c2c26c8bSAndroid Build Coastguard Worker #ifdef NO_FORK
52*c2c26c8bSAndroid Build Coastguard Worker     "no-MMU "
53*c2c26c8bSAndroid Build Coastguard Worker #endif
54*c2c26c8bSAndroid Build Coastguard Worker #ifndef LOCALEDIR
55*c2c26c8bSAndroid Build Coastguard Worker     "no-"
56*c2c26c8bSAndroid Build Coastguard Worker #endif
57*c2c26c8bSAndroid Build Coastguard Worker     "I18N "
58*c2c26c8bSAndroid Build Coastguard Worker #ifndef HAVE_DHCP
59*c2c26c8bSAndroid Build Coastguard Worker     "no-"
60*c2c26c8bSAndroid Build Coastguard Worker #endif
61*c2c26c8bSAndroid Build Coastguard Worker     "DHCP "
62*c2c26c8bSAndroid Build Coastguard Worker #if defined(HAVE_DHCP) && !defined(HAVE_SCRIPT)
63*c2c26c8bSAndroid Build Coastguard Worker     "no-scripts"
64*c2c26c8bSAndroid Build Coastguard Worker #endif
65*c2c26c8bSAndroid Build Coastguard Worker     "";
66*c2c26c8bSAndroid Build Coastguard Worker 
67*c2c26c8bSAndroid Build Coastguard Worker static volatile pid_t pid = 0;
68*c2c26c8bSAndroid Build Coastguard Worker static volatile int pipewrite;
69*c2c26c8bSAndroid Build Coastguard Worker 
70*c2c26c8bSAndroid Build Coastguard Worker static int set_dns_listeners(time_t now, fd_set* set, int* maxfdp);
71*c2c26c8bSAndroid Build Coastguard Worker static void check_dns_listeners(fd_set* set, time_t now);
72*c2c26c8bSAndroid Build Coastguard Worker static void sig_handler(int sig);
73*c2c26c8bSAndroid Build Coastguard Worker static void async_event(int pipe, time_t now);
74*c2c26c8bSAndroid Build Coastguard Worker static void fatal_event(struct event_desc* ev);
75*c2c26c8bSAndroid Build Coastguard Worker static void poll_resolv(void);
76*c2c26c8bSAndroid Build Coastguard Worker #ifdef __ANDROID__
77*c2c26c8bSAndroid Build Coastguard Worker static int set_android_listeners(fd_set* set, int* maxfdp);
78*c2c26c8bSAndroid Build Coastguard Worker static int check_android_listeners(fd_set* set);
79*c2c26c8bSAndroid Build Coastguard Worker #endif
80*c2c26c8bSAndroid Build Coastguard Worker 
setupSignalHandling()81*c2c26c8bSAndroid Build Coastguard Worker void setupSignalHandling() {
82*c2c26c8bSAndroid Build Coastguard Worker     struct sigaction sigact;
83*c2c26c8bSAndroid Build Coastguard Worker 
84*c2c26c8bSAndroid Build Coastguard Worker     sigact.sa_handler = sig_handler;
85*c2c26c8bSAndroid Build Coastguard Worker     sigact.sa_flags = 0;
86*c2c26c8bSAndroid Build Coastguard Worker     sigemptyset(&sigact.sa_mask);
87*c2c26c8bSAndroid Build Coastguard Worker     sigaction(SIGUSR1, &sigact, NULL);
88*c2c26c8bSAndroid Build Coastguard Worker     sigaction(SIGUSR2, &sigact, NULL);
89*c2c26c8bSAndroid Build Coastguard Worker     sigaction(SIGHUP, &sigact, NULL);
90*c2c26c8bSAndroid Build Coastguard Worker     sigaction(SIGTERM, &sigact, NULL);
91*c2c26c8bSAndroid Build Coastguard Worker     sigaction(SIGALRM, &sigact, NULL);
92*c2c26c8bSAndroid Build Coastguard Worker     sigaction(SIGCHLD, &sigact, NULL);
93*c2c26c8bSAndroid Build Coastguard Worker 
94*c2c26c8bSAndroid Build Coastguard Worker     /* ignore SIGPIPE */
95*c2c26c8bSAndroid Build Coastguard Worker     sigact.sa_handler = SIG_IGN;
96*c2c26c8bSAndroid Build Coastguard Worker     sigaction(SIGPIPE, &sigact, NULL);
97*c2c26c8bSAndroid Build Coastguard Worker }
98*c2c26c8bSAndroid Build Coastguard Worker 
closeUnwantedFileDescriptors()99*c2c26c8bSAndroid Build Coastguard Worker void closeUnwantedFileDescriptors() {
100*c2c26c8bSAndroid Build Coastguard Worker     const long kMaxFd = sysconf(_SC_OPEN_MAX);
101*c2c26c8bSAndroid Build Coastguard Worker     long i;
102*c2c26c8bSAndroid Build Coastguard Worker     struct stat stat_buf;
103*c2c26c8bSAndroid Build Coastguard Worker 
104*c2c26c8bSAndroid Build Coastguard Worker     /* Close any file descriptors we inherited apart from std{in|out|err}. */
105*c2c26c8bSAndroid Build Coastguard Worker     for (i = 0; i < kMaxFd; i++) {
106*c2c26c8bSAndroid Build Coastguard Worker         // TODO: Evaluate just skipping STDIN, since netd does not
107*c2c26c8bSAndroid Build Coastguard Worker         // (intentionally) pass in any other file descriptors.
108*c2c26c8bSAndroid Build Coastguard Worker         if (i == STDOUT_FILENO || i == STDERR_FILENO || i == STDIN_FILENO) {
109*c2c26c8bSAndroid Build Coastguard Worker             continue;
110*c2c26c8bSAndroid Build Coastguard Worker         }
111*c2c26c8bSAndroid Build Coastguard Worker 
112*c2c26c8bSAndroid Build Coastguard Worker         if (fstat(i, &stat_buf) != 0) {
113*c2c26c8bSAndroid Build Coastguard Worker             if (errno == EBADF) continue;
114*c2c26c8bSAndroid Build Coastguard Worker             if (errno == EACCES) continue;  // Lessen the log spam.
115*c2c26c8bSAndroid Build Coastguard Worker             my_syslog(LOG_ERR, "fstat(%d) error: %d/%s", i, errno, strerror(errno));
116*c2c26c8bSAndroid Build Coastguard Worker         } else {
117*c2c26c8bSAndroid Build Coastguard Worker             my_syslog(LOG_ERR, "Closing inherited file descriptor %d (%u:%u)", i, stat_buf.st_dev,
118*c2c26c8bSAndroid Build Coastguard Worker                       stat_buf.st_ino);
119*c2c26c8bSAndroid Build Coastguard Worker         }
120*c2c26c8bSAndroid Build Coastguard Worker         close(i);
121*c2c26c8bSAndroid Build Coastguard Worker     }
122*c2c26c8bSAndroid Build Coastguard Worker }
123*c2c26c8bSAndroid Build Coastguard Worker 
main(int argc,char ** argv)124*c2c26c8bSAndroid Build Coastguard Worker int main(int argc, char** argv) {
125*c2c26c8bSAndroid Build Coastguard Worker     int bind_fallback = 0;
126*c2c26c8bSAndroid Build Coastguard Worker     time_t now;
127*c2c26c8bSAndroid Build Coastguard Worker     struct iname* if_tmp;
128*c2c26c8bSAndroid Build Coastguard Worker     int piperead, pipefd[2], err_pipe[2];
129*c2c26c8bSAndroid Build Coastguard Worker     struct passwd* ent_pw = NULL;
130*c2c26c8bSAndroid Build Coastguard Worker #if defined(HAVE_DHCP) && defined(HAVE_SCRIPT)
131*c2c26c8bSAndroid Build Coastguard Worker     uid_t script_uid = 0;
132*c2c26c8bSAndroid Build Coastguard Worker     gid_t script_gid = 0;
133*c2c26c8bSAndroid Build Coastguard Worker #endif
134*c2c26c8bSAndroid Build Coastguard Worker     struct group* gp = NULL;
135*c2c26c8bSAndroid Build Coastguard Worker     long i, max_fd = sysconf(_SC_OPEN_MAX);
136*c2c26c8bSAndroid Build Coastguard Worker     char* baduser = NULL;
137*c2c26c8bSAndroid Build Coastguard Worker     int log_err;
138*c2c26c8bSAndroid Build Coastguard Worker #if defined(HAVE_LINUX_NETWORK)
139*c2c26c8bSAndroid Build Coastguard Worker     cap_user_header_t hdr = NULL;
140*c2c26c8bSAndroid Build Coastguard Worker     cap_user_data_t data = NULL;
141*c2c26c8bSAndroid Build Coastguard Worker #endif
142*c2c26c8bSAndroid Build Coastguard Worker 
143*c2c26c8bSAndroid Build Coastguard Worker #ifdef LOCALEDIR
144*c2c26c8bSAndroid Build Coastguard Worker     setlocale(LC_ALL, "");
145*c2c26c8bSAndroid Build Coastguard Worker     bindtextdomain("dnsmasq", LOCALEDIR);
146*c2c26c8bSAndroid Build Coastguard Worker     textdomain("dnsmasq");
147*c2c26c8bSAndroid Build Coastguard Worker #endif
148*c2c26c8bSAndroid Build Coastguard Worker 
149*c2c26c8bSAndroid Build Coastguard Worker     setupSignalHandling();
150*c2c26c8bSAndroid Build Coastguard Worker 
151*c2c26c8bSAndroid Build Coastguard Worker     umask(022); /* known umask, create leases and pid files as 0644 */
152*c2c26c8bSAndroid Build Coastguard Worker 
153*c2c26c8bSAndroid Build Coastguard Worker     read_opts(argc, argv, compile_opts);
154*c2c26c8bSAndroid Build Coastguard Worker 
155*c2c26c8bSAndroid Build Coastguard Worker     if (daemon->edns_pktsz < PACKETSZ) daemon->edns_pktsz = PACKETSZ;
156*c2c26c8bSAndroid Build Coastguard Worker     daemon->packet_buff_sz =
157*c2c26c8bSAndroid Build Coastguard Worker         daemon->edns_pktsz > DNSMASQ_PACKETSZ ? daemon->edns_pktsz : DNSMASQ_PACKETSZ;
158*c2c26c8bSAndroid Build Coastguard Worker     daemon->packet = safe_malloc(daemon->packet_buff_sz);
159*c2c26c8bSAndroid Build Coastguard Worker 
160*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_DHCP
161*c2c26c8bSAndroid Build Coastguard Worker     if (!daemon->lease_file) {
162*c2c26c8bSAndroid Build Coastguard Worker         if (daemon->dhcp) daemon->lease_file = LEASEFILE;
163*c2c26c8bSAndroid Build Coastguard Worker     }
164*c2c26c8bSAndroid Build Coastguard Worker #endif
165*c2c26c8bSAndroid Build Coastguard Worker 
166*c2c26c8bSAndroid Build Coastguard Worker     closeUnwantedFileDescriptors();
167*c2c26c8bSAndroid Build Coastguard Worker 
168*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_LINUX_NETWORK
169*c2c26c8bSAndroid Build Coastguard Worker     netlink_init();
170*c2c26c8bSAndroid Build Coastguard Worker #elif !(defined(IP_RECVDSTADDR) && defined(IP_RECVIF) && defined(IP_SENDSRCADDR))
171*c2c26c8bSAndroid Build Coastguard Worker     if (!(daemon->options & OPT_NOWILD)) {
172*c2c26c8bSAndroid Build Coastguard Worker         bind_fallback = 1;
173*c2c26c8bSAndroid Build Coastguard Worker         daemon->options |= OPT_NOWILD;
174*c2c26c8bSAndroid Build Coastguard Worker     }
175*c2c26c8bSAndroid Build Coastguard Worker #endif
176*c2c26c8bSAndroid Build Coastguard Worker 
177*c2c26c8bSAndroid Build Coastguard Worker     rand_init();
178*c2c26c8bSAndroid Build Coastguard Worker 
179*c2c26c8bSAndroid Build Coastguard Worker     now = dnsmasq_time();
180*c2c26c8bSAndroid Build Coastguard Worker 
181*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_DHCP
182*c2c26c8bSAndroid Build Coastguard Worker     if (daemon->dhcp) {
183*c2c26c8bSAndroid Build Coastguard Worker         /* Note that order matters here, we must call lease_init before
184*c2c26c8bSAndroid Build Coastguard Worker        creating any file descriptors which shouldn't be leaked
185*c2c26c8bSAndroid Build Coastguard Worker        to the lease-script init process. */
186*c2c26c8bSAndroid Build Coastguard Worker         lease_init(now);
187*c2c26c8bSAndroid Build Coastguard Worker         dhcp_init();
188*c2c26c8bSAndroid Build Coastguard Worker     }
189*c2c26c8bSAndroid Build Coastguard Worker #endif
190*c2c26c8bSAndroid Build Coastguard Worker 
191*c2c26c8bSAndroid Build Coastguard Worker     if (!enumerate_interfaces()) die(_("failed to find list of interfaces: %s"), NULL, EC_MISC);
192*c2c26c8bSAndroid Build Coastguard Worker 
193*c2c26c8bSAndroid Build Coastguard Worker     if (daemon->options & OPT_NOWILD) {
194*c2c26c8bSAndroid Build Coastguard Worker         daemon->listeners = create_bound_listeners();
195*c2c26c8bSAndroid Build Coastguard Worker 
196*c2c26c8bSAndroid Build Coastguard Worker         for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
197*c2c26c8bSAndroid Build Coastguard Worker             if (if_tmp->name && !if_tmp->used)
198*c2c26c8bSAndroid Build Coastguard Worker                 die(_("unknown interface %s"), if_tmp->name, EC_BADNET);
199*c2c26c8bSAndroid Build Coastguard Worker 
200*c2c26c8bSAndroid Build Coastguard Worker         for (if_tmp = daemon->if_addrs; if_tmp; if_tmp = if_tmp->next)
201*c2c26c8bSAndroid Build Coastguard Worker             if (!if_tmp->used) {
202*c2c26c8bSAndroid Build Coastguard Worker                 prettyprint_addr(&if_tmp->addr, daemon->namebuff);
203*c2c26c8bSAndroid Build Coastguard Worker                 die(_("no interface with address %s"), daemon->namebuff, EC_BADNET);
204*c2c26c8bSAndroid Build Coastguard Worker             }
205*c2c26c8bSAndroid Build Coastguard Worker     } else if ((daemon->port != 0 || (daemon->options & OPT_TFTP)) &&
206*c2c26c8bSAndroid Build Coastguard Worker                !(daemon->listeners = create_wildcard_listeners()))
207*c2c26c8bSAndroid Build Coastguard Worker         die(_("failed to create listening socket: %s"), NULL, EC_BADNET);
208*c2c26c8bSAndroid Build Coastguard Worker 
209*c2c26c8bSAndroid Build Coastguard Worker     if (daemon->port != 0) cache_init();
210*c2c26c8bSAndroid Build Coastguard Worker 
211*c2c26c8bSAndroid Build Coastguard Worker     if (daemon->port != 0) pre_allocate_sfds();
212*c2c26c8bSAndroid Build Coastguard Worker 
213*c2c26c8bSAndroid Build Coastguard Worker #if defined(HAVE_DHCP) && defined(HAVE_SCRIPT)
214*c2c26c8bSAndroid Build Coastguard Worker     /* Note getpwnam returns static storage */
215*c2c26c8bSAndroid Build Coastguard Worker     if (daemon->dhcp && daemon->lease_change_command && daemon->scriptuser) {
216*c2c26c8bSAndroid Build Coastguard Worker         if ((ent_pw = getpwnam(daemon->scriptuser))) {
217*c2c26c8bSAndroid Build Coastguard Worker             script_uid = ent_pw->pw_uid;
218*c2c26c8bSAndroid Build Coastguard Worker             script_gid = ent_pw->pw_gid;
219*c2c26c8bSAndroid Build Coastguard Worker         } else
220*c2c26c8bSAndroid Build Coastguard Worker             baduser = daemon->scriptuser;
221*c2c26c8bSAndroid Build Coastguard Worker     }
222*c2c26c8bSAndroid Build Coastguard Worker #endif
223*c2c26c8bSAndroid Build Coastguard Worker 
224*c2c26c8bSAndroid Build Coastguard Worker     if (daemon->username && !(ent_pw = getpwnam(daemon->username)))
225*c2c26c8bSAndroid Build Coastguard Worker         baduser = daemon->username;
226*c2c26c8bSAndroid Build Coastguard Worker     else if (daemon->groupname && !(gp = getgrnam(daemon->groupname)))
227*c2c26c8bSAndroid Build Coastguard Worker         baduser = daemon->groupname;
228*c2c26c8bSAndroid Build Coastguard Worker 
229*c2c26c8bSAndroid Build Coastguard Worker     if (baduser) die(_("unknown user or group: %s"), baduser, EC_BADCONF);
230*c2c26c8bSAndroid Build Coastguard Worker 
231*c2c26c8bSAndroid Build Coastguard Worker     /* implement group defaults, "dip" if available, or group associated with uid */
232*c2c26c8bSAndroid Build Coastguard Worker     if (!daemon->group_set && !gp) {
233*c2c26c8bSAndroid Build Coastguard Worker         if (!(gp = getgrnam(CHGRP)) && ent_pw) gp = getgrgid(ent_pw->pw_gid);
234*c2c26c8bSAndroid Build Coastguard Worker 
235*c2c26c8bSAndroid Build Coastguard Worker         /* for error message */
236*c2c26c8bSAndroid Build Coastguard Worker         if (gp) daemon->groupname = gp->gr_name;
237*c2c26c8bSAndroid Build Coastguard Worker     }
238*c2c26c8bSAndroid Build Coastguard Worker 
239*c2c26c8bSAndroid Build Coastguard Worker #if defined(HAVE_LINUX_NETWORK)
240*c2c26c8bSAndroid Build Coastguard Worker     /* determine capability API version here, while we can still
241*c2c26c8bSAndroid Build Coastguard Worker        call safe_malloc */
242*c2c26c8bSAndroid Build Coastguard Worker     if (ent_pw && ent_pw->pw_uid != 0) {
243*c2c26c8bSAndroid Build Coastguard Worker         int capsize = 1; /* for header version 1 */
244*c2c26c8bSAndroid Build Coastguard Worker         hdr = safe_malloc(sizeof(*hdr));
245*c2c26c8bSAndroid Build Coastguard Worker 
246*c2c26c8bSAndroid Build Coastguard Worker         /* find version supported by kernel */
247*c2c26c8bSAndroid Build Coastguard Worker         memset(hdr, 0, sizeof(*hdr));
248*c2c26c8bSAndroid Build Coastguard Worker         capget(hdr, NULL);
249*c2c26c8bSAndroid Build Coastguard Worker 
250*c2c26c8bSAndroid Build Coastguard Worker         if (hdr->version != LINUX_CAPABILITY_VERSION_1) {
251*c2c26c8bSAndroid Build Coastguard Worker             /* if unknown version, use largest supported version (3) */
252*c2c26c8bSAndroid Build Coastguard Worker             if (hdr->version != LINUX_CAPABILITY_VERSION_2)
253*c2c26c8bSAndroid Build Coastguard Worker                 hdr->version = LINUX_CAPABILITY_VERSION_3;
254*c2c26c8bSAndroid Build Coastguard Worker             capsize = 2;
255*c2c26c8bSAndroid Build Coastguard Worker         }
256*c2c26c8bSAndroid Build Coastguard Worker 
257*c2c26c8bSAndroid Build Coastguard Worker         data = safe_malloc(sizeof(*data) * capsize);
258*c2c26c8bSAndroid Build Coastguard Worker         memset(data, 0, sizeof(*data) * capsize);
259*c2c26c8bSAndroid Build Coastguard Worker     }
260*c2c26c8bSAndroid Build Coastguard Worker #endif
261*c2c26c8bSAndroid Build Coastguard Worker 
262*c2c26c8bSAndroid Build Coastguard Worker     /* Use a pipe to carry signals and other events back to the event loop
263*c2c26c8bSAndroid Build Coastguard Worker        in a race-free manner and another to carry errors to daemon-invoking process */
264*c2c26c8bSAndroid Build Coastguard Worker     safe_pipe(pipefd, 1);
265*c2c26c8bSAndroid Build Coastguard Worker 
266*c2c26c8bSAndroid Build Coastguard Worker     piperead = pipefd[0];
267*c2c26c8bSAndroid Build Coastguard Worker     pipewrite = pipefd[1];
268*c2c26c8bSAndroid Build Coastguard Worker     /* prime the pipe to load stuff first time. */
269*c2c26c8bSAndroid Build Coastguard Worker     send_event(pipewrite, EVENT_RELOAD, 0);
270*c2c26c8bSAndroid Build Coastguard Worker 
271*c2c26c8bSAndroid Build Coastguard Worker     err_pipe[1] = -1;
272*c2c26c8bSAndroid Build Coastguard Worker 
273*c2c26c8bSAndroid Build Coastguard Worker     if (!(daemon->options & OPT_DEBUG)) {
274*c2c26c8bSAndroid Build Coastguard Worker #ifndef __ANDROID__
275*c2c26c8bSAndroid Build Coastguard Worker         int nullfd;
276*c2c26c8bSAndroid Build Coastguard Worker #endif
277*c2c26c8bSAndroid Build Coastguard Worker 
278*c2c26c8bSAndroid Build Coastguard Worker         /* The following code "daemonizes" the process.
279*c2c26c8bSAndroid Build Coastguard Worker        See Stevens section 12.4 */
280*c2c26c8bSAndroid Build Coastguard Worker 
281*c2c26c8bSAndroid Build Coastguard Worker         if (chdir("/") != 0) die(_("cannot chdir to filesystem root: %s"), NULL, EC_MISC);
282*c2c26c8bSAndroid Build Coastguard Worker 
283*c2c26c8bSAndroid Build Coastguard Worker #ifndef NO_FORK
284*c2c26c8bSAndroid Build Coastguard Worker         if (!(daemon->options & OPT_NO_FORK)) {
285*c2c26c8bSAndroid Build Coastguard Worker             pid_t pid;
286*c2c26c8bSAndroid Build Coastguard Worker 
287*c2c26c8bSAndroid Build Coastguard Worker             /* pipe to carry errors back to original process.
288*c2c26c8bSAndroid Build Coastguard Worker                When startup is complete we close this and the process terminates. */
289*c2c26c8bSAndroid Build Coastguard Worker             safe_pipe(err_pipe, 0);
290*c2c26c8bSAndroid Build Coastguard Worker 
291*c2c26c8bSAndroid Build Coastguard Worker             if ((pid = fork()) == -1) /* fd == -1 since we've not forked, never returns. */
292*c2c26c8bSAndroid Build Coastguard Worker                 send_event(-1, EVENT_FORK_ERR, errno);
293*c2c26c8bSAndroid Build Coastguard Worker 
294*c2c26c8bSAndroid Build Coastguard Worker             if (pid != 0) {
295*c2c26c8bSAndroid Build Coastguard Worker                 struct event_desc ev;
296*c2c26c8bSAndroid Build Coastguard Worker 
297*c2c26c8bSAndroid Build Coastguard Worker                 /* close our copy of write-end */
298*c2c26c8bSAndroid Build Coastguard Worker                 close(err_pipe[1]);
299*c2c26c8bSAndroid Build Coastguard Worker 
300*c2c26c8bSAndroid Build Coastguard Worker                 /* check for errors after the fork */
301*c2c26c8bSAndroid Build Coastguard Worker                 if (read_write(err_pipe[0], (unsigned char*) &ev, sizeof(ev), 1)) fatal_event(&ev);
302*c2c26c8bSAndroid Build Coastguard Worker 
303*c2c26c8bSAndroid Build Coastguard Worker                 _exit(EC_GOOD);
304*c2c26c8bSAndroid Build Coastguard Worker             }
305*c2c26c8bSAndroid Build Coastguard Worker 
306*c2c26c8bSAndroid Build Coastguard Worker             close(err_pipe[0]);
307*c2c26c8bSAndroid Build Coastguard Worker 
308*c2c26c8bSAndroid Build Coastguard Worker             /* NO calls to die() from here on. */
309*c2c26c8bSAndroid Build Coastguard Worker 
310*c2c26c8bSAndroid Build Coastguard Worker             setsid();
311*c2c26c8bSAndroid Build Coastguard Worker 
312*c2c26c8bSAndroid Build Coastguard Worker             if ((pid = fork()) == -1) send_event(err_pipe[1], EVENT_FORK_ERR, errno);
313*c2c26c8bSAndroid Build Coastguard Worker 
314*c2c26c8bSAndroid Build Coastguard Worker             if (pid != 0) _exit(0);
315*c2c26c8bSAndroid Build Coastguard Worker         }
316*c2c26c8bSAndroid Build Coastguard Worker #endif
317*c2c26c8bSAndroid Build Coastguard Worker 
318*c2c26c8bSAndroid Build Coastguard Worker         /* write pidfile _after_ forking ! */
319*c2c26c8bSAndroid Build Coastguard Worker         if (daemon->runfile) {
320*c2c26c8bSAndroid Build Coastguard Worker             FILE* pidfile;
321*c2c26c8bSAndroid Build Coastguard Worker 
322*c2c26c8bSAndroid Build Coastguard Worker             /* only complain if started as root */
323*c2c26c8bSAndroid Build Coastguard Worker             if ((pidfile = fopen(daemon->runfile, "w"))) {
324*c2c26c8bSAndroid Build Coastguard Worker                 fprintf(pidfile, "%d\n", (int) getpid());
325*c2c26c8bSAndroid Build Coastguard Worker                 fclose(pidfile);
326*c2c26c8bSAndroid Build Coastguard Worker             } else if (getuid() == 0) {
327*c2c26c8bSAndroid Build Coastguard Worker                 send_event(err_pipe[1], EVENT_PIDFILE, errno);
328*c2c26c8bSAndroid Build Coastguard Worker                 _exit(0);
329*c2c26c8bSAndroid Build Coastguard Worker             }
330*c2c26c8bSAndroid Build Coastguard Worker         }
331*c2c26c8bSAndroid Build Coastguard Worker 
332*c2c26c8bSAndroid Build Coastguard Worker #ifndef __ANDROID__
333*c2c26c8bSAndroid Build Coastguard Worker         /* open  stdout etc to /dev/null */
334*c2c26c8bSAndroid Build Coastguard Worker         nullfd = open("/dev/null", O_RDWR);
335*c2c26c8bSAndroid Build Coastguard Worker         dup2(nullfd, STDOUT_FILENO);
336*c2c26c8bSAndroid Build Coastguard Worker         dup2(nullfd, STDERR_FILENO);
337*c2c26c8bSAndroid Build Coastguard Worker         dup2(nullfd, STDIN_FILENO);
338*c2c26c8bSAndroid Build Coastguard Worker         close(nullfd);
339*c2c26c8bSAndroid Build Coastguard Worker #endif
340*c2c26c8bSAndroid Build Coastguard Worker     }
341*c2c26c8bSAndroid Build Coastguard Worker 
342*c2c26c8bSAndroid Build Coastguard Worker     log_err = log_start(ent_pw, err_pipe[1]);
343*c2c26c8bSAndroid Build Coastguard Worker 
344*c2c26c8bSAndroid Build Coastguard Worker     /* if we are to run scripts, we need to fork a helper before dropping root. */
345*c2c26c8bSAndroid Build Coastguard Worker     daemon->helperfd = -1;
346*c2c26c8bSAndroid Build Coastguard Worker #if defined(HAVE_DHCP) && defined(HAVE_SCRIPT)
347*c2c26c8bSAndroid Build Coastguard Worker     if (daemon->dhcp && daemon->lease_change_command)
348*c2c26c8bSAndroid Build Coastguard Worker         daemon->helperfd = create_helper(pipewrite, err_pipe[1], script_uid, script_gid, max_fd);
349*c2c26c8bSAndroid Build Coastguard Worker #endif
350*c2c26c8bSAndroid Build Coastguard Worker 
351*c2c26c8bSAndroid Build Coastguard Worker     if (!(daemon->options & OPT_DEBUG) && getuid() == 0) {
352*c2c26c8bSAndroid Build Coastguard Worker         int bad_capabilities = 0;
353*c2c26c8bSAndroid Build Coastguard Worker         gid_t unused;
354*c2c26c8bSAndroid Build Coastguard Worker 
355*c2c26c8bSAndroid Build Coastguard Worker         /* remove all supplimentary groups */
356*c2c26c8bSAndroid Build Coastguard Worker         if (gp && (setgroups(0, &unused) == -1 || setgid(gp->gr_gid) == -1)) {
357*c2c26c8bSAndroid Build Coastguard Worker             send_event(err_pipe[1], EVENT_GROUP_ERR, errno);
358*c2c26c8bSAndroid Build Coastguard Worker             _exit(0);
359*c2c26c8bSAndroid Build Coastguard Worker         }
360*c2c26c8bSAndroid Build Coastguard Worker 
361*c2c26c8bSAndroid Build Coastguard Worker         if (ent_pw && ent_pw->pw_uid != 0) {
362*c2c26c8bSAndroid Build Coastguard Worker #if defined(HAVE_LINUX_NETWORK)
363*c2c26c8bSAndroid Build Coastguard Worker             /* On linux, we keep CAP_NETADMIN (for ARP-injection) and
364*c2c26c8bSAndroid Build Coastguard Worker                CAP_NET_RAW (for icmp) if we're doing dhcp */
365*c2c26c8bSAndroid Build Coastguard Worker             data->effective = data->permitted = data->inheritable =
366*c2c26c8bSAndroid Build Coastguard Worker #ifdef __ANDROID__
367*c2c26c8bSAndroid Build Coastguard Worker                 (1 << CAP_NET_BIND_SERVICE) |
368*c2c26c8bSAndroid Build Coastguard Worker #endif
369*c2c26c8bSAndroid Build Coastguard Worker                 (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW) | (1 << CAP_SETUID);
370*c2c26c8bSAndroid Build Coastguard Worker 
371*c2c26c8bSAndroid Build Coastguard Worker             /* Tell kernel to not clear capabilities when dropping root */
372*c2c26c8bSAndroid Build Coastguard Worker             if (capset(hdr, data) == -1 || prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1)
373*c2c26c8bSAndroid Build Coastguard Worker                 bad_capabilities = errno;
374*c2c26c8bSAndroid Build Coastguard Worker 
375*c2c26c8bSAndroid Build Coastguard Worker #endif
376*c2c26c8bSAndroid Build Coastguard Worker 
377*c2c26c8bSAndroid Build Coastguard Worker             if (bad_capabilities != 0) {
378*c2c26c8bSAndroid Build Coastguard Worker                 send_event(err_pipe[1], EVENT_CAP_ERR, bad_capabilities);
379*c2c26c8bSAndroid Build Coastguard Worker                 _exit(0);
380*c2c26c8bSAndroid Build Coastguard Worker             }
381*c2c26c8bSAndroid Build Coastguard Worker 
382*c2c26c8bSAndroid Build Coastguard Worker             /* finally drop root */
383*c2c26c8bSAndroid Build Coastguard Worker             if (setuid(ent_pw->pw_uid) == -1) {
384*c2c26c8bSAndroid Build Coastguard Worker                 send_event(err_pipe[1], EVENT_USER_ERR, errno);
385*c2c26c8bSAndroid Build Coastguard Worker                 _exit(0);
386*c2c26c8bSAndroid Build Coastguard Worker             }
387*c2c26c8bSAndroid Build Coastguard Worker 
388*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_LINUX_NETWORK
389*c2c26c8bSAndroid Build Coastguard Worker             data->effective = data->permitted =
390*c2c26c8bSAndroid Build Coastguard Worker #ifdef __ANDROID__
391*c2c26c8bSAndroid Build Coastguard Worker                 (1 << CAP_NET_BIND_SERVICE) |
392*c2c26c8bSAndroid Build Coastguard Worker #endif
393*c2c26c8bSAndroid Build Coastguard Worker                 (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW);
394*c2c26c8bSAndroid Build Coastguard Worker             data->inheritable = 0;
395*c2c26c8bSAndroid Build Coastguard Worker 
396*c2c26c8bSAndroid Build Coastguard Worker             /* lose the setuid and setgid capbilities */
397*c2c26c8bSAndroid Build Coastguard Worker             if (capset(hdr, data) == -1) {
398*c2c26c8bSAndroid Build Coastguard Worker                 send_event(err_pipe[1], EVENT_CAP_ERR, errno);
399*c2c26c8bSAndroid Build Coastguard Worker                 _exit(0);
400*c2c26c8bSAndroid Build Coastguard Worker             }
401*c2c26c8bSAndroid Build Coastguard Worker #endif
402*c2c26c8bSAndroid Build Coastguard Worker         }
403*c2c26c8bSAndroid Build Coastguard Worker     }
404*c2c26c8bSAndroid Build Coastguard Worker 
405*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_LINUX_NETWORK
406*c2c26c8bSAndroid Build Coastguard Worker     if (daemon->options & OPT_DEBUG) prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
407*c2c26c8bSAndroid Build Coastguard Worker #endif
408*c2c26c8bSAndroid Build Coastguard Worker 
409*c2c26c8bSAndroid Build Coastguard Worker     if (daemon->port == 0)
410*c2c26c8bSAndroid Build Coastguard Worker         my_syslog(LOG_INFO, _("started, version %s DNS disabled"), VERSION);
411*c2c26c8bSAndroid Build Coastguard Worker     else if (daemon->cachesize != 0)
412*c2c26c8bSAndroid Build Coastguard Worker         my_syslog(LOG_INFO, _("started, version %s cachesize %d"), VERSION, daemon->cachesize);
413*c2c26c8bSAndroid Build Coastguard Worker     else
414*c2c26c8bSAndroid Build Coastguard Worker         my_syslog(LOG_INFO, _("started, version %s cache disabled"), VERSION);
415*c2c26c8bSAndroid Build Coastguard Worker 
416*c2c26c8bSAndroid Build Coastguard Worker     my_syslog(LOG_INFO, _("compile time options: %s"), compile_opts);
417*c2c26c8bSAndroid Build Coastguard Worker 
418*c2c26c8bSAndroid Build Coastguard Worker     if (log_err != 0)
419*c2c26c8bSAndroid Build Coastguard Worker         my_syslog(LOG_WARNING, _("warning: failed to change owner of %s: %s"), daemon->log_file,
420*c2c26c8bSAndroid Build Coastguard Worker                   strerror(log_err));
421*c2c26c8bSAndroid Build Coastguard Worker 
422*c2c26c8bSAndroid Build Coastguard Worker     if (bind_fallback)
423*c2c26c8bSAndroid Build Coastguard Worker         my_syslog(LOG_WARNING, _("setting --bind-interfaces option because of OS limitations"));
424*c2c26c8bSAndroid Build Coastguard Worker 
425*c2c26c8bSAndroid Build Coastguard Worker     if (!(daemon->options & OPT_NOWILD))
426*c2c26c8bSAndroid Build Coastguard Worker         for (if_tmp = daemon->if_names; if_tmp; if_tmp = if_tmp->next)
427*c2c26c8bSAndroid Build Coastguard Worker             if (if_tmp->name && !if_tmp->used)
428*c2c26c8bSAndroid Build Coastguard Worker                 my_syslog(LOG_WARNING, _("warning: interface %s does not currently exist"),
429*c2c26c8bSAndroid Build Coastguard Worker                           if_tmp->name);
430*c2c26c8bSAndroid Build Coastguard Worker 
431*c2c26c8bSAndroid Build Coastguard Worker     if (daemon->port != 0 && (daemon->options & OPT_NO_RESOLV)) {
432*c2c26c8bSAndroid Build Coastguard Worker         if (daemon->resolv_files && !daemon->resolv_files->is_default)
433*c2c26c8bSAndroid Build Coastguard Worker             my_syslog(LOG_WARNING,
434*c2c26c8bSAndroid Build Coastguard Worker                       _("warning: ignoring resolv-file flag because no-resolv is set"));
435*c2c26c8bSAndroid Build Coastguard Worker         daemon->resolv_files = NULL;
436*c2c26c8bSAndroid Build Coastguard Worker         if (!daemon->servers) my_syslog(LOG_WARNING, _("warning: no upstream servers configured"));
437*c2c26c8bSAndroid Build Coastguard Worker     }
438*c2c26c8bSAndroid Build Coastguard Worker 
439*c2c26c8bSAndroid Build Coastguard Worker     if (daemon->max_logs != 0)
440*c2c26c8bSAndroid Build Coastguard Worker         my_syslog(LOG_INFO, _("asynchronous logging enabled, queue limit is %d messages"),
441*c2c26c8bSAndroid Build Coastguard Worker                   daemon->max_logs);
442*c2c26c8bSAndroid Build Coastguard Worker 
443*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_DHCP
444*c2c26c8bSAndroid Build Coastguard Worker     if (daemon->dhcp) {
445*c2c26c8bSAndroid Build Coastguard Worker         struct dhcp_context* dhcp_tmp;
446*c2c26c8bSAndroid Build Coastguard Worker 
447*c2c26c8bSAndroid Build Coastguard Worker         for (dhcp_tmp = daemon->dhcp; dhcp_tmp; dhcp_tmp = dhcp_tmp->next) {
448*c2c26c8bSAndroid Build Coastguard Worker             prettyprint_time(daemon->dhcp_buff2, dhcp_tmp->lease_time);
449*c2c26c8bSAndroid Build Coastguard Worker             strcpy(daemon->dhcp_buff, inet_ntoa(dhcp_tmp->start));
450*c2c26c8bSAndroid Build Coastguard Worker             my_syslog(MS_DHCP | LOG_INFO,
451*c2c26c8bSAndroid Build Coastguard Worker                       (dhcp_tmp->flags & CONTEXT_STATIC)
452*c2c26c8bSAndroid Build Coastguard Worker                           ? _("DHCP, static leases only on %.0s%s, lease time %s")
453*c2c26c8bSAndroid Build Coastguard Worker                           : (dhcp_tmp->flags & CONTEXT_PROXY)
454*c2c26c8bSAndroid Build Coastguard Worker                                 ? _("DHCP, proxy on subnet %.0s%s%.0s")
455*c2c26c8bSAndroid Build Coastguard Worker                                 : _("DHCP, IP range %s -- %s, lease time %s"),
456*c2c26c8bSAndroid Build Coastguard Worker                       daemon->dhcp_buff, inet_ntoa(dhcp_tmp->end), daemon->dhcp_buff2);
457*c2c26c8bSAndroid Build Coastguard Worker         }
458*c2c26c8bSAndroid Build Coastguard Worker     }
459*c2c26c8bSAndroid Build Coastguard Worker #endif
460*c2c26c8bSAndroid Build Coastguard Worker 
461*c2c26c8bSAndroid Build Coastguard Worker     /* finished start-up - release original process */
462*c2c26c8bSAndroid Build Coastguard Worker     if (err_pipe[1] != -1) close(err_pipe[1]);
463*c2c26c8bSAndroid Build Coastguard Worker 
464*c2c26c8bSAndroid Build Coastguard Worker     if (daemon->port != 0) check_servers();
465*c2c26c8bSAndroid Build Coastguard Worker 
466*c2c26c8bSAndroid Build Coastguard Worker     pid = getpid();
467*c2c26c8bSAndroid Build Coastguard Worker 
468*c2c26c8bSAndroid Build Coastguard Worker     while (1) {
469*c2c26c8bSAndroid Build Coastguard Worker         int maxfd = -1;
470*c2c26c8bSAndroid Build Coastguard Worker         struct timeval t, *tp = NULL;
471*c2c26c8bSAndroid Build Coastguard Worker         fd_set rset, wset, eset;
472*c2c26c8bSAndroid Build Coastguard Worker 
473*c2c26c8bSAndroid Build Coastguard Worker         FD_ZERO(&rset);
474*c2c26c8bSAndroid Build Coastguard Worker         FD_ZERO(&wset);
475*c2c26c8bSAndroid Build Coastguard Worker         FD_ZERO(&eset);
476*c2c26c8bSAndroid Build Coastguard Worker 
477*c2c26c8bSAndroid Build Coastguard Worker         /* if we are out of resources, find how long we have to wait
478*c2c26c8bSAndroid Build Coastguard Worker        for some to come free, we'll loop around then and restart
479*c2c26c8bSAndroid Build Coastguard Worker        listening for queries */
480*c2c26c8bSAndroid Build Coastguard Worker         if ((t.tv_sec = set_dns_listeners(now, &rset, &maxfd)) != 0) {
481*c2c26c8bSAndroid Build Coastguard Worker             t.tv_usec = 0;
482*c2c26c8bSAndroid Build Coastguard Worker             tp = &t;
483*c2c26c8bSAndroid Build Coastguard Worker         }
484*c2c26c8bSAndroid Build Coastguard Worker #ifdef __ANDROID__
485*c2c26c8bSAndroid Build Coastguard Worker         set_android_listeners(&rset, &maxfd);
486*c2c26c8bSAndroid Build Coastguard Worker #endif
487*c2c26c8bSAndroid Build Coastguard Worker 
488*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_DHCP
489*c2c26c8bSAndroid Build Coastguard Worker         if (daemon->dhcp) {
490*c2c26c8bSAndroid Build Coastguard Worker             FD_SET(daemon->dhcpfd, &rset);
491*c2c26c8bSAndroid Build Coastguard Worker             bump_maxfd(daemon->dhcpfd, &maxfd);
492*c2c26c8bSAndroid Build Coastguard Worker         }
493*c2c26c8bSAndroid Build Coastguard Worker #endif
494*c2c26c8bSAndroid Build Coastguard Worker 
495*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_LINUX_NETWORK
496*c2c26c8bSAndroid Build Coastguard Worker         FD_SET(daemon->netlinkfd, &rset);
497*c2c26c8bSAndroid Build Coastguard Worker         bump_maxfd(daemon->netlinkfd, &maxfd);
498*c2c26c8bSAndroid Build Coastguard Worker #endif
499*c2c26c8bSAndroid Build Coastguard Worker 
500*c2c26c8bSAndroid Build Coastguard Worker         FD_SET(piperead, &rset);
501*c2c26c8bSAndroid Build Coastguard Worker         bump_maxfd(piperead, &maxfd);
502*c2c26c8bSAndroid Build Coastguard Worker 
503*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_DHCP
504*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_SCRIPT
505*c2c26c8bSAndroid Build Coastguard Worker         while (helper_buf_empty() && do_script_run(now))
506*c2c26c8bSAndroid Build Coastguard Worker             ;
507*c2c26c8bSAndroid Build Coastguard Worker 
508*c2c26c8bSAndroid Build Coastguard Worker         if (!helper_buf_empty()) {
509*c2c26c8bSAndroid Build Coastguard Worker             FD_SET(daemon->helperfd, &wset);
510*c2c26c8bSAndroid Build Coastguard Worker             bump_maxfd(daemon->helperfd, &maxfd);
511*c2c26c8bSAndroid Build Coastguard Worker         }
512*c2c26c8bSAndroid Build Coastguard Worker #else
513*c2c26c8bSAndroid Build Coastguard Worker         /* need this for other side-effects */
514*c2c26c8bSAndroid Build Coastguard Worker         while (do_script_run(now))
515*c2c26c8bSAndroid Build Coastguard Worker             ;
516*c2c26c8bSAndroid Build Coastguard Worker #endif
517*c2c26c8bSAndroid Build Coastguard Worker #endif
518*c2c26c8bSAndroid Build Coastguard Worker 
519*c2c26c8bSAndroid Build Coastguard Worker         /* must do this just before select(), when we know no
520*c2c26c8bSAndroid Build Coastguard Worker        more calls to my_syslog() can occur */
521*c2c26c8bSAndroid Build Coastguard Worker         set_log_writer(&wset, &maxfd);
522*c2c26c8bSAndroid Build Coastguard Worker 
523*c2c26c8bSAndroid Build Coastguard Worker         if (select(maxfd + 1, &rset, &wset, &eset, tp) < 0) {
524*c2c26c8bSAndroid Build Coastguard Worker             /* otherwise undefined after error */
525*c2c26c8bSAndroid Build Coastguard Worker             FD_ZERO(&rset);
526*c2c26c8bSAndroid Build Coastguard Worker             FD_ZERO(&wset);
527*c2c26c8bSAndroid Build Coastguard Worker             FD_ZERO(&eset);
528*c2c26c8bSAndroid Build Coastguard Worker         }
529*c2c26c8bSAndroid Build Coastguard Worker 
530*c2c26c8bSAndroid Build Coastguard Worker         now = dnsmasq_time();
531*c2c26c8bSAndroid Build Coastguard Worker 
532*c2c26c8bSAndroid Build Coastguard Worker         check_log_writer(&wset);
533*c2c26c8bSAndroid Build Coastguard Worker 
534*c2c26c8bSAndroid Build Coastguard Worker         /* Check for changes to resolv files once per second max. */
535*c2c26c8bSAndroid Build Coastguard Worker         /* Don't go silent for long periods if the clock goes backwards. */
536*c2c26c8bSAndroid Build Coastguard Worker         if (daemon->last_resolv == 0 || difftime(now, daemon->last_resolv) > 1.0 ||
537*c2c26c8bSAndroid Build Coastguard Worker             difftime(now, daemon->last_resolv) < -1.0) {
538*c2c26c8bSAndroid Build Coastguard Worker             daemon->last_resolv = now;
539*c2c26c8bSAndroid Build Coastguard Worker 
540*c2c26c8bSAndroid Build Coastguard Worker             if (daemon->port != 0 && !(daemon->options & OPT_NO_POLL)) poll_resolv();
541*c2c26c8bSAndroid Build Coastguard Worker         }
542*c2c26c8bSAndroid Build Coastguard Worker 
543*c2c26c8bSAndroid Build Coastguard Worker         if (FD_ISSET(piperead, &rset)) async_event(piperead, now);
544*c2c26c8bSAndroid Build Coastguard Worker 
545*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_LINUX_NETWORK
546*c2c26c8bSAndroid Build Coastguard Worker         if (FD_ISSET(daemon->netlinkfd, &rset)) netlink_multicast();
547*c2c26c8bSAndroid Build Coastguard Worker #endif
548*c2c26c8bSAndroid Build Coastguard Worker 
549*c2c26c8bSAndroid Build Coastguard Worker #ifdef __ANDROID__
550*c2c26c8bSAndroid Build Coastguard Worker         check_android_listeners(&rset);
551*c2c26c8bSAndroid Build Coastguard Worker #endif
552*c2c26c8bSAndroid Build Coastguard Worker 
553*c2c26c8bSAndroid Build Coastguard Worker         check_dns_listeners(&rset, now);
554*c2c26c8bSAndroid Build Coastguard Worker 
555*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_DHCP
556*c2c26c8bSAndroid Build Coastguard Worker         if (daemon->dhcp && FD_ISSET(daemon->dhcpfd, &rset)) dhcp_packet(now);
557*c2c26c8bSAndroid Build Coastguard Worker 
558*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_SCRIPT
559*c2c26c8bSAndroid Build Coastguard Worker         if (daemon->helperfd != -1 && FD_ISSET(daemon->helperfd, &wset)) helper_write();
560*c2c26c8bSAndroid Build Coastguard Worker #endif
561*c2c26c8bSAndroid Build Coastguard Worker #endif
562*c2c26c8bSAndroid Build Coastguard Worker     }
563*c2c26c8bSAndroid Build Coastguard Worker }
564*c2c26c8bSAndroid Build Coastguard Worker 
sig_handler(int sig)565*c2c26c8bSAndroid Build Coastguard Worker static void sig_handler(int sig) {
566*c2c26c8bSAndroid Build Coastguard Worker     if (pid == 0) {
567*c2c26c8bSAndroid Build Coastguard Worker         /* ignore anything other than TERM during startup
568*c2c26c8bSAndroid Build Coastguard Worker            and in helper proc. (helper ignore TERM too) */
569*c2c26c8bSAndroid Build Coastguard Worker         if (sig == SIGTERM) exit(EC_MISC);
570*c2c26c8bSAndroid Build Coastguard Worker     } else if (pid != getpid()) {
571*c2c26c8bSAndroid Build Coastguard Worker         /* alarm is used to kill TCP children after a fixed time. */
572*c2c26c8bSAndroid Build Coastguard Worker         if (sig == SIGALRM) _exit(0);
573*c2c26c8bSAndroid Build Coastguard Worker     } else {
574*c2c26c8bSAndroid Build Coastguard Worker         /* main process */
575*c2c26c8bSAndroid Build Coastguard Worker         const int errsave = errno;
576*c2c26c8bSAndroid Build Coastguard Worker         int event;
577*c2c26c8bSAndroid Build Coastguard Worker 
578*c2c26c8bSAndroid Build Coastguard Worker         if (sig == SIGHUP)
579*c2c26c8bSAndroid Build Coastguard Worker             event = EVENT_RELOAD;
580*c2c26c8bSAndroid Build Coastguard Worker         else if (sig == SIGCHLD)
581*c2c26c8bSAndroid Build Coastguard Worker             event = EVENT_CHILD;
582*c2c26c8bSAndroid Build Coastguard Worker         else if (sig == SIGALRM)
583*c2c26c8bSAndroid Build Coastguard Worker             event = EVENT_ALARM;
584*c2c26c8bSAndroid Build Coastguard Worker         else if (sig == SIGTERM)
585*c2c26c8bSAndroid Build Coastguard Worker             event = EVENT_TERM;
586*c2c26c8bSAndroid Build Coastguard Worker         else if (sig == SIGUSR1)
587*c2c26c8bSAndroid Build Coastguard Worker             event = EVENT_DUMP;
588*c2c26c8bSAndroid Build Coastguard Worker         else if (sig == SIGUSR2)
589*c2c26c8bSAndroid Build Coastguard Worker             event = EVENT_REOPEN;
590*c2c26c8bSAndroid Build Coastguard Worker         else
591*c2c26c8bSAndroid Build Coastguard Worker             return;
592*c2c26c8bSAndroid Build Coastguard Worker 
593*c2c26c8bSAndroid Build Coastguard Worker         send_event(pipewrite, event, 0);
594*c2c26c8bSAndroid Build Coastguard Worker         errno = errsave;
595*c2c26c8bSAndroid Build Coastguard Worker     }
596*c2c26c8bSAndroid Build Coastguard Worker }
597*c2c26c8bSAndroid Build Coastguard Worker 
send_event(int fd,int event,int data)598*c2c26c8bSAndroid Build Coastguard Worker void send_event(int fd, int event, int data) {
599*c2c26c8bSAndroid Build Coastguard Worker     struct event_desc ev;
600*c2c26c8bSAndroid Build Coastguard Worker 
601*c2c26c8bSAndroid Build Coastguard Worker     ev.event = event;
602*c2c26c8bSAndroid Build Coastguard Worker     ev.data = data;
603*c2c26c8bSAndroid Build Coastguard Worker 
604*c2c26c8bSAndroid Build Coastguard Worker     /* error pipe, debug mode. */
605*c2c26c8bSAndroid Build Coastguard Worker     if (fd == -1)
606*c2c26c8bSAndroid Build Coastguard Worker         fatal_event(&ev);
607*c2c26c8bSAndroid Build Coastguard Worker     else
608*c2c26c8bSAndroid Build Coastguard Worker         /* pipe is non-blocking and struct event_desc is smaller than
609*c2c26c8bSAndroid Build Coastguard Worker            PIPE_BUF, so this either fails or writes everything */
610*c2c26c8bSAndroid Build Coastguard Worker         while (write(fd, &ev, sizeof(ev)) == -1 && errno == EINTR)
611*c2c26c8bSAndroid Build Coastguard Worker             ;
612*c2c26c8bSAndroid Build Coastguard Worker }
613*c2c26c8bSAndroid Build Coastguard Worker 
fatal_event(struct event_desc * ev)614*c2c26c8bSAndroid Build Coastguard Worker static void fatal_event(struct event_desc* ev) {
615*c2c26c8bSAndroid Build Coastguard Worker     errno = ev->data;
616*c2c26c8bSAndroid Build Coastguard Worker 
617*c2c26c8bSAndroid Build Coastguard Worker     switch (ev->event) {
618*c2c26c8bSAndroid Build Coastguard Worker         case EVENT_DIE:
619*c2c26c8bSAndroid Build Coastguard Worker             exit(0);
620*c2c26c8bSAndroid Build Coastguard Worker 
621*c2c26c8bSAndroid Build Coastguard Worker         case EVENT_FORK_ERR:
622*c2c26c8bSAndroid Build Coastguard Worker             die(_("cannot fork into background: %s"), NULL, EC_MISC);
623*c2c26c8bSAndroid Build Coastguard Worker 
624*c2c26c8bSAndroid Build Coastguard Worker         case EVENT_PIPE_ERR:
625*c2c26c8bSAndroid Build Coastguard Worker             die(_("failed to create helper: %s"), NULL, EC_MISC);
626*c2c26c8bSAndroid Build Coastguard Worker 
627*c2c26c8bSAndroid Build Coastguard Worker         case EVENT_CAP_ERR:
628*c2c26c8bSAndroid Build Coastguard Worker             die(_("setting capabilities failed: %s"), NULL, EC_MISC);
629*c2c26c8bSAndroid Build Coastguard Worker 
630*c2c26c8bSAndroid Build Coastguard Worker         case EVENT_USER_ERR:
631*c2c26c8bSAndroid Build Coastguard Worker         case EVENT_HUSER_ERR:
632*c2c26c8bSAndroid Build Coastguard Worker             die(_("failed to change user-id to %s: %s"),
633*c2c26c8bSAndroid Build Coastguard Worker                 ev->event == EVENT_USER_ERR ? daemon->username : daemon->scriptuser, EC_MISC);
634*c2c26c8bSAndroid Build Coastguard Worker 
635*c2c26c8bSAndroid Build Coastguard Worker         case EVENT_GROUP_ERR:
636*c2c26c8bSAndroid Build Coastguard Worker             die(_("failed to change group-id to %s: %s"), daemon->groupname, EC_MISC);
637*c2c26c8bSAndroid Build Coastguard Worker 
638*c2c26c8bSAndroid Build Coastguard Worker         case EVENT_PIDFILE:
639*c2c26c8bSAndroid Build Coastguard Worker             die(_("failed to open pidfile %s: %s"), daemon->runfile, EC_FILE);
640*c2c26c8bSAndroid Build Coastguard Worker 
641*c2c26c8bSAndroid Build Coastguard Worker         case EVENT_LOG_ERR:
642*c2c26c8bSAndroid Build Coastguard Worker             die(_("cannot open %s: %s"), daemon->log_file ? daemon->log_file : "log", EC_FILE);
643*c2c26c8bSAndroid Build Coastguard Worker     }
644*c2c26c8bSAndroid Build Coastguard Worker }
645*c2c26c8bSAndroid Build Coastguard Worker 
async_event(int pipe,time_t now)646*c2c26c8bSAndroid Build Coastguard Worker static void async_event(int pipe, time_t now) {
647*c2c26c8bSAndroid Build Coastguard Worker     pid_t p;
648*c2c26c8bSAndroid Build Coastguard Worker     struct event_desc ev;
649*c2c26c8bSAndroid Build Coastguard Worker     int i;
650*c2c26c8bSAndroid Build Coastguard Worker 
651*c2c26c8bSAndroid Build Coastguard Worker     if (read_write(pipe, (unsigned char*) &ev, sizeof(ev), 1)) switch (ev.event) {
652*c2c26c8bSAndroid Build Coastguard Worker             case EVENT_RELOAD:
653*c2c26c8bSAndroid Build Coastguard Worker                 clear_cache_and_reload(now);
654*c2c26c8bSAndroid Build Coastguard Worker                 if (daemon->port != 0 && daemon->resolv_files && (daemon->options & OPT_NO_POLL)) {
655*c2c26c8bSAndroid Build Coastguard Worker                     reload_servers(daemon->resolv_files->name);
656*c2c26c8bSAndroid Build Coastguard Worker                     check_servers();
657*c2c26c8bSAndroid Build Coastguard Worker                 }
658*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_DHCP
659*c2c26c8bSAndroid Build Coastguard Worker                 rerun_scripts();
660*c2c26c8bSAndroid Build Coastguard Worker #endif
661*c2c26c8bSAndroid Build Coastguard Worker                 break;
662*c2c26c8bSAndroid Build Coastguard Worker 
663*c2c26c8bSAndroid Build Coastguard Worker             case EVENT_DUMP:
664*c2c26c8bSAndroid Build Coastguard Worker                 if (daemon->port != 0) dump_cache(now);
665*c2c26c8bSAndroid Build Coastguard Worker                 break;
666*c2c26c8bSAndroid Build Coastguard Worker 
667*c2c26c8bSAndroid Build Coastguard Worker             case EVENT_ALARM:
668*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_DHCP
669*c2c26c8bSAndroid Build Coastguard Worker                 if (daemon->dhcp) {
670*c2c26c8bSAndroid Build Coastguard Worker                     lease_prune(NULL, now);
671*c2c26c8bSAndroid Build Coastguard Worker                     lease_update_file(now);
672*c2c26c8bSAndroid Build Coastguard Worker                 }
673*c2c26c8bSAndroid Build Coastguard Worker #endif
674*c2c26c8bSAndroid Build Coastguard Worker                 break;
675*c2c26c8bSAndroid Build Coastguard Worker 
676*c2c26c8bSAndroid Build Coastguard Worker             case EVENT_CHILD:
677*c2c26c8bSAndroid Build Coastguard Worker                 /* See Stevens 5.10 */
678*c2c26c8bSAndroid Build Coastguard Worker                 while ((p = waitpid(-1, NULL, WNOHANG)) != 0)
679*c2c26c8bSAndroid Build Coastguard Worker                     if (p == -1) {
680*c2c26c8bSAndroid Build Coastguard Worker                         if (errno != EINTR) break;
681*c2c26c8bSAndroid Build Coastguard Worker                     } else
682*c2c26c8bSAndroid Build Coastguard Worker                         for (i = 0; i < MAX_PROCS; i++)
683*c2c26c8bSAndroid Build Coastguard Worker                             if (daemon->tcp_pids[i] == p) daemon->tcp_pids[i] = 0;
684*c2c26c8bSAndroid Build Coastguard Worker                 break;
685*c2c26c8bSAndroid Build Coastguard Worker 
686*c2c26c8bSAndroid Build Coastguard Worker             case EVENT_KILLED:
687*c2c26c8bSAndroid Build Coastguard Worker                 my_syslog(LOG_WARNING, _("child process killed by signal %d"), ev.data);
688*c2c26c8bSAndroid Build Coastguard Worker                 break;
689*c2c26c8bSAndroid Build Coastguard Worker 
690*c2c26c8bSAndroid Build Coastguard Worker             case EVENT_EXITED:
691*c2c26c8bSAndroid Build Coastguard Worker                 my_syslog(LOG_WARNING, _("child process exited with status %d"), ev.data);
692*c2c26c8bSAndroid Build Coastguard Worker                 break;
693*c2c26c8bSAndroid Build Coastguard Worker 
694*c2c26c8bSAndroid Build Coastguard Worker             case EVENT_EXEC_ERR:
695*c2c26c8bSAndroid Build Coastguard Worker                 my_syslog(LOG_ERR, _("failed to execute %s: %s"), daemon->lease_change_command,
696*c2c26c8bSAndroid Build Coastguard Worker                           strerror(ev.data));
697*c2c26c8bSAndroid Build Coastguard Worker                 break;
698*c2c26c8bSAndroid Build Coastguard Worker 
699*c2c26c8bSAndroid Build Coastguard Worker                 /* necessary for fatal errors in helper */
700*c2c26c8bSAndroid Build Coastguard Worker             case EVENT_HUSER_ERR:
701*c2c26c8bSAndroid Build Coastguard Worker             case EVENT_DIE:
702*c2c26c8bSAndroid Build Coastguard Worker                 fatal_event(&ev);
703*c2c26c8bSAndroid Build Coastguard Worker                 break;
704*c2c26c8bSAndroid Build Coastguard Worker 
705*c2c26c8bSAndroid Build Coastguard Worker             case EVENT_REOPEN:
706*c2c26c8bSAndroid Build Coastguard Worker                 /* Note: this may leave TCP-handling processes with the old file still open.
707*c2c26c8bSAndroid Build Coastguard Worker                    Since any such process will die in CHILD_LIFETIME or probably much sooner,
708*c2c26c8bSAndroid Build Coastguard Worker                    we leave them logging to the old file. */
709*c2c26c8bSAndroid Build Coastguard Worker                 if (daemon->log_file != NULL) log_reopen(daemon->log_file);
710*c2c26c8bSAndroid Build Coastguard Worker                 break;
711*c2c26c8bSAndroid Build Coastguard Worker 
712*c2c26c8bSAndroid Build Coastguard Worker             case EVENT_TERM:
713*c2c26c8bSAndroid Build Coastguard Worker                 /* Knock all our children on the head. */
714*c2c26c8bSAndroid Build Coastguard Worker                 for (i = 0; i < MAX_PROCS; i++)
715*c2c26c8bSAndroid Build Coastguard Worker                     if (daemon->tcp_pids[i] != 0) kill(daemon->tcp_pids[i], SIGALRM);
716*c2c26c8bSAndroid Build Coastguard Worker 
717*c2c26c8bSAndroid Build Coastguard Worker #if defined(HAVE_DHCP) && defined(HAVE_SCRIPT)
718*c2c26c8bSAndroid Build Coastguard Worker                 /* handle pending lease transitions */
719*c2c26c8bSAndroid Build Coastguard Worker                 if (daemon->helperfd != -1) {
720*c2c26c8bSAndroid Build Coastguard Worker                     /* block in writes until all done */
721*c2c26c8bSAndroid Build Coastguard Worker                     if ((i = fcntl(daemon->helperfd, F_GETFL)) != -1)
722*c2c26c8bSAndroid Build Coastguard Worker                         fcntl(daemon->helperfd, F_SETFL, i & ~O_NONBLOCK);
723*c2c26c8bSAndroid Build Coastguard Worker                     do {
724*c2c26c8bSAndroid Build Coastguard Worker                         helper_write();
725*c2c26c8bSAndroid Build Coastguard Worker                     } while (!helper_buf_empty() || do_script_run(now));
726*c2c26c8bSAndroid Build Coastguard Worker                     close(daemon->helperfd);
727*c2c26c8bSAndroid Build Coastguard Worker                 }
728*c2c26c8bSAndroid Build Coastguard Worker #endif
729*c2c26c8bSAndroid Build Coastguard Worker 
730*c2c26c8bSAndroid Build Coastguard Worker                 if (daemon->lease_stream) fclose(daemon->lease_stream);
731*c2c26c8bSAndroid Build Coastguard Worker 
732*c2c26c8bSAndroid Build Coastguard Worker                 if (daemon->runfile) unlink(daemon->runfile);
733*c2c26c8bSAndroid Build Coastguard Worker 
734*c2c26c8bSAndroid Build Coastguard Worker                 my_syslog(LOG_INFO, _("exiting on receipt of SIGTERM"));
735*c2c26c8bSAndroid Build Coastguard Worker                 flush_log();
736*c2c26c8bSAndroid Build Coastguard Worker                 exit(EC_GOOD);
737*c2c26c8bSAndroid Build Coastguard Worker         }
738*c2c26c8bSAndroid Build Coastguard Worker }
739*c2c26c8bSAndroid Build Coastguard Worker 
poll_resolv()740*c2c26c8bSAndroid Build Coastguard Worker static void poll_resolv() {
741*c2c26c8bSAndroid Build Coastguard Worker     struct resolvc *res, *latest;
742*c2c26c8bSAndroid Build Coastguard Worker     struct stat statbuf;
743*c2c26c8bSAndroid Build Coastguard Worker     time_t last_change = 0;
744*c2c26c8bSAndroid Build Coastguard Worker     /* There may be more than one possible file.
745*c2c26c8bSAndroid Build Coastguard Worker        Go through and find the one which changed _last_.
746*c2c26c8bSAndroid Build Coastguard Worker        Warn of any which can't be read. */
747*c2c26c8bSAndroid Build Coastguard Worker     for (latest = NULL, res = daemon->resolv_files; res; res = res->next)
748*c2c26c8bSAndroid Build Coastguard Worker         if (stat(res->name, &statbuf) == -1) {
749*c2c26c8bSAndroid Build Coastguard Worker             if (!res->logged)
750*c2c26c8bSAndroid Build Coastguard Worker                 my_syslog(LOG_WARNING, _("failed to access %s: %s"), res->name, strerror(errno));
751*c2c26c8bSAndroid Build Coastguard Worker             res->logged = 1;
752*c2c26c8bSAndroid Build Coastguard Worker         } else {
753*c2c26c8bSAndroid Build Coastguard Worker             res->logged = 0;
754*c2c26c8bSAndroid Build Coastguard Worker             if (statbuf.st_mtime != res->mtime) {
755*c2c26c8bSAndroid Build Coastguard Worker                 res->mtime = statbuf.st_mtime;
756*c2c26c8bSAndroid Build Coastguard Worker                 if (difftime(statbuf.st_mtime, last_change) > 0.0) {
757*c2c26c8bSAndroid Build Coastguard Worker                     last_change = statbuf.st_mtime;
758*c2c26c8bSAndroid Build Coastguard Worker                     latest = res;
759*c2c26c8bSAndroid Build Coastguard Worker                 }
760*c2c26c8bSAndroid Build Coastguard Worker             }
761*c2c26c8bSAndroid Build Coastguard Worker         }
762*c2c26c8bSAndroid Build Coastguard Worker 
763*c2c26c8bSAndroid Build Coastguard Worker     if (latest) {
764*c2c26c8bSAndroid Build Coastguard Worker         static int warned = 0;
765*c2c26c8bSAndroid Build Coastguard Worker         if (reload_servers(latest->name)) {
766*c2c26c8bSAndroid Build Coastguard Worker             my_syslog(LOG_INFO, _("reading %s"), latest->name);
767*c2c26c8bSAndroid Build Coastguard Worker             warned = 0;
768*c2c26c8bSAndroid Build Coastguard Worker             check_servers();
769*c2c26c8bSAndroid Build Coastguard Worker             if (daemon->options & OPT_RELOAD) cache_reload();
770*c2c26c8bSAndroid Build Coastguard Worker         } else {
771*c2c26c8bSAndroid Build Coastguard Worker             latest->mtime = 0;
772*c2c26c8bSAndroid Build Coastguard Worker             if (!warned) {
773*c2c26c8bSAndroid Build Coastguard Worker                 my_syslog(LOG_WARNING, _("no servers found in %s, will retry"), latest->name);
774*c2c26c8bSAndroid Build Coastguard Worker                 warned = 1;
775*c2c26c8bSAndroid Build Coastguard Worker             }
776*c2c26c8bSAndroid Build Coastguard Worker         }
777*c2c26c8bSAndroid Build Coastguard Worker     }
778*c2c26c8bSAndroid Build Coastguard Worker }
779*c2c26c8bSAndroid Build Coastguard Worker 
clear_cache_and_reload(time_t now)780*c2c26c8bSAndroid Build Coastguard Worker void clear_cache_and_reload(time_t now) {
781*c2c26c8bSAndroid Build Coastguard Worker     if (daemon->port != 0) cache_reload();
782*c2c26c8bSAndroid Build Coastguard Worker 
783*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_DHCP
784*c2c26c8bSAndroid Build Coastguard Worker     if (daemon->dhcp) {
785*c2c26c8bSAndroid Build Coastguard Worker         reread_dhcp();
786*c2c26c8bSAndroid Build Coastguard Worker         dhcp_update_configs(daemon->dhcp_conf);
787*c2c26c8bSAndroid Build Coastguard Worker         check_dhcp_hosts(0);
788*c2c26c8bSAndroid Build Coastguard Worker         lease_update_from_configs();
789*c2c26c8bSAndroid Build Coastguard Worker         lease_update_file(now);
790*c2c26c8bSAndroid Build Coastguard Worker         lease_update_dns();
791*c2c26c8bSAndroid Build Coastguard Worker     }
792*c2c26c8bSAndroid Build Coastguard Worker #endif
793*c2c26c8bSAndroid Build Coastguard Worker }
794*c2c26c8bSAndroid Build Coastguard Worker 
795*c2c26c8bSAndroid Build Coastguard Worker #ifdef __ANDROID__
796*c2c26c8bSAndroid Build Coastguard Worker 
set_android_listeners(fd_set * set,int * maxfdp)797*c2c26c8bSAndroid Build Coastguard Worker static int set_android_listeners(fd_set* set, int* maxfdp) {
798*c2c26c8bSAndroid Build Coastguard Worker     FD_SET(STDIN_FILENO, set);
799*c2c26c8bSAndroid Build Coastguard Worker     bump_maxfd(STDIN_FILENO, maxfdp);
800*c2c26c8bSAndroid Build Coastguard Worker     return 0;
801*c2c26c8bSAndroid Build Coastguard Worker }
802*c2c26c8bSAndroid Build Coastguard Worker 
check_android_listeners(fd_set * set)803*c2c26c8bSAndroid Build Coastguard Worker static int check_android_listeners(fd_set* set) {
804*c2c26c8bSAndroid Build Coastguard Worker     int retcode = 0;
805*c2c26c8bSAndroid Build Coastguard Worker     if (FD_ISSET(STDIN_FILENO, set)) {
806*c2c26c8bSAndroid Build Coastguard Worker         char buffer[1024];
807*c2c26c8bSAndroid Build Coastguard Worker         int rc;
808*c2c26c8bSAndroid Build Coastguard Worker         int consumed = 0;
809*c2c26c8bSAndroid Build Coastguard Worker 
810*c2c26c8bSAndroid Build Coastguard Worker         if ((rc = read(STDIN_FILENO, buffer, sizeof(buffer) - 1)) < 0) {
811*c2c26c8bSAndroid Build Coastguard Worker             my_syslog(LOG_ERR, _("Error reading from stdin (%s)"), strerror(errno));
812*c2c26c8bSAndroid Build Coastguard Worker             return -1;
813*c2c26c8bSAndroid Build Coastguard Worker         }
814*c2c26c8bSAndroid Build Coastguard Worker         buffer[rc] = '\0';
815*c2c26c8bSAndroid Build Coastguard Worker         while (consumed < rc) {
816*c2c26c8bSAndroid Build Coastguard Worker             char* cmd;
817*c2c26c8bSAndroid Build Coastguard Worker             char* current_cmd = &buffer[consumed];
818*c2c26c8bSAndroid Build Coastguard Worker             char* params = current_cmd;
819*c2c26c8bSAndroid Build Coastguard Worker             int len = strlen(current_cmd);
820*c2c26c8bSAndroid Build Coastguard Worker 
821*c2c26c8bSAndroid Build Coastguard Worker             cmd = strsep(&params, "|");
822*c2c26c8bSAndroid Build Coastguard Worker             if (!strcmp(cmd, "update_dns")) {
823*c2c26c8bSAndroid Build Coastguard Worker                 if (params != NULL) {
824*c2c26c8bSAndroid Build Coastguard Worker                     set_servers(params);
825*c2c26c8bSAndroid Build Coastguard Worker                     check_servers();
826*c2c26c8bSAndroid Build Coastguard Worker                 } else {
827*c2c26c8bSAndroid Build Coastguard Worker                     my_syslog(LOG_ERR, _("Misformatted msg '%s'"), current_cmd);
828*c2c26c8bSAndroid Build Coastguard Worker                     retcode = -1;
829*c2c26c8bSAndroid Build Coastguard Worker                 }
830*c2c26c8bSAndroid Build Coastguard Worker             } else if (!strcmp(cmd, "update_ifaces")) {
831*c2c26c8bSAndroid Build Coastguard Worker                 if (params != NULL) {
832*c2c26c8bSAndroid Build Coastguard Worker                     set_interfaces(params);
833*c2c26c8bSAndroid Build Coastguard Worker                 } else {
834*c2c26c8bSAndroid Build Coastguard Worker                     my_syslog(LOG_ERR, _("Misformatted msg '%s'"), current_cmd);
835*c2c26c8bSAndroid Build Coastguard Worker                     retcode = -1;
836*c2c26c8bSAndroid Build Coastguard Worker                 }
837*c2c26c8bSAndroid Build Coastguard Worker             } else {
838*c2c26c8bSAndroid Build Coastguard Worker                 my_syslog(LOG_ERR, _("Unknown cmd '%s'"), cmd);
839*c2c26c8bSAndroid Build Coastguard Worker                 retcode = -1;
840*c2c26c8bSAndroid Build Coastguard Worker             }
841*c2c26c8bSAndroid Build Coastguard Worker             consumed += len + 1;
842*c2c26c8bSAndroid Build Coastguard Worker         }
843*c2c26c8bSAndroid Build Coastguard Worker     }
844*c2c26c8bSAndroid Build Coastguard Worker     return retcode;
845*c2c26c8bSAndroid Build Coastguard Worker }
846*c2c26c8bSAndroid Build Coastguard Worker #endif
847*c2c26c8bSAndroid Build Coastguard Worker 
set_dns_listeners(time_t now,fd_set * set,int * maxfdp)848*c2c26c8bSAndroid Build Coastguard Worker static int set_dns_listeners(time_t now, fd_set* set, int* maxfdp) {
849*c2c26c8bSAndroid Build Coastguard Worker     struct serverfd* serverfdp;
850*c2c26c8bSAndroid Build Coastguard Worker     struct listener* listener;
851*c2c26c8bSAndroid Build Coastguard Worker     int wait = 0, i;
852*c2c26c8bSAndroid Build Coastguard Worker 
853*c2c26c8bSAndroid Build Coastguard Worker     /* will we be able to get memory? */
854*c2c26c8bSAndroid Build Coastguard Worker     if (daemon->port != 0) get_new_frec(now, &wait);
855*c2c26c8bSAndroid Build Coastguard Worker 
856*c2c26c8bSAndroid Build Coastguard Worker     for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next) {
857*c2c26c8bSAndroid Build Coastguard Worker         FD_SET(serverfdp->fd, set);
858*c2c26c8bSAndroid Build Coastguard Worker         bump_maxfd(serverfdp->fd, maxfdp);
859*c2c26c8bSAndroid Build Coastguard Worker     }
860*c2c26c8bSAndroid Build Coastguard Worker 
861*c2c26c8bSAndroid Build Coastguard Worker     if (daemon->port != 0 && !daemon->osport)
862*c2c26c8bSAndroid Build Coastguard Worker         for (i = 0; i < RANDOM_SOCKS; i++)
863*c2c26c8bSAndroid Build Coastguard Worker             if (daemon->randomsocks[i].refcount != 0) {
864*c2c26c8bSAndroid Build Coastguard Worker                 FD_SET(daemon->randomsocks[i].fd, set);
865*c2c26c8bSAndroid Build Coastguard Worker                 bump_maxfd(daemon->randomsocks[i].fd, maxfdp);
866*c2c26c8bSAndroid Build Coastguard Worker             }
867*c2c26c8bSAndroid Build Coastguard Worker 
868*c2c26c8bSAndroid Build Coastguard Worker     for (listener = daemon->listeners; listener; listener = listener->next) {
869*c2c26c8bSAndroid Build Coastguard Worker         /* only listen for queries if we have resources */
870*c2c26c8bSAndroid Build Coastguard Worker         if (listener->fd != -1 && wait == 0) {
871*c2c26c8bSAndroid Build Coastguard Worker             FD_SET(listener->fd, set);
872*c2c26c8bSAndroid Build Coastguard Worker             bump_maxfd(listener->fd, maxfdp);
873*c2c26c8bSAndroid Build Coastguard Worker         }
874*c2c26c8bSAndroid Build Coastguard Worker 
875*c2c26c8bSAndroid Build Coastguard Worker         /* death of a child goes through the select loop, so
876*c2c26c8bSAndroid Build Coastguard Worker        we don't need to explicitly arrange to wake up here */
877*c2c26c8bSAndroid Build Coastguard Worker         if (listener->tcpfd != -1)
878*c2c26c8bSAndroid Build Coastguard Worker             for (i = 0; i < MAX_PROCS; i++)
879*c2c26c8bSAndroid Build Coastguard Worker                 if (daemon->tcp_pids[i] == 0) {
880*c2c26c8bSAndroid Build Coastguard Worker                     FD_SET(listener->tcpfd, set);
881*c2c26c8bSAndroid Build Coastguard Worker                     bump_maxfd(listener->tcpfd, maxfdp);
882*c2c26c8bSAndroid Build Coastguard Worker                     break;
883*c2c26c8bSAndroid Build Coastguard Worker                 }
884*c2c26c8bSAndroid Build Coastguard Worker     }
885*c2c26c8bSAndroid Build Coastguard Worker 
886*c2c26c8bSAndroid Build Coastguard Worker     return wait;
887*c2c26c8bSAndroid Build Coastguard Worker }
888*c2c26c8bSAndroid Build Coastguard Worker 
check_dns_listeners(fd_set * set,time_t now)889*c2c26c8bSAndroid Build Coastguard Worker static void check_dns_listeners(fd_set* set, time_t now) {
890*c2c26c8bSAndroid Build Coastguard Worker     struct serverfd* serverfdp;
891*c2c26c8bSAndroid Build Coastguard Worker     struct listener* listener;
892*c2c26c8bSAndroid Build Coastguard Worker     int i;
893*c2c26c8bSAndroid Build Coastguard Worker 
894*c2c26c8bSAndroid Build Coastguard Worker     for (serverfdp = daemon->sfds; serverfdp; serverfdp = serverfdp->next)
895*c2c26c8bSAndroid Build Coastguard Worker         if (FD_ISSET(serverfdp->fd, set))
896*c2c26c8bSAndroid Build Coastguard Worker             reply_query(serverfdp->fd, serverfdp->source_addr.sa.sa_family, now);
897*c2c26c8bSAndroid Build Coastguard Worker 
898*c2c26c8bSAndroid Build Coastguard Worker     if (daemon->port != 0 && !daemon->osport)
899*c2c26c8bSAndroid Build Coastguard Worker         for (i = 0; i < RANDOM_SOCKS; i++)
900*c2c26c8bSAndroid Build Coastguard Worker             if (daemon->randomsocks[i].refcount != 0 && FD_ISSET(daemon->randomsocks[i].fd, set))
901*c2c26c8bSAndroid Build Coastguard Worker                 reply_query(daemon->randomsocks[i].fd, daemon->randomsocks[i].family, now);
902*c2c26c8bSAndroid Build Coastguard Worker 
903*c2c26c8bSAndroid Build Coastguard Worker     for (listener = daemon->listeners; listener; listener = listener->next) {
904*c2c26c8bSAndroid Build Coastguard Worker         if (listener->fd != -1 && FD_ISSET(listener->fd, set)) receive_query(listener, now);
905*c2c26c8bSAndroid Build Coastguard Worker 
906*c2c26c8bSAndroid Build Coastguard Worker         if (listener->tcpfd != -1 && FD_ISSET(listener->tcpfd, set)) {
907*c2c26c8bSAndroid Build Coastguard Worker             int confd;
908*c2c26c8bSAndroid Build Coastguard Worker             struct irec* iface = NULL;
909*c2c26c8bSAndroid Build Coastguard Worker             pid_t p;
910*c2c26c8bSAndroid Build Coastguard Worker 
911*c2c26c8bSAndroid Build Coastguard Worker             while ((confd = accept(listener->tcpfd, NULL, NULL)) == -1 && errno == EINTR)
912*c2c26c8bSAndroid Build Coastguard Worker                 ;
913*c2c26c8bSAndroid Build Coastguard Worker 
914*c2c26c8bSAndroid Build Coastguard Worker             if (confd == -1) continue;
915*c2c26c8bSAndroid Build Coastguard Worker 
916*c2c26c8bSAndroid Build Coastguard Worker             if (daemon->options & OPT_NOWILD)
917*c2c26c8bSAndroid Build Coastguard Worker                 iface = listener->iface;
918*c2c26c8bSAndroid Build Coastguard Worker             else {
919*c2c26c8bSAndroid Build Coastguard Worker                 union mysockaddr tcp_addr;
920*c2c26c8bSAndroid Build Coastguard Worker                 socklen_t tcp_len = sizeof(union mysockaddr);
921*c2c26c8bSAndroid Build Coastguard Worker                 /* Check for allowed interfaces when binding the wildcard address:
922*c2c26c8bSAndroid Build Coastguard Worker                we do this by looking for an interface with the same address as
923*c2c26c8bSAndroid Build Coastguard Worker                the local address of the TCP connection, then looking to see if that's
924*c2c26c8bSAndroid Build Coastguard Worker                an allowed interface. As a side effect, we get the netmask of the
925*c2c26c8bSAndroid Build Coastguard Worker                interface too, for localisation. */
926*c2c26c8bSAndroid Build Coastguard Worker 
927*c2c26c8bSAndroid Build Coastguard Worker                 /* interface may be new since startup */
928*c2c26c8bSAndroid Build Coastguard Worker                 if (enumerate_interfaces() &&
929*c2c26c8bSAndroid Build Coastguard Worker                     getsockname(confd, (struct sockaddr*) &tcp_addr, &tcp_len) != -1)
930*c2c26c8bSAndroid Build Coastguard Worker                     for (iface = daemon->interfaces; iface; iface = iface->next)
931*c2c26c8bSAndroid Build Coastguard Worker                         if (sockaddr_isequal(&iface->addr, &tcp_addr)) break;
932*c2c26c8bSAndroid Build Coastguard Worker             }
933*c2c26c8bSAndroid Build Coastguard Worker 
934*c2c26c8bSAndroid Build Coastguard Worker             if (!iface) {
935*c2c26c8bSAndroid Build Coastguard Worker                 shutdown(confd, SHUT_RDWR);
936*c2c26c8bSAndroid Build Coastguard Worker                 close(confd);
937*c2c26c8bSAndroid Build Coastguard Worker             }
938*c2c26c8bSAndroid Build Coastguard Worker #ifndef NO_FORK
939*c2c26c8bSAndroid Build Coastguard Worker             else if (!(daemon->options & OPT_DEBUG) && (p = fork()) != 0) {
940*c2c26c8bSAndroid Build Coastguard Worker                 if (p != -1) {
941*c2c26c8bSAndroid Build Coastguard Worker                     int i;
942*c2c26c8bSAndroid Build Coastguard Worker                     for (i = 0; i < MAX_PROCS; i++)
943*c2c26c8bSAndroid Build Coastguard Worker                         if (daemon->tcp_pids[i] == 0) {
944*c2c26c8bSAndroid Build Coastguard Worker                             daemon->tcp_pids[i] = p;
945*c2c26c8bSAndroid Build Coastguard Worker                             break;
946*c2c26c8bSAndroid Build Coastguard Worker                         }
947*c2c26c8bSAndroid Build Coastguard Worker                 }
948*c2c26c8bSAndroid Build Coastguard Worker                 close(confd);
949*c2c26c8bSAndroid Build Coastguard Worker             }
950*c2c26c8bSAndroid Build Coastguard Worker #endif
951*c2c26c8bSAndroid Build Coastguard Worker             else {
952*c2c26c8bSAndroid Build Coastguard Worker                 unsigned char* buff;
953*c2c26c8bSAndroid Build Coastguard Worker                 struct server* s;
954*c2c26c8bSAndroid Build Coastguard Worker                 int flags;
955*c2c26c8bSAndroid Build Coastguard Worker                 struct in_addr dst_addr_4;
956*c2c26c8bSAndroid Build Coastguard Worker 
957*c2c26c8bSAndroid Build Coastguard Worker                 dst_addr_4.s_addr = 0;
958*c2c26c8bSAndroid Build Coastguard Worker 
959*c2c26c8bSAndroid Build Coastguard Worker                 /* Arrange for SIGALARM after CHILD_LIFETIME seconds to
960*c2c26c8bSAndroid Build Coastguard Worker                terminate the process. */
961*c2c26c8bSAndroid Build Coastguard Worker                 if (!(daemon->options & OPT_DEBUG)) alarm(CHILD_LIFETIME);
962*c2c26c8bSAndroid Build Coastguard Worker 
963*c2c26c8bSAndroid Build Coastguard Worker                 /* start with no upstream connections. */
964*c2c26c8bSAndroid Build Coastguard Worker                 for (s = daemon->servers; s; s = s->next) s->tcpfd = -1;
965*c2c26c8bSAndroid Build Coastguard Worker 
966*c2c26c8bSAndroid Build Coastguard Worker                 /* The connected socket inherits non-blocking
967*c2c26c8bSAndroid Build Coastguard Worker                attribute from the listening socket.
968*c2c26c8bSAndroid Build Coastguard Worker                Reset that here. */
969*c2c26c8bSAndroid Build Coastguard Worker                 if ((flags = fcntl(confd, F_GETFL, 0)) != -1)
970*c2c26c8bSAndroid Build Coastguard Worker                     fcntl(confd, F_SETFL, flags & ~O_NONBLOCK);
971*c2c26c8bSAndroid Build Coastguard Worker 
972*c2c26c8bSAndroid Build Coastguard Worker                 if (listener->family == AF_INET) dst_addr_4 = iface->addr.in.sin_addr;
973*c2c26c8bSAndroid Build Coastguard Worker 
974*c2c26c8bSAndroid Build Coastguard Worker                 buff = tcp_request(confd, now, dst_addr_4, iface->netmask);
975*c2c26c8bSAndroid Build Coastguard Worker 
976*c2c26c8bSAndroid Build Coastguard Worker                 shutdown(confd, SHUT_RDWR);
977*c2c26c8bSAndroid Build Coastguard Worker                 close(confd);
978*c2c26c8bSAndroid Build Coastguard Worker 
979*c2c26c8bSAndroid Build Coastguard Worker                 if (buff) free(buff);
980*c2c26c8bSAndroid Build Coastguard Worker 
981*c2c26c8bSAndroid Build Coastguard Worker                 for (s = daemon->servers; s; s = s->next)
982*c2c26c8bSAndroid Build Coastguard Worker                     if (s->tcpfd != -1) {
983*c2c26c8bSAndroid Build Coastguard Worker                         shutdown(s->tcpfd, SHUT_RDWR);
984*c2c26c8bSAndroid Build Coastguard Worker                         close(s->tcpfd);
985*c2c26c8bSAndroid Build Coastguard Worker                     }
986*c2c26c8bSAndroid Build Coastguard Worker #ifndef NO_FORK
987*c2c26c8bSAndroid Build Coastguard Worker                 if (!(daemon->options & OPT_DEBUG)) {
988*c2c26c8bSAndroid Build Coastguard Worker                     flush_log();
989*c2c26c8bSAndroid Build Coastguard Worker                     _exit(0);
990*c2c26c8bSAndroid Build Coastguard Worker                 }
991*c2c26c8bSAndroid Build Coastguard Worker #endif
992*c2c26c8bSAndroid Build Coastguard Worker             }
993*c2c26c8bSAndroid Build Coastguard Worker         }
994*c2c26c8bSAndroid Build Coastguard Worker     }
995*c2c26c8bSAndroid Build Coastguard Worker }
996*c2c26c8bSAndroid Build Coastguard Worker 
997*c2c26c8bSAndroid Build Coastguard Worker #ifdef HAVE_DHCP
make_icmp_sock(void)998*c2c26c8bSAndroid Build Coastguard Worker int make_icmp_sock(void) {
999*c2c26c8bSAndroid Build Coastguard Worker     int fd;
1000*c2c26c8bSAndroid Build Coastguard Worker     int zeroopt = 0;
1001*c2c26c8bSAndroid Build Coastguard Worker 
1002*c2c26c8bSAndroid Build Coastguard Worker     if ((fd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) != -1) {
1003*c2c26c8bSAndroid Build Coastguard Worker         if (!fix_fd(fd) ||
1004*c2c26c8bSAndroid Build Coastguard Worker             setsockopt(fd, SOL_SOCKET, SO_DONTROUTE, &zeroopt, sizeof(zeroopt)) == -1) {
1005*c2c26c8bSAndroid Build Coastguard Worker             close(fd);
1006*c2c26c8bSAndroid Build Coastguard Worker             fd = -1;
1007*c2c26c8bSAndroid Build Coastguard Worker         }
1008*c2c26c8bSAndroid Build Coastguard Worker     }
1009*c2c26c8bSAndroid Build Coastguard Worker 
1010*c2c26c8bSAndroid Build Coastguard Worker     return fd;
1011*c2c26c8bSAndroid Build Coastguard Worker }
1012*c2c26c8bSAndroid Build Coastguard Worker 
icmp_ping(struct in_addr addr)1013*c2c26c8bSAndroid Build Coastguard Worker int icmp_ping(struct in_addr addr) {
1014*c2c26c8bSAndroid Build Coastguard Worker     /* Try and get an ICMP echo from a machine. */
1015*c2c26c8bSAndroid Build Coastguard Worker 
1016*c2c26c8bSAndroid Build Coastguard Worker     /* Note that whilst in the three second wait, we check for
1017*c2c26c8bSAndroid Build Coastguard Worker        (and service) events on the DNS sockets, (so doing that
1018*c2c26c8bSAndroid Build Coastguard Worker        better not use any resources our caller has in use...)
1019*c2c26c8bSAndroid Build Coastguard Worker        but we remain deaf to signals or further DHCP packets. */
1020*c2c26c8bSAndroid Build Coastguard Worker 
1021*c2c26c8bSAndroid Build Coastguard Worker     int fd;
1022*c2c26c8bSAndroid Build Coastguard Worker     struct sockaddr_in saddr;
1023*c2c26c8bSAndroid Build Coastguard Worker     struct {
1024*c2c26c8bSAndroid Build Coastguard Worker         struct ip ip;
1025*c2c26c8bSAndroid Build Coastguard Worker         struct icmp icmp;
1026*c2c26c8bSAndroid Build Coastguard Worker     } packet;
1027*c2c26c8bSAndroid Build Coastguard Worker     unsigned short id = rand16();
1028*c2c26c8bSAndroid Build Coastguard Worker     unsigned int i, j;
1029*c2c26c8bSAndroid Build Coastguard Worker     int gotreply = 0;
1030*c2c26c8bSAndroid Build Coastguard Worker     time_t start, now;
1031*c2c26c8bSAndroid Build Coastguard Worker 
1032*c2c26c8bSAndroid Build Coastguard Worker #if defined(HAVE_LINUX_NETWORK)
1033*c2c26c8bSAndroid Build Coastguard Worker     if ((fd = make_icmp_sock()) == -1) return 0;
1034*c2c26c8bSAndroid Build Coastguard Worker #else
1035*c2c26c8bSAndroid Build Coastguard Worker     int opt = 2000;
1036*c2c26c8bSAndroid Build Coastguard Worker     fd = daemon->dhcp_icmp_fd;
1037*c2c26c8bSAndroid Build Coastguard Worker     setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
1038*c2c26c8bSAndroid Build Coastguard Worker #endif
1039*c2c26c8bSAndroid Build Coastguard Worker 
1040*c2c26c8bSAndroid Build Coastguard Worker     saddr.sin_family = AF_INET;
1041*c2c26c8bSAndroid Build Coastguard Worker     saddr.sin_port = 0;
1042*c2c26c8bSAndroid Build Coastguard Worker     saddr.sin_addr = addr;
1043*c2c26c8bSAndroid Build Coastguard Worker 
1044*c2c26c8bSAndroid Build Coastguard Worker     memset(&packet.icmp, 0, sizeof(packet.icmp));
1045*c2c26c8bSAndroid Build Coastguard Worker     packet.icmp.icmp_type = ICMP_ECHO;
1046*c2c26c8bSAndroid Build Coastguard Worker     packet.icmp.icmp_id = id;
1047*c2c26c8bSAndroid Build Coastguard Worker     for (j = 0, i = 0; i < sizeof(struct icmp) / 2; i++) j += ((u16*) &packet.icmp)[i];
1048*c2c26c8bSAndroid Build Coastguard Worker     while (j >> 16) j = (j & 0xffff) + (j >> 16);
1049*c2c26c8bSAndroid Build Coastguard Worker     packet.icmp.icmp_cksum = (j == 0xffff) ? j : ~j;
1050*c2c26c8bSAndroid Build Coastguard Worker 
1051*c2c26c8bSAndroid Build Coastguard Worker     while (sendto(fd, (char*) &packet.icmp, sizeof(struct icmp), 0, (struct sockaddr*) &saddr,
1052*c2c26c8bSAndroid Build Coastguard Worker                   sizeof(saddr)) == -1 &&
1053*c2c26c8bSAndroid Build Coastguard Worker            retry_send())
1054*c2c26c8bSAndroid Build Coastguard Worker         ;
1055*c2c26c8bSAndroid Build Coastguard Worker 
1056*c2c26c8bSAndroid Build Coastguard Worker     for (now = start = dnsmasq_time(); difftime(now, start) < (float) PING_WAIT;) {
1057*c2c26c8bSAndroid Build Coastguard Worker         struct timeval tv;
1058*c2c26c8bSAndroid Build Coastguard Worker         fd_set rset, wset;
1059*c2c26c8bSAndroid Build Coastguard Worker         struct sockaddr_in faddr;
1060*c2c26c8bSAndroid Build Coastguard Worker         int maxfd = fd;
1061*c2c26c8bSAndroid Build Coastguard Worker         socklen_t len = sizeof(faddr);
1062*c2c26c8bSAndroid Build Coastguard Worker 
1063*c2c26c8bSAndroid Build Coastguard Worker         tv.tv_usec = 250000;
1064*c2c26c8bSAndroid Build Coastguard Worker         tv.tv_sec = 0;
1065*c2c26c8bSAndroid Build Coastguard Worker 
1066*c2c26c8bSAndroid Build Coastguard Worker         FD_ZERO(&rset);
1067*c2c26c8bSAndroid Build Coastguard Worker         FD_ZERO(&wset);
1068*c2c26c8bSAndroid Build Coastguard Worker         FD_SET(fd, &rset);
1069*c2c26c8bSAndroid Build Coastguard Worker         set_dns_listeners(now, &rset, &maxfd);
1070*c2c26c8bSAndroid Build Coastguard Worker         set_log_writer(&wset, &maxfd);
1071*c2c26c8bSAndroid Build Coastguard Worker 
1072*c2c26c8bSAndroid Build Coastguard Worker         if (select(maxfd + 1, &rset, &wset, NULL, &tv) < 0) {
1073*c2c26c8bSAndroid Build Coastguard Worker             FD_ZERO(&rset);
1074*c2c26c8bSAndroid Build Coastguard Worker             FD_ZERO(&wset);
1075*c2c26c8bSAndroid Build Coastguard Worker         }
1076*c2c26c8bSAndroid Build Coastguard Worker 
1077*c2c26c8bSAndroid Build Coastguard Worker         now = dnsmasq_time();
1078*c2c26c8bSAndroid Build Coastguard Worker 
1079*c2c26c8bSAndroid Build Coastguard Worker         check_log_writer(&wset);
1080*c2c26c8bSAndroid Build Coastguard Worker         check_dns_listeners(&rset, now);
1081*c2c26c8bSAndroid Build Coastguard Worker 
1082*c2c26c8bSAndroid Build Coastguard Worker         if (FD_ISSET(fd, &rset) &&
1083*c2c26c8bSAndroid Build Coastguard Worker             recvfrom(fd, &packet, sizeof(packet), 0, (struct sockaddr*) &faddr, &len) ==
1084*c2c26c8bSAndroid Build Coastguard Worker                 sizeof(packet) &&
1085*c2c26c8bSAndroid Build Coastguard Worker             saddr.sin_addr.s_addr == faddr.sin_addr.s_addr &&
1086*c2c26c8bSAndroid Build Coastguard Worker             packet.icmp.icmp_type == ICMP_ECHOREPLY && packet.icmp.icmp_seq == 0 &&
1087*c2c26c8bSAndroid Build Coastguard Worker             packet.icmp.icmp_id == id) {
1088*c2c26c8bSAndroid Build Coastguard Worker             gotreply = 1;
1089*c2c26c8bSAndroid Build Coastguard Worker             break;
1090*c2c26c8bSAndroid Build Coastguard Worker         }
1091*c2c26c8bSAndroid Build Coastguard Worker     }
1092*c2c26c8bSAndroid Build Coastguard Worker 
1093*c2c26c8bSAndroid Build Coastguard Worker #if defined(HAVE_LINUX_NETWORK)
1094*c2c26c8bSAndroid Build Coastguard Worker     close(fd);
1095*c2c26c8bSAndroid Build Coastguard Worker #else
1096*c2c26c8bSAndroid Build Coastguard Worker     opt = 1;
1097*c2c26c8bSAndroid Build Coastguard Worker     setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
1098*c2c26c8bSAndroid Build Coastguard Worker #endif
1099*c2c26c8bSAndroid Build Coastguard Worker 
1100*c2c26c8bSAndroid Build Coastguard Worker     return gotreply;
1101*c2c26c8bSAndroid Build Coastguard Worker }
1102*c2c26c8bSAndroid Build Coastguard Worker #endif
1103