diff --git a/.gitignore b/.gitignore index b1904b76a24db1535a27320153af8adeff34ebff..9735242a6cbad83662468a98bd055a429ae77591 100644 --- a/.gitignore +++ b/.gitignore @@ -51,7 +51,6 @@ /m4/lt~obsolete.m4 # Binaries /src/tests/unittests -/src/tests/unittests_xfr /src/zscanner/zscanner-tool /src/knotc /src/knotd @@ -73,4 +72,3 @@ src/zscanner/test/cases/06-0_INCLUDE.in src/zscanner/test/cases/06-3_INCLUDE.in src/zscanner/test/cases/06-4_INCLUDE.in src/zscanner/test/run_tests.sh -/knot-*/ diff --git a/Knot.files b/Knot.files index eedbed47969f81fa327a60734de841b7683c8fc3..c3d9f1fd2be1b4e5c69f37b9674e4f9ad56b02bf 100644 --- a/Knot.files +++ b/Knot.files @@ -20,8 +20,6 @@ doc/troubleshooting.texi man/Makefile.am samples/Makefile.am src/Makefile.am -src/Makefile.am -src/Makefile.am src/common/acl.c src/common/acl.h src/common/atomic.h @@ -243,8 +241,6 @@ src/tests/libknot/wire_tests.h src/tests/libknot/ztree_tests.c src/tests/libknot/ztree_tests.h src/tests/unittests_main.c -src/tests/xfr_tests.c -src/tests/xfr_tests.h src/utils/common/exec.c src/utils/common/exec.h src/utils/common/msg.c diff --git a/configure.ac b/configure.ac index 294f04eb1d4daa0761329353c7a611058863f77a..a43761fb103d60969cfdc60db70f500e524de5ca 100644 --- a/configure.ac +++ b/configure.ac @@ -9,6 +9,10 @@ AC_CONFIG_HEADERS([src/config.h]) AC_CONFIG_MACRO_DIR([m4]) AC_USE_SYSTEM_EXTENSIONS([_GNU_SOURCE]) +# Automatically update release date based on configure.ac date +release_date=`doc/mdate-sh configure.ac` +AC_SUBST([RELEASE_DATE], $release_date) + # Check SSE, SSE2 and SSE3 support AX_EXT CFLAGS="$CFLAGS $SIMD_FLAGS" @@ -64,7 +68,7 @@ AC_PROG_INSTALL # Check for Ragel AC_PATH_PROG([RAGEL], [ragel], [true]) AM_CONDITIONAL([HAVE_RAGEL], test "$RAGEL" != "true") - + # Set FSM type for Ragel AC_SUBST([FSM_TYPE], [-T0]) AC_ARG_ENABLE([fastparser], @@ -140,6 +144,11 @@ AC_ARG_ENABLE([recvmmsg], fi ]) +# Enable integrity check +AC_ARG_ENABLE([integrity-check], + AS_HELP_STRING([--enable-integrity-check], [enable integrity check in knotd via SIGUSR1]), + [AC_DEFINE([INTEGRITY_CHECK], [1], [integrity check in knotd])]) + # Check for link time optimizations support and predictive commoning AC_ARG_ENABLE([lto], AS_HELP_STRING([--enable-lto=yes|no], [enable link-time optimizations, enable if not broken for some extra speed [default=no]]), @@ -163,16 +172,22 @@ AX_CHECK_COMPILE_FLAG("-fno-strict-aliasing", [CFLAGS="$CFLAGS -fno-strict-alias # Default directories run_dir="${localstatedir}/run/knot" AC_ARG_WITH([rundir], - AC_HELP_STRING([--with-rundir=path], [Path to run-time variable data (pid, sockets...). [default=`eval echo ${localstatedir}`/run/knot]]), + AC_HELP_STRING([--with-rundir=path], [Path to run-time variable data (pid, sockets...). [default=LOCALSTATEDIR/run/knot]]), [run_dir=$withval]) AC_SUBST(run_dir) -storage_dir="${sharedstatedir}/knot" +storage_dir="${localstatedir}/lib/knot" AC_ARG_WITH([storage], - AC_HELP_STRING([--with-storage=path], [Default storage directory (slave zones, persistent data). [default=$(sharedstatedir)/knot]]), + AC_HELP_STRING([--with-storage=path], [Default storage directory (slave zones, persistent data). [default=LOCALSTATEDIR/lib/knot]]), [storage_dir=$withval]) AC_SUBST(storage_dir) +config_dir="${sysconfdir}/knot" +AC_ARG_WITH([configdir], + AC_HELP_STRING([--with-configdir=path], [Default directory for configuration. [default=SYSCONFDIR/knot]]), + [config_dir=$withval]) +AC_SUBST(config_dir) + # Checks for libraries. # FIXME: Replace `main' with a function in `-lm': diff --git a/doc/configuration.texi b/doc/configuration.texi index 1f1a5cab3680c03254b61333fac1c4db09d00545..5dd55497d9ab49448a623169a2e80a2b028cd2fd 100644 --- a/doc/configuration.texi +++ b/doc/configuration.texi @@ -57,8 +57,8 @@ Now let's go step by step through this minimal configuration file: @item In @code{system} statement we have configured @code{storage} -directory where Knot DNS will store compiled zone files, -PID file and for slave zone also their journal files. (See @ref{system} and @ref{storage}) +directory where Knot DNS will store slave zones and journal files. +(See @ref{system} and @ref{storage}) @item The @code{interfaces} statement defines interfaces where Knot diff --git a/doc/knot.texi b/doc/knot.texi index f4eaa5613732938e164a69980b47ac35872efd54..4398432fded0249335da471a418b001dbd6bdf7d 100644 --- a/doc/knot.texi +++ b/doc/knot.texi @@ -172,6 +172,7 @@ Statement Definition and Usage * nsid:: * storage:: * rundir:: +* pidfile:: * workers:: * user:: * max-conn-idle:: diff --git a/doc/reference.texi b/doc/reference.texi index 57324b75e21f8fc9624d7d9ed5a0f4a3ddefb2a1..734495632fab6887a9fa5f1916aba2bca2b7e7e2 100644 --- a/doc/reference.texi +++ b/doc/reference.texi @@ -40,6 +40,7 @@ else. [ @code{nsid} ( @code{"}@kbd{string}@code{"} | @kbd{hex_string} )@code{;} ] [ @code{storage} @code{"}@kbd{string}@code{";} ] [ @code{rundir} @code{"}@kbd{string}@code{";} ] + [ @code{pidfile} @code{"}@kbd{string}@code{";} ] [ @code{workers} @kbd{integer}@code{;} ] [ @code{user} @kbd{string}[@code{.}@kbd{string}]@code{;} ] [ @code{max-conn-idle} ( @kbd{integer} | @kbd{integer}(@code{s} | @code{m} | @code{h} | @code{d})@code{;} ) ] @@ -62,6 +63,7 @@ else. * nsid:: * storage:: * rundir:: +* pidfile:: * workers:: * user:: * max-conn-idle:: @@ -139,9 +141,8 @@ system @{ @subsubsection storage @vindex storage -The working directory of Knot DNS, it is used to store compiled zone files and -other persistent data. -Default: @file{$@{sharedstatedir@}/knot}, configured with @code{--with-storage=path} +The working directory of Knot DNS, it is used to store zone files and journal files. +Default: @file{$@{localstatedir@}/lib/knot}, configured with @code{--with-storage=path} @example system @{ @@ -162,6 +163,20 @@ system @{ @} @end example +@node pidfile +@subsubsection pidfile +@vindex pidfile + +Specifies a custom PID file location. + +Default value: @file{knot.pid} in @code{rundir} directory. + +@example +system @{ + pidfile "/var/run/knot/knot_dmz.pid"; +@} +@end example + @node workers @subsubsection workers @vindex workers diff --git a/doc/running.texi b/doc/running.texi index 1a98a072aa331a8224dd1ba05ee3eee5ee86b6fc..cfa88109c33642fc3b7b5f09ef8130997d646ec6 100644 --- a/doc/running.texi +++ b/doc/running.texi @@ -37,7 +37,8 @@ Usage: knotc [parameters] <action> [action_args] Parameters: -c [file], --config=[file] Select configuration file. - -s [server] Remote UNIX socket/IP address (default $@{rundir@}/knot.sock). + -s [server] Remote UNIX socket/IP address + (default $@{rundir@}/knot.sock). -p [port] Remote server port (only for IP). -y [[hmac:]name:key] Use key_id specified on the command line. -k [file] Use key file (as in config section 'keys'). @@ -61,24 +62,34 @@ Actions: zonestatus Show status of configured zones. checkconf Check current server configuration. checkzone [zone] Check zone (all if not specified). - memstats [zone] Estimate memory consumption for zone (all if not specified). + memstats [zone] Estimate memory consumption for zone + (all if not specified). @end example -Also, the server needs to create several files in order to run properly. -Zones and related data are stored in the directory described by @code{storage} (@pxref{storage}). +Also, the server needs to create several files in order to run properly. These +files are stored in the folowing directories. + +@code{storage} (@pxref{storage}): + @itemize @bullet +@item +@emph{Zone files} - default directory for storing zone files. This can be overriden +using absolute zone file location. + @item @emph{Journal files} - each zone has a journal file to store differences for IXFR and -dynamic updates. Journal for zone @code{example.com} will be -placed in @file{STORAGE/example.com.diff.db}. +dynamic updates. Journal for zone @code{example.com} will be placed in @file{example.com.diff.db}. +@end itemize + +@code{rundir} (@pxref{rundir}): +@itemize @bullet @item -@emph{PID file} - is created automatically in @code{rundir} (@pxref{rundir}) when -the server is run in background. +@emph{PID file} - is created automatically when the server is run in background. @item -@emph{Control sockets} - as a default, UNIX sockets are created in @code{rundir} (@pxref{rundir}), -but can be overriden. +@emph{Control sockets} - as a default, UNIX sockets are created here, +but this can be overriden. @end itemize @node Running a slave server diff --git a/man/kdig.1.in b/man/kdig.1.in index b4d58be235c1db0f8ba6e1f6a85227816f2983b3..4679abfb0911a902225d79d1313ea2110fb05ba2 100644 --- a/man/kdig.1.in +++ b/man/kdig.1.in @@ -1,4 +1,4 @@ -.TH "kdig" "1" "April 2013" "CZ.NIC Labs" "Knot DNS, version @VERSION@" +.TH "kdig" "1" "@RELEASE_DATE@" "CZ.NIC Labs" "Knot DNS, version @VERSION@" .SH NAME .TP 5 .B kdig diff --git a/man/khost.1.in b/man/khost.1.in index 805d96c5093ebf6bc52712f32af8173bbb020b62..e25ba359d06882f465ef072427ac1107f518e5e7 100644 --- a/man/khost.1.in +++ b/man/khost.1.in @@ -1,4 +1,4 @@ -.TH "khost" "1" "April 2013" "CZ.NIC Labs" "Knot DNS, version @VERSION@" +.TH "khost" "1" "@RELEASE_DATE@" "CZ.NIC Labs" "Knot DNS, version @VERSION@" .SH NAME .TP 6 .B khost diff --git a/man/knot.conf.5.in b/man/knot.conf.5.in index 2821673cbcac56fe9c09fe3256e5bc446d06fe53..2ccc7678e2ad550b854eaa94a9b68292f0b09373 100644 --- a/man/knot.conf.5.in +++ b/man/knot.conf.5.in @@ -1,4 +1,4 @@ -.TH "knot.conf" "5" "September 2012" "CZ.NIC Labs" "Knot DNS, version @VERSION@" +.TH "knot.conf" "5" "@RELEASE_DATE@" "CZ.NIC Labs" "Knot DNS, version @VERSION@" .SH "NAME" .LP .B knot.conf diff --git a/man/knotc.8.in b/man/knotc.8.in index 441f15625a6e497c486526af857837efee54588a..343fd023395e57031e9d78602d35f40eaaae8f40 100644 --- a/man/knotc.8.in +++ b/man/knotc.8.in @@ -1,4 +1,4 @@ -.TH knotc "8" "September 2012" "CZ.NIC Labs" "Knot DNS, version @VERSION@" +.TH knotc "8" "@RELEASE_DATE@" "CZ.NIC Labs" "Knot DNS, version @VERSION@" .SH NAME .B knotc \- Knot DNS control utility diff --git a/man/knotd.8.in b/man/knotd.8.in index 83088c5f7a291159a2aa43eebfbf0d2b30c14c1b..d587315fee29041e7abc71c0e788e4bac0bc7935 100644 --- a/man/knotd.8.in +++ b/man/knotd.8.in @@ -1,4 +1,4 @@ -.TH "knotd" "8" "September 2012" "CZ.NIC Labs" "Knot DNS, version @VERSION@" +.TH "knotd" "8" "@RELEASE_DATE@" "CZ.NIC Labs" "Knot DNS, version @VERSION@" .SH NAME .B knotd \- Knot DNS daemon diff --git a/man/knsupdate.1.in b/man/knsupdate.1.in index 24ebbb9a1988e50ca8c0605acb59ac34735d3c86..b7857dfc53648222c7e9f3513fea01298be1b7a6 100644 --- a/man/knsupdate.1.in +++ b/man/knsupdate.1.in @@ -1,4 +1,4 @@ -.TH "knsupdate" "1" "April 2013" "CZ.NIC Labs" "Knot DNS, version @VERSION@" +.TH "knsupdate" "1" "@RELEASE_DATE@" "CZ.NIC Labs" "Knot DNS, version @VERSION@" .SH NAME .TP 10 .B knsupdate diff --git a/samples/Makefile.am b/samples/Makefile.am index 755ef078f299d8559eb94eae29aa5891e8df6e6a..73f8760ce99981df11de00cbc3a0ae3c4e4fbc6e 100644 --- a/samples/Makefile.am +++ b/samples/Makefile.am @@ -3,7 +3,10 @@ edit = sed \ -e 's|@package[@]|$(PACKAGE_NAME)|g' \ -e 's|@localstatedir[@]|$(localstatedir)|g' \ -e 's|@prefix[@]|$(prefix)|g' \ - -e 's|@sysconfdir[@]|$(sysconfdir)|g' + -e 's|@sysconfdir[@]|$(sysconfdir)|g' \ + -e 's|@config_dir[@]|$(config_dir)|g' \ + -e 's|@storage_dir[@]|$(storage_dir)|g' \ + -e 's|@run_dir[@]|$(run_dir)|g' knot.sample.conf: knot.sample.conf.in rm -f $@ $@.tmp @@ -15,16 +18,16 @@ knot.sample.conf: knot.sample.conf.in EXTRA_DIST = knot.sample.conf.in knot.full.conf knot.keys.conf example.com.zone install-data-local: knot.sample.conf - [ -d $(DESTDIR)/$(sysconfdir) ] || \ - $(INSTALL) -d $(DESTDIR)/$(sysconfdir) - [ -f $(DESTDIR)/$(sysconfdir)/knot.sample.conf ] || \ - $(INSTALL_DATA) knot.sample.conf $(srcdir)/example.com.zone $(DESTDIR)/$(sysconfdir) + [ -d $(DESTDIR)/$(config_dir) ] || \ + $(INSTALL) -d $(DESTDIR)/$(config_dir) + [ -f $(DESTDIR)/$(config_dir)/knot.sample.conf ] || \ + $(INSTALL_DATA) knot.sample.conf $(srcdir)/example.com.zone $(DESTDIR)/$(config_dir) uninstall-local: - [ -f $(DESTDIR)/$(sysconfdir)/knot.sample.conf ] && \ - rm -f $(DESTDIR)/$(sysconfdir)/knot.sample.conf - [ -f $(DESTDIR)/$(sysconfdir)/example.com.zone ] && \ - rm -f $(DESTDIR)/$(sysconfdir)/example.com.zone + [ -f $(DESTDIR)/$(config_dir)/knot.sample.conf ] && \ + rm -f $(DESTDIR)/$(config_dir)/knot.sample.conf + [ -f $(DESTDIR)/$(config_dir)/example.com.zone ] && \ + rm -f $(DESTDIR)/$(config_dir)/example.com.zone clean-local: rm -f knot.sample.conf diff --git a/samples/knot.full.conf b/samples/knot.full.conf index 36289789f4f4b26d2484dc7431373a23e24d7823..49edf13aa3cbeeca02e214e89f155e442cad2d8d 100644 --- a/samples/knot.full.conf +++ b/samples/knot.full.conf @@ -28,12 +28,12 @@ system { # Or hexstring 0x01ab00 nsid "myserver0"; - # Working directory of the server - # Used to store compiled zones and PID file - # default: ${sharedstatedir}/knot, configured with --with-storage + # This is a default directory to place slave zone files, journals etc. + # default: ${localstatedir}/lib/knot, configured with --with-storage storage "/var/lib/knot"; # Directory for storing run-time data + # e.g. PID file and control sockets # default: ${localstatedir}/run/knot, configured with --with-rundir rundir "/var/run/knot"; diff --git a/samples/knot.sample.conf.in b/samples/knot.sample.conf.in index 6530d1f57238913b43138a8d9b7e75e01ed678d5..a8021c4aa11261c888722956fd3fcbe62cd8fbd7 100644 --- a/samples/knot.sample.conf.in +++ b/samples/knot.sample.conf.in @@ -13,14 +13,14 @@ system { # May also specify user.group (e.g. knot.knot) user knot.knot; - # Working directory of the server - # Used to store compiled zones and PID file - # default: ${sharedstatedir}/knot, configured with --with-storage - # storage "/var/lib/knot"; + # This is a default directory to place slave zone files, journals etc. + # default: ${localstatedir}/lib/knot, configured with --with-storage + # storage "@storage_dir@"; # Directory for storing run-time data + # e.g. PID file and control sockets # default: ${localstatedir}/run/knot, configured with --with-rundir - # rundir "/var/run/knot"; + # rundir "@run_dir@"; } interfaces { @@ -36,7 +36,7 @@ interfaces { control { # Specifies interface, syntax is exactly the same as in 'interfaces' section - # Default: $(run_dir)/knot.sock + # Default: knot.sock (relative to rundir) listen-on "knot.sock"; # As an alternative, you can use an IPv4/v6 address and port @@ -61,14 +61,14 @@ control { zones { # Example master zone # example.com { -# file "@sysconfdir@/example.com.zone"; +# file "@config_dir@/example.com.zone"; # xfr-out slave0; # notify-out slave0; # } # # Example slave zone # example.net { -# file "@localstatedir@/example.net.zone +# file "@storage_dir@/example.net.zone # xfr-in master0; # notify-in master0; # } diff --git a/src/Makefile.am b/src/Makefile.am index f94c63af72c84eac65dfa0eb7f933a2dc004bbc9..29881bd1d71ad499419b87eecd454c0e801bca12 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -7,8 +7,8 @@ noinst_LTLIBRARIES = libknot.la libknotd.la libknots.la # $(YACC) will generate header file AM_CPPFLAGS = -I$(top_srcdir)/src/libknot -DSYSCONFDIR='"$(sysconfdir)"' \ - -DSBINDIR='"$(sbindir)"' -DSTORAGE_DIR='"${storage_dir}"' \ - -DRUN_DIR='"${run_dir}"' + -DSBINDIR='"$(sbindir)"' -DCONFIG_DIR='"${config_dir}"' \ + -DSTORAGE_DIR='"${storage_dir}"' -DRUN_DIR='"${run_dir}"' AM_YFLAGS = -d libknotd_la_YFLAGS = -pcf_ -d libknotd_la_LFLAGS = # TODO: reentrant parser, prefix @@ -283,5 +283,6 @@ knsupdate_LDADD = libknotd.la libknot.la libknots.la zscanner/libzscanner.la @LI # Create storage and run-time directories install-data-hook: + $(INSTALL) -d $(DESTDIR)/@config_dir@ $(INSTALL) -d $(DESTDIR)/@run_dir@ $(INSTALL) -d $(DESTDIR)/@storage_dir@ diff --git a/src/common/evqueue.c b/src/common/evqueue.c index 097d177deb2c8c2af7167eff051ba97dcbd622e2..4b895549cd746a77855ee64862fb8885debefb89 100644 --- a/src/common/evqueue.c +++ b/src/common/evqueue.c @@ -22,9 +22,6 @@ #include "common/evqueue.h" #include "common/fdset.h" -/*! \brief Singleton application-wide event queue. */ -evqueue_t *s_evqueue = 0; - evqueue_t *evqueue_new() { evqueue_t* q = malloc(sizeof(evqueue_t)); diff --git a/src/common/evqueue.h b/src/common/evqueue.h index ffb3860bb78cfab788184f0a259c9e3a98a010c0..794b2d53d994c6744be32ca4e8bf383eaa6ab282 100644 --- a/src/common/evqueue.h +++ b/src/common/evqueue.h @@ -178,23 +178,6 @@ int evqueue_get(evqueue_t *q, event_t *ev); */ int evqueue_add(evqueue_t *q, const event_t *ev); -/* Singleton event queue pointer. */ -extern evqueue_t *s_evqueue; - -/*! - * \brief Event queue singleton. - */ -static inline evqueue_t *evqueue() { - return s_evqueue; -} - -/*! - * \brief Set event queue singleton. - */ -static inline void evqueue_set(evqueue_t *q) { - s_evqueue = q; -} - #endif /* _KNOTD_COMMON_EVQUEUE_H_ */ /*! @} */ diff --git a/src/knot/conf/cf-parse.y b/src/knot/conf/cf-parse.y index 663adad2e59c87515b8c9c566ad999ce8968cee2..3d94a11d17b20963e16c1a205916ff3ffd2eb190 100644 --- a/src/knot/conf/cf-parse.y +++ b/src/knot/conf/cf-parse.y @@ -531,11 +531,7 @@ system: | system NSID TEXT ';' { new_config->nsid = $3.t; new_config->nsid_len = strlen(new_config->nsid); } | system STORAGE TEXT ';' { new_config->storage = $3.t; } | system RUNDIR TEXT ';' { new_config->rundir = $3.t; } - | system PIDFILE TEXT ';' { - fprintf(stderr, "warning: Config option 'system.pidfile' is deprecated " - "and has no effect. Use 'rundir' instead.\n"); - free($3.t); - } + | system PIDFILE TEXT ';' { new_config->pidfile = $3.t; } | system KEY TSIG_ALGO_NAME TEXT ';' { fprintf(stderr, "warning: Config option 'system.key' is deprecated " "and has no effect.\n"); diff --git a/src/knot/conf/conf.c b/src/knot/conf/conf.c index 9ed354aab3aaa1bf2c0eaf0a6da3ce5690f632f4..0c75b8b457443e0f892cb73f101c8f80bbc8f12a 100644 --- a/src/knot/conf/conf.c +++ b/src/knot/conf/conf.c @@ -680,6 +680,10 @@ void conf_truncate(conf_t *conf, int unload_hooks) free(conf->rundir); conf->rundir = 0; } + if (conf->pidfile) { + free(conf->pidfile); + conf->pidfile = 0; + } if (conf->nsid) { free(conf->nsid); conf->nsid = 0; diff --git a/src/knot/conf/conf.h b/src/knot/conf/conf.h index 57b250e2c938bd3c592e59c548e2b82679812a11..30075c3be6a8e8d2edb8f79e2de2291a1c1ed0a5 100644 --- a/src/knot/conf/conf.h +++ b/src/knot/conf/conf.h @@ -194,7 +194,8 @@ typedef struct conf_t { char *hostname; /*!< Host name to return on CH TXT hostname.{bind,server} */ char *version; /*!< Version for CH TXT version.{bind|server} */ char *storage; /*!< Persistent storage path for databases and such. */ - char *rundir; /*!< Run-time directory path. */ + char *rundir; /*!< Run-time directory path. */ + char *pidfile; /*!< PID file location. */ char *nsid; /*!< Server's NSID. */ size_t nsid_len;/*!< Server's NSID length. */ int workers; /*!< Number of workers per interface. */ diff --git a/src/knot/ctl/process.c b/src/knot/ctl/process.c index f5db3ca062d6eb16ff3e50c88bab5d0c78cd88c0..564fff2eddd086730f79ab289e0a43b0e5b655c4 100644 --- a/src/knot/ctl/process.c +++ b/src/knot/ctl/process.c @@ -39,8 +39,12 @@ char* pid_filename() /* Read configuration. */ char* ret = NULL; - if (conf() && conf()->rundir != NULL) { - ret = strcdup(conf()->rundir, "/knot.pid"); + + if (conf()) { + if (conf()->pidfile != NULL) + ret = strdup(conf()->pidfile); + else if (conf()->rundir != NULL) + ret = strcdup(conf()->rundir, "/knot.pid"); } rcu_read_unlock(); diff --git a/src/knot/ctl/remote.c b/src/knot/ctl/remote.c index 685a48b6235ae2b8c8907f7dc6c9904670393c60..2234bca20e13e13f7793f42c4745f4a6c7e90c2d 100644 --- a/src/knot/ctl/remote.c +++ b/src/knot/ctl/remote.c @@ -402,14 +402,15 @@ int remote_unbind(int r) int remote_poll(int r) { - if (r < 0) { - return -1; - } - /* Wait for events. */ fd_set rfds; FD_ZERO(&rfds); - FD_SET(r, &rfds); + if (r > -1) { + FD_SET(r, &rfds); + } else { + r = -1; /* Make sure n == r + 1 == 0 */ + } + return fdset_pselect(r + 1, &rfds, NULL, NULL, NULL, NULL); } diff --git a/src/knot/main.c b/src/knot/main.c index 874b08215e869e2031b72213efe18bcc9a0fd73d..685d5f247658f5a795ca85e7349262c189d2372d 100644 --- a/src/knot/main.c +++ b/src/knot/main.c @@ -42,9 +42,14 @@ /* Signal flags. */ static volatile short sig_req_stop = 0; static volatile short sig_req_reload = 0; -static volatile short sig_req_refresh = 0; static volatile short sig_stopping = 0; +#ifdef INTEGRITY_CHECK +static volatile short sig_integrity_check = 0; +int check_iteration = 0; +char *zone = NULL; +#endif /* INTEGRITY_CHECK */ + // Cleanup handler static int do_cleanup(server_t *server, char *configf, char *pidf); @@ -57,12 +62,6 @@ void interrupt_handle(int s) return; } - // Refresh - if (s == SIGUSR2) { - sig_req_refresh = 1; - return; - } - // Stop server if (s == SIGINT || s == SIGTERM) { if (sig_stopping == 0) { @@ -72,6 +71,14 @@ void interrupt_handle(int s) exit(1); } } + +#ifdef INTEGRITY_CHECK + // Start zone integrity check + if (s == SIGUSR1) { + sig_integrity_check = 1; + return; + } +#endif /* INTEGRITY_CHECK */ } void help(void) @@ -80,6 +87,10 @@ void help(void) PACKAGE_NAME); printf("\nParameters:\n" " -c, --config [file] Select configuration file.\n" +#ifdef INTEGRITY_CHECK + " -z, --zone [zone] Set zone to check. Send SIGUSR1 to trigger\n" + " integrity check.\n" +#endif /* INTEGRITY_CHECK */ " -d, --daemonize Run server as a daemon.\n" " -v, --verbose Verbose mode - additional runtime information.\n" " -V, --version Print version of the server.\n" @@ -97,6 +108,9 @@ int main(int argc, char **argv) /* Long options. */ struct option opts[] = { {"config", required_argument, 0, 'c'}, +#ifdef INTEGRITY_CHECK + {"zone", required_argument, 0, 'z'}, +#endif /* INTEGRITY_CHECK */ {"daemonize", no_argument, 0, 'd'}, {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, @@ -104,12 +118,25 @@ int main(int argc, char **argv) {0, 0, 0, 0} }; +#ifndef INTEGRITY_CHECK while ((c = getopt_long(argc, argv, "c:dvVh", opts, &li)) != -1) { +#else + while ((c = getopt_long(argc, argv, "c:z:dvVh", opts, &li)) != -1) { +#endif /* INTEGRITY_CHECK */ switch (c) { case 'c': config_fn = strdup(optarg); break; +#ifdef INTEGRITY_CHECK + case 'z': + if (optarg[strlen(optarg) - 1] != '.') { + zone = strcdup(optarg, "."); + } else { + zone = strdup(optarg); + } + break; +#endif /* INTEGRITY_CHECK */ case 'd': daemonize = 1; break; @@ -151,9 +178,6 @@ int main(int argc, char **argv) sigaction(SIGPIPE, &emptyset, NULL); // Mask rcu_register_thread(); - // Setup event queue - evqueue_set(evqueue_new()); - // Initialize log log_init(); @@ -296,7 +320,9 @@ int main(int argc, char **argv) sigaction(SIGTERM, &sa, NULL); sigaction(SIGHUP, &sa, NULL); sigaction(SIGPIPE, &sa, NULL); - sigaction(SIGUSR2, &sa, NULL); +#ifdef INTEGRITY_CHECK + sigaction(SIGUSR1, &sa, NULL); +#endif /* INTEGRITY_CHECK */ sa.sa_flags = 0; pthread_sigmask(SIG_BLOCK, &sa.sa_mask, NULL); @@ -315,9 +341,6 @@ int main(int argc, char **argv) ctl_if->address, (char*)buf); remote = remote_bind(ctl_if); } - if (remote < 0) - remote = evqueue()->fds[EVQUEUE_READFD]; - /* Run event loop. */ for(;;) { @@ -348,28 +371,40 @@ int main(int argc, char **argv) sig_req_reload = 0; server_reload(server, config_fn); } - if (sig_req_refresh) { - log_server_info("Refreshing slave zones...\n"); - sig_req_reload = 0; - int cf_ret = server_refresh(server); - if (cf_ret != KNOT_EOK) { - log_server_error("Couldn't refresh " - "slave zones - %s", - knot_strerror(cf_ret)); - } - +#ifdef INTEGRITY_CHECK + if (zone == NULL) + sig_integrity_check = 0; + if (sig_integrity_check) { + log_server_info("Starting integrity check of " + "zone: %s\n", zone); + knot_dname_t *zdn = + knot_dname_new_from_str(zone, + strlen(zone), + NULL); + knot_zone_t *z = + knot_zonedb_find_zone(server->nameserver->zone_db, + zdn); + int ic_ret = + knot_zone_contents_integrity_check(z->contents); + log_server_info("Integrity check: %d errors " + "discovered.\n", ic_ret); + knot_dname_free(&zdn); + log_server_info("Integrity check %d finished.\n", + check_iteration); + ++check_iteration; } +#endif /* INTEGRITY_CHECK */ } pthread_sigmask(SIG_UNBLOCK, &sa.sa_mask, NULL); /* Close remote control interface */ if (remote > -1) { close(remote); - } - /* Remove control socket. */ - if (remote > -1 && conf()->ctl.iface->family == AF_UNIX) { - unlink(conf()->ctl.iface->address); + /* Remove control socket. */ + conf_iface_t *ctl_if = conf()->ctl.iface; + if (ctl_if && ctl_if->family == AF_UNIX) + unlink(conf()->ctl.iface->address); } if ((server_wait(server)) != KNOT_EOK) { @@ -394,6 +429,10 @@ int main(int argc, char **argv) log_server_warning("Failed to remove PID file.\n"); do_cleanup(server, config_fn, pidf); +#ifdef INTEGRITY_CHECK + free(zone); +#endif /* INTEGRITY_CHECK */ + if (!daemonize) { fflush(stdout); fflush(stderr); @@ -422,8 +461,5 @@ static int do_cleanup(server_t *server, char *configf, char *pidf) /* Unhook from RCU */ rcu_unregister_thread(); - /* Free event loop. */ - evqueue_t *q = evqueue(); - evqueue_free(&q); return 1; } diff --git a/src/knot/zone/zone-load.c b/src/knot/zone/zone-load.c index 19f65fb0b5a1291acce11d7ce9c241361c12cbc4..71974fc37aa3e3ee83cce5b48771ee4c3b7aac53 100644 --- a/src/knot/zone/zone-load.c +++ b/src/knot/zone/zone-load.c @@ -55,7 +55,7 @@ static int rrset_list_add(rrset_list_t **head, knot_rrset_t *rrsig) tmp->data = rrsig; *head = tmp; } - + dbg_zp_verb("zp: rrset_add: Added RRSIG %p to list.\n", rrsig); return KNOT_EOK; @@ -80,7 +80,7 @@ static void rrset_list_delete(rrset_list_t **head) } *head = NULL; - + dbg_zp("zp: list_delete: List deleleted.\n"); } @@ -121,9 +121,9 @@ static int find_rrset_for_rrsig_in_node(knot_zone_contents_t *zone, return KNOT_ERROR; } } - + assert(tmp_rrset); - + if (tmp_rrset->ttl != rrsig->ttl) { char *name = knot_dname_to_str(tmp_rrset->owner); assert(name); @@ -165,7 +165,7 @@ static knot_node_t *create_node(knot_zone_contents_t *zone, knot_strerror(ret)); return NULL; } - + assert(current_rrset->owner == node->owner); return node; @@ -223,7 +223,7 @@ static size_t calculate_item_size(const knot_rrset_t *rrset, scanner->r_data_blocks[i]; } } - + return size; } @@ -233,16 +233,16 @@ static int add_rdata_to_rr(knot_rrset_t *rrset, const scanner_t *scanner) dbg_zp("zp: add_rdata_to_rr: No RRSet.\n"); return KNOT_EINVAL; } - + parser_context_t *parser = scanner->data; - + const rdata_descriptor_t *desc = get_rdata_descriptor(knot_rrset_type(rrset)); assert(desc); - + dbg_zp_detail("zp: add_rdata_to_rr: Adding type %d, RRSet has %d RRs.\n", rrset->type, rrset->rdata_count); - + size_t rdlen = calculate_item_size(rrset, scanner); size_t offset = 0; uint8_t *rdata = knot_rrset_create_rdata(rrset, rdlen); @@ -250,7 +250,7 @@ static int add_rdata_to_rr(knot_rrset_t *rrset, const scanner_t *scanner) dbg_zp("zp: create_rdata: Could not create RR.\n"); return KNOT_ENOMEM; } - + for (int i = 0; desc->block_types[i] != KNOT_RDATA_WF_END; i++) { int item = desc->block_types[i]; if (descriptor_item_is_dname(item)) { @@ -293,7 +293,7 @@ dbg_zp_exec_detail( scanner->r_data_blocks[i]; } } - + return KNOT_EOK; } @@ -309,23 +309,23 @@ static void process_rr(const scanner_t *scanner) knot_zone_contents_t *contents = parser->current_zone; knot_dname_t *current_owner = NULL; knot_rrset_t *current_rrset = NULL; - if (parser->last_node && - (scanner->r_owner_length == parser->last_node->owner->size) && - (strncmp((char *)parser->last_node->owner->name, - (char *)scanner->r_owner, scanner->r_owner_length) == 0)) { - // no need to create new dname; - current_owner = parser->last_node->owner; + if (parser->last_node && + (scanner->r_owner_length == parser->last_node->owner->size) && + (strncmp((char *)parser->last_node->owner->name, + (char *)scanner->r_owner, scanner->r_owner_length) == 0)) { + // no need to create new dname; + current_owner = parser->last_node->owner; knot_dname_retain(current_owner); - } else { - current_owner = - knot_dname_new_from_wire(scanner->r_owner, - scanner->r_owner_length, - NULL); - if (current_owner == NULL) { + } else { + current_owner = + knot_dname_new_from_wire(scanner->r_owner, + scanner->r_owner_length, + NULL); + if (current_owner == NULL) { parser->ret = KNOT_ERROR; return; } - knot_dname_to_lower(current_owner); + knot_dname_to_lower(current_owner); /*!< \todo * If name is already in the table, we might not need to create * dname object, just compare wires. @@ -333,30 +333,30 @@ static void process_rr(const scanner_t *scanner) knot_zone_contents_insert_dname_into_table(¤t_owner, parser->lookup_tree); } - + /*!< \todo Do not create RRSet each time - merging needs to be sorted though. */ current_rrset = knot_rrset_new(current_owner, scanner->r_type, scanner->r_class, scanner->r_ttl); knot_dname_release(current_owner); - + assert(current_owner); assert(current_rrset); parser->current_rrset = current_rrset; - + int ret = add_rdata_to_rr(current_rrset, scanner); if (ret != KNOT_EOK) { log_zone_error("Cannot add RDATA to zone, load failed.\n"); parser->ret = ret; return; } - + dbg_zp_verb("zp: process_rr: Processing type: %d.\n", parser->current_rrset->type); assert(current_rrset->rdata_count); - + /* Node add/get functions. */ int (*node_add_func)(knot_zone_contents_t *, knot_node_t *, int, uint8_t); @@ -431,12 +431,12 @@ static void process_rr(const scanner_t *scanner) parser->last_node); rrset_list_delete(&parser->node_rrsigs); } - + /* The node might however been created previously. */ parser->last_node = knot_zone_contents_get_node(contents, knot_rrset_owner(current_rrset)); - + if (parser->last_node == NULL) { /* Try NSEC3 tree. */ if (current_rrset->type == KNOT_RRTYPE_NSEC3 || @@ -448,7 +448,7 @@ static void process_rr(const scanner_t *scanner) current_rrset)); } } - + if (parser->last_node == NULL) { /* Still NULL, node has to be created. */ if ((parser->last_node = create_node(contents, @@ -472,12 +472,12 @@ static void process_rr(const scanner_t *scanner) parser->ret = KNOT_ERROR; return; } - + dbg_zp_verb("zp: process_rr: RRSIG proccesed successfully.\n"); parser->ret = KNOT_EOK; return; } - + /*! \todo Move RRSIG and RRSet handling to funtions. */ assert(current_rrset->type != KNOT_RRTYPE_RRSIG); @@ -520,13 +520,13 @@ static void process_rr(const scanner_t *scanner) return; } } - + if (current_rrset->type != KNOT_RRTYPE_RRSIG) { /* * If there's already an RRSet of this type in a node, check - * that TTLs are the same, if not, give warning a change TTL. + * that TTLs are the same, if not, give warning a change TTL. */ - const knot_rrset_t *rrset_in_node = + const knot_rrset_t *rrset_in_node = knot_node_rrset(node, current_rrset->type); if (rrset_in_node && current_rrset->ttl != rrset_in_node->ttl) { @@ -536,7 +536,7 @@ static void process_rr(const scanner_t *scanner) /* Actual change will happen in merge. */ } } - + ret = knot_zone_contents_add_rrset(contents, current_rrset, &node, KNOT_RRSET_DUPL_MERGE); @@ -568,40 +568,40 @@ static void process_rr(const scanner_t *scanner) parser->ret = KNOT_EMALF; return; } - + parser->last_node = node; - + dbg_zp_verb("zp: process_rr: RRSet %p processed successfully.\n", parser->current_rrset); parser->ret = KNOT_EOK; } -int knot_zload_open(zloader_t **dst, const char *source, const char *origin, +int knot_zload_open(zloader_t **dst, const char *source, const char *origin, int semantic_checks) { if (!dst || !source || !origin) { dbg_zload("zload: open: Bad arguments.\n"); return KNOT_EINVAL; } - + *dst = NULL; - + /* Check zone file. */ struct stat st; if (stat(source, &st) < 0) { return knot_map_errno(errno); } - + /* Create context. */ parser_context_t *context = xmalloc(sizeof(parser_context_t)); - + /* Create trie for DNAME duplicits. */ context->lookup_tree = hattrie_create(); if (context->lookup_tree == NULL) { free(context); return KNOT_ENOMEM; } - + context->origin_from_config = knot_dname_new_from_str(origin, strlen(origin), NULL); assert(context->origin_from_config); @@ -616,7 +616,7 @@ int knot_zload_open(zloader_t **dst, const char *source, const char *origin, context->current_zone = knot_zone_get_contents(zone); context->node_rrsigs = NULL; context->ret = KNOT_EOK; - + /* Create file loader. */ file_loader_t *loader = file_loader_create(source, origin, KNOT_CLASS_IN, 3600, @@ -628,17 +628,17 @@ int knot_zload_open(zloader_t **dst, const char *source, const char *origin, free(context); return KNOT_ERROR; } - + /* Allocate new loader. */ zloader_t *zl = xmalloc(sizeof(zloader_t)); - + zl->source = strdup(source); zl->origin = strdup(origin); zl->file_loader = loader; zl->context = context; zl->semantic_checks = semantic_checks; *dst = zl; - + /* Log all information for now - possibly more config options. */ zl->err_handler = handler_new(1, 1, 1, 1, 1); if (zl->err_handler == NULL) { @@ -647,9 +647,9 @@ int knot_zload_open(zloader_t **dst, const char *source, const char *origin, "Semantic check skipped for zone %s\n", origin); } - + context->err_handler = zl->err_handler; - + return KNOT_EOK; } @@ -660,7 +660,7 @@ knot_zone_t *knot_zload_load(zloader_t *loader) dbg_zload("zload: load: NULL loader!\n"); return NULL; } - + parser_context_t *c = loader->context; assert(c); int ret = file_loader_process(loader->file_loader); @@ -681,7 +681,7 @@ knot_zone_t *knot_zload_load(zloader_t *loader) knot_zone_deep_free(&zone_to_free); return NULL; } - + if (loader->file_loader->scanner->error_counter > 0) { log_zone_error("Zone could not be loaded due to %"PRIu64" errors" " encountered.\n", @@ -691,7 +691,7 @@ knot_zone_t *knot_zload_load(zloader_t *loader) knot_zone_deep_free(&zone_to_free); return NULL; } - + if (knot_zone_contents_apex(c->current_zone) == NULL || knot_node_rrset(knot_zone_contents_apex(c->current_zone), KNOT_RRTYPE_SOA) == NULL) { log_zone_error("No SOA record in the zone file.\n"); @@ -700,13 +700,13 @@ knot_zone_t *knot_zload_load(zloader_t *loader) knot_zone_deep_free(&zone_to_free); return NULL; } - + knot_node_t *first_nsec3_node = NULL; knot_node_t *last_nsec3_node = NULL; rrset_list_delete(&c->node_rrsigs); knot_zone_contents_adjust(c->current_zone, &first_nsec3_node, &last_nsec3_node, 0); - + if (loader->semantic_checks) { int check_level = 1; const knot_rrset_t *soa_rr = @@ -729,7 +729,7 @@ knot_zone_t *knot_zload_load(zloader_t *loader) log_zone_info("Semantic checks completed for zone=%s\n", zname); free(zname); } - + return c->current_zone->zone; } @@ -738,9 +738,9 @@ void knot_zload_close(zloader_t *loader) if (!loader) { return; } - + hattrie_free(loader->context->lookup_tree); - + file_loader_free(loader->file_loader); free(loader->source); diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am index 3606215fa9bbfa922c775cd6e755b8697962de83..f4b5c5d37293c20d7f0812139037b1687d735b45 100644 --- a/src/tests/Makefile.am +++ b/src/tests/Makefile.am @@ -3,8 +3,7 @@ ACLOCAL_AMFLAGS = -I $(top_srcdir)/m4 AM_CPPFLAGS = -I$(top_srcdir)/src/libknot -I$(top_srcdir)/src -DSYSCONFDIR='"$(sysconfdir)"' -DSBINDIR='"$(sbindir)"' check_PROGRAMS = \ - unittests \ - unittests_xfr + unittests TESTS = unittests @@ -61,12 +60,7 @@ unittests_SOURCES = \ libknot/sign_tests.h \ unittests_main.c -unittests_xfr_SOURCES = \ - xfr_tests.c \ - xfr_tests.h - unittests_LDADD = ../libknotd.la ../libknots.la @LIBOBJS@ -unittests_xfr_LDADD = ../libknotd.la ../libknot.la ../libknots.la @LIBOBJS@ sample_conf.rc: files/sample_conf $(top_srcdir)/resource.sh $(srcdir)/files/sample_conf >$@ diff --git a/src/tests/README b/src/tests/README deleted file mode 100644 index 1d9748b1542b4f701680cb261c11fe4e0f651eae..0000000000000000000000000000000000000000 --- a/src/tests/README +++ /dev/null @@ -1,4 +0,0 @@ -Unit testing ------------- - -Make assembles "unittest" binary with all of the planned tests included. diff --git a/src/tests/xfr_tests.c b/src/tests/xfr_tests.c deleted file mode 100644 index fee09f2680d8e44d98da2f3199e1d5468f6bff87..0000000000000000000000000000000000000000 --- a/src/tests/xfr_tests.c +++ /dev/null @@ -1,384 +0,0 @@ -/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/* - * This test is basically a copy of the whole server, with following exceptions: - * - signal handler now handles one more signal - * SIGUSR1 is used to signal this - * binary that an integrity check should be done -*/ - -#include <config.h> -#include <time.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <getopt.h> -#include <assert.h> - -#include "knot/knot.h" -#include "knot/server/server.h" -#include "knot/ctl/process.h" -#include "knot/conf/conf.h" -#include "knot/conf/logconf.h" -#include "common/evqueue.h" -#include "knot/server/zones.h" - -/*----------------------------------------------------------------------------*/ - -/* Signal flags. */ -static volatile short sig_req_stop = 0; -static volatile short sig_req_reload = 0; -static volatile short sig_stopping = 0; -static volatile short sig_integrity_check = 0; - - -// SIGINT signal handler -void interrupt_handle(int s) -{ - // Reload configuration - if (s == SIGHUP) { - sig_req_reload = 1; - return; - } - - // Stop server - if (s == SIGINT || s == SIGTERM) { - if (sig_stopping == 0) { - sig_req_stop = 1; - sig_stopping = 1; - } else { - log_server_notice("OK! Exiting immediately.\n"); - exit(1); - } - } - - // Start zone integrity check - if (s == SIGUSR1) { - sig_integrity_check = 1; - return; - } -} - -void help(int argc, char **argv) -{ - printf("Usage: %sd [parameters]\n", - PACKAGE_NAME); - printf("Parameters:\n" - " -c, --config [file] Select configuration file.\n" - " -z, --zone [origin] Inspected zone origin.\n" - " -d, --daemonize Run server as a daemon.\n" - " -v, --verbose Verbose mode - additional runtime information.\n" - " -V, --version Print version of the server.\n" - " -h, --help Print help and usage.\n" - "Send SIGUSR1 to trigger integrity check.\n"); -} - -int main(int argc, char **argv) -{ - // Parse command line arguments - int check_iteration = 0; - int c = 0, li = 0; - int verbose = 0; - int daemonize = 0; - char *config_fn = NULL; - char *zone = NULL; - - /* Long options. */ - struct option opts[] = { - {"config", required_argument, 0, 'c'}, - {"zone", required_argument, 0, 'z'}, - {"daemonize", no_argument, 0, 'd'}, - {"verbose", no_argument, 0, 'v'}, - {"version", no_argument, 0, 'V'}, - {"help", no_argument, 0, 'h'}, - {0, 0, 0, 0} - }; - - while ((c = getopt_long(argc, argv, "c:z:dvVh", opts, &li)) != -1) { - switch (c) - { - case 'c': - config_fn = strdup(optarg); - break; - case 'd': - daemonize = 1; - break; - case 'v': - verbose = 1; - break; - case 'V': - printf("%s, version %s\n", "Knot DNS", PACKAGE_VERSION); - return 0; - case 'z': - if (optarg[strlen(optarg) - 1] != '.') { - zone = strcdup(optarg, "."); - } else { - zone = strdup(optarg); - } - break; - case 'h': - case '?': - default: - help(argc, argv); - return 1; - } - } - - // Now check if we want to daemonize - if (daemonize) { - if (daemon(1, 0) != 0) { - free(zone); - free(config_fn); - fprintf(stderr, "Daemonization failed, " - "shutting down...\n"); - return 1; - } - } - - // Register service and signal handler - struct sigaction emptyset; - memset(&emptyset, 0, sizeof(struct sigaction)); - emptyset.sa_handler = interrupt_handle; - sigemptyset(&emptyset.sa_mask); - emptyset.sa_flags = 0; - sigaction(SIGALRM, &emptyset, NULL); // Interrupt - - // Setup event queue - evqueue_set(evqueue_new()); - - // Initialize log - log_init(); - - // Verbose mode - if (verbose) { - int mask = LOG_MASK(LOG_INFO)|LOG_MASK(LOG_DEBUG); - log_levels_add(LOGT_STDOUT, LOG_ANY, mask); - } - - // Initialize pseudorandom number generator - srand(time(0)); - - // Create server - server_t *server = server_create(); - - // Initialize configuration - rcu_read_lock(); - conf_add_hook(conf(), CONF_LOG, log_conf_hook, 0); - conf_add_hook(conf(), CONF_LOG, zones_ns_conf_hook, server->nameserver); - conf_add_hook(conf(), CONF_LOG, server_conf_hook, server); - rcu_read_unlock(); - - // Find implicit configuration file - if (!config_fn) { - config_fn = conf_find_default(); - } - - // Find absolute path for config file - if (config_fn[0] != '/') - { - // Get absolute path to cwd - size_t cwbuflen = 64; - char *cwbuf = malloc((cwbuflen + 2) * sizeof(char)); - while (getcwd(cwbuf, cwbuflen) == 0) { - cwbuflen *= 2; - cwbuf = realloc(cwbuf, (cwbuflen + 2) * sizeof(char)); - } - cwbuflen = strlen(cwbuf); - - // Append ending slash - if (cwbuf[cwbuflen - 1] != '/') { - cwbuf = strncat(cwbuf, "/", 1); - } - - // Assemble path to config file - char *abs_cfg = strcdup(cwbuf, config_fn); - free(config_fn); - free(cwbuf); - config_fn = abs_cfg; - } - - // Open configuration - log_server_info("Reading configuration '%s' ...\n", config_fn); - int conf_ret = conf_open(config_fn); - if (conf_ret != KNOT_EOK) { - if (conf_ret == KNOT_ENOENT) { - log_server_error("Couldn't open configuration file " - "'%s'.\n", config_fn); - } else { - log_server_error("Failed to load configuration '%s'.\n", - config_fn); - } - server_destroy(&server); - free(config_fn); - return 1; - } else { - log_server_info("Configured %d interfaces and %d zones.\n", - conf()->ifaces_count, conf()->zones_count); - } - log_server_info("\n"); - - // Create server instance - char* pidfile = pid_filename(); - - // Run server - int res = 0; - log_server_info("Starting server...\n"); - if ((res = server_start(server)) == KNOT_EOK) { - - // Save PID - int has_pid = 1; - int rc = pid_write(pidfile); - if (rc < 0) { - has_pid = 0; - log_server_warning("Failed to create " - "PID file '%s'.\n", pidfile); - } - - // Change directory if daemonized - if (daemonize) { - log_server_info("Server started as a daemon, " - "PID = %ld\n", (long)getpid()); - res = chdir("/"); - } else { - log_server_info("Server started in foreground, " - "PID = %ld\n", (long)getpid()); - } - if (has_pid) { - log_server_info("PID stored in %s\n", pidfile); - } else { - log_server_warning("Server running without PID file.\n"); - } - size_t zcount = server->nameserver->zone_db->zone_count; - if (!zcount) { - log_server_warning("Server started, but no zones served.\n"); - } - - // Setup signal handler - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = interrupt_handle; - sigemptyset(&sa.sa_mask); - sigaction(SIGINT, &sa, NULL); - sigaction(SIGTERM, &sa, NULL); - sigaction(SIGHUP, &sa, NULL); - sigaction(SIGUSR1, &sa, NULL); - sa.sa_flags = 0; - pthread_sigmask(SIG_BLOCK, &sa.sa_mask, NULL); - - /* Run event loop. */ - for(;;) { - pthread_sigmask(SIG_UNBLOCK, &sa.sa_mask, NULL); - int ret = evqueue_poll(evqueue(), 0, 0); - pthread_sigmask(SIG_BLOCK, &sa.sa_mask, NULL); - - /* Interrupts. */ - /*! \todo More robust way to exit evloop. - * Event loop should exit with a special - * event. - */ - if (sig_req_stop) { - sig_req_stop = 0; - server_stop(server); - break; - } - if (sig_req_reload) { - log_server_info("Reloading configuration...\n"); - sig_req_reload = 0; - int cf_ret = conf_open(config_fn); - switch (cf_ret) { - case KNOT_EOK: - log_server_info("Configuration " - "reloaded.\n"); - break; - case KNOT_ENOENT: - log_server_error("Configuration " - "file '%s' " - "not found.\n", - conf()->filename); - break; - default: - log_server_error("Configuration " - "reload failed.\n"); - break; - } - } - if (zone == NULL) sig_integrity_check = 0; - if (sig_integrity_check) { - log_server_info("Starting integrity check of zone: %s\n", zone); - knot_dname_t* zdn = knot_dname_new_from_str(zone, strlen(zone), NULL); - assert(zdn); - knot_zone_t *z = knot_zonedb_find_zone(server->nameserver->zone_db, zdn); - int ic_ret = knot_zone_contents_integrity_check(z->contents); - log_server_info("Integrity check: %d errors discovered.\n", ic_ret); - knot_dname_free(&zdn); - log_server_info("Integrity check %d finished.\n", check_iteration); - ++check_iteration; - } - - /* Events. */ - if (ret > 0) { - event_t ev; - if (evqueue_get(evqueue(), &ev) == 0) { - dbg_server_verb("Event: " - "received new event.\n"); - if (ev.cb) { - ev.cb(&ev); - } - } - } - } - pthread_sigmask(SIG_UNBLOCK, &sa.sa_mask, NULL); - - if ((res = server_wait(server)) != KNOT_EOK) { - log_server_error("An error occured while " - "waiting for server to finish.\n"); - } else { - log_server_info("Server finished.\n"); - } - - } else { - log_server_fatal("An error occured while " - "starting the server.\n"); - } - - // Stop server and close log - server_destroy(&server); - - // Remove PID file - if (pid_remove(pidfile) < 0) { - log_server_warning("Failed to remove PID file.\n"); - } - - log_server_info("Shut down.\n"); - log_close(); - free(pidfile); - - // Destroy event loop - evqueue_t *q = evqueue(); - evqueue_free(&q); - - // Free default config filename if exists - free(zone); - free(config_fn); - - if (!daemonize) { - fflush(stdout); - fflush(stderr); - } - - return res; -} diff --git a/src/tests/xfr_tests.h b/src/tests/xfr_tests.h deleted file mode 100644 index 29de11dd17d097c0defc00e3acb62336c9e2f49f..0000000000000000000000000000000000000000 --- a/src/tests/xfr_tests.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef XFR_TESTS_H -#define XFR_TESTS_H - -class xfr_tests -{ -public: - xfr_tests(); -}; - -#endif // XFR_TESTS_H