BUILD=build/
LINT=splint
-LINTFLAGS=+quiet -weak -warnposix -unrecog -Din_addr_t=uint32_t -Du_int=unsigned -Du_char=uint8_t -preproc -Drlimit=rlimit64
+LINTFLAGS=+quiet -weak -warnposix -unrecog -Din_addr_t=uint32_t -Du_int=unsigned -Du_char=uint8_t -preproc -Drlimit=rlimit64 +posixlib
# compat with openssl linux edition.
LINTFLAGS+="-DBN_ULONG=unsigned long" -Dkrb5_int32=int "-Dkrb5_ui_4=unsigned int" -DPQ_64BIT=uint64_t
# Checks for header files.
AC_HEADER_STDC
-AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h sys/param.h sys/socket.h sys/uio.h arpa/inet.h],,, [AC_INCLUDES_DEFAULT])
+AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h sys/param.h sys/socket.h sys/uio.h arpa/inet.h syslog.h],,, [AC_INCLUDES_DEFAULT])
# check for types
AC_CHECK_TYPE(int8_t, char)
AC_CHECK_LIB(ldns, ldns_rr_new,, [AC_MSG_ERROR([Can't find ldns library])])
-AC_DEFINE_UNQUOTED([MAXSYSLOGMSGLEN], [512], [Define to the maximum message length to pass to syslog.])
+AC_DEFINE_UNQUOTED([MAXSYSLOGMSGLEN], [5120], [Define to the maximum message length to pass to syslog.])
AH_BOTTOM([
#include <stdio.h>
}
/* init logfile just before fork */
- log_init(cfg->logfile);
+ log_init(cfg->logfile, cfg->use_syslog);
if(!debug_mode && cfg->do_daemonize) {
detach(cfg);
}
if(!done_chroot) {
do_chroot(daemon, cfg, debug_mode);
done_chroot = 1;
- }
+ } else log_init(cfg->logfile, cfg->use_syslog);
/* work */
daemon_fork(daemon);
/* take debug snapshot of heap */
unbound_start_brk = sbrk(0);
- log_init(NULL);
+ log_init(NULL, 0);
/* parse the options */
while( (c=getopt(argc, argv, "c:dhv")) != -1) {
switch(c) {
}
run_daemon(cfgfile, cmdline_verbose, debug_mode);
- log_init(NULL); /* close logfile */
+ log_init(NULL, 0); /* close logfile */
return 0;
}
+26 September 2007: Wouter
+ - SIGHUP will reopen the log file.
+ - Option to log to syslog.
+
25 September 2007: Wouter
- tests for NSEC3. Fixup bitmap checks for NSEC3.
- positive ANY response needs to check if wildcard expansion, and
# the working directory.
# directory: "/etc/unbound"
- # the log file, "" means log to stderr.
+ # the log file, "" means log to stderr.
+ # Use of this option sets use-syslog to "no".
# logfile: ""
+
+ # Log to syslog(3) if yes. The log facility LOG_DAEMON is used to
+ # log to, with identity "unbound". If yes, it overrides the logfile.
+ # use-syslog: yes
# the pid file.
# pidfile: "unbound.pid"
# unbound.conf(5) config file for unbound(8).
server:
directory: "/etc/unbound"
- username: unbound # make sure it can write to pidfile, logfile.
+ username: unbound # make sure it can write to pidfile.
chroot: "/etc/unbound"
- logfile: "/etc/unbound/unbound.log"
+ # logfile: "/etc/unbound/unbound.log" #uncomment to use logfile.
pidfile: "/etc/unbound/unbound.pid"
# verbosity: 1 # uncomment and increase to get more logging.
.fi
If "" is given, logging goes to stderr, or nowhere once daemonized.
The logfile is appended to, in the following format:
[seconds since 1970] unbound[pid:tid]: type: message.
+If this option is given, the use-syslog is option is set to "no".
+.It \fBuse-syslog:\fR <yes or no>
+Sets unbound to send log messages to the syslogd, using
+.Xr syslog 3 .
+The log facility LOG_DAEMON is used, with identity "unbound".
+The logfile setting is overridden when use-syslog is turned on.
+The default is to log to syslog.
.It \fBpidfile:\fR <filename>
The process id is written to the file. Default is "unbound.pid". So,
kill -HUP `cat /etc/unbound/unbound.pid` will trigger a reload,
usage();
return 1;
}
- log_init(NULL);
+ log_init(NULL, 0);
log_ident_set("lock-verify");
/* init */
all_locks = rbtree_create(order_lock_cmp);
/** main program */
int main(int argc, char* argv[])
{
- log_init(NULL);
+ log_init(NULL, 0);
if(argc != 6) {
usage();
}
if(!cfg) fatal_exit("could not open %s: %s",
configfile, strerror(errno));
line[MAX_LINE_LEN-1] = 0;
+ fprintf(cfg, "server: use-syslog: no\n");
while(fgets(line, MAX_LINE_LEN-1, in)) {
parse = line;
(*lineno)++;
char* init_optarg = optarg;
struct replay_scenario* scen = NULL;
- log_init(NULL);
+ log_init(NULL, 0);
log_info("Start of %s testbound program.", PACKAGE_STRING);
/* determine commandline options for the daemon */
cfgfile[0] = 0;
int
main(int argc, char* argv[])
{
- log_init(NULL);
+ log_init(NULL, 0);
if(argc != 1) {
printf("usage: %s\n", argv[0]);
printf("\tperforms unit tests.\n");
cfg->do_ip6 = 1;
cfg->do_udp = 1;
cfg->do_tcp = 1;
+ cfg->use_syslog = 1;
cfg->outgoing_base_port = cfg->port + 2000;
cfg->outgoing_num_ports = 16;
cfg->outgoing_num_tcp = 10;
/** pidfile to write pid to. */
char* pidfile;
+ /** should log messages be sent to syslogd */
+ int use_syslog;
+
/** do not report identity (id.server, hostname.bind) */
int hide_identity;
/** do not report version (version.server, version.bind) */
key-cache-size{COLON} { YDOUT; return VAR_KEY_CACHE_SIZE;}
key-cache-slabs{COLON} { YDOUT; return VAR_KEY_CACHE_SLABS;}
val-nsec3-keysize-iterations{COLON} { YDOUT; return VAR_VAL_NSEC3_KEYSIZE_ITERATIONS;}
+use-syslog{COLON} { YDOUT; return VAR_USE_SYSLOG;}
{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++;}
/* Quoted strings. Strip leading and ending quotes */
%token VAR_BOGUS_TTL VAR_VAL_CLEAN_ADDITIONAL VAR_VAL_PERMISSIVE_MODE
%token VAR_INCOMING_NUM_TCP VAR_MSG_BUFFER_SIZE VAR_KEY_CACHE_SIZE
%token VAR_KEY_CACHE_SLABS VAR_TRUSTED_KEYS_FILE
-%token VAR_VAL_NSEC3_KEYSIZE_ITERATIONS
+%token VAR_VAL_NSEC3_KEYSIZE_ITERATIONS VAR_USE_SYSLOG
%%
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
server_val_clean_additional | server_val_permissive_mode |
server_incoming_num_tcp | server_msg_buffer_size |
server_key_cache_size | server_key_cache_slabs |
- server_trusted_keys_file | server_val_nsec3_keysize_iterations
+ server_trusted_keys_file | server_val_nsec3_keysize_iterations |
+ server_use_syslog
;
stubstart: VAR_STUB_ZONE
{
free($2);
}
;
+server_use_syslog: VAR_USE_SYSLOG STRING
+ {
+ OUTYY(("P(server_use_syslog:%s)\n", $2));
+ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
+ yyerror("expected yes or no.");
+ else cfg_parser->cfg->use_syslog = (strcmp($2, "yes")==0);
+#ifndef HAVE_SYSLOG_H
+ if(strcmp($2, "yes") == 0)
+ yyerror("no syslog services are available. "
+ "(reconfigure and compile to add)");
+#endif
+ free($2);
+ }
+ ;
server_chroot: VAR_CHROOT STRING
{
OUTYY(("P(server_chroot:%s)\n", $2));
OUTYY(("P(server_logfile:%s)\n", $2));
free(cfg_parser->cfg->logfile);
cfg_parser->cfg->logfile = $2;
+ cfg_parser->cfg->use_syslog = 0;
}
;
server_pidfile: VAR_PIDFILE STRING
#ifdef HAVE_TIME_H
#include <time.h>
#endif
+#ifdef HAVE_SYSLOG_H
+# include <syslog.h>
+#else
+/**define LOG_ constants */
+# define LOG_CRIT 2
+# define LOG_ERR 3
+# define LOG_WARNING 4
+# define LOG_NOTICE 5
+# define LOG_INFO 6
+# define LOG_DEBUG 7
+#endif
+/* default verbosity */
enum verbosity_value verbosity = 4;
/** the file logged to. */
static FILE* logfile = 0;
static ub_thread_key_t logkey;
/** the identity of this executable/process */
static const char* ident="unbound";
+#ifdef HAVE_SYSLOG_H
+/** are we using syslog(3) to log to */
+static int log_to_syslog = 0;
+#endif /* HAVE_SYSLOG_H */
void
-log_init(const char* filename)
+log_init(const char* filename, int use_syslog)
{
FILE *f;
if(!key_created) {
key_created = 1;
ub_thread_key_create(&logkey, NULL);
}
-
+ if(logfile || log_to_syslog)
+ verbose(VERB_DETAIL, "switching log to %s",
+ use_syslog?"syslog":(filename&&filename[0]?filename:"stderr"));
+ if(logfile && logfile != stderr)
+ fclose(logfile);
+#ifdef HAVE_SYSLOG_H
+ if(log_to_syslog) {
+ closelog();
+ log_to_syslog = 0;
+ }
+ if(use_syslog) {
+ openlog(ident, 0, LOG_DAEMON);
+ log_to_syslog = 1;
+ return;
+ }
+#endif /* HAVE_SYSLOG_H */
if(!filename || !filename[0]) {
- if(logfile && logfile != stderr)
- fclose(logfile);
logfile = stderr;
return;
}
strerror(errno));
return;
}
- verbose(VERB_DETAIL, "switching to logfile %s", filename);
- if(logfile && logfile != stderr)
- fclose(logfile);
logfile = f;
}
}
void
-log_vmsg(const char* type, const char *format, va_list args)
+log_vmsg(int pri, const char* type,
+ const char *format, va_list args)
{
- char message[MAXSYSLOGMSGLEN * 10];
+ char message[MAXSYSLOGMSGLEN];
unsigned int* tid = (unsigned int*)ub_thread_key_get(logkey);
+ (void)pri;
vsnprintf(message, sizeof(message), format, args);
- fprintf(logfile, "[%d] %s[%d:%x] %s: %s\n",
- (int)time(NULL), ident, (int)getpid(),
- tid?*tid:0, type, message);
+#ifdef HAVE_SYSLOG_H
+ if(log_to_syslog) {
+ syslog(pri, "[%d:%x] %s: %s",
+ (int)getpid(), tid?*tid:0, type, message);
+ return;
+ }
+#endif /* HAVE_SYSLOG_H */
+ fprintf(logfile, "[%d] %s[%d:%x] %s: %s\n", (int)time(NULL),
+ ident, (int)getpid(), tid?*tid:0, type, message);
fflush(logfile);
}
{
va_list args;
va_start(args, format);
- log_vmsg("info", format, args);
+ log_vmsg(LOG_INFO, "info", format, args);
va_end(args);
}
{
va_list args;
va_start(args, format);
- log_vmsg("error", format, args);
+ log_vmsg(LOG_ERR, "error", format, args);
va_end(args);
}
{
va_list args;
va_start(args, format);
- log_vmsg("warning", format, args);
+ log_vmsg(LOG_WARNING, "warning", format, args);
va_end(args);
}
{
va_list args;
va_start(args, format);
- log_vmsg("fatal error", format, args);
+ log_vmsg(LOG_CRIT, "fatal error", format, args);
va_end(args);
exit(1);
}
{
va_list args;
va_start(args, format);
- if(verbosity >= level)
- log_vmsg("note", format, args);
+ if(verbosity >= level) {
+ if(level == VERB_OPS)
+ log_vmsg(LOG_NOTICE, "notice", format, args);
+ else if(level == VERB_DETAIL)
+ log_vmsg(LOG_INFO, "info", format, args);
+ else log_vmsg(LOG_DEBUG, "debug", format, args);
+ }
va_end(args);
}
/**
* call this to initialize logging services.
* @param filename: if NULL stderr is used.
+ * @param use_syslog: set to true to ignore filename and use syslog(3).
*/
-void log_init(const char* filename);
+void log_init(const char* filename, int use_syslog);
/**
* Init a thread (will print this number for the thread log entries).
/**
* va_list argument version of log_info.
+ * @param pri: priority type, for example 5 (INFO).
* @param type: string to designate type of message (info, error).
* @param format: the printf style format to print. no newline.
* @param args: arguments for format string.
*/
-void log_vmsg(const char* type, const char* format, va_list args);
+void log_vmsg(int pri, const char* type, const char* format, va_list args);
/** always assert for now. */
#define UNBOUND_ASSERT 1