1 /* dnsmasq is Copyright (c) 2000-2013 Simon Kelley
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 dated June, 1991, or
6 (at your option) version 3 dated 29 June, 2007.
8 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.
13 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/>.
20 # include <android/log.h>
23 /* Implement logging to /dev/log asynchronously. If syslogd is
24 making DNS lookups through dnsmasq, and dnsmasq blocks awaiting
25 syslogd, then the two daemons can deadlock. We get around this
26 by not blocking when talking to syslog, instead we queue up to
27 MAX_LOGS messages. If more are queued, they will be dropped,
28 and the drop event itself logged. */
30 /* The "wire" protocol for logging is defined in RFC 3164 */
33 #define MAX_MESSAGE 1024
35 /* defaults in case we die() before we log_start() */
36 static int log_fac
= LOG_DAEMON
;
37 static int log_stderr
= 0;
38 static int echo_stderr
= 0;
39 static int log_fd
= -1;
40 static int log_to_file
= 0;
41 static int entries_alloced
= 0;
42 static int entries_lost
= 0;
43 static int connection_good
= 1;
44 static int max_logs
= 0;
45 static int connection_type
= SOCK_DGRAM
;
49 pid_t pid
; /* to avoid duplicates over a fork */
50 struct log_entry
*next
;
51 char payload
[MAX_MESSAGE
];
54 static struct log_entry
*entries
= NULL
;
55 static struct log_entry
*free_entries
= NULL
;
58 int log_start(struct passwd
*ent_pw
, int errfd
)
62 echo_stderr
= option_bool(OPT_DEBUG
);
64 if (daemon
->log_fac
!= -1)
65 log_fac
= daemon
->log_fac
;
67 else if (option_bool(OPT_DEBUG
))
75 if (strcmp(daemon
->log_file
, "-") == 0)
79 log_fd
= dup(STDERR_FILENO
);
83 max_logs
= daemon
->max_logs
;
85 if (!log_reopen(daemon
->log_file
))
87 send_event(errfd
, EVENT_LOG_ERR
, errno
, daemon
->log_file
? daemon
->log_file
: "");
91 /* if queuing is inhibited, make sure we allocate
92 the one required buffer now. */
95 free_entries
= safe_malloc(sizeof(struct log_entry
));
96 free_entries
->next
= NULL
;
100 /* If we're running as root and going to change uid later,
101 change the ownership here so that the file is always owned by
102 the dnsmasq user. Then logrotate can just copy the owner.
103 Failure of the chown call is OK, (for instance when started as non-root) */
104 if (log_to_file
&& !log_stderr
&& ent_pw
&& ent_pw
->pw_uid
!= 0 &&
105 fchown(log_fd
, ent_pw
->pw_uid
, -1) != 0)
111 int log_reopen(char *log_file
)
118 /* NOTE: umask is set to 022 by the time this gets called */
121 log_fd
= open(log_file
, O_WRONLY
|O_CREAT
|O_APPEND
, S_IRUSR
|S_IWUSR
|S_IRGRP
);
124 #if defined(HAVE_SOLARIS_NETWORK) || defined(__ANDROID__)
125 /* Solaris logging is "different", /dev/log is not unix-domain socket.
126 Just leave log_fd == -1 and use the vsyslog call for everything.... */
127 # define _PATH_LOG "" /* dummy */
131 log_fd
= socket(AF_UNIX
, connection_type
, 0);
133 /* if max_logs is zero, leave the socket blocking */
134 if (log_fd
!= -1 && max_logs
!= 0 && (flags
= fcntl(log_fd
, F_GETFL
)) != -1)
135 fcntl(log_fd
, F_SETFL
, flags
| O_NONBLOCK
);
143 static void free_entry(void)
145 struct log_entry
*tmp
= entries
;
147 tmp
->next
= free_entries
;
151 static void log_write(void)
157 /* The data in the payoad is written with a terminating zero character
158 and the length reflects this. For a stream connection we need to
159 send the zero as a record terminator, but this isn't done for a
160 datagram connection, so treat the length as one less than reality
161 to elide the zero. If we're logging to a file, turn the zero into
162 a newline, and leave the length alone. */
166 entries
->payload
[entries
->offset
+ entries
->length
- 1] = '\n';
167 else if (connection_type
== SOCK_DGRAM
)
170 /* Avoid duplicates over a fork() */
171 if (entries
->pid
!= getpid())
179 if ((rc
= write(log_fd
, entries
->payload
+ entries
->offset
, entries
->length
- len_adjust
)) != -1)
181 entries
->length
-= rc
;
182 entries
->offset
+= rc
;
183 if (entries
->length
== len_adjust
)
186 if (entries_lost
!= 0)
188 int e
= entries_lost
;
189 entries_lost
= 0; /* avoid wild recursion */
190 my_syslog(LOG_WARNING
, _("overflow: %d log entries lost"), e
);
199 if (errno
== EAGAIN
|| errno
== EWOULDBLOCK
)
200 return; /* syslogd busy, go again when select() or poll() says so */
202 if (errno
== ENOBUFS
)
208 /* errors handling after this assumes sockets */
211 /* Once a stream socket hits EPIPE, we have to close and re-open
212 (we ignore SIGPIPE) */
215 if (log_reopen(NULL
))
218 else if (errno
== ECONNREFUSED
||
220 errno
== EDESTADDRREQ
||
223 /* socket went (syslogd down?), try and reconnect. If we fail,
224 stop trying until the next call to my_syslog()
225 ECONNREFUSED -> connection went down
226 ENOTCONN -> nobody listening
227 (ECONNRESET, EDESTADDRREQ are *BSD equivalents) */
229 struct sockaddr_un logaddr
;
231 #ifdef HAVE_SOCKADDR_SA_LEN
232 logaddr
.sun_len
= sizeof(logaddr
) - sizeof(logaddr
.sun_path
) + strlen(_PATH_LOG
) + 1;
234 logaddr
.sun_family
= AF_UNIX
;
235 strncpy(logaddr
.sun_path
, _PATH_LOG
, sizeof(logaddr
.sun_path
));
237 /* Got connection back? try again. */
238 if (connect(log_fd
, (struct sockaddr
*)&logaddr
, sizeof(logaddr
)) != -1)
241 /* errors from connect which mean we should keep trying */
242 if (errno
== ENOENT
||
244 errno
== ECONNREFUSED
||
248 errno
== EWOULDBLOCK
)
250 /* try again on next syslog() call */
255 /* try the other sort of socket... */
256 if (errno
== EPROTOTYPE
)
258 connection_type
= connection_type
== SOCK_DGRAM
? SOCK_STREAM
: SOCK_DGRAM
;
259 if (log_reopen(NULL
))
265 /* give up - fall back to syslog() - this handles out-of-space
266 when logging to a file, for instance. */
268 my_syslog(LOG_CRIT
, _("log failed: %s"), strerror(errno
));
273 /* priority is one of LOG_DEBUG, LOG_INFO, LOG_NOTICE, etc. See sys/syslog.h.
274 OR'd to priority can be MS_TFTP, MS_DHCP, ... to be able to do log separation between
275 DNS, DHCP and TFTP services.
277 void my_syslog(int priority
, const char *format
, ...)
280 struct log_entry
*entry
;
284 pid_t pid
= getpid();
287 if ((LOG_FACMASK
& priority
) == MS_TFTP
)
289 else if ((LOG_FACMASK
& priority
) == MS_DHCP
)
293 priority
= LOG_PRI(priority
);
295 /* Solaris doesn't have LOG_PRI */
296 priority
&= LOG_PRIMASK
;
301 fprintf(stderr
, "dnsmasq%s: ", func
);
302 va_start(ap
, format
);
303 vfprintf(stderr
, format
, ap
);
311 /* do android-specific logging.
312 log_fd is always -1 on Android except when logging to a file. */
315 if (priority
<= LOG_ERR
)
316 alog_lvl
= ANDROID_LOG_ERROR
;
317 else if (priority
== LOG_WARNING
)
318 alog_lvl
= ANDROID_LOG_WARN
;
319 else if (priority
<= LOG_INFO
)
320 alog_lvl
= ANDROID_LOG_INFO
;
322 alog_lvl
= ANDROID_LOG_DEBUG
;
324 va_start(ap
, format
);
325 __android_log_vprint(alog_lvl
, "dnsmasq", format
, ap
);
328 /* fall-back to syslog if we die during startup or
329 fail during running (always on Solaris). */
330 static int isopen
= 0;
334 openlog("dnsmasq", LOG_PID
, log_fac
);
337 va_start(ap
, format
);
338 vsyslog(priority
, format
, ap
);
345 if ((entry
= free_entries
))
346 free_entries
= entry
->next
;
347 else if (entries_alloced
< max_logs
&& (entry
= malloc(sizeof(struct log_entry
))))
354 /* add to end of list, consumed from the start */
360 struct log_entry
*tmp
;
361 for (tmp
= entries
; tmp
->next
; tmp
= tmp
->next
);
368 p
+= sprintf(p
, "<%d>", priority
| log_fac
);
370 /* Omit timestamp for default daemontools situation */
371 if (!log_stderr
|| !option_bool(OPT_NO_FORK
))
372 p
+= sprintf(p
, "%.15s ", ctime(&time_now
) + 4);
374 p
+= sprintf(p
, "dnsmasq%s[%d]: ", func
, (int)pid
);
376 len
= p
- entry
->payload
;
377 va_start(ap
, format
);
378 len
+= vsnprintf(p
, MAX_MESSAGE
- len
, format
, ap
) + 1; /* include zero-terminator */
380 entry
->length
= len
> MAX_MESSAGE
? MAX_MESSAGE
: len
;
385 /* almost always, logging won't block, so try and write this now,
386 to save collecting too many log messages during a select loop. */
389 /* Since we're doing things asynchronously, a cache-dump, for instance,
390 can now generate log lines very fast. With a small buffer (desirable),
391 that means it can overflow the log-buffer very quickly,
392 so that the cache dump becomes mainly a count of how many lines
393 overflowed. To avoid this, we delay here, the delay is controlled
394 by queue-occupancy, and grows exponentially. The delay is limited to (2^8)ms.
395 The scaling stuff ensures that when the queue is bigger than 8, the delay
396 only occurs for the last 8 entries. Once the queue is full, we stop delaying
397 to preserve performance.
400 if (entries
&& max_logs
!= 0)
404 for (d
= 0,entry
= entries
; entry
; entry
= entry
->next
, d
++);
408 else if (max_logs
> 8)
413 struct timespec waiter
;
415 waiter
.tv_nsec
= 1000000 << (d
- 1); /* 1 ms */
416 nanosleep(&waiter
, NULL
);
418 /* Have another go now */
424 void set_log_writer(fd_set
*set
, int *maxfdp
)
426 if (entries
&& log_fd
!= -1 && connection_good
)
429 bump_maxfd(log_fd
, maxfdp
);
433 void check_log_writer(fd_set
*set
)
435 if (log_fd
!= -1 && (!set
|| FD_ISSET(log_fd
, set
)))
441 /* write until queue empty, but don't loop forever if there's
442 no connection to the syslog in existance */
445 struct timespec waiter
;
447 if (!entries
|| !connection_good
)
453 waiter
.tv_nsec
= 1000000; /* 1 ms */
454 nanosleep(&waiter
, NULL
);
458 void die(char *message
, char *arg1
, int exit_code
)
460 char *errmess
= strerror(errno
);
467 echo_stderr
= 1; /* print as well as log when we die.... */
468 fputc('\n', stderr
); /* prettyfy startup-script message */
470 my_syslog(LOG_CRIT
, message
, arg1
, errmess
);
472 my_syslog(LOG_CRIT
, _("FAILED to start up"));