summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.in2
-rw-r--r--NEWS12
-rwxr-xr-xconfigure59
-rw-r--r--configure.ac27
-rw-r--r--doc/Makefile.in2
-rw-r--r--doc/configuration.texi4
-rw-r--r--doc/knot.info354
-rw-r--r--doc/knot.texi1
-rw-r--r--doc/reference.texi21
-rw-r--r--doc/running.texi44
-rw-r--r--doc/stamp-vti8
-rw-r--r--doc/version.texi8
-rw-r--r--man/Makefile.in2
-rw-r--r--man/kdig.1180
-rw-r--r--man/kdig.1.in180
-rw-r--r--man/khost.165
-rw-r--r--man/khost.1.in65
-rw-r--r--man/knot.conf.54
-rw-r--r--man/knot.conf.5.in4
-rw-r--r--man/knotc.822
-rw-r--r--man/knotc.8.in22
-rw-r--r--man/knotd.82
-rw-r--r--man/knotd.8.in2
-rw-r--r--man/knsupdate.1146
-rw-r--r--man/knsupdate.1.in146
-rw-r--r--samples/Makefile.am21
-rw-r--r--samples/Makefile.in23
-rw-r--r--samples/knot.full.conf6
-rw-r--r--samples/knot.sample.conf.in77
-rw-r--r--src/Makefile.am11
-rw-r--r--src/Makefile.in35
-rw-r--r--src/common/errcode.c1
-rw-r--r--src/common/errcode.h1
-rw-r--r--src/common/evqueue.c3
-rw-r--r--src/common/evqueue.h17
-rw-r--r--src/common/fdset.c217
-rw-r--r--src/common/fdset.h207
-rw-r--r--src/common/fdset_epoll.c205
-rw-r--r--src/common/fdset_epoll.h132
-rw-r--r--src/common/fdset_kqueue.c260
-rw-r--r--src/common/fdset_kqueue.h132
-rw-r--r--src/common/fdset_poll.c218
-rw-r--r--src/common/fdset_poll.h132
-rw-r--r--src/config.h.in9
-rw-r--r--src/knot/conf/cf-parse.y9
-rw-r--r--src/knot/conf/conf.c12
-rw-r--r--src/knot/conf/conf.h3
-rw-r--r--src/knot/conf/libknotd_la-cf-parse.c442
-rw-r--r--src/knot/conf/logconf.c29
-rw-r--r--src/knot/ctl/knotc_main.c51
-rw-r--r--src/knot/ctl/process.c8
-rw-r--r--src/knot/ctl/remote.c25
-rw-r--r--src/knot/knot.h26
-rw-r--r--src/knot/main.c104
-rw-r--r--src/knot/server/server.c9
-rw-r--r--src/knot/server/server.h3
-rw-r--r--src/knot/server/socket.h4
-rw-r--r--src/knot/server/tcp-handler.c222
-rw-r--r--src/knot/server/xfr-handler.c417
-rw-r--r--src/knot/server/xfr-handler.h7
-rw-r--r--src/knot/server/zones.c58
-rw-r--r--src/knot/server/zones.h8
-rw-r--r--src/knot/zone/semantic-check.c5
-rw-r--r--src/knot/zone/zone-load.c122
-rw-r--r--src/libknot/nameserver/name-server.c22
-rw-r--r--src/libknot/nameserver/name-server.h5
-rw-r--r--src/libknot/rrset-dump.c4
-rw-r--r--src/libknot/zone/zone-contents.c6
-rw-r--r--src/tests/Makefile.am8
-rw-r--r--src/tests/Makefile.in24
-rw-r--r--src/tests/README4
-rw-r--r--src/tests/common/fdset_tests.c59
-rw-r--r--src/tests/xfr_tests.c384
-rw-r--r--src/tests/xfr_tests.h10
-rw-r--r--src/utils/common/params.c16
-rw-r--r--src/utils/dig/dig_params.c6
-rw-r--r--src/utils/host/host_params.c2
-rw-r--r--src/zscanner/test/cases/06-0_INCLUDE.in4
-rw-r--r--src/zscanner/test/cases/06-3_INCLUDE.in2
-rw-r--r--src/zscanner/test/cases/06-4_INCLUDE.in2
-rw-r--r--src/zscanner/test/run_tests.sh4
81 files changed, 1909 insertions, 3306 deletions
diff --git a/Makefile.in b/Makefile.in
index 9bf4b44..22bbfc2 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -214,6 +214,7 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
RAGEL = @RAGEL@
RANLIB = @RANLIB@
+RELEASE_DATE = @RELEASE_DATE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -241,6 +242,7 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+config_dir = @config_dir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
diff --git a/NEWS b/NEWS
index f3c7909..1497951 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,17 @@
Knot DNS NEWS
+v1.3.0-rc4 - Jul 15, 2013
+-------------------------
+Features:
+ * --with-configdir option for default config path
+ * Reintroducted 'pidfile' config option
+Bugfixes:
+ * AXFR/IXFR subsystem performance improvements
+ * Rescheduling of AXFR in some cases
+ * RRSIGs not in the same section for DS records
+ * Log messages leaking to syslog
+ * 'knotc restart' option removed due to several limitations
+
v1.3.0-rc3 - Jun 28, 2013
-------------------------
diff --git a/configure b/configure
index 3630ebb..51e19f3 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for knot 1.3.0-rc3.
+# Generated by GNU Autoconf 2.69 for knot 1.3.0-rc4.
#
# Report bugs to <knot-dns@labs.nic.cz>.
#
@@ -590,8 +590,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='knot'
PACKAGE_TARNAME='knot'
-PACKAGE_VERSION='1.3.0-rc3'
-PACKAGE_STRING='knot 1.3.0-rc3'
+PACKAGE_VERSION='1.3.0-rc4'
+PACKAGE_STRING='knot 1.3.0-rc4'
PACKAGE_BUGREPORT='knot-dns@labs.nic.cz'
PACKAGE_URL=''
@@ -643,6 +643,7 @@ libcrypto_LIBS
libcrypto_CFLAGS
liburcu_LIBS
liburcu_CFLAGS
+config_dir
storage_dir
run_dir
FSM_TYPE
@@ -685,6 +686,7 @@ LIBTOOL
ac_ct_AR
AR
SIMD_FLAGS
+RELEASE_DATE
EGREP
GREP
CPP
@@ -786,10 +788,12 @@ enable_fastparser
enable_debug
enable_debuglevel
enable_recvmmsg
+enable_integrity_check
enable_lto
enable_microseconds_log
with_rundir
with_storage
+with_configdir
with_urcu
with_openssl
'
@@ -1351,7 +1355,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures knot 1.3.0-rc3 to adapt to many kinds of systems.
+\`configure' configures knot 1.3.0-rc4 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1421,7 +1425,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of knot 1.3.0-rc3:";;
+ short | recursive ) echo "Configuration of knot 1.3.0-rc4:";;
esac
cat <<\_ACEOF
@@ -1447,6 +1451,8 @@ Optional Features:
enable recvmmsg() network API under Linux (kernel
support required) (set to 'no' if you have trouble
running server under valgrind) [default=yes]
+ --enable-integrity-check
+ enable integrity check in knotd via SIGUSR1
--enable-lto=yes|no enable link-time optimizations, enable if not broken
for some extra speed [default=no]
--enable-microseconds-log
@@ -1461,9 +1467,11 @@ Optional Packages:
--with-sysroot=DIR Search for dependent libraries within DIR
(or the compiler's sysroot if not specified).
--with-rundir=path Path to run-time variable data (pid, sockets...).
- [default=`eval echo ${localstatedir}`/run/knot]
+ [default=LOCALSTATEDIR/run/knot]
--with-storage=path Default storage directory (slave zones, persistent
- data). [default=$(sharedstatedir)/knot]
+ data). [default=LOCALSTATEDIR/lib/knot]
+ --with-configdir=path Default directory for configuration.
+ [default=SYSCONFDIR/knot]
--with-urcu=DIR where to find userspace-rcu library
--with-openssl=DIR where to find openssl library
@@ -1562,7 +1570,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-knot configure 1.3.0-rc3
+knot configure 1.3.0-rc4
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1985,7 +1993,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by knot $as_me 1.3.0-rc3, which was
+It was created by knot $as_me 1.3.0-rc4, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2808,7 +2816,7 @@ fi
# Define the identity of the package.
PACKAGE='knot'
- VERSION='1.3.0-rc3'
+ VERSION='1.3.0-rc4'
cat >>confdefs.h <<_ACEOF
@@ -4331,6 +4339,11 @@ $as_echo "$ac_cv_safe_to_define___extensions__" >&6; }
+# Automatically update release date based on configure.ac date
+release_date=`doc/mdate-sh configure.ac`
+RELEASE_DATE=$release_date
+
+
# Check SSE, SSE2 and SSE3 support
ac_ext=c
@@ -13097,6 +13110,15 @@ $as_echo "#define ENABLE_RECVMMSG 1" >>confdefs.h
fi
+# Enable integrity check
+# Check whether --enable-integrity-check was given.
+if test "${enable_integrity_check+set}" = set; then :
+ enableval=$enable_integrity_check;
+$as_echo "#define INTEGRITY_CHECK 1" >>confdefs.h
+
+fi
+
+
# Check for link time optimizations support and predictive commoning
# Check whether --enable-lto was given.
if test "${enable_lto+set}" = set; then :
@@ -13241,7 +13263,7 @@ fi
-storage_dir="${sharedstatedir}/knot"
+storage_dir="${localstatedir}/lib/knot"
# Check whether --with-storage was given.
if test "${with_storage+set}" = set; then :
@@ -13250,6 +13272,15 @@ fi
+config_dir="${sysconfdir}/knot"
+
+# Check whether --with-configdir was given.
+if test "${with_configdir+set}" = set; then :
+ withval=$with_configdir; config_dir=$withval
+fi
+
+
+
# Checks for libraries.
# FIXME: Replace `main' with a function in `-lm':
@@ -14348,7 +14379,7 @@ $as_echo "#define DSFMT_MEXP 521" >>confdefs.h
# Checks for library functions.
-for ac_func in clock_gettime gettimeofday epoll_wait fgetln getline kqueue madvise poll posix_memalign pselect pthread_setaffinity_np regcomp select sendmmsg setgroups
+for ac_func in clock_gettime gettimeofday fgetln getline madvise poll posix_memalign pselect pthread_setaffinity_np regcomp select sendmmsg setgroups
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -14998,7 +15029,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by knot $as_me 1.3.0-rc3, which was
+This file was extended by knot $as_me 1.3.0-rc4, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -15064,7 +15095,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-knot config.status 1.3.0-rc3
+knot config.status 1.3.0-rc4
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/configure.ac b/configure.ac
index 2bc79f9..770a6fc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,7 +1,7 @@
# -*- Autoconf -*-
AC_PREREQ([2.60])
-AC_INIT([knot], [1.3.0-rc3], [knot-dns@labs.nic.cz])
+AC_INIT([knot], [1.3.0-rc4], [knot-dns@labs.nic.cz])
AM_INIT_AUTOMAKE([gnits subdir-objects dist-bzip2 dist-xz -Wall -Werror])
AM_SILENT_RULES([yes])
AC_CONFIG_SRCDIR([src/knot/main.c])
@@ -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':
@@ -287,7 +302,7 @@ AC_TYPE_SSIZE_T
AC_DEFINE([DSFMT_MEXP], [521], [DSFMT parameters])
# Checks for library functions.
-AC_CHECK_FUNCS([clock_gettime gettimeofday epoll_wait fgetln getline kqueue madvise poll posix_memalign pselect pthread_setaffinity_np regcomp select sendmmsg setgroups])
+AC_CHECK_FUNCS([clock_gettime gettimeofday fgetln getline madvise poll posix_memalign pselect pthread_setaffinity_np regcomp select sendmmsg setgroups])
# Check for cpu_set_t/cpuset_t compatibility
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]], [[cpu_set_t set; CPU_ZERO(&set);]])],
diff --git a/doc/Makefile.in b/doc/Makefile.in
index 5e6bfe5..d8e93dd 100644
--- a/doc/Makefile.in
+++ b/doc/Makefile.in
@@ -189,6 +189,7 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
RAGEL = @RAGEL@
RANLIB = @RANLIB@
+RELEASE_DATE = @RELEASE_DATE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -216,6 +217,7 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+config_dir = @config_dir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
diff --git a/doc/configuration.texi b/doc/configuration.texi
index 1f1a5ca..5dd5549 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.info b/doc/knot.info
index bed79fe..c2ad015 100644
--- a/doc/knot.info
+++ b/doc/knot.info
@@ -1,7 +1,6 @@
-This is ../../doc/knot.info, produced by makeinfo version 4.13 from
-../../doc/knot.texi.
+This is knot.info, produced by makeinfo version 4.13 from knot.texi.
-This manual is for Knot DNS (version 1.3.0-rc3, 26 June 2013), which is
+This manual is for Knot DNS (version 1.3.0-rc4, 9 July 2013), which is
a high-performance authoritative-only DNS server.
Copyright (C) 2012 CZ.NIC, z.s.p.o.
@@ -31,7 +30,7 @@ File: knot.info, Node: Top, Next: Introduction, Prev: (dir), Up: (dir)
Knot DNS
********
-This manual is for Knot DNS (version 1.3.0-rc3, 26 June 2013).
+This manual is for Knot DNS (version 1.3.0-rc4, 9 July 2013).
* Menu:
@@ -147,6 +146,7 @@ Statement Definition and Usage
* nsid::
* storage::
* rundir::
+* pidfile::
* workers::
* user::
* max-conn-idle::
@@ -732,9 +732,8 @@ can be used as a base for your Knot DNS setup.
Now let's go step by step through this minimal configuration file:
1. In `system' statement we have configured `storage' directory where
- Knot DNS will store compiled zone files, PID file and for slave
- zone also their journal files. (See *note system:: and *note
- storage::)
+ Knot DNS will store slave zones and journal files. (See *note
+ system:: and *note storage::)
2. The `interfaces' statement defines interfaces where Knot DNS will
listen for incoming connections. We have defined two interfaces:
@@ -1005,7 +1004,7 @@ the same way.
Use knotc tool for convenience when working with the server daemon. As
of Knot DNS 1.3.0, the zones are not compiled anymore. That makes
working with the server much more user friendly.
- $ knotc -c knot.conf reload|restart
+ $ knotc -c knot.conf reload
The tool `knotc' is designed as a front-end for user, making it easier
to do everything from server startup to state checking of a running
@@ -1016,7 +1015,8 @@ server daemon. If you want to control the daemon directly, use
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').
@@ -1026,15 +1026,13 @@ server daemon. If you want to control the daemon directly, use
-v, --verbose Verbose mode - additional runtime
information.
-V, --version Print knot server version.
- -w, --wait Wait for the server to finish start/stop
+ -w, --wait Wait for the server to finish stop
operations.
-i, --interactive Interactive mode (do not daemonize).
-h, --help Print help and usage.
Actions:
- start Start server (if not running).
stop Stop server.
- restart Restart server.
reload Reload configuration and changed zones.
refresh [zone] Refresh slave zone (all if not specified).
flush Flush journal and update zone files.
@@ -1042,20 +1040,28 @@ server daemon. If you want to control the daemon directly, use
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).
+
+Also, the server needs to create several files in order to run
+properly. These files are stored in the folowing directories.
+
+`storage' (*note storage::):
+
+ * _Zone files_ - default directory for storing zone files. This can
+ be overriden using absolute zone file location.
-Also, the server needs to create several files in order to run properly.
-Zones and related data are stored in the directory described by
-`storage' (*note storage::).
* _Journal files_ - each zone has a journal file to store
differences for IXFR and dynamic updates. Journal for zone
- `example.com' will be placed in `STORAGE/example.com.diff.db'.
+ `example.com' will be placed in `example.com.diff.db'.
+
+`rundir' (*note rundir::):
- * _PID file_ - is created automatically in `rundir' (*note rundir::)
- when the server is run in background.
+ * _PID file_ - is created automatically when the server is run in
+ background.
- * _Control sockets_ - as a default, UNIX sockets are created in
- `rundir' (*note rundir::), but can be overriden.
+ * _Control sockets_ - as a default, UNIX sockets are created here,
+ but this can be overriden.

File: knot.info, Node: Running a slave server, Next: Running a master server, Up: Running Knot DNS
@@ -1132,12 +1138,6 @@ is in _experimental_ stage and should be used with care. If you
encounter a bug using this feature, please send it to Knot developers
(*note Submitting a bugreport::).
-You can also choose to tear-down the server fully and restart with the
-`knotc restart' action. Note that some actions like start, stop and
-restart cannot be done remotely.
- $ knotc -c master.conf status # check if running
- $ knotc -c master.conf restart # fully restart
-
If you want to force refresh the slave zones, you can do this with the
`knotc refresh' action.
$ knotc -c slave.conf refresh
@@ -1332,6 +1332,7 @@ Statement Index
* notify-retries: notify-retries. (line 6)
* notify-timeout: notify-timeout. (line 6)
* nsid: nsid. (line 6)
+* pidfile: pidfile. (line 6)
* port: port. (line 6)
* rate-limit: rate-limit. (line 6)
* rate-limit-size: rate-limit-size. (line 6)
@@ -1403,6 +1404,7 @@ A.1.1 `system' Syntax
[ `nsid' ( `"'string`"' | hex_string )`;' ]
[ `storage' `"'string`";' ]
[ `rundir' `"'string`";' ]
+ [ `pidfile' `"'string`";' ]
[ `workers' integer`;' ]
[ `user' string[`.'string]`;' ]
[ `max-conn-idle' ( integer | integer(`s' | `m' | `h' | `d')`;' ) ]
@@ -1428,6 +1430,7 @@ A.1.2 Statement Definition and Usage
* nsid::
* storage::
* rundir::
+* pidfile::
* workers::
* user::
* max-conn-idle::
@@ -1507,16 +1510,16 @@ File: knot.info, Node: storage, Next: rundir, Prev: nsid, Up: system Stateme
A.1.2.5 storage
...............
-The working directory of Knot DNS, it is used to store compiled zone
-files and other persistent data. Default: `${sharedstatedir}/knot',
-configured with `--with-storage=path'
+The working directory of Knot DNS, it is used to store zone files and
+journal files. Default: `${localstatedir}/lib/knot', configured with
+`--with-storage=path'
system {
storage "/var/lib/knot";
}

-File: knot.info, Node: rundir, Next: workers, Prev: storage, Up: system Statement Definition and Usage
+File: knot.info, Node: rundir, Next: pidfile, Prev: storage, Up: system Statement Definition and Usage
A.1.2.6 rundir
..............
@@ -1530,9 +1533,23 @@ Default: `${localstatedir}/run/knot', configured with
}

-File: knot.info, Node: workers, Next: user, Prev: rundir, Up: system Statement Definition and Usage
+File: knot.info, Node: pidfile, Next: workers, Prev: rundir, Up: system Statement Definition and Usage
+
+A.1.2.7 pidfile
+...............
+
+Specifies a custom PID file location.
+
+Default value: `knot.pid' in `rundir' directory.
+
+ system {
+ pidfile "/var/run/knot/knot_dmz.pid";
+ }
+
+
+File: knot.info, Node: workers, Next: user, Prev: pidfile, Up: system Statement Definition and Usage
-A.1.2.7 workers
+A.1.2.8 workers
...............
Number of workers (threads) per server interface. This option is used
@@ -1548,7 +1565,7 @@ online CPUs)

File: knot.info, Node: user, Next: max-conn-idle, Prev: workers, Up: system Statement Definition and Usage
-A.1.2.8 user
+A.1.2.9 user
............
System `user' or `user'.`group' under which the Knot DNS is run after
@@ -1565,8 +1582,8 @@ Default value: `root.root'

File: knot.info, Node: max-conn-idle, Next: max-conn-hs, Prev: user, Up: system Statement Definition and Usage
-A.1.2.9 max-conn-idle
-.....................
+A.1.2.10 max-conn-idle
+......................
Maximum idle time between requests on a TCP connection. This also
limits receiving of a single query, each query must be received in this
@@ -1575,7 +1592,7 @@ time limit.

File: knot.info, Node: max-conn-hs, Next: max-conn-reply, Prev: max-conn-idle, Up: system Statement Definition and Usage
-A.1.2.10 max-conn-hs
+A.1.2.11 max-conn-hs
....................
Maximum time between newly accepted TCP connection and first query.
@@ -1585,7 +1602,7 @@ connection that already made at least 1 meaningful query.

File: knot.info, Node: max-conn-reply, Next: transfers, Prev: max-conn-hs, Up: system Statement Definition and Usage
-A.1.2.11 max-conn-reply
+A.1.2.12 max-conn-reply
.......................
Maximum time to wait for a reply to an issued SOA query.
@@ -1593,7 +1610,7 @@ Maximum time to wait for a reply to an issued SOA query.

File: knot.info, Node: transfers, Next: rate-limit, Prev: max-conn-reply, Up: system Statement Definition and Usage
-A.1.2.12 transfers
+A.1.2.13 transfers
..................
Maximum parallel transfers, including pending SOA queries. Lowest
@@ -1602,7 +1619,7 @@ possible number is the number of CPUs. Default is 10.

File: knot.info, Node: rate-limit, Next: rate-limit-size, Prev: transfers, Up: system Statement Definition and Usage
-A.1.2.13 rate-limit
+A.1.2.14 rate-limit
...................
Rate limiting is based on a token bucket scheme, rate basically
@@ -1619,7 +1636,7 @@ Default value: `0 (disabled)'

File: knot.info, Node: rate-limit-size, Next: rate-limit-slip, Prev: rate-limit, Up: system Statement Definition and Usage
-A.1.2.14 rate-limit-size
+A.1.2.15 rate-limit-size
........................
Option controls the size of a hashtable of buckets. The larger the
@@ -1635,7 +1652,7 @@ Default value: `393241'

File: knot.info, Node: rate-limit-slip, Prev: rate-limit-size, Up: system Statement Definition and Usage
-A.1.2.15 rate-limit-slip
+A.1.2.16 rate-limit-slip
........................
As attacks using DNS/UDP are usually based on a forged source address,
@@ -1654,8 +1671,8 @@ A.1.3 system Example
--------------------
system {
- identity "Knot DNS 1.3.0-rc3";
- version "1.3.0-rc3";
+ identity "Knot DNS 1.3.0-rc4";
+ version "1.3.0-rc4";
nsid "amaterasu";
storage "/var/lib/knot";
rundir "/var/run/knot";
@@ -2576,130 +2593,131 @@ A.9.2 Examples

Tag Table:
-Node: Top1060
-Node: Introduction4057
-Node: What is Knot DNS4355
-Node: Knot DNS features4873
-Node: Scope of this document5894
-Node: Knot DNS Resource Requirements6156
-Node: Hardware requirements6454
-Node: CPU requirements7094
-Node: Memory requirements7479
-Node: Supported operating system8195
-Node: Knot DNS Installation8663
-Node: Required build environment8970
-Node: Required libraries9594
-Node: Userspace RCU10399
-Node: Installation from the sources11351
-Node: Configuring and generating Makefiles11936
-Node: Compilation13594
-Node: Installation14170
-Node: Installation from packages14677
-Node: Installing Knot DNS packages on Debian15201
-Node: Installing Knot DNS packages on Ubuntu16179
-Node: Adding official PPA repository for Knot DNS17093
-Node: Installing Knot DNS packages on Fedora17721
-Node: Installing Knot DNS from ports on FreeBSD19120
-Node: Knot DNS Configuration19467
-Node: Minimal configuration20038
-Node: Slave configuration22099
-Node: Master configuration24095
-Node: Configuring multiple interfaces25141
-Node: Using DNS UPDATE25626
-Node: Remote control interface27193
-Node: Enabling zone semantic checks28285
-Node: Creating IXFR differences from zone file changes28752
-Node: Using Response Rate Limiting29325
-Node: Running Knot DNS30826
-Node: Running a slave server34527
-Node: Running a master server35823
-Node: Controlling running daemon36804
-Node: Troubleshooting38255
-Node: Submitting a bugreport38663
-Node: Generating backtrace39833
-Node: Debug messages40835
-Node: Enabling debug messages in server41505
-Node: Debug messages Example43065
-Node: Statement Index43264
-Node: Knot DNS Configuration Reference47014
-Node: system47380
-Node: system Syntax47741
-Node: system Statement Definition and Usage48585
-Node: identity49006
-Node: version49416
-Node: hostname49850
-Node: nsid50288
-Node: storage50608
-Node: rundir50979
-Node: workers51320
-Node: user51704
-Node: max-conn-idle52138
-Node: max-conn-hs52453
-Node: max-conn-reply52814
-Node: transfers53045
-Node: rate-limit53330
-Node: rate-limit-size54072
-Node: rate-limit-slip54743
-Node: system Example55327
-Node: keys55692
-Node: keys Syntax55999
-Node: keys Statement Definition and Usage56228
-Node: key_id56434
-Node: Example57396
-Node: interfaces57630
-Node: interfaces Syntax57965
-Node: interfaces Statement Definition and Usage58303
-Node: interface_id58545
-Node: interfaces Examples58909
-Node: remotes59388
-Node: remotes Syntax59987
-Node: remotes Statement Definition and Grammar60426
-Node: remote_id60696
-Node: address60896
-Node: port61115
-Node: key61369
-Node: via61584
-Node: remotes Examples61814
-Node: groups62340
-Node: groups Syntax63030
-Node: groups Statement Definition and Grammar63248
-Node: group_id63506
-Node: groups_remote_id63713
-Node: groups Examples63960
-Node: control64366
-Node: control Syntax64903
-Node: control Statement Definition and Grammar65271
-Node: control Examples65854
-Node: zones66336
-Node: zones Syntax66680
-Node: zones Statement Definition and Grammar67640
-Node: zone_id68072
-Node: file68460
-Node: xfr-in68804
-Node: xfr-out69143
-Node: notify-in69488
-Node: notify-out69736
-Node: update-in69991
-Node: semantic-checks70334
-Node: ixfr-from-differences70753
-Node: disable-any71310
-Node: notify-timeout71697
-Node: notify-retries72042
-Node: zonefile-sync72361
-Node: ixfr-fslimit73071
-Node: zones Example73477
-Node: zones List of zone semantic checks74299
-Node: log76099
-Node: log Syntax76322
-Node: log Statement Definition and Grammar76646
-Node: log_name77356
-Node: category77685
-Node: severity78152
-Node: log_file78894
-Node: log Example79149
-Node: include79532
-Node: include Syntax80001
-Node: include Examples80139
+Node: Top1039
+Node: Introduction4047
+Node: What is Knot DNS4345
+Node: Knot DNS features4863
+Node: Scope of this document5884
+Node: Knot DNS Resource Requirements6146
+Node: Hardware requirements6444
+Node: CPU requirements7084
+Node: Memory requirements7469
+Node: Supported operating system8185
+Node: Knot DNS Installation8653
+Node: Required build environment8960
+Node: Required libraries9584
+Node: Userspace RCU10389
+Node: Installation from the sources11341
+Node: Configuring and generating Makefiles11926
+Node: Compilation13584
+Node: Installation14160
+Node: Installation from packages14667
+Node: Installing Knot DNS packages on Debian15191
+Node: Installing Knot DNS packages on Ubuntu16169
+Node: Adding official PPA repository for Knot DNS17083
+Node: Installing Knot DNS packages on Fedora17711
+Node: Installing Knot DNS from ports on FreeBSD19110
+Node: Knot DNS Configuration19457
+Node: Minimal configuration20028
+Node: Slave configuration22041
+Node: Master configuration24037
+Node: Configuring multiple interfaces25083
+Node: Using DNS UPDATE25568
+Node: Remote control interface27135
+Node: Enabling zone semantic checks28227
+Node: Creating IXFR differences from zone file changes28694
+Node: Using Response Rate Limiting29267
+Node: Running Knot DNS30768
+Node: Running a slave server34499
+Node: Running a master server35795
+Node: Controlling running daemon36776
+Node: Troubleshooting37947
+Node: Submitting a bugreport38355
+Node: Generating backtrace39525
+Node: Debug messages40527
+Node: Enabling debug messages in server41197
+Node: Debug messages Example42757
+Node: Statement Index42956
+Node: Knot DNS Configuration Reference46779
+Node: system47145
+Node: system Syntax47506
+Node: system Statement Definition and Usage48385
+Node: identity48818
+Node: version49228
+Node: hostname49662
+Node: nsid50100
+Node: storage50420
+Node: rundir50777
+Node: pidfile51118
+Node: workers51417
+Node: user51802
+Node: max-conn-idle52236
+Node: max-conn-hs52553
+Node: max-conn-reply52914
+Node: transfers53145
+Node: rate-limit53430
+Node: rate-limit-size54172
+Node: rate-limit-slip54843
+Node: system Example55427
+Node: keys55792
+Node: keys Syntax56099
+Node: keys Statement Definition and Usage56328
+Node: key_id56534
+Node: Example57496
+Node: interfaces57730
+Node: interfaces Syntax58065
+Node: interfaces Statement Definition and Usage58403
+Node: interface_id58645
+Node: interfaces Examples59009
+Node: remotes59488
+Node: remotes Syntax60087
+Node: remotes Statement Definition and Grammar60526
+Node: remote_id60796
+Node: address60996
+Node: port61215
+Node: key61469
+Node: via61684
+Node: remotes Examples61914
+Node: groups62440
+Node: groups Syntax63130
+Node: groups Statement Definition and Grammar63348
+Node: group_id63606
+Node: groups_remote_id63813
+Node: groups Examples64060
+Node: control64466
+Node: control Syntax65003
+Node: control Statement Definition and Grammar65371
+Node: control Examples65954
+Node: zones66436
+Node: zones Syntax66780
+Node: zones Statement Definition and Grammar67740
+Node: zone_id68172
+Node: file68560
+Node: xfr-in68904
+Node: xfr-out69243
+Node: notify-in69588
+Node: notify-out69836
+Node: update-in70091
+Node: semantic-checks70434
+Node: ixfr-from-differences70853
+Node: disable-any71410
+Node: notify-timeout71797
+Node: notify-retries72142
+Node: zonefile-sync72461
+Node: ixfr-fslimit73171
+Node: zones Example73577
+Node: zones List of zone semantic checks74399
+Node: log76199
+Node: log Syntax76422
+Node: log Statement Definition and Grammar76746
+Node: log_name77456
+Node: category77785
+Node: severity78252
+Node: log_file78994
+Node: log Example79249
+Node: include79632
+Node: include Syntax80101
+Node: include Examples80239

End Tag Table
diff --git a/doc/knot.texi b/doc/knot.texi
index f4eaa56..4398432 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 57324b7..7344956 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 aa5b93c..cfa8810 100644
--- a/doc/running.texi
+++ b/doc/running.texi
@@ -25,7 +25,7 @@ Use knotc tool for convenience when working with the server daemon.
As of Knot DNS 1.3.0, the zones are not compiled anymore. That makes working
with the server much more user friendly.
@example
-$ knotc -c knot.conf reload|restart
+$ knotc -c knot.conf reload
@end example
The tool @code{knotc} is designed as a front-end for user, making it easier
@@ -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').
@@ -47,15 +48,13 @@ Parameters:
-v, --verbose Verbose mode - additional runtime
information.
-V, --version Print knot server version.
- -w, --wait Wait for the server to finish start/stop
+ -w, --wait Wait for the server to finish stop
operations.
-i, --interactive Interactive mode (do not daemonize).
-h, --help Print help and usage.
Actions:
- start Start server (if not running).
stop Stop server.
- restart Restart server.
reload Reload configuration and changed zones.
refresh [zone] Refresh slave zone (all if not specified).
flush Flush journal and update zone files.
@@ -63,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
@@ -152,13 +161,6 @@ If @emph{SOA}'s @emph{serial} is not changed no differences will be created. Ple
that this feature is in @emph{experimental} stage and should be used with care.
If you encounter a bug using this feature, please send it to Knot developers (@pxref{Submitting a bugreport}).
-You can also choose to tear-down the server fully and restart with the @code{knotc restart} action.
-Note that some actions like start, stop and restart cannot be done remotely.
-@example
-$ knotc -c master.conf status # check if running
-$ knotc -c master.conf restart # fully restart
-@end example
-
If you want to force refresh the slave zones, you can do this with the @code{knotc refresh} action.
@example
$ knotc -c slave.conf refresh
diff --git a/doc/stamp-vti b/doc/stamp-vti
index b53f702..b309676 100644
--- a/doc/stamp-vti
+++ b/doc/stamp-vti
@@ -1,4 +1,4 @@
-@set UPDATED 26 June 2013
-@set UPDATED-MONTH June 2013
-@set EDITION 1.3.0-rc3
-@set VERSION 1.3.0-rc3
+@set UPDATED 9 July 2013
+@set UPDATED-MONTH July 2013
+@set EDITION 1.3.0-rc4
+@set VERSION 1.3.0-rc4
diff --git a/doc/version.texi b/doc/version.texi
index b53f702..b309676 100644
--- a/doc/version.texi
+++ b/doc/version.texi
@@ -1,4 +1,4 @@
-@set UPDATED 26 June 2013
-@set UPDATED-MONTH June 2013
-@set EDITION 1.3.0-rc3
-@set VERSION 1.3.0-rc3
+@set UPDATED 9 July 2013
+@set UPDATED-MONTH July 2013
+@set EDITION 1.3.0-rc4
+@set VERSION 1.3.0-rc4
diff --git a/man/Makefile.in b/man/Makefile.in
index 3c98806..67abfaa 100644
--- a/man/Makefile.in
+++ b/man/Makefile.in
@@ -185,6 +185,7 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
RAGEL = @RAGEL@
RANLIB = @RANLIB@
+RELEASE_DATE = @RELEASE_DATE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -212,6 +213,7 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+config_dir = @config_dir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
diff --git a/man/kdig.1 b/man/kdig.1
index de740cf..53b0779 100644
--- a/man/kdig.1
+++ b/man/kdig.1
@@ -1,176 +1,202 @@
-.TH "kdig" "1" "April 2013" "CZ.NIC Labs" "Knot DNS, version 1.3.0-rc3"
+.TH "kdig" "1" "15 July 2013" "CZ.NIC Labs" "Knot DNS, version 1.3.0-rc4"
.SH NAME
+.TP 5
.B kdig
\- Advanced DNS lookup utility (libknot equivalent of ISC dig)
.SH SYNOPSIS
.B kdig
-[\fIcommon-settings\fR] [\fIquery\fR [\fIsettings\fR]]...
+[\fIcommon\-settings\fR] [\fIquery\fR [\fIsettings\fR]]...
.TP 5
-.B kdig
-\fB-h\fR
+.B kdig \-h
.SH DESCRIPTION
This utility sends one or more DNS \fIqueries\fR to a nameserver. Each query can
-have individual \fIsettings\fR, or it can be specified globally via \fIcommon-settings\fR,
+have individual \fIsettings\fR, or it can be specified globally via \fIcommon\-settings\fR,
which must precede \fIquery\fR specification.
.TP 4
-\fIquery
-\fIname\fR | \fB-q\fR \fIname\fR | \fB-x\fR \fIaddress\fR
+.I query
+\fIname\fR | \fB\-q\fR \fIname\fR | \fB\-x\fR \fIaddress\fR
.TP
-\fIcommon-settings, settings
+.I common\-settings, settings
[\fIclass\fR] [\fItype\fR] [\fB@\fIserver\fR]... [\fIoptions\fR]
.TP
-\fIname\fR
+.I name
Is a domain name that is to be looked up.
.TP
-\fIserver\fR
-Is a name or an address of the nameserver to send a query to. The address
-can be specified using [address]:port notation. If no server is specified
+.I server
+Is a domain name or an IPv4 or IPv6 address of the nameserver to send a query to.
+The address can be specified using [address]:port notation. If no server is specified,
the servers from \fB/etc/resolv.conf\fR are used.
.TP
-If no arguments are provided, \fBkdig\fR sends \fINS\fR query for root zone.
+If no arguments are provided, \fBkdig\fR sends \fINS\fR query for the root zone.
.SH OPTIONS
.TP 4
-.BI -4
+.B \-4
Use IPv4 protocol only.
.TP
-.BI -6
+.B \-6
Use IPv6 protocol only.
.TP
-.BI -b \ address
+.BI \-b \ address
Set the source IP address of the query to \fIaddress\fR. The address
-can be specified using [address]:port notation.
+must be a valid address for local interface or :: or 0.0.0.0.
+Optional port can be specified using [address]:port notation.
.TP
-.BI -c \ class
-Set query class (e.g. \fICH\fR, \fICLASS4\fR).
-An explicit variant of \fIclass\fR specification.
-The default class is \fIIN\fR.
+.BI \-c \ class
+Set query class (e.g. \fICH\fR, \fICLASS4\fR). An explicit variant of
+\fIclass\fR specification. The default class is \fIIN\fR.
.TP
-.BI -d
+.B \-d
Enable debug messages if any.
.TP
-\fB\-h\fR, \fB\-\-help\fR
+.BR \-h ,\ \-\-help
Print short help.
.TP
-.BI -k \ keyfile
+.BI \-k \ keyfile
Use TSIG or SIG\-0 key stored in a file \fIkeyfile\fR to authenticate the request.
Supported file format is the same as generated by ISC \fBdnssec\-keygen\fR.
The key comprises of public (.key extension) and private part (.private extension).
Either of these file names or a name without the extension can be specified as \fIkeyfile\fR
parameter.
.TP
-.BI -p \ port
+.BI \-p \ port
Set nameserver port number or service name to send a query to.
The default port is \fI53\fR.
.TP
-.BI -q \ name
+.BI \-q \ name
Set query name. An explicit variant of \fIname\fR specification.
.TP
-.BI -t \ type
+.BI \-t \ type
Set query type (e.g. \fINS\fR, \fIIXFR=12345\fR, \fITYPE65535\fR).
An explicit variant of \fItype\fR specification. The default type is \fIA\fR.
.TP
-\fB\-v\fR, \fB\-\-version\fR
+.BR \-v ,\ \-\-version
Print program version.
.TP
-.BI -x \ address
-Send \fIPTR\fR query for IPv4 or IPv6 \fIaddress\fR.
+.BI \-x \ address
+Send reverse (\fIPTR\fR) query for IPv4 or IPv6 \fIaddress\fR. Correct name,
+class and type is set automatically.
.TP
-.BI -y \ \fR[\fIalgo:\fR]\fIkeyname:key\fR
+.B \-y \fR[\fIalgo:\fR]\fIkeyname:key\fR
Use TSIG key with a name \fIkeyname\fR to authenticate the request. The \fIalgo\fR
part specifies the algorithm (the default is hmac\-md5) and \fIkey\fR specifies
the shared secret encoded in Base64.
.TP
-\fB+\fR[\fBno\fR]\fBmultiline\fR
-Wrap long records to more lines.
+.BR + [ no ] multiline
+Wrap long records to more lines and improve human readability.
.TP
-\fB+\fR[\fBno\fR]\fBshort\fR
+.BR + [ no ] short
Show record data only.
.TP
-\fB+\fR[\fBno\fR]\fBaaflag\fR
+.BR + [ no ] aaflag
Set AA flag.
.TP
-\fB+\fR[\fBno\fR]\fBtcflag\fR
+.BR + [ no ] tcflag
Set TC flag.
.TP
-\fB+\fR[\fBno\fR]\fBrdflag\fR
+.BR + [ no ] rdflag
Set RD flag.
.TP
-\fB+\fR[\fBno\fR]\fBrecurse\fR
-Same as +\fR[\fBno\fR]\fBrdflag\fR
+.BR + [ no ] recurse
+.RB "Same as " + [ no ] rdflag
.TP
-\fB+\fR[\fBno\fR]\fBrec\fR
-Same as +\fR[\fBno\fR]\fBrdflag\fR
+.BR + [ no ] rec
+.RB "Same as " + [ no ] rdflag
.TP
-\fB+\fR[\fBno\fR]\fBraflag\fR
+.BR + [ no ] raflag
Set RA flag.
.TP
-\fB+\fR[\fBno\fR]\fBzflag\fR
+.BR + [ no ] zflag
Set zero flag bit.
.TP
-\fB+\fR[\fBno\fR]\fBadflag\fR
+.BR + [ no ] adflag
Set AD flag.
.TP
-\fB+\fR[\fBno\fR]\fBcdflag\fR
+.BR + [ no ] cdflag
Set CD flag.
.TP
-\fB+\fR[\fBno\fR]\fBdnssec\fR
+.BR + [ no ] dnssec
Set DO flag.
.TP
-\fB+\fR[\fBno\fR]\fBall\fR
+.BR + [ no ] all
Show all packet sections.
.TP
-\fB+\fR[\fBno\fR]\fBqr\fR
+.BR + [ no ] qr
Show query packet.
.TP
-\fB+\fR[\fBno\fR]\fBheader\fR
+.BR + [ no ] header
Show packet header.
.TP
-\fB+\fR[\fBno\fR]\fBedns\fR
-Show EDNS pseudosectio.
+.BR + [ no ] edns
+Show EDNS pseudosection.
.TP
-\fB+\fR[\fBno\fR]\fBquestion\fR
+.BR + [ no ] question
Show question section.
.TP
-\fB+\fR[\fBno\fR]\fBanswer\fR
+.BR + [ no ] answer
Show answer section.
.TP
-\fB+\fR[\fBno\fR]\fBauthority\fR
+.BR + [ no ] authority
Show authority section.
.TP
-\fB+\fR[\fBno\fR]\fBadditional\fR
+.BR + [ no ] additional
Show additional section.
.TP
-\fB+\fR[\fBno\fR]\fBstats\fR
+.BR + [ no ] stats
Show trailing packet statistics.
.TP
-\fB+\fR[\fBno\fR]\fBcl\fR
+.BR + [ no ] cl
Show DNS class.
.TP
-\fB+\fR[\fBno\fR]\fBttl\fR
+.BR + [ no ] ttl
Show TTL value.
.TP
-\fB+time=\fIT\fR
+.BI +time= T
Set wait for reply interval in seconds (default is 5 seconds).
+This timeout applies to each query try.
.TP
-\fB+retries=\fIN\fR
-Set number of retries (default is 2). This doesn't apply to AXFR or IXFR.
+.BI +retry= N
+Set number (>=0) of UDP retries (default is 2). This doesn't apply to AXFR/IXFR.
.TP
-\fB+bufsize=\fIB\fR
+.BI +bufsize= B
Set EDNS buffer size in bytes (default is 512 bytes).
.TP
-\fB+\fR[\fBno\fR]\fBtcp\fR
-Use TCP protocol.
+.BR + [ no ] tcp
+Use TCP protocol (default is UDP for standard query and TCP for AXFR/IXFR).
.TP
-\fB+\fR[\fBno\fR]\fBfail\fR
-Stop if SERVFAIL.
+.BR + [ no ] fail
+Stop quering next nameserver if SERVFAIL response is received.
.TP
-\fB+\fR[\fBno\fR]\fBignore\fR
+.BR + [ no ] ignore
Don't use TCP automatically if truncated reply is received.
.TP
-\fB+\fR[\fBno\fR]\fBnsid\fR
+.BR + [ no ] nsid
Request nameserver identifier (NSID).
.SH NOTE
-Options \fB-k\fR and \fB-y\fR cannot be used mutually.
+Options \fB\-k\fR and \fB\-y\fR cannot be used mutually.
+.SS Missing features with regard to ISC dig
+Options \fB\-f\fR and \fB\-m\fR and query options:
+.br
+.BR +split=\fIW\fR ,\ +tries=\fIT\fR ,\ +ndots=\fID\fR ,
+.br
+.BR +domain=\fIsomename\fR , +trusted\-key=\fI####\fR ,
+.br
+.BR + [ no ] vc ,\ + [ no ] search ,\ + [ no ] showsearch ,
+.br
+.BR + [ no ] defname ,\ + [ no ] aaonly ,\ + [ no ] cmd ,
+.br
+.BR + [ no ] identify ,\ + [ no ] comments ,\ + [ no ] rrcomments ,
+.br
+.BR + [ no ] onesoa ,\ + [ no ] besteffort ,\ + [ no ] sigchase ,
+.br
+.BR + [ no ] topdown ,\ + [ no ] nssearch ,\ + [ no ] trace.
+.TP
+Per-user file configuration via ${HOME}/.digrc.
+.SS Differences with regard to ISC dig
+Optional port specification has a form of [address]:port instead of address#port.
+.TP
+.BR + [ no ] ttl " instead of " + [ no ] ttlid
+.TP
+Trailing information is formatted slightly different.
.SH EXAMPLES
.B Example 1. Get A record for example.com:
.TP
@@ -178,18 +204,18 @@ Options \fB-k\fR and \fB-y\fR cannot be used mutually.
.TP
.B Example 2. Perform AXFR for zone example.com from the server 192.0.2.1:
.TP
-# kdig example.com -t AXFR @192.0.2.1
-.TP 12
+# kdig example.com \-t AXFR @192.0.2.1
+.TP
.B Example 3. Send one A query for example.com from 192.0.2.1 and one reverse \
lookup for address 2001:DB8::1 from 192.0.2.2. Both using TCP protocol:
.TP
-# kdig +tcp example.com -t A @192.0.2.1 -x 2001:DB8::1 @192.0.2.2
+# kdig +tcp example.com \-t A @192.0.2.1 \-x 2001:DB8::1 @192.0.2.2
.SH FILES
-.BI /etc/resolv.conf
+.I /etc/resolv.conf
.SH AUTHOR
-Daniel Salzman (\fBhttp://knot-dns.cz\fR)
+Daniel Salzman (\fBwww.knot\-dns.cz\fR)
.TP
-Please send any bugs or comments to \fBknot-dns@labs.nic.cz\fR
+Please send any bug reports or comments to \fBknot\-dns@labs.nic.cz\fR
.SH SEE ALSO
-.BI khost\fR(8),
-.BI knsupdate\fR(8).
+.BR khost (1),
+.BR knsupdate (1).
diff --git a/man/kdig.1.in b/man/kdig.1.in
index 473bf69..4679abf 100644
--- a/man/kdig.1.in
+++ b/man/kdig.1.in
@@ -1,176 +1,202 @@
-.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
\- Advanced DNS lookup utility (libknot equivalent of ISC dig)
.SH SYNOPSIS
.B kdig
-[\fIcommon-settings\fR] [\fIquery\fR [\fIsettings\fR]]...
+[\fIcommon\-settings\fR] [\fIquery\fR [\fIsettings\fR]]...
.TP 5
-.B kdig
-\fB-h\fR
+.B kdig \-h
.SH DESCRIPTION
This utility sends one or more DNS \fIqueries\fR to a nameserver. Each query can
-have individual \fIsettings\fR, or it can be specified globally via \fIcommon-settings\fR,
+have individual \fIsettings\fR, or it can be specified globally via \fIcommon\-settings\fR,
which must precede \fIquery\fR specification.
.TP 4
-\fIquery
-\fIname\fR | \fB-q\fR \fIname\fR | \fB-x\fR \fIaddress\fR
+.I query
+\fIname\fR | \fB\-q\fR \fIname\fR | \fB\-x\fR \fIaddress\fR
.TP
-\fIcommon-settings, settings
+.I common\-settings, settings
[\fIclass\fR] [\fItype\fR] [\fB@\fIserver\fR]... [\fIoptions\fR]
.TP
-\fIname\fR
+.I name
Is a domain name that is to be looked up.
.TP
-\fIserver\fR
-Is a name or an address of the nameserver to send a query to. The address
-can be specified using [address]:port notation. If no server is specified
+.I server
+Is a domain name or an IPv4 or IPv6 address of the nameserver to send a query to.
+The address can be specified using [address]:port notation. If no server is specified,
the servers from \fB/etc/resolv.conf\fR are used.
.TP
-If no arguments are provided, \fBkdig\fR sends \fINS\fR query for root zone.
+If no arguments are provided, \fBkdig\fR sends \fINS\fR query for the root zone.
.SH OPTIONS
.TP 4
-.BI -4
+.B \-4
Use IPv4 protocol only.
.TP
-.BI -6
+.B \-6
Use IPv6 protocol only.
.TP
-.BI -b \ address
+.BI \-b \ address
Set the source IP address of the query to \fIaddress\fR. The address
-can be specified using [address]:port notation.
+must be a valid address for local interface or :: or 0.0.0.0.
+Optional port can be specified using [address]:port notation.
.TP
-.BI -c \ class
-Set query class (e.g. \fICH\fR, \fICLASS4\fR).
-An explicit variant of \fIclass\fR specification.
-The default class is \fIIN\fR.
+.BI \-c \ class
+Set query class (e.g. \fICH\fR, \fICLASS4\fR). An explicit variant of
+\fIclass\fR specification. The default class is \fIIN\fR.
.TP
-.BI -d
+.B \-d
Enable debug messages if any.
.TP
-\fB\-h\fR, \fB\-\-help\fR
+.BR \-h ,\ \-\-help
Print short help.
.TP
-.BI -k \ keyfile
+.BI \-k \ keyfile
Use TSIG or SIG\-0 key stored in a file \fIkeyfile\fR to authenticate the request.
Supported file format is the same as generated by ISC \fBdnssec\-keygen\fR.
The key comprises of public (.key extension) and private part (.private extension).
Either of these file names or a name without the extension can be specified as \fIkeyfile\fR
parameter.
.TP
-.BI -p \ port
+.BI \-p \ port
Set nameserver port number or service name to send a query to.
The default port is \fI53\fR.
.TP
-.BI -q \ name
+.BI \-q \ name
Set query name. An explicit variant of \fIname\fR specification.
.TP
-.BI -t \ type
+.BI \-t \ type
Set query type (e.g. \fINS\fR, \fIIXFR=12345\fR, \fITYPE65535\fR).
An explicit variant of \fItype\fR specification. The default type is \fIA\fR.
.TP
-\fB\-v\fR, \fB\-\-version\fR
+.BR \-v ,\ \-\-version
Print program version.
.TP
-.BI -x \ address
-Send \fIPTR\fR query for IPv4 or IPv6 \fIaddress\fR.
+.BI \-x \ address
+Send reverse (\fIPTR\fR) query for IPv4 or IPv6 \fIaddress\fR. Correct name,
+class and type is set automatically.
.TP
-.BI -y \ \fR[\fIalgo:\fR]\fIkeyname:key\fR
+.B \-y \fR[\fIalgo:\fR]\fIkeyname:key\fR
Use TSIG key with a name \fIkeyname\fR to authenticate the request. The \fIalgo\fR
part specifies the algorithm (the default is hmac\-md5) and \fIkey\fR specifies
the shared secret encoded in Base64.
.TP
-\fB+\fR[\fBno\fR]\fBmultiline\fR
-Wrap long records to more lines.
+.BR + [ no ] multiline
+Wrap long records to more lines and improve human readability.
.TP
-\fB+\fR[\fBno\fR]\fBshort\fR
+.BR + [ no ] short
Show record data only.
.TP
-\fB+\fR[\fBno\fR]\fBaaflag\fR
+.BR + [ no ] aaflag
Set AA flag.
.TP
-\fB+\fR[\fBno\fR]\fBtcflag\fR
+.BR + [ no ] tcflag
Set TC flag.
.TP
-\fB+\fR[\fBno\fR]\fBrdflag\fR
+.BR + [ no ] rdflag
Set RD flag.
.TP
-\fB+\fR[\fBno\fR]\fBrecurse\fR
-Same as +\fR[\fBno\fR]\fBrdflag\fR
+.BR + [ no ] recurse
+.RB "Same as " + [ no ] rdflag
.TP
-\fB+\fR[\fBno\fR]\fBrec\fR
-Same as +\fR[\fBno\fR]\fBrdflag\fR
+.BR + [ no ] rec
+.RB "Same as " + [ no ] rdflag
.TP
-\fB+\fR[\fBno\fR]\fBraflag\fR
+.BR + [ no ] raflag
Set RA flag.
.TP
-\fB+\fR[\fBno\fR]\fBzflag\fR
+.BR + [ no ] zflag
Set zero flag bit.
.TP
-\fB+\fR[\fBno\fR]\fBadflag\fR
+.BR + [ no ] adflag
Set AD flag.
.TP
-\fB+\fR[\fBno\fR]\fBcdflag\fR
+.BR + [ no ] cdflag
Set CD flag.
.TP
-\fB+\fR[\fBno\fR]\fBdnssec\fR
+.BR + [ no ] dnssec
Set DO flag.
.TP
-\fB+\fR[\fBno\fR]\fBall\fR
+.BR + [ no ] all
Show all packet sections.
.TP
-\fB+\fR[\fBno\fR]\fBqr\fR
+.BR + [ no ] qr
Show query packet.
.TP
-\fB+\fR[\fBno\fR]\fBheader\fR
+.BR + [ no ] header
Show packet header.
.TP
-\fB+\fR[\fBno\fR]\fBedns\fR
-Show EDNS pseudosectio.
+.BR + [ no ] edns
+Show EDNS pseudosection.
.TP
-\fB+\fR[\fBno\fR]\fBquestion\fR
+.BR + [ no ] question
Show question section.
.TP
-\fB+\fR[\fBno\fR]\fBanswer\fR
+.BR + [ no ] answer
Show answer section.
.TP
-\fB+\fR[\fBno\fR]\fBauthority\fR
+.BR + [ no ] authority
Show authority section.
.TP
-\fB+\fR[\fBno\fR]\fBadditional\fR
+.BR + [ no ] additional
Show additional section.
.TP
-\fB+\fR[\fBno\fR]\fBstats\fR
+.BR + [ no ] stats
Show trailing packet statistics.
.TP
-\fB+\fR[\fBno\fR]\fBcl\fR
+.BR + [ no ] cl
Show DNS class.
.TP
-\fB+\fR[\fBno\fR]\fBttl\fR
+.BR + [ no ] ttl
Show TTL value.
.TP
-\fB+time=\fIT\fR
+.BI +time= T
Set wait for reply interval in seconds (default is 5 seconds).
+This timeout applies to each query try.
.TP
-\fB+retries=\fIN\fR
-Set number of retries (default is 2). This doesn't apply to AXFR or IXFR.
+.BI +retry= N
+Set number (>=0) of UDP retries (default is 2). This doesn't apply to AXFR/IXFR.
.TP
-\fB+bufsize=\fIB\fR
+.BI +bufsize= B
Set EDNS buffer size in bytes (default is 512 bytes).
.TP
-\fB+\fR[\fBno\fR]\fBtcp\fR
-Use TCP protocol.
+.BR + [ no ] tcp
+Use TCP protocol (default is UDP for standard query and TCP for AXFR/IXFR).
.TP
-\fB+\fR[\fBno\fR]\fBfail\fR
-Stop if SERVFAIL.
+.BR + [ no ] fail
+Stop quering next nameserver if SERVFAIL response is received.
.TP
-\fB+\fR[\fBno\fR]\fBignore\fR
+.BR + [ no ] ignore
Don't use TCP automatically if truncated reply is received.
.TP
-\fB+\fR[\fBno\fR]\fBnsid\fR
+.BR + [ no ] nsid
Request nameserver identifier (NSID).
.SH NOTE
-Options \fB-k\fR and \fB-y\fR cannot be used mutually.
+Options \fB\-k\fR and \fB\-y\fR cannot be used mutually.
+.SS Missing features with regard to ISC dig
+Options \fB\-f\fR and \fB\-m\fR and query options:
+.br
+.BR +split=\fIW\fR ,\ +tries=\fIT\fR ,\ +ndots=\fID\fR ,
+.br
+.BR +domain=\fIsomename\fR , +trusted\-key=\fI####\fR ,
+.br
+.BR + [ no ] vc ,\ + [ no ] search ,\ + [ no ] showsearch ,
+.br
+.BR + [ no ] defname ,\ + [ no ] aaonly ,\ + [ no ] cmd ,
+.br
+.BR + [ no ] identify ,\ + [ no ] comments ,\ + [ no ] rrcomments ,
+.br
+.BR + [ no ] onesoa ,\ + [ no ] besteffort ,\ + [ no ] sigchase ,
+.br
+.BR + [ no ] topdown ,\ + [ no ] nssearch ,\ + [ no ] trace.
+.TP
+Per-user file configuration via ${HOME}/.digrc.
+.SS Differences with regard to ISC dig
+Optional port specification has a form of [address]:port instead of address#port.
+.TP
+.BR + [ no ] ttl " instead of " + [ no ] ttlid
+.TP
+Trailing information is formatted slightly different.
.SH EXAMPLES
.B Example 1. Get A record for example.com:
.TP
@@ -178,18 +204,18 @@ Options \fB-k\fR and \fB-y\fR cannot be used mutually.
.TP
.B Example 2. Perform AXFR for zone example.com from the server 192.0.2.1:
.TP
-# kdig example.com -t AXFR @192.0.2.1
-.TP 12
+# kdig example.com \-t AXFR @192.0.2.1
+.TP
.B Example 3. Send one A query for example.com from 192.0.2.1 and one reverse \
lookup for address 2001:DB8::1 from 192.0.2.2. Both using TCP protocol:
.TP
-# kdig +tcp example.com -t A @192.0.2.1 -x 2001:DB8::1 @192.0.2.2
+# kdig +tcp example.com \-t A @192.0.2.1 \-x 2001:DB8::1 @192.0.2.2
.SH FILES
-.BI /etc/resolv.conf
+.I /etc/resolv.conf
.SH AUTHOR
-Daniel Salzman (\fBhttp://knot-dns.cz\fR)
+Daniel Salzman (\fBwww.knot\-dns.cz\fR)
.TP
-Please send any bugs or comments to \fBknot-dns@labs.nic.cz\fR
+Please send any bug reports or comments to \fBknot\-dns@labs.nic.cz\fR
.SH SEE ALSO
-.BI khost\fR(8),
-.BI knsupdate\fR(8).
+.BR khost (1),
+.BR knsupdate (1).
diff --git a/man/khost.1 b/man/khost.1
index f68519a..9d4a2c4 100644
--- a/man/khost.1
+++ b/man/khost.1
@@ -1,5 +1,6 @@
-.TH "khost" "1" "April 2013" "CZ.NIC Labs" "Knot DNS, version 1.3.0-rc3"
+.TH "khost" "1" "15 July 2013" "CZ.NIC Labs" "Knot DNS, version 1.3.0-rc4"
.SH NAME
+.TP 6
.B khost
\- Simple DNS lookup utility (libknot equivalent of ISC host)
.SH SYNOPSIS
@@ -7,13 +8,13 @@
[\fIoptions\fR] \fIname\fR [\fIserver\fR]
.SH DESCRIPTION
This utility sends a DNS query for the \fIname\fR to the \fIserver\fR and prints
-a reply in more user-readable form. For more advanced DNS queries use \fBkdig\fR instead.
+a reply in more user\-readable form. For more advanced DNS queries use \fBkdig\fR instead.
.TP 4
-\fI name\fR
+.I name
Is a domain name that is to be looked up.
If the \fIname\fR is IPv4 or IPv6 address the \fIPTR\fR query type is used.
.TP
-\fI server\fR
+.I server
Is a name or an address of the nameserver to send a query to. The address
can be specified using [address]:port notation. If no server is specified
the servers from \fB/etc/resolv.conf\fR are used.
@@ -21,51 +22,61 @@ the servers from \fB/etc/resolv.conf\fR are used.
If no arguments are provided, \fBkhost\fR prints short help.
.SH OPTIONS
.TP 4
-.BI -4
+.B \-4
Use IPv4 protocol only.
.TP
-.BI -6
+.B \-6
Use IPv6 protocol only.
.TP
-.BI -a
+.B \-a
Send ANY query with verbose mode.
.TP
-.BI -d
+.B \-d
Enable debug messages if any.
.TP
-\fB\-h\fR, \fB\-\-help\fR
+.BR \-h ,\ \-\-help
Print help.
.TP
-.BI -r
+.B \-r
Disable recursion.
.TP
-.BI -s
+.B \-s
Stop quering next nameserver if SERVFAIL response is received.
.TP
-.BI -T
+.B \-T
Use TCP protocol.
.TP
-.BI -v
+.B \-v
Enable verbose output.
.TP
-\fB\-V\fR, \fB\-\-version\fR
+.BR \-V ,\ \-\-version
Print program version.
.TP
-.BI -w
+.B \-w
Wait forever for the reply.
.TP
-.BI -c \ class
+.BI \-c \ class
Set query class (e.g. \fICH\fR, \fICLASS4\fR). The default class is \fIIN\fR.
.TP
-.BI -t \ type
+.BI \-t \ type
Set query type (e.g. \fINS\fR, \fIIXFR=12345\fR, \fITYPE65535\fR).
The default is to send 3 queries (\fIA\fR, \fIAAAA\fR and \fIMX\fR).
.TP
-.BI -R \ retries
-The number of UDP retries to query a nameserver. The default is \fI1\fR.
+.BI \-R \ retries
+The number (>=0) of UDP retries to query a nameserver. The default is \fI1\fR.
.TP
-.BI -W \ wait
-The time to wait for a reply in seconds. The default is \fI2\fR seconds.
+.BI \-W \ wait
+The time to wait for a reply in seconds. This timeout applies to each query try.
+The default is \fI2\fR seconds.
+.SH NOTES
+.SS Missing features with regard to ISC host
+Options \fB\-C, \-i, \-l, \-m, \-N\fR.
+.SS Differences with regard to ISC host
+Option \fB\-d\fR is not equivalent to \fB-v\fR, but enables debug messages.
+.TP
+The number of retries can be set to zero.
+.TP
+Verbose mode has slightly different format (same as \fBkdig\fR).
.SH EXAMPLES
.B Example 1. Get A, AAAA and MX records for example.com:
.TP
@@ -77,13 +88,13 @@ The time to wait for a reply in seconds. The default is \fI2\fR seconds.
.TP
.B Example 3. Perform verbose zone transfer for zone example.com:
.TP
-# khost -t AXFR -v example.com
+# khost \-t AXFR \-v example.com
.SH FILES
-.BI /etc/resolv.conf
+.I /etc/resolv.conf
.SH AUTHOR
-Daniel Salzman (\fBhttp://knot-dns.cz\fR)
+Daniel Salzman (\fBwww.knot\-dns.cz\fR)
.TP
-Please send any bugs or comments to \fBknot-dns@labs.nic.cz\fR
+Please send any bug reports or comments to \fBknot\-dns@labs.nic.cz\fR
.SH SEE ALSO
-.BI kdig\fR(8),
-.BI knsupdate\fR(8).
+.BR kdig (1),
+.BR knsupdate (1).
diff --git a/man/khost.1.in b/man/khost.1.in
index a931968..e25ba35 100644
--- a/man/khost.1.in
+++ b/man/khost.1.in
@@ -1,5 +1,6 @@
-.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
\- Simple DNS lookup utility (libknot equivalent of ISC host)
.SH SYNOPSIS
@@ -7,13 +8,13 @@
[\fIoptions\fR] \fIname\fR [\fIserver\fR]
.SH DESCRIPTION
This utility sends a DNS query for the \fIname\fR to the \fIserver\fR and prints
-a reply in more user-readable form. For more advanced DNS queries use \fBkdig\fR instead.
+a reply in more user\-readable form. For more advanced DNS queries use \fBkdig\fR instead.
.TP 4
-\fI name\fR
+.I name
Is a domain name that is to be looked up.
If the \fIname\fR is IPv4 or IPv6 address the \fIPTR\fR query type is used.
.TP
-\fI server\fR
+.I server
Is a name or an address of the nameserver to send a query to. The address
can be specified using [address]:port notation. If no server is specified
the servers from \fB/etc/resolv.conf\fR are used.
@@ -21,51 +22,61 @@ the servers from \fB/etc/resolv.conf\fR are used.
If no arguments are provided, \fBkhost\fR prints short help.
.SH OPTIONS
.TP 4
-.BI -4
+.B \-4
Use IPv4 protocol only.
.TP
-.BI -6
+.B \-6
Use IPv6 protocol only.
.TP
-.BI -a
+.B \-a
Send ANY query with verbose mode.
.TP
-.BI -d
+.B \-d
Enable debug messages if any.
.TP
-\fB\-h\fR, \fB\-\-help\fR
+.BR \-h ,\ \-\-help
Print help.
.TP
-.BI -r
+.B \-r
Disable recursion.
.TP
-.BI -s
+.B \-s
Stop quering next nameserver if SERVFAIL response is received.
.TP
-.BI -T
+.B \-T
Use TCP protocol.
.TP
-.BI -v
+.B \-v
Enable verbose output.
.TP
-\fB\-V\fR, \fB\-\-version\fR
+.BR \-V ,\ \-\-version
Print program version.
.TP
-.BI -w
+.B \-w
Wait forever for the reply.
.TP
-.BI -c \ class
+.BI \-c \ class
Set query class (e.g. \fICH\fR, \fICLASS4\fR). The default class is \fIIN\fR.
.TP
-.BI -t \ type
+.BI \-t \ type
Set query type (e.g. \fINS\fR, \fIIXFR=12345\fR, \fITYPE65535\fR).
The default is to send 3 queries (\fIA\fR, \fIAAAA\fR and \fIMX\fR).
.TP
-.BI -R \ retries
-The number of UDP retries to query a nameserver. The default is \fI1\fR.
+.BI \-R \ retries
+The number (>=0) of UDP retries to query a nameserver. The default is \fI1\fR.
.TP
-.BI -W \ wait
-The time to wait for a reply in seconds. The default is \fI2\fR seconds.
+.BI \-W \ wait
+The time to wait for a reply in seconds. This timeout applies to each query try.
+The default is \fI2\fR seconds.
+.SH NOTES
+.SS Missing features with regard to ISC host
+Options \fB\-C, \-i, \-l, \-m, \-N\fR.
+.SS Differences with regard to ISC host
+Option \fB\-d\fR is not equivalent to \fB-v\fR, but enables debug messages.
+.TP
+The number of retries can be set to zero.
+.TP
+Verbose mode has slightly different format (same as \fBkdig\fR).
.SH EXAMPLES
.B Example 1. Get A, AAAA and MX records for example.com:
.TP
@@ -77,13 +88,13 @@ The time to wait for a reply in seconds. The default is \fI2\fR seconds.
.TP
.B Example 3. Perform verbose zone transfer for zone example.com:
.TP
-# khost -t AXFR -v example.com
+# khost \-t AXFR \-v example.com
.SH FILES
-.BI /etc/resolv.conf
+.I /etc/resolv.conf
.SH AUTHOR
-Daniel Salzman (\fBhttp://knot-dns.cz\fR)
+Daniel Salzman (\fBwww.knot\-dns.cz\fR)
.TP
-Please send any bugs or comments to \fBknot-dns@labs.nic.cz\fR
+Please send any bug reports or comments to \fBknot\-dns@labs.nic.cz\fR
.SH SEE ALSO
-.BI kdig\fR(8),
-.BI knsupdate\fR(8).
+.BR kdig (1),
+.BR knsupdate (1).
diff --git a/man/knot.conf.5 b/man/knot.conf.5
index 00d7542..de5ce64 100644
--- a/man/knot.conf.5
+++ b/man/knot.conf.5
@@ -1,4 +1,4 @@
-.TH "knot.conf" "5" "September 2012" "CZ.NIC Labs" "Knot DNS, version 1.3.0-rc3"
+.TH "knot.conf" "5" "15 July 2013" "CZ.NIC Labs" "Knot DNS, version 1.3.0-rc4"
.SH "NAME"
.LP
.B knot.conf
@@ -190,7 +190,7 @@ serves as an example of the configuration for knotc(8) and knotd(8).
control {
# Specifies interface, syntax is exactly the same as in 'interfaces' section
- # Default: OFF
+ # Default: $(run_dir)/knot.sock
listen-on "knot.sock";
# As an alternative, you can use an IPv4/v6 address and port
diff --git a/man/knot.conf.5.in b/man/knot.conf.5.in
index d8a0d67..2ccc767 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
@@ -190,7 +190,7 @@ serves as an example of the configuration for knotc(8) and knotd(8).
control {
# Specifies interface, syntax is exactly the same as in 'interfaces' section
- # Default: OFF
+ # Default: $(run_dir)/knot.sock
listen-on "knot.sock";
# As an alternative, you can use an IPv4/v6 address and port
diff --git a/man/knotc.8 b/man/knotc.8
index 7864cff..3d5c398 100644
--- a/man/knotc.8
+++ b/man/knotc.8
@@ -1,4 +1,4 @@
-.TH knotc "8" "September 2012" "CZ.NIC Labs" "Knot DNS, version 1.3.0-rc3"
+.TH knotc "8" "15 July 2013" "CZ.NIC Labs" "Knot DNS, version 1.3.0-rc4"
.SH NAME
.B knotc
\- Knot DNS control utility
@@ -10,15 +10,15 @@
.HP
\fB\-c\fR [file], \fB\-\-config\fR=\fI[file]\fR Select configuration file.
.TP
-\fB\-s\fR [server]\fR Remote UNIX socket/IP address (default @rundir@/knot.sock)
+\fB\-s\fR [server]\fR Remote UNIX socket/IP address (default ${prefix}/var/run/knot/knot.sock)
.TP
\fB\-p\fR [port]\fR Remote server port (only for IP).
.TP
\fB\-y\fR [hmac:]name:key]\fR Use key_id for specified on the command line.
.TP
\fB\-k\fR [file]\fR Use key file (as in config section 'keys').
-f.e. echo "knotc-key hmac-md5 Wg==" > knotc.key
-If you omit algorithm, hmac-md5 will be used as default.
+f.e. echo "knotc\-key hmac\-md5 Wg==" > knotc.key
+If you omit algorithm, hmac\-md5 will be used as default.
.TP
\fB\-f\fR, \fB\-\-force\fR
Force operation \- override some checks.
@@ -30,7 +30,7 @@ Verbose mode \- additional runtime information.
Print knot server version.
.TP
\fB\-w\fR, \fB\-\-wait\fR
-Wait for the server to finish start/stop operations.
+Wait for the server to finish stop operation.
.TP
\fB\-i\fR, \fB\-\-interactive\fR
Interactive mode (do not daemonize).
@@ -39,15 +39,9 @@ Interactive mode (do not daemonize).
Print help and usage.
.SS "Actions:"
.TP
-start
-Start knot server daemon (no\-op if running).
-.TP
stop
Stop knot server daemon (no\-op if not running).
.TP
-restart
-Stops and then starts knot server daemon.
-.TP
reload
Reload knot configuration and zones.
.TP
@@ -76,17 +70,17 @@ Estimate memory consumption for zone files. Useful mainly for big zones.
.B Setup a keyfile for remote control
.TP
1. Generate keys
-dnssec-keygen -a hmac-md5 -b 256 -n HOST knotc-key
+dnssec\-keygen \-a hmac\-md5 \-b 256 \-n HOST knotc\-key
.TP
2. Extract secret in base64 format and create keyfile
-echo "knotc-key hmac-md5 <secret>" > knotc.key
+echo "knotc\-key hmac\-md5 <secret>" > knotc.key
Make sure the key can be read/written only by owner for
security reasons.
.TP
.B Reload server remotely
-knotc -s 127.0.0.1 -k knotc.key reload
+knotc \-s 127.0.0.1 \-k knotc.key reload
.SH "SEE ALSO"
The full documentation for
.B Knot
diff --git a/man/knotc.8.in b/man/knotc.8.in
index f845c96..343fd02 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
@@ -10,15 +10,15 @@
.HP
\fB\-c\fR [file], \fB\-\-config\fR=\fI[file]\fR Select configuration file.
.TP
-\fB\-s\fR [server]\fR Remote UNIX socket/IP address (default @rundir@/knot.sock)
+\fB\-s\fR [server]\fR Remote UNIX socket/IP address (default @run_dir@/knot.sock)
.TP
\fB\-p\fR [port]\fR Remote server port (only for IP).
.TP
\fB\-y\fR [hmac:]name:key]\fR Use key_id for specified on the command line.
.TP
\fB\-k\fR [file]\fR Use key file (as in config section 'keys').
-f.e. echo "knotc-key hmac-md5 Wg==" > knotc.key
-If you omit algorithm, hmac-md5 will be used as default.
+f.e. echo "knotc\-key hmac\-md5 Wg==" > knotc.key
+If you omit algorithm, hmac\-md5 will be used as default.
.TP
\fB\-f\fR, \fB\-\-force\fR
Force operation \- override some checks.
@@ -30,7 +30,7 @@ Verbose mode \- additional runtime information.
Print knot server version.
.TP
\fB\-w\fR, \fB\-\-wait\fR
-Wait for the server to finish start/stop operations.
+Wait for the server to finish stop operation.
.TP
\fB\-i\fR, \fB\-\-interactive\fR
Interactive mode (do not daemonize).
@@ -39,15 +39,9 @@ Interactive mode (do not daemonize).
Print help and usage.
.SS "Actions:"
.TP
-start
-Start knot server daemon (no\-op if running).
-.TP
stop
Stop knot server daemon (no\-op if not running).
.TP
-restart
-Stops and then starts knot server daemon.
-.TP
reload
Reload knot configuration and zones.
.TP
@@ -76,17 +70,17 @@ Estimate memory consumption for zone files. Useful mainly for big zones.
.B Setup a keyfile for remote control
.TP
1. Generate keys
-dnssec-keygen -a hmac-md5 -b 256 -n HOST knotc-key
+dnssec\-keygen \-a hmac\-md5 \-b 256 \-n HOST knotc\-key
.TP
2. Extract secret in base64 format and create keyfile
-echo "knotc-key hmac-md5 <secret>" > knotc.key
+echo "knotc\-key hmac\-md5 <secret>" > knotc.key
Make sure the key can be read/written only by owner for
security reasons.
.TP
.B Reload server remotely
-knotc -s 127.0.0.1 -k knotc.key reload
+knotc \-s 127.0.0.1 \-k knotc.key reload
.SH "SEE ALSO"
The full documentation for
.B Knot
diff --git a/man/knotd.8 b/man/knotd.8
index 1809c9c..59ff8b5 100644
--- a/man/knotd.8
+++ b/man/knotd.8
@@ -1,4 +1,4 @@
-.TH "knotd" "8" "September 2012" "CZ.NIC Labs" "Knot DNS, version 1.3.0-rc3"
+.TH "knotd" "8" "15 July 2013" "CZ.NIC Labs" "Knot DNS, version 1.3.0-rc4"
.SH NAME
.B knotd
\- Knot DNS daemon
diff --git a/man/knotd.8.in b/man/knotd.8.in
index 83088c5..d587315 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 b/man/knsupdate.1
index 5d2bd32..c402b31 100644
--- a/man/knsupdate.1
+++ b/man/knsupdate.1
@@ -1,4 +1,4 @@
-.TH "knsupdate" "1" "April 2013" "CZ.NIC Labs" "Knot DNS, version 1.3.0-rc3"
+.TH "knsupdate" "1" "15 July 2013" "CZ.NIC Labs" "Knot DNS, version 1.3.0-rc4"
.SH NAME
.TP 10
.B knsupdate
@@ -6,142 +6,140 @@
.SH SYNOPSIS
.B knsupdate
[\fIoptions\fR] [\fIfilename\fR]
-
.SH DESCRIPTION
-
The utility sends Dynamic DNS update message to DNS server. Update content is
read from a file (if the parameter \fIfilename\fR is given) or from standard
input. The format of the update is described in \fBINPUT FORMAT\fR section.
-
.SH OPTIONS
.TP 4
-.BI -d
+.B \-d
Enable debugging messages.
.TP
-.BI -v
+.B \-v
Use TCP protocol instead of the default UDP.
.TP
-.BI -p \ port
-Set the port to use when connecting to server and the port was not explicitly
-specified in the update. The default is 53.
+.BI \-p \ port
+Set the port to use for connections to a server (if not explicitly
+specified in the update). The default is \fI53\fR.
.TP
-.BI -t \ timeout
-The timeout of the update request in seconds. The default is 12. If set to
+.BI \-t \ timeout
+The total timeout (all UDP update tries) of the update request in seconds. The default is \fI12\fR. If set to
zero, the timeout is infinite.
.TP
-.BI -r \ retries
-The number of retries for UDP requests. The default is 3. Partial timeout for
-each try is computed from total timeout (option \fB-t\fR).
+.BI \-r \ retries
+The number of retries for UDP requests. The default is \fI3\fR.
.TP
-.BI -k \ keyfile
+.BI \-k \ keyfile
Use TSIG or SIG\-0 key stored in file to authenticate the request. The tool
supports keys generated by ISC \fBdnssec\-keygen\fR. The key comprises of
public (.key extension) and private part (.private extension). Either of these
file names or a name without the extension can be specified as \fIkeyfile\fR
parameter.
-
.TP
-.BI -y \ \fR[\fIhmac:\fR]\fIname:key
+.BI \-y \ \fR[\fIhmac:\fR]\fIname:key
Use TSIG key to authenticate the request. The \fIhmac\fR part specifies the
algorithm (the default is hmac\-md5), \fIname\fR specifies the key name, and
\fIkey\fR specifies the shared secret encoded in Base64.
-
.TP
-\fB\-\-help\fR
+.BR \-h ,\ \-\-help
Print help.
-
.TP
-\fB\-\-version\fR
+.BR \-V ,\ \-\-version
Print program version.
-
-.TP
-Options \fB-k\fR and \fB-y\fR cannot be used mutually.
-
+.SH NOTE
+Options \fB\-k\fR and \fB\-y\fR cannot be used mutually.
.SH INPUT FORMAT
-
The input format is textual and is made up of commands. Every command is placed
on a separate line of the input. Lines starting with a semicolon are comments
and are not processed.
-
+.TP
List of commands format and their description:
-
.TP
-\fBserver\fR \fIname\fR [\fIport\fR]
-
+.BI server \ name \ \fR[\fIport\fR]
Specifies a receiving server of the dynamic update message. Parameter \fIname\fR
can be either a host name or an IP address. If the \fIport\fR is not specified,
default port is used. The default port value can be controlled using program
-option \fB-p\fR.
-
+option \fB\-p\fR.
+.TP
+.BI local \ address \ \fR[\fIport\fR]
+Specifies outgoing \fIaddress\fR and \fIport\fR. If no local is specified,
+the address and port are set by the system automatically. Default port number
+is \fI0\fR.
.TP
-\fBzone\fR \fIname\fR
-
+.BI zone \ name
Specifies that all updates are done within a zone named \fIname\fR. If not used,
the default zone is the root zone.
-
.TP
-\fBorigin\fR \fIname\fR
-
+.BI origin \ name
Specifies fully qualified domain name suffix which is appended to
-non-fqd owners in update commands. The default origin is the root zone.
-
+non\-fqd owners in update commands. The default origin is the root zone.
.TP
-\fBclass\fR \fIname\fR
-
+.BI class \ name
Sets \fIname\fR as a default class for all updates. If not used, the default
-class is IN.
-
+class is \fIIN\fR.
.TP
-\fBttl\fR \fIvalue\fR
-
+.BI ttl \ value
Sets \fIvalue\fR as a default TTL (time to live) in seconds. If not used, the
-default value is zero.
-
+default value is \fI0\fR.
.TP
-\fBkey\fB \fIname\fR \fIkey\fR
-
+.BI key \ name \ \fIkey\fR
Specifies TSIG key to authenticate the request. This command has the same
semantics as the program option \fB\-y\fR, except that the MAC algorithm
cannot be set.
-
.TP
-[\fBupdate\fR] \fBadd\fR \fIname\fR \fIttl\fR [\fIclass\fR] \fItype\fR \fIdata\fR
-
+[\fBupdate\fR] \fBadd\fR \fIname\fR [\fIttl\fR] [\fIclass\fR] \fItype\fR \fIdata\fR
Adds a request to add a new resource record into the zone. Please note that if the
\fIname\fR is not fully qualified domain name, current \fIorigin\fR name is appended to it.
-
.TP
[\fBupdate\fR] \fBdel\fR[\fBete\fR] \fIname\fR [\fIttl\fR] [\fIclass\fR] [\fItype\fR] [\fIdata\fR]
-
Adds a request to remove all (or matching \fIclass\fR, \fItype\fR, \fIdata\fR)
resource records from the zone. There is the same requirement for the
\fIname\fR parameter as in the \fBupdate add\fR command. The \fIttl\fR item is ignored.
-
.TP
-\fBshow\fR
-
+.B show
Displays current content of the update message.
-
.TP
-\fBsend\fR
-
+.B send
Sends the current update message and cleans the list of updates.
-
.TP
-\fBanswer\fR
-
+.B answer
Displays the last answer from the server.
-
.TP
-\fBdebug\fR
-
+.B debug
Enable debugging. This command has the same meaning as program option \fB\-d\fR.
-
-.SH BUGS
-
-Please note that there are slight differences from ISC nsupdate and some
-features are not supported. Any bugs, comments, or feature requests can be sent
-to \fBknot-dns@labs.nic.cz\fR.
+.SH NOTE
+.SS Missing features with regard to ISC nsupdate
+Options \fB\-D\fR, \fB\-g\fR, \fB\-o\fR, \fB\-l\fR, \fB\-L\fR, \fB\-R\fR, \fB\-u\fR.
+.TP
+Commands: \fBgsstsig\fR, \fBoldgsstsig\fR, \fBrealm\fR, \fBprereq\fR (\fBnxdomain\fR, \fByxdomain\fR, \fBnxrrset\fR, \fByxrrset\fR).
+.SS Differences with regard to ISC nsupdate
+Zone name/server guessing, if the zone name/server is not specified.
+.TP 0
+Empty line doesn't send an update.
+.TP
+Bind-like key format (\fBddns\-confgen\fR output) is not supported.
+.TP
+Command \fBadd\fR doesn't require \fIttl\fR item to be set. In such case,
+the default ttl value is used.
+.SH EXAMPLES
+.B Example 1. Add two records to the zone example.com.:
+.TP 0
+.nf
+knsupdate
+server 192.168.1.1
+zone example.com.
+origin example.com.
+ttl 3600
+add test1.example.com. 7200 A 192.168.2.2
+add test2 TXT "hello"
+show
+send
+answer
+.fi
+.SH AUTHOR
+Marek Vavruša, Daniel Salzman, Jan Včelák (\fBwww.knot\-dns.cz\fR)
+.TP
+Please send any bug reports or comments to \fBknot\-dns@labs.nic.cz\fR
.SH SEE ALSO
-.BI khost\fR(8),
-.BI kdig\fR(8).
+.BR kdig (1),
+.BR khost (1).
diff --git a/man/knsupdate.1.in b/man/knsupdate.1.in
index 847475b..b7857df 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
@@ -6,142 +6,140 @@
.SH SYNOPSIS
.B knsupdate
[\fIoptions\fR] [\fIfilename\fR]
-
.SH DESCRIPTION
-
The utility sends Dynamic DNS update message to DNS server. Update content is
read from a file (if the parameter \fIfilename\fR is given) or from standard
input. The format of the update is described in \fBINPUT FORMAT\fR section.
-
.SH OPTIONS
.TP 4
-.BI -d
+.B \-d
Enable debugging messages.
.TP
-.BI -v
+.B \-v
Use TCP protocol instead of the default UDP.
.TP
-.BI -p \ port
-Set the port to use when connecting to server and the port was not explicitly
-specified in the update. The default is 53.
+.BI \-p \ port
+Set the port to use for connections to a server (if not explicitly
+specified in the update). The default is \fI53\fR.
.TP
-.BI -t \ timeout
-The timeout of the update request in seconds. The default is 12. If set to
+.BI \-t \ timeout
+The total timeout (all UDP update tries) of the update request in seconds. The default is \fI12\fR. If set to
zero, the timeout is infinite.
.TP
-.BI -r \ retries
-The number of retries for UDP requests. The default is 3. Partial timeout for
-each try is computed from total timeout (option \fB-t\fR).
+.BI \-r \ retries
+The number of retries for UDP requests. The default is \fI3\fR.
.TP
-.BI -k \ keyfile
+.BI \-k \ keyfile
Use TSIG or SIG\-0 key stored in file to authenticate the request. The tool
supports keys generated by ISC \fBdnssec\-keygen\fR. The key comprises of
public (.key extension) and private part (.private extension). Either of these
file names or a name without the extension can be specified as \fIkeyfile\fR
parameter.
-
.TP
-.BI -y \ \fR[\fIhmac:\fR]\fIname:key
+.BI \-y \ \fR[\fIhmac:\fR]\fIname:key
Use TSIG key to authenticate the request. The \fIhmac\fR part specifies the
algorithm (the default is hmac\-md5), \fIname\fR specifies the key name, and
\fIkey\fR specifies the shared secret encoded in Base64.
-
.TP
-\fB\-\-help\fR
+.BR \-h ,\ \-\-help
Print help.
-
.TP
-\fB\-\-version\fR
+.BR \-V ,\ \-\-version
Print program version.
-
-.TP
-Options \fB-k\fR and \fB-y\fR cannot be used mutually.
-
+.SH NOTE
+Options \fB\-k\fR and \fB\-y\fR cannot be used mutually.
.SH INPUT FORMAT
-
The input format is textual and is made up of commands. Every command is placed
on a separate line of the input. Lines starting with a semicolon are comments
and are not processed.
-
+.TP
List of commands format and their description:
-
.TP
-\fBserver\fR \fIname\fR [\fIport\fR]
-
+.BI server \ name \ \fR[\fIport\fR]
Specifies a receiving server of the dynamic update message. Parameter \fIname\fR
can be either a host name or an IP address. If the \fIport\fR is not specified,
default port is used. The default port value can be controlled using program
-option \fB-p\fR.
-
+option \fB\-p\fR.
+.TP
+.BI local \ address \ \fR[\fIport\fR]
+Specifies outgoing \fIaddress\fR and \fIport\fR. If no local is specified,
+the address and port are set by the system automatically. Default port number
+is \fI0\fR.
.TP
-\fBzone\fR \fIname\fR
-
+.BI zone \ name
Specifies that all updates are done within a zone named \fIname\fR. If not used,
the default zone is the root zone.
-
.TP
-\fBorigin\fR \fIname\fR
-
+.BI origin \ name
Specifies fully qualified domain name suffix which is appended to
-non-fqd owners in update commands. The default origin is the root zone.
-
+non\-fqd owners in update commands. The default origin is the root zone.
.TP
-\fBclass\fR \fIname\fR
-
+.BI class \ name
Sets \fIname\fR as a default class for all updates. If not used, the default
-class is IN.
-
+class is \fIIN\fR.
.TP
-\fBttl\fR \fIvalue\fR
-
+.BI ttl \ value
Sets \fIvalue\fR as a default TTL (time to live) in seconds. If not used, the
-default value is zero.
-
+default value is \fI0\fR.
.TP
-\fBkey\fB \fIname\fR \fIkey\fR
-
+.BI key \ name \ \fIkey\fR
Specifies TSIG key to authenticate the request. This command has the same
semantics as the program option \fB\-y\fR, except that the MAC algorithm
cannot be set.
-
.TP
-[\fBupdate\fR] \fBadd\fR \fIname\fR \fIttl\fR [\fIclass\fR] \fItype\fR \fIdata\fR
-
+[\fBupdate\fR] \fBadd\fR \fIname\fR [\fIttl\fR] [\fIclass\fR] \fItype\fR \fIdata\fR
Adds a request to add a new resource record into the zone. Please note that if the
\fIname\fR is not fully qualified domain name, current \fIorigin\fR name is appended to it.
-
.TP
[\fBupdate\fR] \fBdel\fR[\fBete\fR] \fIname\fR [\fIttl\fR] [\fIclass\fR] [\fItype\fR] [\fIdata\fR]
-
Adds a request to remove all (or matching \fIclass\fR, \fItype\fR, \fIdata\fR)
resource records from the zone. There is the same requirement for the
\fIname\fR parameter as in the \fBupdate add\fR command. The \fIttl\fR item is ignored.
-
.TP
-\fBshow\fR
-
+.B show
Displays current content of the update message.
-
.TP
-\fBsend\fR
-
+.B send
Sends the current update message and cleans the list of updates.
-
.TP
-\fBanswer\fR
-
+.B answer
Displays the last answer from the server.
-
.TP
-\fBdebug\fR
-
+.B debug
Enable debugging. This command has the same meaning as program option \fB\-d\fR.
-
-.SH BUGS
-
-Please note that there are slight differences from ISC nsupdate and some
-features are not supported. Any bugs, comments, or feature requests can be sent
-to \fBknot-dns@labs.nic.cz\fR.
+.SH NOTE
+.SS Missing features with regard to ISC nsupdate
+Options \fB\-D\fR, \fB\-g\fR, \fB\-o\fR, \fB\-l\fR, \fB\-L\fR, \fB\-R\fR, \fB\-u\fR.
+.TP
+Commands: \fBgsstsig\fR, \fBoldgsstsig\fR, \fBrealm\fR, \fBprereq\fR (\fBnxdomain\fR, \fByxdomain\fR, \fBnxrrset\fR, \fByxrrset\fR).
+.SS Differences with regard to ISC nsupdate
+Zone name/server guessing, if the zone name/server is not specified.
+.TP 0
+Empty line doesn't send an update.
+.TP
+Bind-like key format (\fBddns\-confgen\fR output) is not supported.
+.TP
+Command \fBadd\fR doesn't require \fIttl\fR item to be set. In such case,
+the default ttl value is used.
+.SH EXAMPLES
+.B Example 1. Add two records to the zone example.com.:
+.TP 0
+.nf
+knsupdate
+server 192.168.1.1
+zone example.com.
+origin example.com.
+ttl 3600
+add test1.example.com. 7200 A 192.168.2.2
+add test2 TXT "hello"
+show
+send
+answer
+.fi
+.SH AUTHOR
+Marek Vavruša, Daniel Salzman, Jan Včelák (\fBwww.knot\-dns.cz\fR)
+.TP
+Please send any bug reports or comments to \fBknot\-dns@labs.nic.cz\fR
.SH SEE ALSO
-.BI khost\fR(8),
-.BI kdig\fR(8).
+.BR kdig (1),
+.BR khost (1).
diff --git a/samples/Makefile.am b/samples/Makefile.am
index 755ef07..73f8760 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/Makefile.in b/samples/Makefile.in
index 582a416..e18846e 100644
--- a/samples/Makefile.in
+++ b/samples/Makefile.in
@@ -147,6 +147,7 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
RAGEL = @RAGEL@
RANLIB = @RANLIB@
+RELEASE_DATE = @RELEASE_DATE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -174,6 +175,7 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+config_dir = @config_dir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
@@ -218,7 +220,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'
EXTRA_DIST = knot.sample.conf.in knot.full.conf knot.keys.conf example.com.zone
all: all-am
@@ -420,16 +425,16 @@ knot.sample.conf: knot.sample.conf.in
mv $@.tmp $@
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 3628978..49edf13 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 5ef43bc..a8021c4 100644
--- a/samples/knot.sample.conf.in
+++ b/samples/knot.sample.conf.in
@@ -6,19 +6,86 @@
#
system {
+ # Identity of the server (see RFC 4892).
identity "@package@ @version@";
+
+ # User for running server
+ # May also specify user.group (e.g. knot.knot)
+ user knot.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 "@run_dir@";
}
interfaces {
- my-iface { address 127.0.0.1@53533; }
+ all_ipv4 {
+ address 0.0.0.0;
+ port 53;
+ }
+ all_ipv6 {
+ address [::];
+ port 53;
+ }
}
+control {
+ # Specifies interface, syntax is exactly the same as in 'interfaces' section
+ # Default: knot.sock (relative to rundir)
+ listen-on "knot.sock";
+
+ # As an alternative, you can use an IPv4/v6 address and port
+ # listen-on { address 127.0.0.1@5533; }
+
+ # Specifies ACL list for remote control
+ # Same syntax as for ACLs in zones
+ # List of remotes or groups delimited by comma
+ # Notice: keep in mind that ACLs bear no effect with UNIX sockets
+ # allow server0, admins;
+}
+
+#remotes {
+# master0 {
+# address 198.51.100.1@53;
+# }
+# slave0 {
+# address 203.0.113.1@53;
+# }
+#}
+
zones {
- example.com {
- file "@sysconfdir@/example.com.zone";
- }
+# Example master zone
+# example.com {
+# file "@config_dir@/example.com.zone";
+# xfr-out slave0;
+# notify-out slave0;
+# }
+#
+# Example slave zone
+# example.net {
+# file "@storage_dir@/example.net.zone
+# xfr-in master0;
+# notify-in master0;
+# }
}
log {
- syslog { any info, notice, warning, error; }
+ syslog {
+ # log errors of any category
+ any error; # for <category> and <severity> see above
+ # log also warnings and notices from category 'zone'
+ zone warning, notice;
+ # log info from server
+ server info;
+ }
+
+ # Log fatal, warnings and errors to stderr
+ stderr {
+ any error, warning;
+ }
}
diff --git a/src/Makefile.am b/src/Makefile.am
index a542399..46fe292 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -8,8 +8,8 @@ noinst_LTLIBRARIES = libknot.la libknotd.la libknots.la libzscanner.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
@@ -218,12 +218,6 @@ libknots_la_SOURCES = \
common/prng.c \
common/fdset.h \
common/fdset.c \
- common/fdset_poll.h \
- common/fdset_poll.c \
- common/fdset_kqueue.h \
- common/fdset_kqueue.c \
- common/fdset_epoll.h \
- common/fdset_epoll.c \
common/getline.h \
common/getline.c \
common/log.c \
@@ -316,5 +310,6 @@ zscanner_tool_LDADD = libknots.la libknot.la libknotd.la libzscanner.la @LIBOBJS
# 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/Makefile.in b/src/Makefile.in
index 90f5050..b6494fd 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -118,10 +118,9 @@ am_libknots_la_OBJECTS = common/slab/slab.lo common/libtap/tap.lo \
common/evsched.lo common/acl.lo common/sockaddr.lo \
common/ref.lo common/errors.lo common/errcode.lo \
common/dSFMT.lo common/prng.lo common/fdset.lo \
- common/fdset_poll.lo common/fdset_kqueue.lo \
- common/fdset_epoll.lo common/getline.lo common/log.lo \
- common/mempool.lo common/hattrie/ahtable.lo \
- common/hattrie/hat-trie.lo common/hattrie/murmurhash3.lo
+ common/getline.lo common/log.lo common/mempool.lo \
+ common/hattrie/ahtable.lo common/hattrie/hat-trie.lo \
+ common/hattrie/murmurhash3.lo
libknots_la_OBJECTS = $(am_libknots_la_OBJECTS)
libzscanner_la_DEPENDENCIES = @LIBOBJS@
am_libzscanner_la_OBJECTS = zscanner/file_loader.lo \
@@ -326,6 +325,7 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
RAGEL = @RAGEL@
RANLIB = @RANLIB@
+RELEASE_DATE = @RELEASE_DATE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -353,6 +353,7 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+config_dir = @config_dir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
@@ -398,8 +399,8 @@ noinst_LTLIBRARIES = libknot.la libknotd.la libknots.la libzscanner.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
@@ -595,12 +596,6 @@ libknots_la_SOURCES = \
common/prng.c \
common/fdset.h \
common/fdset.c \
- common/fdset_poll.h \
- common/fdset_poll.c \
- common/fdset_kqueue.h \
- common/fdset_kqueue.c \
- common/fdset_epoll.h \
- common/fdset_epoll.c \
common/getline.h \
common/getline.c \
common/log.c \
@@ -992,12 +987,6 @@ common/prng.lo: common/$(am__dirstamp) \
common/$(DEPDIR)/$(am__dirstamp)
common/fdset.lo: common/$(am__dirstamp) \
common/$(DEPDIR)/$(am__dirstamp)
-common/fdset_poll.lo: common/$(am__dirstamp) \
- common/$(DEPDIR)/$(am__dirstamp)
-common/fdset_kqueue.lo: common/$(am__dirstamp) \
- common/$(DEPDIR)/$(am__dirstamp)
-common/fdset_epoll.lo: common/$(am__dirstamp) \
- common/$(DEPDIR)/$(am__dirstamp)
common/getline.lo: common/$(am__dirstamp) \
common/$(DEPDIR)/$(am__dirstamp)
common/log.lo: common/$(am__dirstamp) common/$(DEPDIR)/$(am__dirstamp)
@@ -1282,12 +1271,6 @@ mostlyclean-compile:
-rm -f common/evsched.lo
-rm -f common/fdset.$(OBJEXT)
-rm -f common/fdset.lo
- -rm -f common/fdset_epoll.$(OBJEXT)
- -rm -f common/fdset_epoll.lo
- -rm -f common/fdset_kqueue.$(OBJEXT)
- -rm -f common/fdset_kqueue.lo
- -rm -f common/fdset_poll.$(OBJEXT)
- -rm -f common/fdset_poll.lo
-rm -f common/getline.$(OBJEXT)
-rm -f common/getline.lo
-rm -f common/hattrie/ahtable.$(OBJEXT)
@@ -1467,9 +1450,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/evqueue.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/evsched.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/fdset.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/fdset_epoll.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/fdset_kqueue.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/fdset_poll.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/getline.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/heap.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/lists.Plo@am__quote@
@@ -2009,6 +1989,7 @@ uninstall-am: uninstall-binPROGRAMS uninstall-sbinPROGRAMS
# 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/errcode.c b/src/common/errcode.c
index c03b473..b555805 100644
--- a/src/common/errcode.c
+++ b/src/common/errcode.c
@@ -76,7 +76,6 @@ const error_table_t knot_error_msgs[] = {
/* Control states. */
{ KNOT_CTL_STOP, "Stopping server." },
- { KNOT_CTL_RESTART, "Restarting server." },
/* Network errors. */
{ KNOT_NET_EADDR, "Bad address or host name." },
diff --git a/src/common/errcode.h b/src/common/errcode.h
index 13d1943..69f6ed5 100644
--- a/src/common/errcode.h
+++ b/src/common/errcode.h
@@ -95,7 +95,6 @@ enum knot_error {
/* Control states. */
KNOT_CTL_STOP, /*!< Stop requested. */
- KNOT_CTL_RESTART, /*!< Restart requested. */
/* Network errors. */
KNOT_NET_EADDR,
diff --git a/src/common/evqueue.c b/src/common/evqueue.c
index 097d177..4b89554 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 ffb3860..794b2d5 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/common/fdset.c b/src/common/fdset.c
index 3b4b75a..5f93d27 100644
--- a/src/common/fdset.c
+++ b/src/common/fdset.c
@@ -15,12 +15,11 @@
*/
#include <config.h>
-#include <dlfcn.h>
+#include <stdlib.h>
#include <string.h>
-#include <stdio.h>
#include <time.h>
-#include <stdlib.h>
#include "common/fdset.h"
+#include "common.h"
/* Workarounds for clock_gettime() not available on some platforms. */
#ifdef HAVE_CLOCK_GETTIME
@@ -34,171 +33,137 @@ typedef struct timeval timev_t;
#error Neither clock_gettime() nor gettimeofday() found. At least one is required.
#endif
-struct fdset_backend_t _fdset_backend = {
- NULL
-};
+/* Realloc memory or return error (part of fdset_resize). */
+#define MEM_RESIZE(tmp, p, n) \
+ if ((tmp = realloc((p), (n))) == NULL) \
+ return KNOT_ENOMEM; \
+ (p) = tmp;
-/*! \brief Set backend implementation. */
-static void fdset_set_backend(struct fdset_backend_t *backend) {
- memcpy(&_fdset_backend, backend, sizeof(struct fdset_backend_t));
+static int fdset_resize(fdset_t *set, unsigned size)
+{
+ void *tmp = NULL;
+ MEM_RESIZE(tmp, set->ctx, size * sizeof(void*));
+ MEM_RESIZE(tmp, set->pfd, size * sizeof(struct pollfd));
+ MEM_RESIZE(tmp, set->timeout, size * sizeof(timev_t));
+ set->size = size;
+ return KNOT_EOK;
}
-/* Linux epoll API. */
-#ifdef HAVE_EPOLL_WAIT
- #include "common/fdset_epoll.h"
-#endif /* HAVE_EPOLL_WAIT */
-
-/* BSD kqueue API */
-#ifdef HAVE_KQUEUE
- #include "common/fdset_kqueue.h"
-#endif /* HAVE_KQUEUE */
-
-/* POSIX poll API */
-#ifdef HAVE_POLL
- #include "common/fdset_poll.h"
-#endif /* HAVE_POLL */
-
-/*! \brief Bootstrap polling subsystem (it is called automatically). */
-void __attribute__ ((constructor)) fdset_init()
+int fdset_init(fdset_t *set, unsigned size)
{
- /* Preference: epoll */
-#ifdef HAVE_EPOLL_WAIT
- if (dlsym(RTLD_DEFAULT, "epoll_wait") != 0) {
- fdset_set_backend(&FDSET_EPOLL);
- return;
+ if (set == NULL) {
+ return KNOT_EINVAL;
}
-#endif
- /* Preference: kqueue */
-#ifdef HAVE_KQUEUE
- if (dlsym(RTLD_DEFAULT, "kqueue") != 0) {
- fdset_set_backend(&FDSET_KQUEUE);
- return;
- }
-#endif
+ memset(set, 0, sizeof(fdset_t));
+ return fdset_resize(set, size);
+}
- /* Fallback: poll */
-#ifdef HAVE_POLL
- if (dlsym(RTLD_DEFAULT, "poll") != 0) {
- fdset_set_backend(&FDSET_POLL);
- return;
+int fdset_clear(fdset_t* set)
+{
+ if (set == NULL) {
+ return KNOT_EINVAL;
}
-#endif
- /* This shouldn't happen. */
- fprintf(stderr, "fdset: fatal error - no valid fdset backend found\n");
- return;
+ free(set->ctx);
+ free(set->pfd);
+ free(set->timeout);
+ memset(set, 0, sizeof(fdset_t));
+ return KNOT_EOK;
}
-/*!
- * \brief Compare file descriptors.
- *
- * \param a File descriptor.
- * \param b File descriptor.
- *
- * \retval -1 if a < b
- * \retval 0 if a == b
- * \retval 1 if a > b
- */
-static inline int fdset_compare(void *a, void *b)
+int fdset_add(fdset_t *set, int fd, unsigned events, void *ctx)
{
- if (a > b) return 1;
- if (a < b) return -1;
- return 0;
-}
-
-fdset_t *fdset_new() {
- fdset_t* set = _fdset_backend.fdset_new();
- fdset_base_t *base = (fdset_base_t*)set;
- if (base != NULL) {
- /* Create atimes list. */
- base->atimes = skip_create_list(fdset_compare);
- if (base->atimes == NULL) {
- fdset_destroy(set);
- set = NULL;
- }
+ if (set == NULL || fd < 0) {
+ return KNOT_EINVAL;
}
- return set;
+
+ /* Realloc needed. */
+ if (set->n == set->size && fdset_resize(set, set->size + FDSET_INIT_SIZE))
+ return KNOT_ENOMEM;
+
+ /* Initialize. */
+ int i = set->n++;
+ set->pfd[i].fd = fd;
+ set->pfd[i].events = events;
+ set->pfd[i].revents = 0;
+ set->ctx[i] = ctx;
+ set->timeout[i] = 0;
+
+ /* Return index to this descriptor. */
+ return i;
}
-int fdset_destroy(fdset_t* fdset) {
- fdset_base_t *base = (fdset_base_t*)fdset;
- if (base != NULL && base->atimes != NULL) {
- skip_destroy_list(&base->atimes, NULL, free);
+int fdset_remove(fdset_t *set, unsigned i)
+{
+ if (set == NULL || i >= set->n) {
+ return KNOT_EINVAL;
}
- return _fdset_backend.fdset_destroy(fdset);
-}
-int fdset_remove(fdset_t *fdset, int fd) {
- fdset_base_t *base = (fdset_base_t*)fdset;
- if (base != NULL && base->atimes != NULL) {
- skip_remove(base->atimes, (void*)((size_t)fd), NULL, free);
+ /* Decrement number of elms. */
+ --set->n;
+
+ /* Nothing else if it is the last one.
+ * Move last -> i if some remain. */
+ unsigned last = set->n; /* Already decremented */
+ if (i < last) {
+ set->pfd[i] = set->pfd[last];
+ set->timeout[i] = set->timeout[last];
+ set->ctx[i] = set->ctx[last];
}
- return _fdset_backend.fdset_remove(fdset, fd);
+
+ return KNOT_EOK;
}
-int fdset_set_watchdog(fdset_t* fdset, int fd, int interval)
+int fdset_set_watchdog(fdset_t* set, int i, int interval)
{
- fdset_base_t *base = (fdset_base_t*)fdset;
- if (base == NULL || base->atimes == NULL) {
- return -1;
+ if (set == NULL || i >= set->n) {
+ return KNOT_EINVAL;
}
/* Lift watchdog if interval is negative. */
if (interval < 0) {
- skip_remove(base->atimes, (void*)((size_t)fd), NULL, free);
- return 0;
- }
-
- /* Find if exists. */
- timev_t *ts = NULL;
- ts = (timev_t*)skip_find(base->atimes, (void*)((size_t)fd));
- if (ts == NULL) {
- ts = malloc(sizeof(timev_t));
- if (ts == NULL) {
- return -1;
- }
- skip_insert(base->atimes, (void*)((size_t)fd), (void*)ts, NULL);
+ set->timeout[i] = 0;
+ return KNOT_EOK;
}
/* Update clock. */
- if (time_now(ts) < 0) {
- return -1;
- }
+ timev_t now;
+ if (time_now(&now) < 0)
+ return KNOT_ERROR;
- ts->tv_sec += interval; /* Only seconds precision. */
- return 0;
+ set->timeout[i] = now.tv_sec + interval; /* Only seconds precision. */
+ return KNOT_EOK;
}
-int fdset_sweep(fdset_t* fdset, void(*cb)(fdset_t*, int, void*), void *data)
+int fdset_sweep(fdset_t* set, fdset_sweep_cb_t cb, void *data)
{
- fdset_base_t *base = (fdset_base_t*)fdset;
- if (base == NULL || base->atimes == NULL) {
- return -1;
+ if (set == NULL || cb == NULL) {
+ return KNOT_EINVAL;
}
/* Get time threshold. */
timev_t now;
if (time_now(&now) < 0) {
- return -1;
+ return KNOT_ERROR;
}
- /* Inspect all nodes. */
- int sweeped = 0;
- const skip_node_t *n = skip_first(base->atimes);
- while (n != NULL) {
- const skip_node_t* pnext = skip_next(n);
-
- /* Evaluate */
- timev_t *ts = (timev_t*)n->value;
- if (ts->tv_sec <= now.tv_sec) {
- cb(fdset, (int)(((ssize_t)n->key)), data);
- ++sweeped;
+ unsigned i = 0;
+ while (i < set->n) {
+
+ /* Check sweep state, remove if requested. */
+ if (set->timeout[i] > 0 && set->timeout[i] <= now.tv_sec) {
+ if (cb(set, i, data) == FDSET_SWEEP) {
+ if (fdset_remove(set, i) == KNOT_EOK)
+ continue; /* Stay on the index. */
+ }
}
- n = pnext;
+
+ /* Next descriptor. */
+ ++i;
}
- return sweeped;
+ return KNOT_EOK;
}
/* OpenBSD compatibility. */
diff --git a/src/common/fdset.h b/src/common/fdset.h
index e1facdb..f0ef849 100644
--- a/src/common/fdset.h
+++ b/src/common/fdset.h
@@ -18,12 +18,7 @@
*
* \author Marek Vavrusa <marek.vavrusa@nic.cz>
*
- * \brief Wrapper for native I/O multiplexing.
- *
- * Selects best implementation according to config.
- * - poll()
- * - epoll()
- * - kqueue()
+ * \brief I/O multiplexing with context and timeouts for each fd.
*
* \addtogroup common_lib
* @{
@@ -32,88 +27,36 @@
#ifndef _KNOTD_FDSET_H_
#define _KNOTD_FDSET_H_
+#include <config.h>
#include <stddef.h>
-#ifdef HAVE_SYS_SELECT_H
- #include <sys/select.h>
-#endif
-#ifdef HAVE_SYS_TIME_H
- #include <sys/time.h>
-#endif
-#ifdef HAVE_SIGNAL_H
- #include <signal.h>
-#endif
-#include "skip-list.h"
-#include "mempattern.h"
-
-/*! \brief Waiting for completion constants. */
-enum fdset_wait_t {
- OS_EV_FOREVER = -1, /*!< Wait forever. */
- OS_EV_NOWAIT = 0 /*!< Return immediately. */
+#include <poll.h>
+#include <sys/time.h>
+#include <signal.h>
+
+#define FDSET_INIT_SIZE 256 /* Resize step. */
+
+/*! \brief Set of filedescriptors with associated context and timeouts. */
+typedef struct fdset {
+ unsigned n; /*!< Active fds. */
+ unsigned size; /*!< Array size (allocated). */
+ void* *ctx; /*!< Context for each fd. */
+ struct pollfd *pfd; /*!< poll state for each fd */
+ time_t *timeout; /*!< Timeout for each fd (seconds precision). */
+} fdset_t;
+
+/*! \brief Mark-and-sweep state. */
+enum fdset_sweep_state {
+ FDSET_KEEP,
+ FDSET_SWEEP
};
-/*! \brief Base for implementation-specific fdsets. */
-typedef struct fdset_base_t {
- skip_list_t *atimes;
-} fdset_base_t;
+/*! \brief Sweep callback (set, index, data) */
+typedef enum fdset_sweep_state (*fdset_sweep_cb_t)(fdset_t*, int, void*);
/*!
- * \brief Opaque pointer to implementation-specific fdset data.
- * \warning Implementation MUST have fdset_base_t member on the first place.
- * Example:
- * struct fdset_t {
- * fdset_base_t base;
- * ...other members...
- * }
+ * \brief Initialize fdset to given size.
*/
-typedef struct fdset_t fdset_t;
-
-/*! \brief Unified event types. */
-enum fdset_event_t {
- OS_EV_READ = 1 << 0, /*!< Readable event. */
- OS_EV_WRITE = 1 << 1, /*!< Writeable event. */
- OS_EV_ERROR = 1 << 2 /*!< Error event. */
-};
-
-/*! \brief File descriptor set iterator. */
-typedef struct fdset_it_t {
- int fd; /*!< Current file descriptor. */
- int events; /*!< Returned events. */
- size_t pos; /* Internal usage. */
-} fdset_it_t;
-
-/*!
- * \brief File descriptor set implementation backend.
- * \note Functions documentation following.
- * \internal
- */
-struct fdset_backend_t
-{
- fdset_t* (*fdset_new)();
- int (*fdset_destroy)(fdset_t*);
- int (*fdset_add)(fdset_t*, int, int);
- int (*fdset_remove)(fdset_t*, int);
- int (*fdset_wait)(fdset_t*, int);
- int (*fdset_begin)(fdset_t*, fdset_it_t*);
- int (*fdset_end)(fdset_t*, fdset_it_t*);
- int (*fdset_next)(fdset_t*, fdset_it_t*);
- const char* (*fdset_method)();
-};
-
-/*!
- * \brief Selected backend.
- * \internal
- */
-extern struct fdset_backend_t _fdset_backend;
-
-/*!
- * \brief Create new fdset.
- *
- * FDSET implementation depends on system.
- *
- * \retval Pointer to initialized FDSET structure if successful.
- * \retval NULL on error.
- */
-fdset_t *fdset_new();
+int fdset_init(fdset_t *set, unsigned size);
/*!
* \brief Destroy FDSET.
@@ -121,125 +64,61 @@ fdset_t *fdset_new();
* \retval 0 if successful.
* \retval -1 on error.
*/
-int fdset_destroy(fdset_t* fdset);
+int fdset_clear(fdset_t* set);
/*!
* \brief Add file descriptor to watched set.
*
- * \param fdset Target set.
+ * \param set Target set.
* \param fd Added file descriptor.
* \param events Mask of watched events.
+ * \param ctx Context (optional).
*
- * \retval 0 if successful.
+ * \retval index of the added fd if successful.
* \retval -1 on errors.
*/
-static inline int fdset_add(fdset_t *fdset, int fd, int events) {
- return _fdset_backend.fdset_add(fdset, fd, events);
-}
-
+int fdset_add(fdset_t *set, int fd, unsigned events, void *ctx);
/*!
* \brief Remove file descriptor from watched set.
*
- * \param fdset Target set.
- * \param fd File descriptor to be removed.
- *
- * \retval 0 if successful.
- * \retval -1 on errors.
- */
-int fdset_remove(fdset_t *fdset, int fd);
-
-/*!
- * \brief Poll set for new events.
- *
- * \param fdset Target set.
- * \param timeout Timeout (OS_EV_FOREVER, OS_EV_NOWAIT or value in miliseconds).
- *
- * \retval Number of events if successful.
- * \retval -1 on errors.
- */
-static inline int fdset_wait(fdset_t *fdset, int timeout) {
- return _fdset_backend.fdset_wait(fdset, timeout);
-}
-
-/*!
- * \brief Set event iterator to the beginning of last polled events.
- *
- * \param fdset Target set.
- * \param it Event iterator.
- *
- * \retval 0 if successful.
- * \retval -1 on errors.
- */
-static inline int fdset_begin(fdset_t *fdset, fdset_it_t *it) {
- return _fdset_backend.fdset_begin(fdset, it);
-}
-
-/*!
- * \brief Set event iterator to the end of last polled events.
- *
- * \param fdset Target set.
- * \param it Event iterator.
+ * \param set Target set.
+ * \param i Index of the removed fd.
*
* \retval 0 if successful.
* \retval -1 on errors.
*/
-static inline int fdset_end(fdset_t *fdset, fdset_it_t *it) {
- return _fdset_backend.fdset_end(fdset, it);
-}
-
-/*!
- * \brief Set event iterator to the next event.
- *
- * Event iterator fd will be set to -1 if next event doesn't exist.
- *
- * \param fdset Target set.
- * \param it Event iterator.
- *
- * \retval 0 if successful.
- * \retval -1 on errors.
- */
-static inline int fdset_next(fdset_t *fdset, fdset_it_t *it) {
- return _fdset_backend.fdset_next(fdset, it);
-}
-
-/*!
- * \brief Returned name of underlying poll method.
- *
- * \retval Name if successful.
- * \retval NULL if no method was loaded (shouldn't happen).
- */
-static inline const char* fdset_method() {
- return _fdset_backend.fdset_method();
-}
+int fdset_remove(fdset_t *set, unsigned i);
/*!
* \brief Set file descriptor watchdog interval.
*
- * Descriptors without activity in given interval
- * can be disposed with fdset_sweep().
+ * Set time (interval from now) after which the associated file descriptor
+ * should be sweeped (see fdset_sweep). Good example is setting a grace period
+ * of N seconds between socket activity. If socket is not active within
+ * <now, now + interval>, it is sweeped and potentially closed.
*
- * \param fdset Target set.
- * \param fd File descriptor.
+ * \param set Target set.
+ * \param i Index for the file descriptor.
* \param interval Allowed interval without activity (seconds).
- * <0 removes watchdog interval.
+ * -1 disables watchdog timer
*
* \retval 0 if successful.
* \retval -1 on errors.
*/
-int fdset_set_watchdog(fdset_t* fdset, int fd, int interval);
+int fdset_set_watchdog(fdset_t* set, int i, int interval);
/*!
* \brief Sweep file descriptors with exceeding inactivity period.
*
* \param fdset Target set.
* \param cb Callback for sweeped descriptors.
- * \param data Custom data for sweep operation.
+ * \param data Pointer to extra data.
*
* \retval number of sweeped descriptors.
* \retval -1 on errors.
*/
-int fdset_sweep(fdset_t* fdset, void(*cb)(fdset_t*, int, void*), void *data);
+int fdset_sweep(fdset_t* set, fdset_sweep_cb_t cb, void *data);
/*!
* \brief pselect(2) compatibility wrapper.
diff --git a/src/common/fdset_epoll.c b/src/common/fdset_epoll.c
deleted file mode 100644
index f889dd3..0000000
--- a/src/common/fdset_epoll.c
+++ /dev/null
@@ -1,205 +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/>.
- */
-
-#include <config.h>
-
-#ifdef HAVE_EPOLL_WAIT
-
-#include <sys/epoll.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "fdset_epoll.h"
-#include "skip-list.h"
-
-#define OS_FDS_CHUNKSIZE 8 /*!< Number of pollfd structs in a chunk. */
-
-struct fdset_t {
- fdset_base_t _base;
- int epfd;
- struct epoll_event *events;
- size_t nfds;
- size_t reserved;
- size_t polled;
-};
-
-fdset_t *fdset_epoll_new()
-{
- fdset_t *set = malloc(sizeof(fdset_t));
- if (set) {
- /* Blank memory. */
- memset(set, 0, sizeof(fdset_t));
-
- /* Create epoll fd. */
- set->epfd = epoll_create(OS_FDS_CHUNKSIZE);
- }
-
- return set;
-}
-
-int fdset_epoll_destroy(fdset_t * fdset)
-{
- if(fdset == NULL) {
- return -1;
- }
-
- /* Teardown epoll. */
- close(fdset->epfd);
-
- /* OK if NULL. */
- free(fdset->events);
- free(fdset);
- return 0;
-}
-
-int fdset_epoll_add(fdset_t *fdset, int fd, int events)
-{
- if (fdset == NULL || fd < 0 || events <= 0) {
- return -1;
- }
-
- /* Realloc needed. */
- if (mreserve((char **)&fdset->events, sizeof(struct epoll_event),
- fdset->nfds + 1, OS_FDS_CHUNKSIZE, &fdset->reserved) < 0) {
- return -1;
- }
-
- /* Add to epoll set. */
- struct epoll_event ev;
- memset(&ev, 0, sizeof(struct epoll_event));
- ev.events = EPOLLIN;
- ev.data.fd = fd;
- if (epoll_ctl(fdset->epfd, EPOLL_CTL_ADD, fd, &ev) < 0) {
- return -1;
- }
-
- ++fdset->nfds;
- return 0;
-}
-
-int fdset_epoll_remove(fdset_t *fdset, int fd)
-{
- if (fdset == NULL || fd < 0) {
- return -1;
- }
-
- /* Attempt to remove from set. */
- struct epoll_event ev;
- memset(&ev, 0, sizeof(struct epoll_event));
- if (epoll_ctl(fdset->epfd, EPOLL_CTL_DEL, fd, &ev) < 0) {
- return -1;
- }
-
- /* Overwrite current item. */
- --fdset->nfds;
-
- /* Trim excessive memory if possible (retval is not interesting). */
- mreserve((char **)&fdset->events, sizeof(struct epoll_event),
- fdset->nfds + 1, OS_FDS_CHUNKSIZE, &fdset->reserved);
-
- return 0;
-}
-
-int fdset_epoll_wait(fdset_t *fdset, int timeout)
-{
- if (fdset == NULL || fdset->nfds < 1 || fdset->events == NULL) {
- return -1;
- }
-
- /* Poll new events. */
- fdset->polled = 0;
- int nfds = epoll_wait(fdset->epfd, fdset->events, fdset->nfds, timeout);
-
- /* Check. */
- if (nfds < 0) {
- return -1;
- }
-
- /* Events array is ordered from 0 to nfds. */
- fdset->polled = nfds;
- return nfds;
-}
-
-int fdset_epoll_begin(fdset_t *fdset, fdset_it_t *it)
-{
- if (fdset == NULL || it == NULL) {
- return -1;
- }
-
- /* Find first. */
- it->pos = 0;
- return fdset_next(fdset, it);
-}
-
-int fdset_epoll_end(fdset_t *fdset, fdset_it_t *it)
-{
- if (fdset == NULL || it == NULL || fdset->nfds < 1) {
- return -1;
- }
-
- /* Check for polled events. */
- if (fdset->polled < 1) {
- it->fd = -1;
- it->pos = 0;
- return -1;
- }
-
- /* No end found, ends on the beginning. */
- size_t nid = fdset->polled - 1;
- it->fd = fdset->events[nid].data.fd;
- it->pos = nid;
- it->events = 0;
- return -1;
-}
-
-int fdset_epoll_next(fdset_t *fdset, fdset_it_t *it)
-{
- if (fdset == NULL || it == NULL || fdset->nfds < 1) {
- return -1;
- }
-
- /* Check boundaries. */
- if (it->pos >= fdset->polled || it->pos >= fdset->nfds) {
- return -1;
- }
-
- /* Select next. */
- size_t nid = it->pos++;
- it->fd = fdset->events[nid].data.fd;
- it->events = 0;
- return 0;
-}
-
-const char* fdset_epoll_method()
-{
- return "epoll";
-}
-
-/* Package APIs. */
-struct fdset_backend_t FDSET_EPOLL = {
- .fdset_new = fdset_epoll_new,
- .fdset_destroy = fdset_epoll_destroy,
- .fdset_add = fdset_epoll_add,
- .fdset_remove = fdset_epoll_remove,
- .fdset_wait = fdset_epoll_wait,
- .fdset_begin = fdset_epoll_begin,
- .fdset_end = fdset_epoll_end,
- .fdset_next = fdset_epoll_next,
- .fdset_method = fdset_epoll_method
-};
-
-#endif
diff --git a/src/common/fdset_epoll.h b/src/common/fdset_epoll.h
deleted file mode 100644
index 58f25f8..0000000
--- a/src/common/fdset_epoll.h
+++ /dev/null
@@ -1,132 +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/>.
- */
-/*!
- * \file fdset_epoll.h
- *
- * \author Marek Vavrusa <marek.vavrusa@nic.cz>
- *
- * \brief Wrapper for epoll I/O multiplexing.
- *
- * \addtogroup common_lib
- * @{
- */
-
-#ifndef _KNOTD_FDSET_EPOLL_H_
-#define _KNOTD_FDSET_EPOLL_H_
-
-#include "fdset.h"
-
-/*!
- * \brief Create new fdset.
- *
- * Linux epoll() backend.
- *
- * \retval Pointer to initialized FDSET structure if successful.
- * \retval NULL on error.
- */
-fdset_t *fdset_epoll_new();
-
-/*!
- * \brief Destroy FDSET.
- *
- * \retval 0 if successful.
- * \retval -1 on error.
- */
-int fdset_epoll_destroy(fdset_t * fdset);
-
-/*!
- * \brief Add file descriptor to watched set.
- *
- * \param fdset Target set.
- * \param fd Added file descriptor.
- * \param events Mask of watched events.
- *
- * \retval 0 if successful.
- * \retval -1 on errors.
- */
-int fdset_epoll_add(fdset_t *fdset, int fd, int events);
-
-/*!
- * \brief Remove file descriptor from watched set.
- *
- * \param fdset Target set.
- * \param fd File descriptor to be removed.
- *
- * \retval 0 if successful.
- * \retval -1 on errors.
- */
-int fdset_epoll_remove(fdset_t *fdset, int fd);
-
-/*!
- * \brief Poll set for new events.
- *
- * \param fdset Target set.
- * \param timeout Timeout (OS_EV_FOREVER, OS_EV_NOWAIT or value in miliseconds).
- *
- * \retval Number of events if successful.
- * \retval -1 on errors.
- */
-int fdset_epoll_wait(fdset_t *fdset, int timeout);
-
-/*!
- * \brief Set event iterator to the beginning of last polled events.
- *
- * \param fdset Target set.
- * \param it Event iterator.
- *
- * \retval 0 if successful.
- * \retval -1 on errors.
- */
-int fdset_epoll_begin(fdset_t *fdset, fdset_it_t *it);
-
-/*!
- * \brief Set event iterator to the end of last polled events.
- *
- * \param fdset Target set.
- * \param it Event iterator.
- *
- * \retval 0 if successful.
- * \retval -1 on errors.
- */
-int fdset_epoll_end(fdset_t *fdset, fdset_it_t *it);
-
-/*!
- * \brief Set event iterator to the next event.
- *
- * Event iterator fd will be set to -1 if next event doesn't exist.
- *
- * \param fdset Target set.
- * \param it Event iterator.
- *
- * \retval 0 if successful.
- * \retval -1 on errors.
- */
-int fdset_epoll_next(fdset_t *fdset, fdset_it_t *it);
-
-/*!
- * \brief Returned name of epoll method.
- *
- * \retval Name if successful.
- * \retval NULL if no method was loaded (shouldn't happen).
- */
-const char* fdset_epoll_method();
-
-/*! \brief Exported API. */
-extern struct fdset_backend_t FDSET_EPOLL;
-
-#endif /* _KNOTD_FDSET_EPOLL_H_ */
-
-/*! @} */
diff --git a/src/common/fdset_kqueue.c b/src/common/fdset_kqueue.c
deleted file mode 100644
index 7c52f71..0000000
--- a/src/common/fdset_kqueue.c
+++ /dev/null
@@ -1,260 +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/>.
- */
-
-#include <config.h>
-#ifdef HAVE_KQUEUE
-
-#include <stdint.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/event.h>
-#include <sys/time.h>
-#include <time.h>
-
-#include "fdset_kqueue.h"
-
-#define OS_FDS_CHUNKSIZE 8 /*!< Number of pollfd structs in a chunk. */
-#define OS_FDS_KEEPCHUNKS 32 /*!< Will attempt to free memory when reached. */
-
-struct fdset_t {
- fdset_base_t _base;
- int kq;
- struct kevent *events;
- struct kevent *revents;
- size_t nfds;
- size_t reserved;
- size_t rreserved;
- size_t polled;
-};
-
-fdset_t *fdset_kqueue_new()
-{
- fdset_t *set = malloc(sizeof(fdset_t));
- if (set) {
- /* Blank memory. */
- memset(set, 0, sizeof(fdset_t));
-
- /* Create kqueue fd. */
- set->kq = kqueue();
- if (set->kq < 0) {
- free(set);
- set = 0;
- }
- }
-
- return set;
-}
-
-int fdset_kqueue_destroy(fdset_t * fdset)
-{
- if(fdset == NULL) {
- return -1;
- }
-
- /* Teardown kqueue. */
- close(fdset->kq);
-
- /* OK if NULL. */
- free(fdset->revents);
- free(fdset->events);
- free(fdset);
- return 0;
-}
-
-int fdset_kqueue_add(fdset_t *fdset, int fd, int events)
-{
- if (fdset == NULL || fd < 0 || events <= 0) {
- return -1;
- }
-
- /* Realloc needed. */
- int ret = 0;
- ret += mreserve((char **)&fdset->events, sizeof(struct kevent),
- fdset->nfds + 1, OS_FDS_CHUNKSIZE, &fdset->reserved);
- ret += mreserve((char **)&fdset->revents, sizeof(struct kevent),
- fdset->nfds + 1, OS_FDS_CHUNKSIZE, &fdset->rreserved);
- if (ret != 0) {
- return ret;
- }
-
- /* Add to kqueue set. */
- int evfilt = EVFILT_READ;
- EV_SET(&fdset->events[fdset->nfds], fd, evfilt,
- EV_ADD|EV_ENABLE, 0, 0, 0);
- memset(fdset->revents + fdset->nfds, 0, sizeof(struct kevent));
-
- ++fdset->nfds;
- return 0;
-}
-
-int fdset_kqueue_remove(fdset_t *fdset, int fd)
-{
- if (fdset == NULL || fd < 0) {
- return -1;
- }
-
- /* Find in set. */
- int pos = -1;
- for (int i = 0; i < fdset->nfds; ++i) {
- if (fdset->events[i].ident == fd) {
- pos = i;
- break;
- }
- }
-
- if (pos < 0) {
- return -1;
- }
-
- /* Remove filters. */
- EV_SET(&fdset->events[pos], fd, EVFILT_READ,
- EV_DISABLE|EV_DELETE, 0, 0, 0);
-
- /* Attempt to remove from set. */
- size_t remaining = ((fdset->nfds - pos) - 1) * sizeof(struct kevent);
- memmove(fdset->events + pos, fdset->events + (pos + 1), remaining);
-
- /* Attempt to remove from revents set. */
- pos = -1;
- for (int i = 0; i < fdset->nfds; ++i) {
- if (fdset->events[i].ident == fd) {
- pos = i;
- break;
- }
- }
- if (pos >= 0) {
- size_t remaining = ((fdset->nfds - pos) - 1) * sizeof(struct kevent);
- memmove(fdset->revents + pos, fdset->revents + (pos + 1), remaining);
- }
-
-
- /* Overwrite current item. */
- --fdset->nfds;
-
- /* Trim excessive memory if possible (retval is not interesting). */
- mreserve((char **)&fdset->events, sizeof(struct kevent),
- fdset->nfds, OS_FDS_CHUNKSIZE, &fdset->reserved);
- mreserve((char **)&fdset->revents, sizeof(struct kevent),
- fdset->nfds, OS_FDS_CHUNKSIZE, &fdset->rreserved);
-
- return 0;
-}
-
-int fdset_kqueue_wait(fdset_t *fdset, int timeout)
-{
- if (fdset == NULL || fdset->nfds < 1 || fdset->events == NULL) {
- return -1;
- }
-
- /* Set timeout. */
- struct timespec tmval;
- struct timespec *tm = NULL;
- if (timeout == 0) {
- tmval.tv_sec = tmval.tv_nsec = 0;
- tm = &tmval;
- } else if (timeout > 0) {
- tmval.tv_sec = timeout / 1000; /* ms -> s */
- timeout -= tmval.tv_sec * 1000; /* Cut off */
- tmval.tv_nsec = timeout * 1000000L; /* ms -> ns */
- tm = &tmval;
- }
-
- /* Poll new events. */
- fdset->polled = 0;
- int nfds = kevent(fdset->kq, fdset->events, fdset->nfds,
- fdset->revents, fdset->nfds, tm);
-
- /* Check. */
- if (nfds < 0) {
- return -1;
- }
-
- /* Events array is ordered from 0 to nfds. */
- fdset->polled = nfds;
- return nfds;
-}
-
-int fdset_kqueue_begin(fdset_t *fdset, fdset_it_t *it)
-{
- if (fdset == NULL || it == NULL) {
- return -1;
- }
-
- /* Find first. */
- it->pos = 0;
- it->fd = -1;
- return fdset_next(fdset, it);
-}
-
-int fdset_kqueue_end(fdset_t *fdset, fdset_it_t *it)
-{
- if (fdset == NULL || it == NULL || fdset->nfds < 1) {
- return -1;
- }
-
- /* Check for polled events. */
- if (fdset->polled < 1) {
- it->fd = -1;
- it->pos = 0;
- return -1;
- }
-
- /* No end found, ends on the beginning. */
- size_t nid = fdset->polled - 1;
- it->fd = fdset->revents[nid].ident;
- it->pos = nid;
- it->events = 0; /*! \todo Map events. */
- return -1;
-}
-
-int fdset_kqueue_next(fdset_t *fdset, fdset_it_t *it)
-{
- if (fdset == NULL || it == NULL || fdset->polled < 1) {
- return -1;
- }
-
- /* Check boundaries. */
- if (it->pos >= fdset->polled || it->pos >= fdset->nfds) {
- return -1;
- }
-
- /* Select next. */
- size_t nid = it->pos++;
- it->fd = fdset->revents[nid].ident;
- it->events = 0; /*! \todo Map events. */
- return 0;
-}
-
-const char* fdset_kqueue_method()
-{
- return "kqueue";
-}
-
-/* Package APIs. */
-struct fdset_backend_t FDSET_KQUEUE = {
- .fdset_new = fdset_kqueue_new,
- .fdset_destroy = fdset_kqueue_destroy,
- .fdset_add = fdset_kqueue_add,
- .fdset_remove = fdset_kqueue_remove,
- .fdset_wait = fdset_kqueue_wait,
- .fdset_begin = fdset_kqueue_begin,
- .fdset_end = fdset_kqueue_end,
- .fdset_next = fdset_kqueue_next,
- .fdset_method = fdset_kqueue_method
-};
-
-#endif
diff --git a/src/common/fdset_kqueue.h b/src/common/fdset_kqueue.h
deleted file mode 100644
index 4b650a7..0000000
--- a/src/common/fdset_kqueue.h
+++ /dev/null
@@ -1,132 +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/>.
- */
-/*!
- * \file fdset_kqueue.h
- *
- * \author Marek Vavrusa <marek.vavrusa@nic.cz>
- *
- * \brief Wrapper for kqueue I/O multiplexing.
- *
- * \addtogroup common_lib
- * @{
- */
-
-#ifndef _KNOTD_FDSET_KQUEUE_H_
-#define _KNOTD_FDSET_KQUEUE_H_
-
-#include "fdset.h"
-
-/*!
- * \brief Create new fdset.
- *
- * BSD kqueue() backend.
- *
- * \retval Pointer to initialized FDSET structure if successful.
- * \retval NULL on error.
- */
-fdset_t *fdset_kqueue_new();
-
-/*!
- * \brief Destroy FDSET.
- *
- * \retval 0 if successful.
- * \retval -1 on error.
- */
-int fdset_kqueue_destroy(fdset_t * fdset);
-
-/*!
- * \brief Add file descriptor to watched set.
- *
- * \param fdset Target set.
- * \param fd Added file descriptor.
- * \param events Mask of watched events.
- *
- * \retval 0 if successful.
- * \retval -1 on errors.
- */
-int fdset_kqueue_add(fdset_t *fdset, int fd, int events);
-
-/*!
- * \brief Remove file descriptor from watched set.
- *
- * \param fdset Target set.
- * \param fd File descriptor to be removed.
- *
- * \retval 0 if successful.
- * \retval -1 on errors.
- */
-int fdset_kqueue_remove(fdset_t *fdset, int fd);
-
-/*!
- * \brief Poll set for new events.
- *
- * \param fdset Target set.
- * \param timeout Timeout (OS_EV_FOREVER, OS_EV_NOWAIT or value in miliseconds).
- *
- * \retval Number of events if successful.
- * \retval -1 on errors.
- */
-int fdset_kqueue_wait(fdset_t *fdset, int timeout);
-
-/*!
- * \brief Set event iterator to the beginning of last polled events.
- *
- * \param fdset Target set.
- * \param it Event iterator.
- *
- * \retval 0 if successful.
- * \retval -1 on errors.
- */
-int fdset_kqueue_begin(fdset_t *fdset, fdset_it_t *it);
-
-/*!
- * \brief Set event iterator to the end of last polled events.
- *
- * \param fdset Target set.
- * \param it Event iterator.
- *
- * \retval 0 if successful.
- * \retval -1 on errors.
- */
-int fdset_kqueue_end(fdset_t *fdset, fdset_it_t *it);
-
-/*!
- * \brief Set event iterator to the next event.
- *
- * Event iterator fd will be set to -1 if next event doesn't exist.
- *
- * \param fdset Target set.
- * \param it Event iterator.
- *
- * \retval 0 if successful.
- * \retval -1 on errors.
- */
-int fdset_kqueue_next(fdset_t *fdset, fdset_it_t *it);
-
-/*!
- * \brief Returned name of kqueue method.
- *
- * \retval Name if successful.
- * \retval NULL if no method was loaded (shouldn't happen).
- */
-const char* fdset_kqueue_method();
-
-/*! \brief Exported API. */
-extern struct fdset_backend_t FDSET_KQUEUE;
-
-#endif /* _KNOTD_FDSET_KQUEUE_H_ */
-
-/*! @} */
diff --git a/src/common/fdset_poll.c b/src/common/fdset_poll.c
deleted file mode 100644
index e16ae11..0000000
--- a/src/common/fdset_poll.c
+++ /dev/null
@@ -1,218 +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/>.
- */
-
-#include <config.h>
-
-#ifdef HAVE_POLL
-
-#include <stdlib.h>
-#include <string.h>
-#include <sys/poll.h>
-#include <stddef.h>
-
-#include "common/fdset_poll.h"
-
-#define OS_FDS_CHUNKSIZE 8 /*!< Number of pollfd structs in a chunk. */
-
-struct fdset_t {
- fdset_base_t _base;
- struct pollfd *fds;
- nfds_t nfds;
- size_t reserved;
- size_t polled;
- size_t begin;
-};
-
-fdset_t *fdset_poll_new()
-{
- fdset_t *set = malloc(sizeof(fdset_t));
- if (set != NULL) {
- memset(set, 0, sizeof(fdset_t));
- }
-
- return set;
-}
-
-int fdset_poll_destroy(fdset_t * fdset)
-{
- if(fdset == NULL) {
- return -1;
- }
-
- /* OK if NULL. */
- free(fdset->fds);
- free(fdset);
- return 0;
-}
-
-int fdset_poll_add(fdset_t *fdset, int fd, int events)
-{
- if (fdset == NULL || fd < 0 || events <= 0) {
- return -1;
- }
-
- /* Realloc needed. */
- if (mreserve((char **)&fdset->fds, sizeof(struct pollfd),
- fdset->nfds + 1, OS_FDS_CHUNKSIZE, &fdset->reserved) < 0) {
- return -1;
- }
-
- /* Append. */
- int nid = fdset->nfds++;
- fdset->fds[nid].fd = fd;
- fdset->fds[nid].events = POLLIN;
- fdset->fds[nid].revents = 0;
- return 0;
-}
-
-int fdset_poll_remove(fdset_t *fdset, int fd)
-{
- if (fdset == NULL || fd < 0) {
- return -1;
- }
-
- /* Find file descriptor. */
- unsigned found = 0;
- size_t pos = 0;
- for (size_t i = 0; i < fdset->nfds; ++i) {
- if (fdset->fds[i].fd == fd) {
- found = 1;
- pos = i;
- break;
- }
- }
-
- /* Check. */
- if (!found) {
- return -1;
- }
-
- /* Overwrite current item. */
- size_t remaining = ((fdset->nfds - pos) - 1) * sizeof(struct pollfd);
- memmove(fdset->fds + pos, fdset->fds + (pos + 1), remaining);
- --fdset->nfds;
-
- /* Trim excessive memory if possible (retval is not interesting). */
- mreserve((char **)&fdset->fds, sizeof(struct pollfd), fdset->nfds,
- OS_FDS_CHUNKSIZE, &fdset->reserved);
-
- return 0;
-}
-
-int fdset_poll_wait(fdset_t *fdset, int timeout)
-{
- if (fdset == NULL || fdset->nfds < 1 || fdset->fds == NULL) {
- return -1;
- }
-
- /* Initialize pointers. */
- fdset->polled = 0;
- fdset->begin = 0;
-
- /* Poll for events. */
- int ret = poll(fdset->fds, fdset->nfds, timeout);
- if (ret < 0) {
- return -1;
- }
-
- /* Set pointers for iterating. */
- fdset->polled = ret;
- fdset->begin = 0;
- return ret;
-}
-
-int fdset_poll_begin(fdset_t *fdset, fdset_it_t *it)
-{
- if (fdset == NULL || it == NULL) {
- return -1;
- }
-
- /* Find first. */
- it->pos = 0;
- return fdset_next(fdset, it);
-}
-
-int fdset_poll_end(fdset_t *fdset, fdset_it_t *it)
-{
- if (fdset == NULL || it == NULL || fdset->nfds < 1) {
- return -1;
- }
-
- /* Check for polled events. */
- if (fdset->polled < 1) {
- it->fd = -1;
- it->pos = 0;
- return -1;
- }
-
- /* Trace last matching item from the end. */
- struct pollfd* pfd = fdset->fds + fdset->nfds - 1;
- while (pfd != fdset->fds) {
- if (pfd->events & pfd->revents) {
- it->fd = pfd->fd;
- it->pos = pfd - fdset->fds;
- return 0;
- }
- }
-
- /* No end found, ends on the beginning. */
- it->fd = -1;
- it->pos = 0;
- return -1;
-}
-
-int fdset_poll_next(fdset_t *fdset, fdset_it_t *it)
-{
- if (fdset == NULL || it == NULL || fdset->nfds < 1) {
- return -1;
- }
-
- /* Find next with matching flags. */
- for (; it->pos < fdset->nfds; ++it->pos) {
- struct pollfd* pfd = fdset->fds + it->pos;
- if (pfd->events & pfd->revents) {
- it->fd = pfd->fd;
- it->events = pfd->revents;
- ++it->pos; /* Next will start after current. */
- return 0;
- }
- }
-
- /* No matching event found. */
- it->fd = -1;
- it->pos = 0;
- return -1;
-}
-
-const char* fdset_poll_method()
-{
- return "poll";
-}
-
-/* Package APIs. */
-struct fdset_backend_t FDSET_POLL = {
- .fdset_new = fdset_poll_new,
- .fdset_destroy = fdset_poll_destroy,
- .fdset_add = fdset_poll_add,
- .fdset_remove = fdset_poll_remove,
- .fdset_wait = fdset_poll_wait,
- .fdset_begin = fdset_poll_begin,
- .fdset_end = fdset_poll_end,
- .fdset_next = fdset_poll_next,
- .fdset_method = fdset_poll_method
-};
-
-#endif
diff --git a/src/common/fdset_poll.h b/src/common/fdset_poll.h
deleted file mode 100644
index 68e9e69..0000000
--- a/src/common/fdset_poll.h
+++ /dev/null
@@ -1,132 +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/>.
- */
-/*!
- * \file fdset_poll.h
- *
- * \author Marek Vavrusa <marek.vavrusa@nic.cz>
- *
- * \brief Wrapper for poll I/O multiplexing.
- *
- * \addtogroup common_lib
- * @{
- */
-
-#ifndef _KNOTD_FDSET_POLL_H_
-#define _KNOTD_FDSET_POLL_H_
-
-#include "fdset.h"
-
-/*!
- * \brief Create new fdset.
- *
- * POSIX poll() backend.
- *
- * \retval Pointer to initialized FDSET structure if successful.
- * \retval NULL on error.
- */
-fdset_t *fdset_poll_new();
-
-/*!
- * \brief Destroy FDSET.
- *
- * \retval 0 if successful.
- * \retval -1 on error.
- */
-int fdset_poll_destroy(fdset_t * fdset);
-
-/*!
- * \brief Add file descriptor to watched set.
- *
- * \param fdset Target set.
- * \param fd Added file descriptor.
- * \param events Mask of watched events.
- *
- * \retval 0 if successful.
- * \retval -1 on errors.
- */
-int fdset_poll_add(fdset_t *fdset, int fd, int events);
-
-/*!
- * \brief Remove file descriptor from watched set.
- *
- * \param fdset Target set.
- * \param fd File descriptor to be removed.
- *
- * \retval 0 if successful.
- * \retval -1 on errors.
- */
-int fdset_poll_remove(fdset_t *fdset, int fd);
-
-/*!
- * \brief Poll set for new events.
- *
- * \param fdset Target set.
- * \param timeout Timeout (OS_EV_FOREVER, OS_EV_NOWAIT or value in miliseconds).
- *
- * \retval Number of events if successful.
- * \retval -1 on errors.
- */
-int fdset_poll_wait(fdset_t *fdset, int timeout);
-
-/*!
- * \brief Set event iterator to the beginning of last polled events.
- *
- * \param fdset Target set.
- * \param it Event iterator.
- *
- * \retval 0 if successful.
- * \retval -1 on errors.
- */
-int fdset_poll_begin(fdset_t *fdset, fdset_it_t *it);
-
-/*!
- * \brief Set event iterator to the end of last polled events.
- *
- * \param fdset Target set.
- * \param it Event iterator.
- *
- * \retval 0 if successful.
- * \retval -1 on errors.
- */
-int fdset_poll_end(fdset_t *fdset, fdset_it_t *it);
-
-/*!
- * \brief Set event iterator to the next event.
- *
- * Event iterator fd will be set to -1 if next event doesn't exist.
- *
- * \param fdset Target set.
- * \param it Event iterator.
- *
- * \retval 0 if successful.
- * \retval -1 on errors.
- */
-int fdset_poll_next(fdset_t *fdset, fdset_it_t *it);
-
-/*!
- * \brief Returned name of poll method.
- *
- * \retval Name if successful.
- * \retval NULL if no method was loaded (shouldn't happen).
- */
-const char* fdset_poll_method();
-
-/*! \brief Exported API. */
-extern struct fdset_backend_t FDSET_POLL;
-
-#endif /* _KNOTD_FDSET_POLL_H_ */
-
-/*! @} */
diff --git a/src/config.h.in b/src/config.h.in
index 656c8ef..73c4e3f 100644
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -39,9 +39,6 @@
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
-/* Define to 1 if you have the `epoll_wait' function. */
-#undef HAVE_EPOLL_WAIT
-
/* Define to 1 if you have the `fgetln' function. */
#undef HAVE_FGETLN
@@ -54,9 +51,6 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
-/* Define to 1 if you have the `kqueue' function. */
-#undef HAVE_KQUEUE
-
/* Define to 1 if you have the `madvise' function. */
#undef HAVE_MADVISE
@@ -157,6 +151,9 @@
declarations. */
#undef HAVE_VISIBILITY
+/* integrity check in knotd */
+#undef INTEGRITY_CHECK
+
/* Server debug. */
#undef KNOTD_SERVER_DEBUG
diff --git a/src/knot/conf/cf-parse.y b/src/knot/conf/cf-parse.y
index 663adad..9b277ab 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");
@@ -989,7 +985,8 @@ log_start:
| log_start log_file '{' log_src '}'
;
-log: LOG '{' log_start log_end;
+log: LOG { new_config->logs_count = 0; } '{' log_start log_end
+ ;
ctl_listen_start:
LISTEN_ON { conf_init_iface(scanner, NULL, -1); }
diff --git a/src/knot/conf/conf.c b/src/knot/conf/conf.c
index 9ed354a..9830c04 100644
--- a/src/knot/conf/conf.c
+++ b/src/knot/conf/conf.c
@@ -249,7 +249,8 @@ static int conf_process(conf_t *conf)
}
/* Default parallel transfers. */
- if (conf->xfers <= 0) conf->xfers = CONFIG_XFERS;
+ if (conf->xfers <= 0)
+ conf->xfers = CONFIG_XFERS;
// Postprocess zones
int ret = KNOT_EOK;
@@ -393,7 +394,7 @@ void __attribute__ ((constructor)) conf_init()
map->prios = LOG_MASK(LOG_WARNING)|LOG_MASK(LOG_ERR);
add_tail(&log->map, &map->n);
add_tail(&s_config->logs, &log->n);
- ++s_config->logs_count;
+ s_config->logs_count = 1;
/* Stderr */
log = malloc(sizeof(conf_log_t));
@@ -529,6 +530,7 @@ conf_t *conf_new(const char* path)
c->xfers = -1;
c->rrl_slip = -1;
c->build_diffs = 0; /* Disable by default. */
+ c->logs_count = -1;
/* ACLs. */
c->ctl.acl = acl_new(ACL_DENY, "remote_ctl");
@@ -633,7 +635,7 @@ void conf_truncate(conf_t *conf, int unload_hooks)
WALK_LIST_DELSAFE(n, nxt, conf->logs) {
conf_free_log((conf_log_t*)n);
}
- conf->logs_count = 0;
+ conf->logs_count = -1;
init_list(&conf->logs);
// Free remote interfaces
@@ -680,6 +682,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 57b250e..30075c3 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/conf/libknotd_la-cf-parse.c b/src/knot/conf/libknotd_la-cf-parse.c
index 52280ca..2cea00d 100644
--- a/src/knot/conf/libknotd_la-cf-parse.c
+++ b/src/knot/conf/libknotd_la-cf-parse.c
@@ -830,16 +830,16 @@ union yyalloc
/* YYFINAL -- State number of the termination state. */
#define YYFINAL 3
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 280
+#define YYLAST 281
/* YYNTOKENS -- Number of terminals. */
#define YYNTOKENS 66
/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 34
+#define YYNNTS 35
/* YYNRULES -- Number of rules. */
-#define YYNRULES 146
+#define YYNRULES 147
/* YYNRULES -- Number of states. */
-#define YYNSTATES 290
+#define YYNSTATES 291
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
#define YYUNDEFTOK 2
@@ -903,14 +903,14 @@ static const yytype_uint16 yyprhs[] =
356, 361, 366, 371, 376, 381, 386, 391, 394, 398,
403, 408, 413, 418, 423, 428, 433, 438, 443, 444,
446, 450, 454, 455, 459, 461, 464, 465, 466, 472,
- 478, 483, 485, 487, 490, 496, 501, 507, 511, 513,
- 516, 519, 522, 525, 528, 531, 534
+ 478, 479, 485, 487, 489, 492, 498, 503, 509, 513,
+ 515, 518, 521, 524, 527, 530, 533, 536
};
/* YYRHS -- A `-1'-separated list of the rules' RHS. */
static const yytype_int8 yyrhs[] =
{
- 67, 0, -1, 68, 3, -1, -1, 68, 99, -1,
+ 67, 0, -1, 68, 3, -1, -1, 68, 100, -1,
-1, 5, -1, 24, -1, 58, -1, 56, -1, 59,
-1, 53, -1, -1, 70, 49, 7, 60, -1, 70,
48, 50, 60, -1, 70, 48, 50, 61, 7, 60,
@@ -957,13 +957,13 @@ static const yytype_int8 yyrhs[] =
8, 60, -1, -1, 88, -1, 89, 59, 65, -1,
89, 59, 60, -1, -1, 90, 58, 89, -1, 57,
-1, 27, 5, -1, -1, -1, 94, 91, 62, 90,
- 63, -1, 94, 92, 62, 90, 63, -1, 56, 62,
- 94, 93, -1, 55, -1, 54, -1, 53, 62, -1,
- 98, 96, 62, 70, 63, -1, 98, 96, 5, 60,
- -1, 98, 97, 62, 84, 63, -1, 98, 97, 83,
- -1, 60, -1, 72, 63, -1, 71, 63, -1, 73,
- 63, -1, 76, 63, -1, 80, 63, -1, 87, 63,
- -1, 95, 63, -1, 98, 63, -1
+ 63, -1, 94, 92, 62, 90, 63, -1, -1, 56,
+ 96, 62, 94, 93, -1, 55, -1, 54, -1, 53,
+ 62, -1, 99, 97, 62, 70, 63, -1, 99, 97,
+ 5, 60, -1, 99, 98, 62, 84, 63, -1, 99,
+ 98, 83, -1, 60, -1, 72, 63, -1, 71, 63,
+ -1, 73, 63, -1, 76, 63, -1, 80, 63, -1,
+ 87, 63, -1, 95, 63, -1, 99, 63, -1
};
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
@@ -971,19 +971,19 @@ static const yytype_uint16 yyrline[] =
{
0, 448, 448, 450, 452, 455, 456, 457, 458, 459,
460, 461, 464, 465, 472, 480, 493, 501, 517, 518,
- 526, 527, 528, 529, 530, 531, 532, 533, 534, 539,
- 544, 551, 572, 573, 574, 575, 576, 577, 578, 579,
- 583, 584, 635, 636, 637, 638, 639, 640, 643, 644,
- 651, 660, 669, 683, 692, 701, 715, 723, 727, 731,
- 738, 739, 747, 750, 752, 753, 757, 761, 762, 766,
- 769, 772, 775, 778, 783, 784, 785, 786, 787, 788,
- 791, 792, 793, 796, 797, 825, 826, 827, 828, 829,
- 830, 831, 832, 849, 853, 854, 855, 856, 857, 858,
- 859, 860, 861, 862, 863, 864, 871, 881, 882, 883,
- 884, 885, 886, 887, 888, 895, 902, 909, 912, 921,
- 922, 923, 926, 927, 933, 956, 983, 987, 988, 989,
- 992, 995, 999, 1005, 1006, 1013, 1019, 1020, 1023, 1023,
- 1023, 1023, 1023, 1023, 1023, 1023, 1023
+ 526, 527, 528, 529, 530, 531, 532, 533, 534, 535,
+ 540, 547, 568, 569, 570, 571, 572, 573, 574, 575,
+ 579, 580, 631, 632, 633, 634, 635, 636, 639, 640,
+ 647, 656, 665, 679, 688, 697, 711, 719, 723, 727,
+ 734, 735, 743, 746, 748, 749, 753, 757, 758, 762,
+ 765, 768, 771, 774, 779, 780, 781, 782, 783, 784,
+ 787, 788, 789, 792, 793, 821, 822, 823, 824, 825,
+ 826, 827, 828, 845, 849, 850, 851, 852, 853, 854,
+ 855, 856, 857, 858, 859, 860, 867, 877, 878, 879,
+ 880, 881, 882, 883, 884, 891, 898, 905, 908, 917,
+ 918, 919, 922, 923, 929, 952, 979, 983, 984, 985,
+ 988, 988, 992, 996, 1002, 1003, 1010, 1016, 1017, 1020,
+ 1020, 1020, 1020, 1020, 1020, 1020, 1020, 1020
};
#endif
@@ -1008,7 +1008,7 @@ static const char *const yytname[] =
"group_member", "group", "group_start", "groups", "zone_acl_start",
"zone_acl_item", "zone_acl_list", "zone_acl", "zone_start", "zone",
"zones", "log_prios_start", "log_prios", "log_src", "log_dest",
- "log_file", "log_end", "log_start", "log", "ctl_listen_start",
+ "log_file", "log_end", "log_start", "log", "$@1", "ctl_listen_start",
"ctl_allow_start", "control", "conf", 0
};
#endif
@@ -1044,8 +1044,8 @@ static const yytype_uint8 yyr1[] =
86, 86, 86, 86, 86, 86, 86, 87, 87, 87,
87, 87, 87, 87, 87, 87, 87, 87, 88, 89,
89, 89, 90, 90, 91, 92, 93, 94, 94, 94,
- 95, 96, 97, 98, 98, 98, 98, 98, 99, 99,
- 99, 99, 99, 99, 99, 99, 99
+ 96, 95, 97, 98, 99, 99, 99, 99, 99, 100,
+ 100, 100, 100, 100, 100, 100, 100, 100
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
@@ -1064,8 +1064,8 @@ static const yytype_uint8 yyr2[] =
4, 4, 4, 4, 4, 4, 4, 2, 3, 4,
4, 4, 4, 4, 4, 4, 4, 4, 0, 1,
3, 3, 0, 3, 1, 2, 0, 0, 5, 5,
- 4, 1, 1, 2, 5, 4, 5, 3, 1, 2,
- 2, 2, 2, 2, 2, 2, 2
+ 0, 5, 1, 1, 2, 5, 4, 5, 3, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2
};
/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
@@ -1074,43 +1074,44 @@ static const yytype_uint8 yyr2[] =
static const yytype_uint8 yydefact[] =
{
3, 0, 0, 1, 2, 0, 0, 0, 0, 0,
- 0, 0, 0, 138, 5, 0, 0, 42, 0, 85,
- 0, 0, 4, 20, 40, 60, 67, 107, 18, 133,
- 127, 6, 7, 11, 9, 8, 10, 140, 0, 0,
+ 0, 0, 130, 139, 5, 0, 0, 42, 0, 85,
+ 0, 0, 4, 20, 40, 60, 67, 107, 18, 134,
+ 0, 6, 7, 11, 9, 8, 10, 141, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 139, 0, 141, 43,
- 47, 45, 44, 46, 142, 0, 66, 143, 0, 93,
+ 0, 0, 0, 0, 0, 0, 140, 0, 142, 43,
+ 47, 45, 44, 46, 143, 0, 66, 144, 0, 93,
0, 86, 87, 0, 0, 0, 0, 0, 0, 0,
- 91, 89, 88, 90, 144, 0, 0, 145, 132, 131,
- 146, 0, 80, 126, 12, 0, 0, 0, 0, 0,
+ 91, 89, 88, 90, 145, 0, 0, 146, 133, 132,
+ 147, 0, 80, 127, 12, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 48, 63, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 94, 0, 0,
0, 0, 0, 0, 0, 69, 70, 73, 71, 72,
- 0, 108, 80, 0, 12, 83, 137, 0, 124, 0,
- 0, 130, 0, 22, 23, 21, 25, 24, 26, 0,
- 30, 31, 27, 28, 32, 33, 34, 35, 37, 36,
- 38, 39, 0, 0, 62, 64, 0, 92, 109, 111,
- 114, 115, 116, 117, 113, 112, 110, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 83, 96, 135,
- 0, 0, 75, 79, 77, 76, 78, 0, 125, 122,
- 122, 0, 0, 19, 29, 41, 0, 0, 0, 0,
- 61, 68, 0, 97, 100, 99, 105, 106, 101, 102,
- 104, 103, 98, 0, 134, 0, 136, 82, 81, 0,
+ 0, 108, 80, 0, 12, 83, 138, 126, 0, 22,
+ 23, 21, 25, 24, 26, 0, 30, 31, 27, 28,
+ 32, 33, 34, 35, 37, 36, 38, 39, 0, 0,
+ 62, 64, 0, 92, 109, 111, 114, 115, 116, 117,
+ 113, 112, 110, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 83, 96, 136, 0, 0, 75, 79,
+ 77, 76, 78, 0, 0, 124, 0, 0, 131, 0,
+ 0, 19, 29, 41, 0, 0, 0, 0, 61, 68,
+ 0, 97, 100, 99, 105, 106, 101, 102, 104, 103,
+ 98, 0, 135, 0, 137, 82, 81, 125, 122, 122,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 65, 95, 84, 118, 128, 129, 14, 0, 16,
- 0, 13, 56, 50, 0, 0, 53, 0, 0, 49,
- 59, 57, 58, 119, 123, 0, 0, 0, 0, 0,
- 0, 0, 15, 17, 52, 51, 55, 54, 121, 120
+ 65, 95, 84, 0, 0, 14, 0, 16, 0, 13,
+ 56, 50, 0, 0, 53, 0, 0, 49, 59, 57,
+ 58, 118, 128, 129, 0, 0, 0, 0, 0, 0,
+ 119, 123, 15, 17, 52, 51, 55, 54, 0, 121,
+ 120
};
/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int16 yydefgoto[] =
{
- -1, 1, 2, 38, 152, 14, 15, 16, 65, 173,
- 17, 175, 176, 68, 18, 142, 207, 146, 201, 85,
- 86, 19, 273, 274, 239, 149, 150, 151, 93, 20,
- 91, 92, 21, 22
+ -1, 1, 2, 38, 148, 14, 15, 16, 65, 169,
+ 17, 171, 172, 68, 18, 142, 203, 146, 197, 85,
+ 86, 19, 280, 281, 253, 206, 207, 208, 147, 20,
+ 30, 91, 92, 21, 22
};
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
@@ -1119,43 +1120,44 @@ static const yytype_int16 yydefgoto[] =
static const yytype_int16 yypact[] =
{
-47, 30, 72, -47, -47, -25, 12, 22, 42, 58,
- 67, 68, 69, -47, 14, 93, 0, 23, 1, 3,
+ 67, 68, -47, -47, 14, 93, 0, 23, 1, 3,
5, -42, -47, -47, -47, -47, -47, -47, -47, -47,
- -47, -47, -47, -47, -47, -47, -47, -47, 91, 119,
+ 69, -47, -47, -47, -47, -47, -47, -47, 91, 119,
149, 150, 38, 152, 52, 151, 154, 155, 156, 157,
158, 159, 161, 9, 162, 163, -47, 143, -47, -47,
-47, -47, -47, -47, -47, 101, -47, -47, 102, -47,
107, -47, -47, 164, 165, 166, 170, 87, 71, 168,
-47, -47, -47, -47, -47, 110, 113, -47, -47, -47,
- -47, -4, 117, -18, -47, 120, 121, 122, 123, 124,
+ -47, -4, 117, -47, -47, 120, 121, 122, 123, 124,
125, 181, 127, 128, 129, 130, 131, 132, 133, 134,
135, 136, 137, 138, 194, -47, 195, 196, 142, 144,
145, 146, 147, 148, 153, 160, 167, -47, 198, 199,
200, 204, 205, 92, 78, -47, -47, -47, -47, -47,
- 206, -47, 169, 172, -47, -47, -5, 209, -47, 171,
- 173, -47, -46, -47, -47, -47, -47, -47, -47, 174,
- -47, -47, -47, -47, -47, -47, -47, -47, -47, -47,
- -47, -47, 176, 40, -47, -47, 28, -47, -47, -47,
- -47, -47, -47, -47, -47, -47, -47, 177, 178, 179,
- 180, 182, 183, 184, 185, 186, 187, -47, -5, -47,
- -34, 2, -47, -47, -47, -47, -47, -40, -47, -47,
- -47, 51, 208, -47, -47, -47, 212, 61, 211, -1,
- -47, -47, 195, -47, -47, -47, -47, -47, -47, -47,
- -47, -47, -47, 6, -47, 188, -47, -47, -47, -17,
- -11, 62, 66, 189, 190, -38, 57, 191, 192, 193,
- 197, -47, -47, -47, -47, -47, -47, -47, 214, -47,
- 215, -47, -47, -47, 216, 217, -47, 218, 219, -47,
- -47, -47, -47, -47, 201, 202, 203, 207, 210, 213,
- 220, -20, -47, -47, -47, -47, -47, -47, -47, -47
+ 206, -47, 169, 172, -47, -47, -5, -18, -46, -47,
+ -47, -47, -47, -47, -47, 173, -47, -47, -47, -47,
+ -47, -47, -47, -47, -47, -47, -47, -47, 174, 40,
+ -47, -47, 28, -47, -47, -47, -47, -47, -47, -47,
+ -47, -47, -47, 175, 176, 177, 178, 179, 180, 182,
+ 183, 184, 185, -47, -5, -47, -34, 2, -47, -47,
+ -47, -47, -47, -40, 209, -47, 186, 187, -47, 51,
+ 208, -47, -47, -47, 212, 61, 211, -1, -47, -47,
+ 195, -47, -47, -47, -47, -47, -47, -47, -47, -47,
+ -47, 6, -47, 190, -47, -47, -47, -47, -47, -47,
+ 62, 66, 191, 192, -38, 57, 193, 197, 201, 202,
+ -47, -47, -47, -17, -11, -47, 214, -47, 215, -47,
+ -47, -47, 216, 217, -47, 218, 219, -47, -47, -47,
+ -47, -47, -47, -47, 203, 207, 210, 213, 220, 221,
+ -47, 171, -47, -47, -47, -47, -47, -47, -20, -47,
+ -47
};
/* YYPGOTO[NTERM-NUM]. */
static const yytype_int8 yypgoto[] =
{
-47, -47, -47, -47, 75, -47, -47, -47, -47, -47,
- -47, 7, -47, -47, -47, -47, -47, 86, 33, -47,
- -47, -47, -47, -47, 31, -47, -47, -47, -47, -47,
- -47, -47, -47, -47
+ -47, 8, -47, -47, -47, -47, -47, 99, 36, -47,
+ -47, -47, -47, -47, 7, -47, -47, -47, -47, -47,
+ -47, -47, -47, -47, -47
};
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
@@ -1164,35 +1166,35 @@ static const yytype_int8 yypgoto[] =
#define YYTABLE_NINF -75
static const yytype_int16 yytable[] =
{
- 202, 143, 211, 212, 248, 57, 66, 235, 69, 147,
- 70, 235, 88, 89, 211, 212, 110, 213, 111, 31,
- 237, 90, 263, 264, 71, 238, 265, 72, 59, 234,
- 3, 73, 74, 75, 76, 77, 78, 23, 32, 148,
- 288, 254, 79, 98, 99, 289, 255, 254, 203, 249,
- 250, 204, 256, 205, 206, -74, 80, 216, 144, 81,
- -74, 82, 83, 58, 67, 236, 84, 33, 87, 252,
+ 198, 143, 209, 210, 247, 57, 66, 233, 69, 204,
+ 70, 233, 88, 89, 209, 210, 110, 211, 111, 31,
+ 235, 90, 261, 262, 71, 236, 263, 72, 59, 232,
+ 3, 73, 74, 75, 76, 77, 78, 23, 32, 205,
+ 289, 271, 79, 98, 99, 290, 272, 271, 199, 248,
+ 249, 200, 273, 201, 202, -74, 80, 214, 144, 81,
+ -74, 82, 83, 58, 67, 234, 84, 33, 87, 251,
34, 101, 35, 36, 24, 4, 60, 37, 124, 61,
- 125, 62, 63, 5, 25, 194, 64, 195, 217, 218,
- 6, 221, 219, 222, 122, 123, 7, 8, 9, 192,
- 193, 241, 242, 220, 26, 39, 40, 41, 42, 43,
- 44, 245, 246, 45, 46, 47, 48, 266, 267, 10,
- 27, 268, 257, 258, 95, 11, 259, 260, 12, 28,
- 29, 30, 13, 49, 50, 51, 52, 53, 54, 55,
+ 125, 62, 63, 5, 25, 190, 64, 191, 215, 216,
+ 6, 219, 217, 220, 122, 123, 7, 8, 9, 188,
+ 189, 240, 241, 218, 26, 39, 40, 41, 42, 43,
+ 44, 244, 245, 45, 46, 47, 48, 264, 265, 10,
+ 27, 266, 255, 256, 95, 11, 257, 258, 12, 28,
+ 29, 93, 13, 49, 50, 51, 52, 53, 54, 55,
128, 129, 130, 131, 132, 133, 134, 135, 136, 137,
138, 139, 140, 94, 96, 97, 56, 100, 102, 103,
104, 105, 114, 115, 116, 106, 107, 108, 109, 112,
113, 117, 127, 120, 118, 119, 141, 121, 126, 145,
- 153, 154, 155, 156, 157, 158, 159, 160, 161, 162,
- 163, 164, 165, 166, 167, 168, 169, 170, 171, 172,
- 174, 177, 178, 187, 179, 180, 181, 182, 183, 188,
- 189, 190, 191, 184, 208, 243, 196, 244, 247, 200,
- 185, 275, 276, 277, 278, 279, 280, 186, 198, 251,
- 233, 197, 199, 209, 214, 210, 215, 223, 224, 225,
- 226, 240, 227, 228, 229, 230, 231, 232, 253, 261,
- 262, 269, 270, 271, 0, 0, 0, 272, 0, 0,
- 281, 0, 282, 283, 0, 0, 0, 284, 0, 0,
- 285, 0, 0, 286, 0, 0, 0, 0, 0, 0,
- 287
+ 149, 150, 151, 152, 153, 154, 155, 156, 157, 158,
+ 159, 160, 161, 162, 163, 164, 165, 166, 167, 168,
+ 170, 173, 174, 183, 175, 176, 177, 178, 179, 184,
+ 185, 186, 187, 180, 237, 242, 192, 243, 246, 196,
+ 181, 274, 275, 276, 277, 278, 279, 182, 250, 231,
+ 288, 193, 195, 212, 213, 221, 222, 223, 224, 225,
+ 226, 194, 227, 228, 229, 230, 254, 0, 238, 239,
+ 252, 259, 260, 267, 0, 0, 0, 268, 0, 0,
+ 0, 269, 270, 282, 0, 0, 0, 283, 0, 0,
+ 284, 0, 0, 285, 0, 0, 0, 0, 0, 0,
+ 286, 287
};
#define yypact_value_is_default(yystate) \
@@ -1225,13 +1227,13 @@ static const yytype_int16 yycheck[] =
60, 60, 60, 60, 60, 60, 60, 60, 60, 5,
5, 5, 60, 5, 60, 60, 60, 60, 60, 10,
10, 7, 7, 60, 5, 7, 10, 5, 7, 144,
- 60, 7, 7, 7, 7, 7, 7, 60, 142, 222,
- 197, 62, 60, 62, 60, 62, 60, 60, 60, 60,
- 60, 210, 60, 60, 60, 60, 60, 60, 60, 60,
+ 60, 7, 7, 7, 7, 7, 7, 60, 220, 193,
+ 59, 62, 60, 60, 60, 60, 60, 60, 60, 60,
+ 60, 142, 60, 60, 60, 60, 239, -1, 62, 62,
60, 60, 60, 60, -1, -1, -1, 60, -1, -1,
- 59, -1, 60, 60, -1, -1, -1, 60, -1, -1,
+ -1, 60, 60, 60, -1, -1, -1, 60, -1, -1,
60, -1, -1, 60, -1, -1, -1, -1, -1, -1,
- 60
+ 60, 60
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
@@ -1240,33 +1242,34 @@ static const yytype_uint8 yystos[] =
{
0, 67, 68, 0, 3, 11, 18, 24, 25, 26,
47, 53, 56, 60, 71, 72, 73, 76, 80, 87,
- 95, 98, 99, 62, 62, 62, 62, 62, 62, 62,
- 62, 5, 24, 53, 56, 58, 59, 63, 69, 12,
+ 95, 99, 100, 62, 62, 62, 62, 62, 62, 62,
+ 96, 5, 24, 53, 56, 58, 59, 63, 69, 12,
13, 14, 15, 16, 17, 20, 21, 22, 23, 40,
41, 42, 43, 44, 45, 46, 63, 5, 63, 5,
53, 56, 58, 59, 63, 74, 5, 63, 79, 5,
7, 21, 24, 28, 29, 30, 31, 32, 33, 39,
53, 56, 58, 59, 63, 85, 86, 63, 54, 55,
- 63, 96, 97, 94, 62, 5, 5, 5, 5, 6,
+ 63, 97, 98, 62, 62, 5, 5, 5, 5, 6,
5, 19, 7, 5, 5, 5, 8, 8, 8, 7,
7, 9, 7, 7, 19, 62, 62, 64, 10, 10,
7, 7, 7, 8, 7, 9, 10, 62, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
- 39, 63, 81, 5, 62, 62, 83, 27, 57, 91,
- 92, 93, 70, 60, 60, 60, 60, 60, 60, 5,
- 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
- 60, 60, 5, 75, 5, 77, 78, 5, 60, 60,
- 60, 60, 60, 60, 60, 60, 60, 5, 10, 10,
- 7, 7, 7, 8, 7, 9, 10, 62, 83, 60,
- 70, 84, 5, 53, 56, 58, 59, 82, 5, 62,
- 62, 48, 49, 63, 60, 60, 17, 48, 49, 52,
- 63, 63, 65, 60, 60, 60, 60, 60, 60, 60,
- 60, 60, 60, 84, 63, 5, 63, 60, 65, 90,
- 90, 50, 51, 7, 5, 50, 51, 7, 5, 50,
- 51, 77, 63, 60, 58, 63, 63, 60, 61, 60,
- 61, 60, 60, 60, 61, 64, 60, 61, 64, 60,
- 60, 60, 60, 88, 89, 7, 7, 7, 7, 7,
- 7, 59, 60, 60, 60, 60, 60, 60, 60, 65
+ 39, 63, 81, 5, 62, 62, 83, 94, 70, 60,
+ 60, 60, 60, 60, 60, 5, 60, 60, 60, 60,
+ 60, 60, 60, 60, 60, 60, 60, 60, 5, 75,
+ 5, 77, 78, 5, 60, 60, 60, 60, 60, 60,
+ 60, 60, 60, 5, 10, 10, 7, 7, 7, 8,
+ 7, 9, 10, 62, 83, 60, 70, 84, 5, 53,
+ 56, 58, 59, 82, 27, 57, 91, 92, 93, 48,
+ 49, 63, 60, 60, 17, 48, 49, 52, 63, 63,
+ 65, 60, 60, 60, 60, 60, 60, 60, 60, 60,
+ 60, 84, 63, 5, 63, 60, 65, 5, 62, 62,
+ 50, 51, 7, 5, 50, 51, 7, 5, 50, 51,
+ 77, 63, 60, 90, 90, 60, 61, 60, 61, 60,
+ 60, 60, 61, 64, 60, 61, 64, 60, 60, 60,
+ 60, 58, 63, 63, 7, 7, 7, 7, 7, 7,
+ 88, 89, 60, 60, 60, 60, 60, 60, 59, 60,
+ 65
};
#define yyerrok (yyerrstatus = 0)
@@ -2297,17 +2300,13 @@ yyreduce:
/* Line 1806 of yacc.c */
#line 534 "cf-parse.y"
- {
- fprintf(stderr, "warning: Config option 'system.pidfile' is deprecated "
- "and has no effect. Use 'rundir' instead.\n");
- free((yyvsp[(3) - (4)].tok).t);
- }
+ { new_config->pidfile = (yyvsp[(3) - (4)].tok).t; }
break;
case 29:
/* Line 1806 of yacc.c */
-#line 539 "cf-parse.y"
+#line 535 "cf-parse.y"
{
fprintf(stderr, "warning: Config option 'system.key' is deprecated "
"and has no effect.\n");
@@ -2318,7 +2317,7 @@ yyreduce:
case 30:
/* Line 1806 of yacc.c */
-#line 544 "cf-parse.y"
+#line 540 "cf-parse.y"
{
if ((yyvsp[(3) - (4)].tok).i <= 0) {
cf_error(scanner, "worker count must be greater than 0\n");
@@ -2331,7 +2330,7 @@ yyreduce:
case 31:
/* Line 1806 of yacc.c */
-#line 551 "cf-parse.y"
+#line 547 "cf-parse.y"
{
new_config->uid = new_config->gid = -1; // Invalidate
char* dpos = strchr((yyvsp[(3) - (4)].tok).t, '.'); // Find uid.gid format
@@ -2358,63 +2357,63 @@ yyreduce:
case 32:
/* Line 1806 of yacc.c */
-#line 572 "cf-parse.y"
+#line 568 "cf-parse.y"
{ new_config->max_conn_idle = (yyvsp[(3) - (4)].tok).i; }
break;
case 33:
/* Line 1806 of yacc.c */
-#line 573 "cf-parse.y"
+#line 569 "cf-parse.y"
{ new_config->max_conn_hs = (yyvsp[(3) - (4)].tok).i; }
break;
case 34:
/* Line 1806 of yacc.c */
-#line 574 "cf-parse.y"
+#line 570 "cf-parse.y"
{ new_config->max_conn_reply = (yyvsp[(3) - (4)].tok).i; }
break;
case 35:
/* Line 1806 of yacc.c */
-#line 575 "cf-parse.y"
+#line 571 "cf-parse.y"
{ new_config->rrl = (yyvsp[(3) - (4)].tok).i; }
break;
case 36:
/* Line 1806 of yacc.c */
-#line 576 "cf-parse.y"
+#line 572 "cf-parse.y"
{ new_config->rrl_size = (yyvsp[(3) - (4)].tok).l; }
break;
case 37:
/* Line 1806 of yacc.c */
-#line 577 "cf-parse.y"
+#line 573 "cf-parse.y"
{ new_config->rrl_size = (yyvsp[(3) - (4)].tok).i; }
break;
case 38:
/* Line 1806 of yacc.c */
-#line 578 "cf-parse.y"
+#line 574 "cf-parse.y"
{ new_config->rrl_slip = (yyvsp[(3) - (4)].tok).i; }
break;
case 39:
/* Line 1806 of yacc.c */
-#line 579 "cf-parse.y"
+#line 575 "cf-parse.y"
{ new_config->xfers = (yyvsp[(3) - (4)].tok).i; }
break;
case 41:
/* Line 1806 of yacc.c */
-#line 584 "cf-parse.y"
+#line 580 "cf-parse.y"
{
/* Check algorithm length. */
if (knot_tsig_digest_length((yyvsp[(3) - (5)].tok).alg) == 0) {
@@ -2470,42 +2469,42 @@ yyreduce:
case 43:
/* Line 1806 of yacc.c */
-#line 636 "cf-parse.y"
+#line 632 "cf-parse.y"
{ conf_start_remote(scanner, (yyvsp[(1) - (1)].tok).t); }
break;
case 44:
/* Line 1806 of yacc.c */
-#line 637 "cf-parse.y"
+#line 633 "cf-parse.y"
{ conf_start_remote(scanner, strdup((yyvsp[(1) - (1)].tok).t)); }
break;
case 45:
/* Line 1806 of yacc.c */
-#line 638 "cf-parse.y"
+#line 634 "cf-parse.y"
{ conf_start_remote(scanner, strdup((yyvsp[(1) - (1)].tok).t)); }
break;
case 46:
/* Line 1806 of yacc.c */
-#line 639 "cf-parse.y"
+#line 635 "cf-parse.y"
{ conf_start_remote(scanner, strdup((yyvsp[(1) - (1)].tok).t)); }
break;
case 47:
/* Line 1806 of yacc.c */
-#line 640 "cf-parse.y"
+#line 636 "cf-parse.y"
{ conf_start_remote(scanner, strdup((yyvsp[(1) - (1)].tok).t)); }
break;
case 49:
/* Line 1806 of yacc.c */
-#line 644 "cf-parse.y"
+#line 640 "cf-parse.y"
{
if (this_remote->port != 0) {
cf_error(scanner, "only one port definition is allowed in remote section\n");
@@ -2518,7 +2517,7 @@ yyreduce:
case 50:
/* Line 1806 of yacc.c */
-#line 651 "cf-parse.y"
+#line 647 "cf-parse.y"
{
if (this_remote->address != 0) {
cf_error(scanner, "only one address is allowed in remote section\n");
@@ -2533,7 +2532,7 @@ yyreduce:
case 51:
/* Line 1806 of yacc.c */
-#line 660 "cf-parse.y"
+#line 656 "cf-parse.y"
{
if (this_remote->address != 0) {
cf_error(scanner, "only one address is allowed in remote section\n");
@@ -2548,7 +2547,7 @@ yyreduce:
case 52:
/* Line 1806 of yacc.c */
-#line 669 "cf-parse.y"
+#line 665 "cf-parse.y"
{
if (this_remote->address != 0) {
cf_error(scanner, "only one address is allowed in remote section\n");
@@ -2568,7 +2567,7 @@ yyreduce:
case 53:
/* Line 1806 of yacc.c */
-#line 683 "cf-parse.y"
+#line 679 "cf-parse.y"
{
if (this_remote->address != 0) {
cf_error(scanner, "only one address is allowed in remote section\n");
@@ -2583,7 +2582,7 @@ yyreduce:
case 54:
/* Line 1806 of yacc.c */
-#line 692 "cf-parse.y"
+#line 688 "cf-parse.y"
{
if (this_remote->address != 0) {
cf_error(scanner, "only one address is allowed in remote section\n");
@@ -2598,7 +2597,7 @@ yyreduce:
case 55:
/* Line 1806 of yacc.c */
-#line 701 "cf-parse.y"
+#line 697 "cf-parse.y"
{
if (this_remote->address != 0) {
cf_error(scanner, "only one address is allowed in remote section\n");
@@ -2618,7 +2617,7 @@ yyreduce:
case 56:
/* Line 1806 of yacc.c */
-#line 715 "cf-parse.y"
+#line 711 "cf-parse.y"
{
if (this_remote->key != 0) {
cf_error(scanner, "only one TSIG key definition is allowed in remote section\n");
@@ -2632,7 +2631,7 @@ yyreduce:
case 57:
/* Line 1806 of yacc.c */
-#line 723 "cf-parse.y"
+#line 719 "cf-parse.y"
{
sockaddr_set(&this_remote->via, AF_INET, (yyvsp[(3) - (4)].tok).t, 0);
free((yyvsp[(3) - (4)].tok).t);
@@ -2642,7 +2641,7 @@ yyreduce:
case 58:
/* Line 1806 of yacc.c */
-#line 727 "cf-parse.y"
+#line 723 "cf-parse.y"
{
sockaddr_set(&this_remote->via, AF_INET6, (yyvsp[(3) - (4)].tok).t, 0);
free((yyvsp[(3) - (4)].tok).t);
@@ -2652,7 +2651,7 @@ yyreduce:
case 59:
/* Line 1806 of yacc.c */
-#line 731 "cf-parse.y"
+#line 727 "cf-parse.y"
{
conf_remote_set_via(scanner, (yyvsp[(3) - (4)].tok).t);
free((yyvsp[(3) - (4)].tok).t);
@@ -2662,7 +2661,7 @@ yyreduce:
case 61:
/* Line 1806 of yacc.c */
-#line 739 "cf-parse.y"
+#line 735 "cf-parse.y"
{
if (this_remote->address == 0) {
cf_error(scanner, "remote '%s' has no defined address", this_remote->name);
@@ -2673,21 +2672,21 @@ yyreduce:
case 62:
/* Line 1806 of yacc.c */
-#line 747 "cf-parse.y"
+#line 743 "cf-parse.y"
{ conf_add_member_into_group(scanner, (yyvsp[(1) - (1)].tok).t); }
break;
case 66:
/* Line 1806 of yacc.c */
-#line 757 "cf-parse.y"
+#line 753 "cf-parse.y"
{ conf_start_group(scanner, (yyvsp[(1) - (1)].tok).t); }
break;
case 69:
/* Line 1806 of yacc.c */
-#line 766 "cf-parse.y"
+#line 762 "cf-parse.y"
{
this_list = &this_zone->acl.xfr_in;
}
@@ -2696,7 +2695,7 @@ yyreduce:
case 70:
/* Line 1806 of yacc.c */
-#line 769 "cf-parse.y"
+#line 765 "cf-parse.y"
{
this_list = &this_zone->acl.xfr_out;
}
@@ -2705,7 +2704,7 @@ yyreduce:
case 71:
/* Line 1806 of yacc.c */
-#line 772 "cf-parse.y"
+#line 768 "cf-parse.y"
{
this_list = &this_zone->acl.notify_in;
}
@@ -2714,7 +2713,7 @@ yyreduce:
case 72:
/* Line 1806 of yacc.c */
-#line 775 "cf-parse.y"
+#line 771 "cf-parse.y"
{
this_list = &this_zone->acl.notify_out;
}
@@ -2723,7 +2722,7 @@ yyreduce:
case 73:
/* Line 1806 of yacc.c */
-#line 778 "cf-parse.y"
+#line 774 "cf-parse.y"
{
this_list = &this_zone->acl.update_in;
}
@@ -2732,42 +2731,42 @@ yyreduce:
case 75:
/* Line 1806 of yacc.c */
-#line 784 "cf-parse.y"
+#line 780 "cf-parse.y"
{ conf_acl_item(scanner, (yyvsp[(1) - (1)].tok).t); }
break;
case 76:
/* Line 1806 of yacc.c */
-#line 785 "cf-parse.y"
+#line 781 "cf-parse.y"
{ conf_acl_item(scanner, strdup((yyvsp[(1) - (1)].tok).t)); }
break;
case 77:
/* Line 1806 of yacc.c */
-#line 786 "cf-parse.y"
+#line 782 "cf-parse.y"
{ conf_acl_item(scanner, strdup((yyvsp[(1) - (1)].tok).t)); }
break;
case 78:
/* Line 1806 of yacc.c */
-#line 787 "cf-parse.y"
+#line 783 "cf-parse.y"
{ conf_acl_item(scanner, strdup((yyvsp[(1) - (1)].tok).t)); }
break;
case 79:
/* Line 1806 of yacc.c */
-#line 788 "cf-parse.y"
+#line 784 "cf-parse.y"
{ conf_acl_item(scanner, strdup((yyvsp[(1) - (1)].tok).t)); }
break;
case 84:
/* Line 1806 of yacc.c */
-#line 797 "cf-parse.y"
+#line 793 "cf-parse.y"
{
/* Find existing node in remotes. */
node* r = 0; conf_iface_t* found = 0;
@@ -2799,49 +2798,49 @@ yyreduce:
case 86:
/* Line 1806 of yacc.c */
-#line 826 "cf-parse.y"
+#line 822 "cf-parse.y"
{ conf_zone_start(scanner, strdup((yyvsp[(1) - (1)].tok).t)); }
break;
case 87:
/* Line 1806 of yacc.c */
-#line 827 "cf-parse.y"
+#line 823 "cf-parse.y"
{ conf_zone_start(scanner, strdup((yyvsp[(1) - (1)].tok).t)); }
break;
case 88:
/* Line 1806 of yacc.c */
-#line 828 "cf-parse.y"
+#line 824 "cf-parse.y"
{ conf_zone_start(scanner, strdup((yyvsp[(1) - (1)].tok).t)); }
break;
case 89:
/* Line 1806 of yacc.c */
-#line 829 "cf-parse.y"
+#line 825 "cf-parse.y"
{ conf_zone_start(scanner, strdup((yyvsp[(1) - (1)].tok).t)); }
break;
case 90:
/* Line 1806 of yacc.c */
-#line 830 "cf-parse.y"
+#line 826 "cf-parse.y"
{ conf_zone_start(scanner, strdup((yyvsp[(1) - (1)].tok).t)); }
break;
case 91:
/* Line 1806 of yacc.c */
-#line 831 "cf-parse.y"
+#line 827 "cf-parse.y"
{ conf_zone_start(scanner, strdup((yyvsp[(1) - (1)].tok).t)); }
break;
case 92:
/* Line 1806 of yacc.c */
-#line 832 "cf-parse.y"
+#line 828 "cf-parse.y"
{
if ((yyvsp[(1) - (3)].tok).i < 0 || (yyvsp[(1) - (3)].tok).i > 255) {
cf_error(scanner, "rfc2317 origin prefix '%ld' out of bounds", (yyvsp[(1) - (3)].tok).i);
@@ -2864,70 +2863,70 @@ yyreduce:
case 93:
/* Line 1806 of yacc.c */
-#line 849 "cf-parse.y"
+#line 845 "cf-parse.y"
{ conf_zone_start(scanner, (yyvsp[(1) - (1)].tok).t); }
break;
case 97:
/* Line 1806 of yacc.c */
-#line 856 "cf-parse.y"
+#line 852 "cf-parse.y"
{ this_zone->file = (yyvsp[(3) - (4)].tok).t; }
break;
case 98:
/* Line 1806 of yacc.c */
-#line 857 "cf-parse.y"
+#line 853 "cf-parse.y"
{ this_zone->build_diffs = (yyvsp[(3) - (4)].tok).i; }
break;
case 99:
/* Line 1806 of yacc.c */
-#line 858 "cf-parse.y"
+#line 854 "cf-parse.y"
{ this_zone->enable_checks = (yyvsp[(3) - (4)].tok).i; }
break;
case 100:
/* Line 1806 of yacc.c */
-#line 859 "cf-parse.y"
+#line 855 "cf-parse.y"
{ this_zone->disable_any = (yyvsp[(3) - (4)].tok).i; }
break;
case 101:
/* Line 1806 of yacc.c */
-#line 860 "cf-parse.y"
+#line 856 "cf-parse.y"
{ this_zone->dbsync_timeout = (yyvsp[(3) - (4)].tok).i; }
break;
case 102:
/* Line 1806 of yacc.c */
-#line 861 "cf-parse.y"
+#line 857 "cf-parse.y"
{ this_zone->dbsync_timeout = (yyvsp[(3) - (4)].tok).i; }
break;
case 103:
/* Line 1806 of yacc.c */
-#line 862 "cf-parse.y"
+#line 858 "cf-parse.y"
{ new_config->ixfr_fslimit = (yyvsp[(3) - (4)].tok).l; }
break;
case 104:
/* Line 1806 of yacc.c */
-#line 863 "cf-parse.y"
+#line 859 "cf-parse.y"
{ this_zone->ixfr_fslimit = (yyvsp[(3) - (4)].tok).i; }
break;
case 105:
/* Line 1806 of yacc.c */
-#line 864 "cf-parse.y"
+#line 860 "cf-parse.y"
{
if ((yyvsp[(3) - (4)].tok).i < 1) {
cf_error(scanner, "notify retries must be positive integer");
@@ -2940,7 +2939,7 @@ yyreduce:
case 106:
/* Line 1806 of yacc.c */
-#line 871 "cf-parse.y"
+#line 867 "cf-parse.y"
{
if ((yyvsp[(3) - (4)].tok).i < 1) {
cf_error(scanner, "notify timeout must be positive integer");
@@ -2953,42 +2952,42 @@ yyreduce:
case 109:
/* Line 1806 of yacc.c */
-#line 883 "cf-parse.y"
+#line 879 "cf-parse.y"
{ new_config->disable_any = (yyvsp[(3) - (4)].tok).i; }
break;
case 110:
/* Line 1806 of yacc.c */
-#line 884 "cf-parse.y"
+#line 880 "cf-parse.y"
{ new_config->build_diffs = (yyvsp[(3) - (4)].tok).i; }
break;
case 111:
/* Line 1806 of yacc.c */
-#line 885 "cf-parse.y"
+#line 881 "cf-parse.y"
{ new_config->zone_checks = (yyvsp[(3) - (4)].tok).i; }
break;
case 112:
/* Line 1806 of yacc.c */
-#line 886 "cf-parse.y"
+#line 882 "cf-parse.y"
{ new_config->ixfr_fslimit = (yyvsp[(3) - (4)].tok).l; }
break;
case 113:
/* Line 1806 of yacc.c */
-#line 887 "cf-parse.y"
+#line 883 "cf-parse.y"
{ new_config->ixfr_fslimit = (yyvsp[(3) - (4)].tok).i; }
break;
case 114:
/* Line 1806 of yacc.c */
-#line 888 "cf-parse.y"
+#line 884 "cf-parse.y"
{
if ((yyvsp[(3) - (4)].tok).i < 1) {
cf_error(scanner, "notify retries must be positive integer");
@@ -3001,7 +3000,7 @@ yyreduce:
case 115:
/* Line 1806 of yacc.c */
-#line 895 "cf-parse.y"
+#line 891 "cf-parse.y"
{
if ((yyvsp[(3) - (4)].tok).i < 1) {
cf_error(scanner, "notify timeout must be positive integer");
@@ -3014,7 +3013,7 @@ yyreduce:
case 116:
/* Line 1806 of yacc.c */
-#line 902 "cf-parse.y"
+#line 898 "cf-parse.y"
{
if ((yyvsp[(3) - (4)].tok).i < 1) {
cf_error(scanner, "zonefile sync timeout must be positive integer");
@@ -3027,14 +3026,14 @@ yyreduce:
case 117:
/* Line 1806 of yacc.c */
-#line 909 "cf-parse.y"
+#line 905 "cf-parse.y"
{ new_config->dbsync_timeout = (yyvsp[(3) - (4)].tok).i; }
break;
case 118:
/* Line 1806 of yacc.c */
-#line 912 "cf-parse.y"
+#line 908 "cf-parse.y"
{
this_logmap = malloc(sizeof(conf_log_map_t));
this_logmap->source = 0;
@@ -3046,21 +3045,21 @@ yyreduce:
case 120:
/* Line 1806 of yacc.c */
-#line 922 "cf-parse.y"
+#line 918 "cf-parse.y"
{ this_logmap->prios |= (yyvsp[(2) - (3)].tok).i; }
break;
case 121:
/* Line 1806 of yacc.c */
-#line 923 "cf-parse.y"
+#line 919 "cf-parse.y"
{ this_logmap->prios |= (yyvsp[(2) - (3)].tok).i; }
break;
case 123:
/* Line 1806 of yacc.c */
-#line 927 "cf-parse.y"
+#line 923 "cf-parse.y"
{
this_logmap->source = (yyvsp[(2) - (3)].tok).i;
this_logmap = 0;
@@ -3070,7 +3069,7 @@ yyreduce:
case 124:
/* Line 1806 of yacc.c */
-#line 933 "cf-parse.y"
+#line 929 "cf-parse.y"
{
/* Find already existing rule. */
this_log = 0;
@@ -3097,7 +3096,7 @@ yyreduce:
case 125:
/* Line 1806 of yacc.c */
-#line 956 "cf-parse.y"
+#line 952 "cf-parse.y"
{
/* Find already existing rule. */
this_log = 0;
@@ -3128,38 +3127,45 @@ yyreduce:
case 126:
/* Line 1806 of yacc.c */
-#line 983 "cf-parse.y"
+#line 979 "cf-parse.y"
{
}
break;
- case 131:
+ case 130:
/* Line 1806 of yacc.c */
-#line 995 "cf-parse.y"
- { conf_init_iface(scanner, NULL, -1); }
+#line 988 "cf-parse.y"
+ { new_config->logs_count = 0; }
break;
case 132:
/* Line 1806 of yacc.c */
-#line 999 "cf-parse.y"
+#line 992 "cf-parse.y"
+ { conf_init_iface(scanner, NULL, -1); }
+ break;
+
+ case 133:
+
+/* Line 1806 of yacc.c */
+#line 996 "cf-parse.y"
{
this_list = &new_config->ctl.allow;
}
break;
- case 133:
+ case 134:
/* Line 1806 of yacc.c */
-#line 1005 "cf-parse.y"
+#line 1002 "cf-parse.y"
{ new_config->ctl.have = true; }
break;
- case 134:
+ case 135:
/* Line 1806 of yacc.c */
-#line 1006 "cf-parse.y"
+#line 1003 "cf-parse.y"
{
if (this_iface->address == 0) {
cf_error(scanner, "control interface has no defined address");
@@ -3169,10 +3175,10 @@ yyreduce:
}
break;
- case 135:
+ case 136:
/* Line 1806 of yacc.c */
-#line 1013 "cf-parse.y"
+#line 1010 "cf-parse.y"
{
this_iface->address = (yyvsp[(3) - (4)].tok).t;
this_iface->family = AF_UNIX;
@@ -3184,7 +3190,7 @@ yyreduce:
/* Line 1806 of yacc.c */
-#line 3188 "knot/conf/libknotd_la-cf-parse.c"
+#line 3194 "knot/conf/libknotd_la-cf-parse.c"
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -3415,6 +3421,6 @@ yyreturn:
/* Line 2067 of yacc.c */
-#line 1025 "cf-parse.y"
+#line 1022 "cf-parse.y"
diff --git a/src/knot/conf/logconf.c b/src/knot/conf/logconf.c
index 427e762..4f59755 100644
--- a/src/knot/conf/logconf.c
+++ b/src/knot/conf/logconf.c
@@ -34,13 +34,15 @@ int log_conf_hook(const struct conf_t *conf, void *data)
int ret = 0;
UNUSED(data);
- // Check if log declaration exists, otherwise ignore
- if (conf->logs_count < 1) {
- return KNOT_EINVAL;
+ // Use defaults if no 'log' section is configured.
+ if (conf->logs_count < 0) {
+ log_close();
+ log_init();
+ return KNOT_EOK;
}
// Find maximum log facility id
- node *n = 0; size_t files = 0;
+ node *n = NULL; size_t files = 0;
WALK_LIST(n, conf->logs) {
conf_log_t* log = (conf_log_t*)n;
if (log->type == LOGT_FILE) {
@@ -55,8 +57,7 @@ int log_conf_hook(const struct conf_t *conf, void *data)
}
// Setup logs
- int loaded_sections = 0;
- n = 0;
+ n = NULL;
WALK_LIST(n, conf->logs) {
// Calculate offset
@@ -71,13 +72,6 @@ int log_conf_hook(const struct conf_t *conf, void *data)
}
}
- // Auto-assign fatal errors to syslog or stderr
- if (facility <= LOGT_STDERR) {
- int mask = LOG_MASK(LOG_FATAL);
- log_levels_add(facility, LOG_ANY, mask);
- loaded_sections |= 1 << facility;
- }
-
// Setup sources mapping
node *m = 0;
WALK_LIST(m, log->map) {
@@ -88,14 +82,5 @@ int log_conf_hook(const struct conf_t *conf, void *data)
}
}
- // Load defaults for syslog or stderr
- int bmask = LOG_MASK(LOG_ERR)|LOG_MASK(LOG_FATAL);
- if (!(loaded_sections & (1 << LOGT_SYSLOG))) {
- log_levels_set(LOGT_SYSLOG, LOG_ANY, bmask);
- }
- if (!(loaded_sections & (1 << LOGT_STDERR))) {
- log_levels_set(LOGT_STDERR, LOG_ANY, bmask);
- }
-
return KNOT_EOK;
}
diff --git a/src/knot/ctl/knotc_main.c b/src/knot/ctl/knotc_main.c
index 73c6058..e2c42a1 100644
--- a/src/knot/ctl/knotc_main.c
+++ b/src/knot/ctl/knotc_main.c
@@ -79,7 +79,6 @@ typedef struct knot_cmd {
/* Forward decls. */
static int cmd_stop(int argc, char *argv[], unsigned flags);
-static int cmd_restart(int argc, char *argv[], unsigned flags);
static int cmd_reload(int argc, char *argv[], unsigned flags);
static int cmd_refresh(int argc, char *argv[], unsigned flags);
static int cmd_flush(int argc, char *argv[], unsigned flags);
@@ -92,7 +91,6 @@ static int cmd_memstats(int argc, char *argv[], unsigned flags);
/*! \brief Table of remote commands. */
knot_cmd_t knot_cmd_tbl[] = {
{&cmd_stop, 0, "stop", "", "\t\tStop server."},
- {&cmd_restart, 0, "restart", "", "\tRestart server."},
{&cmd_reload, 0, "reload", "", "\tReload configuration and changed zones."},
{&cmd_refresh, 0, "refresh", "[zone]", "\tRefresh slave zone (all if not specified)."},
{&cmd_flush, 0, "flush", "", "\t\tFlush journal and update zone files."},
@@ -406,7 +404,6 @@ int main(int argc, char **argv)
char *default_config = conf_find_default();
/* Remote server descriptor. */
- int ret = KNOT_EOK;
const char *r_addr = NULL;
int r_port = -1;
knot_tsig_key_t r_key;
@@ -441,23 +438,19 @@ int main(int argc, char **argv)
r_port = atoi(optarg);
break;
case 'y':
- ret = tsig_parse_str(&r_key, optarg);
- if (ret != KNOT_EOK) {
+ if (tsig_parse_str(&r_key, optarg) != KNOT_EOK) {
+ rc = 1;
log_server_error("Couldn't parse TSIG key '%s' "
"\n", optarg);
- knot_tsig_key_free(&r_key);
- log_close();
- return 1;
+ goto exit;
}
break;
case 'k':
- ret = tsig_parse_file(&r_key, optarg);
- if (ret != KNOT_EOK) {
+ if (tsig_parse_file(&r_key, optarg) != KNOT_EOK) {
+ rc = 1;
log_server_error("Couldn't parse TSIG key file "
"'%s'\n", optarg);
- knot_tsig_key_free(&r_key);
- log_close();
- return 1;
+ goto exit;
}
break;
case 'w':
@@ -551,18 +544,15 @@ int main(int argc, char **argv)
if (strchr(r_addr, ':'))
ctl_if->family = AF_INET6;
- /* Check if address could be a UNIX socket. */
- if (strchr(r_addr, '/')) {
- /* Check if file is really a socket. */
- struct stat st;
- if (stat(r_addr, &st) == 0 && !S_ISSOCK(st.st_mode)) {
- log_server_warning("Address '%s' is not a "
- "UNIX socket.\n", r_addr);
- }
-
+ /* Is a valid UNIX socket or at least contains slash ? */
+ struct stat st;
+ bool has_slash = strchr(r_addr, '/') != NULL;
+ bool is_file = stat(r_addr, &st) == 0;
+ if (has_slash || (is_file && S_ISSOCK(st.st_mode))) {
ctl_if->family = AF_UNIX;
r_port = 0; /* Override. */
}
+
}
if (r_port > -1) ctl_if->port = r_port;
@@ -593,15 +583,6 @@ static int cmd_stop(int argc, char *argv[], unsigned flags)
return cmd_remote("stop", KNOT_RRTYPE_TXT, 0, NULL);
}
-static int cmd_restart(int argc, char *argv[], unsigned flags)
-{
- UNUSED(argc);
- UNUSED(argv);
- UNUSED(flags);
-
- return cmd_remote("restart", KNOT_RRTYPE_TXT, 0, NULL);
-}
-
static int cmd_reload(int argc, char *argv[], unsigned flags)
{
UNUSED(argc);
@@ -787,24 +768,26 @@ static int cmd_memstats(int argc, char *argv[], unsigned flags)
process_error,
&est);
if (loader == NULL) {
+ rc = 1;
log_zone_error("Could not load zone.\n");
hattrie_apply_rev(est.node_table, estimator_free_trie_node, NULL);
hattrie_apply_rev(est.dname_table, estimator_free_trie_node, NULL);
hattrie_free(est.node_table);
hattrie_free(est.dname_table);
- return KNOT_ERROR;
+ break;
}
/* Do a parser run, but do not actually create the zone. */
int ret = file_loader_process(loader);
if (ret != KNOT_EOK) {
+ rc = 1;
log_zone_error("Failed to parse zone.\n");
hattrie_apply_rev(est.node_table, estimator_free_trie_node, NULL);
hattrie_apply_rev(est.dname_table, estimator_free_trie_node, NULL);
hattrie_free(est.node_table);
hattrie_free(est.dname_table);
file_loader_free(loader);
- return KNOT_ERROR;
+ break;
}
/* Only size of ahtables inside trie's nodes is missing. */
@@ -830,7 +813,7 @@ static int cmd_memstats(int argc, char *argv[], unsigned flags)
total_size += zone_size;
}
- if (argc == 0) { // for all zones
+ if (rc == 0 && argc == 0) { // for all zones
log_zone_info("Estimated memory consumption for all zones is %zuMB.\n", total_size);
}
diff --git a/src/knot/ctl/process.c b/src/knot/ctl/process.c
index f5db3ca..564fff2 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 7de68b5..2234bca 100644
--- a/src/knot/ctl/remote.c
+++ b/src/knot/ctl/remote.c
@@ -59,7 +59,6 @@ typedef struct remote_cmd_t {
/* Forward decls. */
static int remote_c_stop(server_t *s, remote_cmdargs_t* a);
-static int remote_c_restart(server_t *s, remote_cmdargs_t* a);
static int remote_c_reload(server_t *s, remote_cmdargs_t* a);
static int remote_c_refresh(server_t *s, remote_cmdargs_t* a);
static int remote_c_status(server_t *s, remote_cmdargs_t* a);
@@ -69,7 +68,6 @@ static int remote_c_flush(server_t *s, remote_cmdargs_t* a);
/*! \brief Table of remote commands. */
struct remote_cmd_t remote_cmd_tbl[] = {
{ "stop", &remote_c_stop },
- { "restart", &remote_c_restart },
{ "reload", &remote_c_reload },
{ "refresh", &remote_c_refresh },
{ "status", &remote_c_status },
@@ -177,18 +175,6 @@ static int remote_c_stop(server_t *s, remote_cmdargs_t* a)
}
/*!
- * \brief Remote command 'restart' handler.
- *
- * QNAME: restart
- * DATA: NULL
- */
-static int remote_c_restart(server_t *s, remote_cmdargs_t* a)
-{
- UNUSED(a);
- return KNOT_CTL_RESTART;
-}
-
-/*!
* \brief Remote command 'reload' handler.
*
* QNAME: reload
@@ -416,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/knot.h b/src/knot/knot.h
index fb0f9fd..0f517a9 100644
--- a/src/knot/knot.h
+++ b/src/knot/knot.h
@@ -30,36 +30,20 @@
#include <signal.h>
#include <stdint.h>
-/*
- * Common types and constants.
- */
-
-#define PROJECT_EXENAME "knotd"
-#define PROJECT_EXEC SBINDIR "/" PROJECT_EXENAME /*!< \brief Project executable. */
-#define PID_FILE "knot.pid" /*!< \brief Server PID file name. */
-
-/*
- * Server.
- */
+#include "common/print.h"
+#include "common/log.h"
+#include "common/errcode.h"
+#include "knot/other/debug.h"
#define CPU_ESTIMATE_MAGIC 0 /*!< \brief Extra threads to the number of cores.*/
#define DEFAULT_THR_COUNT 2 /*!< \brief Default thread count. */
-#define TCP_BACKLOG_SIZE 10 /*!< \brief TCP listen backlog size. */
+#define TCP_BACKLOG_SIZE 10 /*!< \brief TCP listen backlog size. */
#define XFR_THREADS_COUNT 3 /*!< \brief Number of threads for XFR handler. */
#define RECVMMSG_BATCHLEN 64 /*!< \brief Define for recvmmsg() batch size. */
///*! \brief If defined, the statistics module will be enabled. */
//#define STAT_COMPILE
-/*
- * Common includes.
- */
-
-#include "common/print.h"
-#include "common/log.h"
-#include "common/errcode.h"
-#include "knot/other/debug.h"
-
/* Workarounds for clock_gettime() not available on some platforms. */
#ifdef HAVE_CLOCK_GETTIME
#define time_now(x) clock_gettime(CLOCK_MONOTONIC, (x))
diff --git a/src/knot/main.c b/src/knot/main.c
index c5e693c..610b21f 100644
--- a/src/knot/main.c
+++ b/src/knot/main.c
@@ -41,11 +41,15 @@
/* Signal flags. */
static volatile short sig_req_stop = 0;
-static volatile short sig_req_rst = 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);
@@ -58,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) {
@@ -73,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)
@@ -81,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"
@@ -98,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'},
@@ -105,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;
@@ -152,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();
@@ -297,12 +320,14 @@ 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);
/* Bind to control interface. */
- uint8_t buf[65535]; /*! \todo #2035 should be on heap */
+ uint8_t buf[SOCKET_MTU_SZ];
size_t buflen = sizeof(buf);
int remote = -1;
if (conf()->ctl.iface != NULL) {
@@ -316,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(;;) {
@@ -331,8 +353,6 @@ int main(int argc, char **argv)
ret = remote_process(server, conf()->ctl.iface,
remote, buf, buflen);
switch(ret) {
- case KNOT_CTL_RESTART:
- sig_req_rst = 1; /* Fall through */
case KNOT_CTL_STOP:
sig_req_stop = 1;
break;
@@ -351,23 +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. */
+ 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) {
@@ -392,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);
@@ -404,10 +445,6 @@ int main(int argc, char **argv)
free(cwd);
}
- /* Restart hook. */
- if (sig_req_rst)
- return execvp(PROJECT_EXEC, argv);
-
return res;
}
@@ -424,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/server/server.c b/src/knot/server/server.c
index cef3801..7244d3c 100644
--- a/src/knot/server/server.c
+++ b/src/knot/server/server.c
@@ -629,18 +629,15 @@ int server_conf_hook(const struct conf_t *conf, void *data)
return ret;
}
-ref_t *server_set_ifaces(server_t *s, fdset_t **fds, int *count, int type)
+ref_t *server_set_ifaces(server_t *s, fdset_t *fds, int type)
{
iface_t *i = NULL;
- *count = 0;
rcu_read_lock();
- fdset_destroy(*fds);
- *fds = fdset_new();
+ fdset_clear(fds);
if (s->ifaces) {
WALK_LIST(i, s->ifaces->l) {
- fdset_add(*fds, i->fd[type], OS_EV_READ);
- *count += 1;
+ fdset_add(fds, i->fd[type], POLLIN, NULL);
}
}
diff --git a/src/knot/server/server.h b/src/knot/server/server.h
index 84a32e3..a766b0b 100644
--- a/src/knot/server/server.h
+++ b/src/knot/server/server.h
@@ -236,11 +236,10 @@ int server_conf_hook(const struct conf_t *conf, void *data);
* \brief Update fdsets from current interfaces list.
* \param s Server.
* \param fds Filedescriptor set.
- * \param count Number of ifaces (will be set to N).
* \param type I/O type (UDP/TCP).
* \return new interface list
*/
-ref_t *server_set_ifaces(server_t *s, fdset_t **fds, int *count, int type);
+ref_t *server_set_ifaces(server_t *s, fdset_t *fds, int type);
#endif // _KNOTD_SERVER_H_
diff --git a/src/knot/server/socket.h b/src/knot/server/socket.h
index 1849f1d..371977a 100644
--- a/src/knot/server/socket.h
+++ b/src/knot/server/socket.h
@@ -39,9 +39,7 @@
#include "common/sockaddr.h"
/*! \brief Socket-related constants. */
-typedef enum {
- SOCKET_MTU_SZ = 65535, /*!< Maximum MTU size. */
-} socket_const_t;
+#define SOCKET_MTU_SZ 65535 /*!< Maximum MTU size. */
/*!
* \brief Create socket.
diff --git a/src/knot/server/tcp-handler.c b/src/knot/server/tcp-handler.c
index f8fe90b..1f18abf 100644
--- a/src/knot/server/tcp-handler.c
+++ b/src/knot/server/tcp-handler.c
@@ -39,13 +39,10 @@
#include "libknot/nameserver/name-server.h"
#include "libknot/util/wire.h"
-/* Defines */
-#define TCP_BUFFER_SIZE 65535 /*! Do not change, as it is used for maximum DNS/TCP packet size. */
-
/*! \brief TCP worker data. */
typedef struct tcp_worker_t {
iohandler_t *ioh; /*!< Shortcut to I/O handler. */
- fdset_t *fdset; /*!< File descriptor set. */
+ fdset_t set; /*!< File descriptor set. */
int pipe[2]; /*!< Master-worker signalization pipes. */
} tcp_worker_t;
@@ -83,17 +80,19 @@ static int tcp_reply(int fd, uint8_t *qbuf, size_t resp_len)
}
/*! \brief Sweep TCP connection. */
-static void tcp_sweep(fdset_t *set, int fd, void* data)
+static enum fdset_sweep_state tcp_sweep(fdset_t *set, int i, void *data)
{
UNUSED(data);
+ assert(set && i < set->n && i >= 0);
+ int fd = set->pfd[i].fd;
char r_addr[SOCKADDR_STRLEN] = { '\0' };
int r_port = 0;
struct sockaddr_storage addr;
socklen_t len = sizeof(addr);
if (getpeername(fd, (struct sockaddr*)&addr, &len) < 0) {
dbg_net("tcp: sweep getpeername() on invalid socket=%d\n", fd);
- return;
+ return FDSET_SWEEP;
}
/* Translate */
@@ -111,8 +110,8 @@ static void tcp_sweep(fdset_t *set, int fd, void* data)
log_server_notice("Connection with '%s@%d' was terminated due to "
"inactivity.\n", r_addr, r_port);
- fdset_remove(set, fd);
close(fd);
+ return FDSET_SWEEP;
}
/*!
@@ -324,13 +323,34 @@ int tcp_accept(int fd)
return incoming;
}
+/*! \brief Read a descriptor from the pipe and assign it to given fdset. */
+static int tcp_loop_assign(int pipe, fdset_t *set)
+{
+ /* Read socket descriptor from pipe. */
+ int client, next_id;
+ if (read(pipe, &client, sizeof(int)) != sizeof(int)) {
+ return KNOT_ENOENT;
+ }
+
+ /* Assign to fdset. */
+ next_id = fdset_add(set, client, POLLIN, NULL);
+ if (next_id < 0) {
+ socket_close(client);
+ return next_id; /* Contains errno. */
+ }
+
+ /* Update watchdog timer. */
+ rcu_read_lock();
+ fdset_set_watchdog(set, next_id, conf()->max_conn_hs);
+ rcu_read_unlock();
+ return next_id;
+}
+
tcp_worker_t* tcp_worker_create()
{
tcp_worker_t *w = malloc(sizeof(tcp_worker_t));
- if (w == NULL) {
- dbg_net("tcp: out of memory when creating worker\n");
+ if (w == NULL)
return NULL;
- }
/* Create signal pipes. */
memset(w, 0, sizeof(tcp_worker_t));
@@ -340,16 +360,14 @@ tcp_worker_t* tcp_worker_create()
}
/* Create fdset. */
- w->fdset = fdset_new();
- if (!w->fdset) {
+ if (fdset_init(&w->set, FDSET_INIT_SIZE) != KNOT_EOK) {
close(w->pipe[0]);
close(w->pipe[1]);
free(w);
return NULL;
}
- fdset_add(w->fdset, w->pipe[0], OS_EV_READ);
-
+ fdset_add(&w->set, w->pipe[0], POLLIN, NULL);
return w;
}
@@ -359,8 +377,8 @@ void tcp_worker_free(tcp_worker_t* w)
return;
}
- /* Destroy fdset. */
- fdset_destroy(w->fdset);
+ /* Clear fdset. */
+ fdset_clear(&w->set);
/* Close pipe write end and worker. */
close(w->pipe[0]);
@@ -394,15 +412,21 @@ int tcp_send(int fd, uint8_t *msg, size_t msglen)
int uncork = setsockopt(fd, SOL_TCP, TCP_CORK, &cork, sizeof(cork));
#endif
+ /* Flags. */
+ int flags = 0;
+#ifdef MSG_NOSIGNAL
+ flags |= MSG_NOSIGNAL;
+#endif
+
/* Send message size. */
unsigned short pktsize = htons(msglen);
- int sent = send(fd, &pktsize, sizeof(pktsize), 0);
+ int sent = send(fd, &pktsize, sizeof(pktsize), flags);
if (sent < 0) {
return KNOT_ERROR;
}
/* Send message data. */
- sent = send(fd, msg, msglen, 0);
+ sent = send(fd, msg, msglen, flags);
if (sent < 0) {
return KNOT_ERROR;
}
@@ -421,9 +445,15 @@ int tcp_send(int fd, uint8_t *msg, size_t msglen)
int tcp_recv(int fd, uint8_t *buf, size_t len, sockaddr_t *addr)
{
+ /* Flags. */
+ int flags = MSG_WAITALL;
+#ifdef MSG_NOSIGNAL
+ flags |= MSG_NOSIGNAL;
+#endif
+
/* Receive size. */
unsigned short pktsize = 0;
- int n = recv(fd, &pktsize, sizeof(unsigned short), MSG_WAITALL);
+ int n = recv(fd, &pktsize, sizeof(unsigned short), flags);
if (n < 0) {
if (errno == EAGAIN) {
return KNOT_EAGAIN;
@@ -455,7 +485,7 @@ int tcp_recv(int fd, uint8_t *buf, size_t len, sockaddr_t *addr)
}
/* Receive payload. */
- n = recv(fd, buf, pktsize, MSG_WAITALL);
+ n = recv(fd, buf, pktsize, flags);
if (n < 0) {
if (errno == EAGAIN) {
return KNOT_EAGAIN;
@@ -481,23 +511,22 @@ int tcp_loop_master(dthread_t *thread)
tcp_worker_t **workers = h->data;
/* Prepare structures for bound sockets. */
- fdset_it_t it;
- fdset_t *fds = NULL;
ref_t *ref = NULL;
- int if_cnt = 0;
+ fdset_t set;
+ fdset_init(&set, conf()->ifaces_count);
/* Accept connections. */
- int id = 0;
- dbg_net("tcp: created 1 master with %d workers, backend is '%s' \n",
- unit->size - 1, fdset_method());
+ int id = 0, ret = 0;
+ dbg_net("tcp: created 1 master with %d workers\n", unit->size - 1);
for(;;) {
/* Check handler state. */
if (knot_unlikely(st->s & ServerReload)) {
st->s &= ~ServerReload;
ref_release(ref);
- ref = server_set_ifaces(h->server, &fds, &if_cnt, IO_TCP);
- if (if_cnt == 0) break;
+ ref = server_set_ifaces(h->server, &set, IO_TCP);
+ if (set.n == 0) /* Terminate on zero interfaces. */
+ break;
}
/* Check for cancellation. */
@@ -506,35 +535,34 @@ int tcp_loop_master(dthread_t *thread)
}
/* Wait for events. */
- int nfds = fdset_wait(fds, OS_EV_FOREVER);
+ int nfds = poll(set.pfd, set.n, -1);
if (nfds <= 0) {
- if (errno == EINTR) continue;
+ if (errno == EINTR)
+ continue;
break;
}
- fdset_begin(fds, &it);
- while(nfds > 0) {
- /* Accept client. */
- int client = tcp_accept(it.fd);
- if (client > -1) {
- /* Add to worker in RR fashion. */
- if (write(workers[id]->pipe[1], &client, sizeof(int)) < 0) {
- dbg_net("tcp: failed to register fd=%d to worker=%d\n",
- client, id);
- close(client);
- continue;
- }
- id = get_next_rr(id, unit->size - 1);
- }
+ for (unsigned i = 0; nfds > 0 && i < set.n; ++i) {
+ /* Skip inactive. */
+ if (!(set.pfd[i].revents & POLLIN))
+ continue;
- if (fdset_next(fds, &it) != 0) {
- break;
- }
+ /* Accept client. */
+ --nfds; /* One less active event. */
+ int client = tcp_accept(set.pfd[i].fd);
+ if (client < 0)
+ continue;
+
+ /* Add to worker in RR fashion. */
+ id = get_next_rr(id, unit->size - 1);
+ ret = write(workers[id]->pipe[1], &client, sizeof(int));
+ if (ret < 0)
+ close(client);
}
}
dbg_net("tcp: master thread finished\n");
- fdset_destroy(fds);
+ fdset_clear(&set);
ref_release(ref);
return KNOT_EOK;
@@ -542,18 +570,6 @@ int tcp_loop_master(dthread_t *thread)
int tcp_loop_worker(dthread_t *thread)
{
- tcp_worker_t *w = thread->data;
- if (!w) {
- return KNOT_EINVAL;
- }
-
- /* Allocate buffer for requests. */
- uint8_t *qbuf = malloc(TCP_BUFFER_SIZE);
- if (qbuf == NULL) {
- dbg_net("tcp: failed to allocate buffers for TCP worker\n");
- return KNOT_EINVAL;
- }
-
/* Drop all capabilities on workers. */
#ifdef HAVE_CAP_NG_H
if (capng_have_capability(CAPNG_EFFECTIVE, CAP_SETPCAP)) {
@@ -562,84 +578,74 @@ int tcp_loop_worker(dthread_t *thread)
}
#endif /* HAVE_CAP_NG_H */
- /* Next sweep time. */
+ uint8_t *qbuf = malloc(SOCKET_MTU_SZ);
+ tcp_worker_t *w = thread->data;
+ if (w == NULL || qbuf == NULL) {
+ free(qbuf);
+ return KNOT_EINVAL;
+ }
+
+ /* Accept clients. */
+ dbg_net("tcp: worker %p started\n", w);
+ fdset_t *set = &w->set;
timev_t next_sweep;
time_now(&next_sweep);
next_sweep.tv_sec += TCP_SWEEP_INTERVAL;
-
- /* Accept clients. */
- dbg_net_verb("tcp: worker %p started\n", w);
for (;;) {
/* Cancellation point. */
- if (dt_is_cancelled(thread)) {
+ if (dt_is_cancelled(thread))
break;
- }
/* Wait for events. */
- int nfds = fdset_wait(w->fdset, (TCP_SWEEP_INTERVAL * 1000)/2);
- if (nfds < 0) {
+ int nfds = poll(set->pfd, set->n, TCP_SWEEP_INTERVAL * 1000);
+ if (nfds < 0)
continue;
- }
/* Establish timeouts. */
rcu_read_lock();
int max_idle = conf()->max_conn_idle;
- int max_hs = conf()->max_conn_hs;
rcu_read_unlock();
/* Process incoming events. */
- dbg_net_verb("tcp: worker %p registered %d events\n",
- w, nfds);
- fdset_it_t it;
- fdset_begin(w->fdset, &it);
- while(nfds > 0) {
-
- /* Handle incoming clients. */
- if (it.fd == w->pipe[0]) {
- int client = 0;
- if (read(it.fd, &client, sizeof(int)) < 0) {
- continue;
- }
+ unsigned i = 0;
+ while (nfds > 0 && i < set->n) {
- dbg_net_verb("tcp: worker %p registered "
- "client %d\n",
- w, client);
- fdset_add(w->fdset, client, OS_EV_READ);
- fdset_set_watchdog(w->fdset, client, max_hs);
- dbg_net("tcp: watchdog for fd=%d set to %ds\n",
- client, max_hs);
+ if (!(set->pfd[i].revents & set->pfd[i].events)) {
+ /* Skip inactive. */
+ ++i;
+ continue;
} else {
- /* Handle other events. */
- int ret = tcp_handle(w, it.fd, qbuf,
- TCP_BUFFER_SIZE);
+ /* One less active event. */
+ --nfds;
+ }
+
+ /* Register new TCP client or process a query. */
+ int fd = set->pfd[i].fd;
+ if (fd == w->pipe[0]) {
+ tcp_loop_assign(fd, set);
+ } else {
+ int ret = tcp_handle(w, fd, qbuf, SOCKET_MTU_SZ);
if (ret == KNOT_EOK) {
- fdset_set_watchdog(w->fdset, it.fd,
- max_idle);
- dbg_net("tcp: watchdog for fd=%d "
- "set to %ds\n",
- it.fd, max_idle);
+ /* Update socket activity timer. */
+ fdset_set_watchdog(set, i, max_idle);
}
- /*! \todo Refactor to allow erase on iterator.*/
if (ret == KNOT_ECONNREFUSED) {
- fdset_remove(w->fdset, it.fd);
- close(it.fd);
- break;
+ fdset_remove(set, i);
+ close(fd);
+ continue; /* Stay on the same index. */
}
-
}
- /* Check if next exists. */
- if (fdset_next(w->fdset, &it) != 0) {
- break;
- }
+ /* Next active. */
+ ++i;
}
/* Sweep inactive. */
timev_t now;
if (time_now(&now) == 0) {
if (now.tv_sec >= next_sweep.tv_sec) {
- fdset_sweep(w->fdset, &tcp_sweep, NULL);
+ fdset_sweep(set, &tcp_sweep, NULL);
memcpy(&next_sweep, &now, sizeof(next_sweep));
next_sweep.tv_sec += TCP_SWEEP_INTERVAL;
}
@@ -648,7 +654,7 @@ int tcp_loop_worker(dthread_t *thread)
/* Stop whole unit. */
free(qbuf);
- dbg_net_verb("tcp: worker %p finished\n", w);
+ dbg_net("tcp: worker %p finished\n", w);
return KNOT_EOK;
}
diff --git a/src/knot/server/xfr-handler.c b/src/knot/server/xfr-handler.c
index c7c1abf..90b0a42 100644
--- a/src/knot/server/xfr-handler.c
+++ b/src/knot/server/xfr-handler.c
@@ -44,9 +44,9 @@
#include "libknot/rrset.h"
/* Constants */
-#define XFR_CHUNKLEN 3 /*! Number of requests assigned in a single pass. */
+#define XFR_MAX_TASKS 1024 /*! Maximum pending tasks. */
+#define XFR_CHUNKLEN 16 /*! Number of requests assigned in a single pass. */
#define XFR_SWEEP_INTERVAL 2 /*! [seconds] between sweeps. */
-#define XFR_BUFFER_SIZE 65535 /*! Do not change this - maximum value for UDP packet length. */
#define XFR_MSG_DLTTR 9 /*! Index of letter differentiating IXFR/AXFR in log msg. */
/* Messages */
@@ -62,14 +62,37 @@ static knot_lookup_table_t xfr_type_table[] = {
{ XFR_TYPE_AIN, NULL }
};
static knot_lookup_table_t xfr_result_table[] = {
- { XFR_TYPE_AIN, "Started" },
- { XFR_TYPE_IIN, "Started" },
- { XFR_TYPE_SOA, "Query issued" },
- { XFR_TYPE_NOTIFY, "Query issued" },
- { XFR_TYPE_FORWARD, "Forwarded query" },
+ { XFR_TYPE_AIN, "Started." },
+ { XFR_TYPE_IIN, "Started." },
+ { XFR_TYPE_SOA, "Query issued." },
+ { XFR_TYPE_NOTIFY, "Query issued." },
+ { XFR_TYPE_FORWARD, "Forwarded query." },
{ XFR_TYPE_AIN, NULL }
};
+/* Limits. */
+static bool xfr_pending_incr(xfrhandler_t *xfr)
+{
+ bool ret = false;
+ pthread_mutex_lock(&xfr->pending_mx);
+ rcu_read_lock();
+ if (xfr->pending < conf()->xfers) {
+ ++xfr->pending;
+ ret = true;
+ }
+ rcu_read_unlock();
+ pthread_mutex_unlock(&xfr->pending_mx);
+
+ return ret;
+}
+
+static void xfr_pending_decr(xfrhandler_t *xfr)
+{
+ pthread_mutex_lock(&xfr->pending_mx);
+ --xfr->pending;
+ pthread_mutex_unlock(&xfr->pending_mx);
+}
+
/* I/O wrappers */
static int xfr_send_tcp(int fd, sockaddr_t *addr, uint8_t *msg, size_t msglen)
@@ -84,28 +107,6 @@ static int xfr_recv_tcp(int fd, sockaddr_t *addr, uint8_t *buf, size_t buflen)
static int xfr_recv_udp(int fd, sockaddr_t *addr, uint8_t *buf, size_t buflen)
{ return recvfrom(fd, buf, buflen, 0, (struct sockaddr *)addr, &addr->len); }
-/* Context fetching. */
-
-static knot_ns_xfr_t* xfr_task_get(xfrworker_t *w, int fd)
-{
- value_t *val = ahtable_tryget(w->pool.t, (const char*)&fd, sizeof(int));
- if (!val) return NULL;
- return *val;
-}
-
-static void xfr_task_set(xfrworker_t *w, int fd, knot_ns_xfr_t *rq)
-{
- fdset_add(w->pool.fds, fd, OS_EV_READ);
- value_t *val = ahtable_get(w->pool.t, (const char*)&fd, sizeof(int));
- *val = rq;
-}
-
-static void xfr_task_clear(xfrworker_t *w, int fd)
-{
- ahtable_del(w->pool.t, (const char*)&fd, sizeof(int));
- fdset_remove(w->pool.fds, fd);
-}
-
/*! \brief Wrapper function for answering AXFR/OUT. */
static int xfr_answer_axfr(knot_nameserver_t *ns, knot_ns_xfr_t *xfr)
{
@@ -241,10 +242,8 @@ static int xfr_task_setsig(knot_ns_xfr_t *rq, knot_tsig_key_t *key)
static int xfr_task_connect(knot_ns_xfr_t *rq)
{
/* Create socket by type. */
- int stype = SOCK_DGRAM;
- if (rq->flags & XFR_FLAG_TCP) {
- stype = SOCK_STREAM;
- }
+ int ret = 0;
+ int stype = (rq->flags & XFR_FLAG_TCP) ? SOCK_STREAM : SOCK_DGRAM;
int fd = socket_create(sockaddr_family(&rq->addr), stype, 0);
if (fd < 0) {
return KNOT_ERROR;
@@ -257,14 +256,22 @@ static int xfr_task_connect(knot_ns_xfr_t *rq)
return KNOT_ERROR;
}
}
+
/* Connect if TCP. */
if (rq->flags & XFR_FLAG_TCP) {
- if (connect(fd, (struct sockaddr *)&rq->addr, rq->addr.len) < 0) {
+ if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
+ ; /* Go silently with blocking if it fails. */
+
+ ret = connect(fd, (struct sockaddr *)&rq->addr, rq->addr.len);
+ if (ret != 0 && errno != EINPROGRESS) {
socket_close(fd);
return KNOT_ECONNREFUSED;
}
}
+ /* Set up for UDP as well to trigger 'send query' event. */
+ rq->flags |= XFR_FLAG_CONNECTING;
+
/* Store new socket descriptor. */
rq->session = fd;
return KNOT_EOK;
@@ -299,15 +306,12 @@ static void xfr_task_cleanup(knot_ns_xfr_t *rq)
hattrie_clear(rq->lookup_tree);
}
-/*! \brief Close and free task. */
-static int xfr_task_close(xfrworker_t *w, int fd)
+/*! \brief End task properly and free it. */
+static int xfr_task_close(knot_ns_xfr_t *rq)
{
- knot_ns_xfr_t *rq = xfr_task_get(w, fd);
- if (!rq) return KNOT_ENOENT;
-
/* Update xfer state. */
+ zonedata_t *zd = (zonedata_t *)knot_zone_data(rq->zone);
if (rq->type == XFR_TYPE_AIN || rq->type == XFR_TYPE_IIN) {
- zonedata_t *zd = (zonedata_t *)knot_zone_data(rq->zone);
pthread_mutex_lock(&zd->lock);
if (zd->xfr_in.state == XFR_PENDING) {
zd->xfr_in.state = XFR_IDLE;
@@ -315,15 +319,25 @@ static int xfr_task_close(xfrworker_t *w, int fd)
pthread_mutex_unlock(&zd->lock);
}
+ /* Reschedule failed bootstrap. */
+ if (rq->type == XFR_TYPE_AIN && !knot_zone_contents(rq->zone)) {
+ int tmr_s = AXFR_BOOTSTRAP_RETRY * tls_rand();
+ event_t *ev = zd->xfr_in.timer;
+ if (ev) {
+ evsched_cancel(ev->parent, ev);
+ evsched_schedule(ev->parent, ev, tmr_s);
+ }
+ log_zone_notice("%s Bootstrap failed, next attempt in %d seconds.\n",
+ rq->msg, tmr_s / 1000);
+ }
+
/* Close socket and free task. */
- xfr_task_clear(w, fd);
xfr_task_free(rq);
- socket_close(fd);
return KNOT_EOK;
}
/*! \brief Timeout handler. */
-static int xfr_task_expire(fdset_t *fds, knot_ns_xfr_t *rq)
+static int xfr_task_expire(fdset_t *set, int i, knot_ns_xfr_t *rq)
{
/* Fetch related zone (refcounted, no RCU). */
knot_zone_t *zone = (knot_zone_t *)rq->zone;
@@ -335,7 +349,7 @@ static int xfr_task_expire(fdset_t *fds, knot_ns_xfr_t *rq)
case XFR_TYPE_NOTIFY:
if ((long)--rq->data > 0) { /* Retries */
notify_create_request(contents, rq->wire, &rq->wire_size);
- fdset_set_watchdog(fds, rq->session, NOTIFY_TIMEOUT);
+ fdset_set_watchdog(set, i, NOTIFY_TIMEOUT);
rq->send(rq->session, &rq->addr, rq->wire, rq->wire_size);
log_zone_info("%s Query issued (serial %u).\n",
rq->msg, knot_zone_serial(contents));
@@ -370,14 +384,6 @@ static int xfr_task_start(knot_ns_xfr_t *rq)
return KNOT_ECONNREFUSED;
}
- /* Connect to remote. */
- if (rq->session <= 0) {
- ret = xfr_task_connect(rq);
- if (ret != KNOT_EOK) {
- return ret;
- }
- }
-
/* Prepare TSIG key if set. */
int add_tsig = 0;
if (rq->tsig_key) {
@@ -437,20 +443,13 @@ static int xfr_task_start(knot_ns_xfr_t *rq)
return KNOT_EOK;
}
-static int xfr_task_process(xfrworker_t *w, knot_ns_xfr_t* rq, uint8_t *buf, size_t buflen)
+static int xfr_task_is_transfer(knot_ns_xfr_t *rq)
{
- /* Check if not already processing, zone is refcounted. */
- zonedata_t *zd = (zonedata_t *)knot_zone_data(rq->zone);
-
- /* Check if the zone is not discarded. */
- if (!zd || knot_zone_flags(rq->zone) & KNOT_ZONE_DISCARDED) {
- dbg_xfr_verb("xfr: request on a discarded zone, ignoring\n");
- return KNOT_EINVAL;
- }
-
- /* Update XFR message prefix. */
- xfr_task_setmsg(rq, NULL);
+ return rq->type == XFR_TYPE_AIN || rq->type == XFR_TYPE_IIN;
+}
+static void xfr_async_setbuf(knot_ns_xfr_t *rq, uint8_t *buf, size_t buflen)
+{
/* Update request. */
rq->wire = buf;
rq->wire_size = buflen;
@@ -461,17 +460,81 @@ static int xfr_task_process(xfrworker_t *w, knot_ns_xfr_t* rq, uint8_t *buf, siz
rq->send = &xfr_send_tcp;
rq->recv = &xfr_recv_tcp;
}
+}
+
+static int xfr_async_start(fdset_t *set, knot_ns_xfr_t *rq)
+{
+ /* Update XFR message prefix. */
+ int ret = KNOT_EOK;
+ xfr_task_setmsg(rq, NULL);
+
+ /* Connect to remote. */
+ if (rq->session <= 0)
+ ret = xfr_task_connect(rq);
+
+ /* Add to set. */
+ if (ret == KNOT_EOK) {
+ unsigned flags = POLLIN;
+ if (rq->flags & XFR_FLAG_CONNECTING)
+ flags = POLLOUT;
+ int next_id = fdset_add(set, rq->session, flags, rq);
+ if (next_id >= 0) {
+ /* Set default connection timeout. */
+ rcu_read_lock();
+ fdset_set_watchdog(set, next_id, conf()->max_conn_reply);
+ rcu_read_unlock();
+ } else {
+ /* Or refuse if failed. */
+ ret = KNOT_ECONNREFUSED;
+ }
+ }
+
+ return ret;
+}
+
+static int xfr_async_state(knot_ns_xfr_t *rq)
+{
+ /* Check socket status. */
+ int err = EINVAL;
+ socklen_t len = sizeof(int);
+ if (getsockopt(rq->session, SOL_SOCKET, SO_ERROR, &err, &len) < 0)
+ return KNOT_ERROR;
+ if (err != 0)
+ return knot_map_errno(err);
+ return KNOT_EOK;
+}
+
+static int xfr_async_finish(fdset_t *set, unsigned id)
+{
+ /* Drop back to synchronous mode. */
+ int ret = KNOT_EOK;
+ knot_ns_xfr_t *rq = (knot_ns_xfr_t *)set->ctx[id];
+ if ((ret = xfr_async_state(rq)) == KNOT_EOK) {
+ rq->flags &= ~XFR_FLAG_CONNECTING;
+ set->pfd[id].events = POLLIN;
+ if (fcntl(set->pfd[id].fd, F_SETFL, 0) < 0)
+ ;
+ } else {
+ /* Do not attempt to start on broken connection. */
+ return KNOT_ECONNREFUSED;
+ }
+
+ /* Check if the zone is not discarded. */
+ zonedata_t *zd = (zonedata_t *)knot_zone_data(rq->zone);
+ if (!zd || knot_zone_flags(rq->zone) & KNOT_ZONE_DISCARDED) {
+ dbg_xfr_verb("xfr: request on a discarded zone, ignoring\n");
+ return KNOT_EINVAL;
+ }
/* Handle request. */
dbg_xfr("%s processing request type '%d'\n", rq->msg, rq->type);
- int ret = xfr_task_start(rq);
+ ret = xfr_task_start(rq);
const char *msg = knot_strerror(ret);
knot_lookup_table_t *xd = knot_lookup_by_id(xfr_result_table, rq->type);
if (xd && ret == KNOT_EOK) {
msg = xd->name;
}
- int bootstrap_fail = 0;
switch(rq->type) {
case XFR_TYPE_AIN:
case XFR_TYPE_IIN:
@@ -480,36 +543,28 @@ static int xfr_task_process(xfrworker_t *w, knot_ns_xfr_t* rq, uint8_t *buf, siz
pthread_mutex_lock(&zd->lock);
zd->xfr_in.state = XFR_IDLE;
pthread_mutex_unlock(&zd->lock);
- bootstrap_fail = !knot_zone_contents(rq->zone);
}
break;
- case XFR_TYPE_NOTIFY: /* Send on first timeout <0,5>s. */
- fdset_set_watchdog(w->pool.fds, rq->session, (int)(tls_rand() * 5));
- xfr_task_set(w, rq->session, rq);
+ case XFR_TYPE_NOTIFY:
+ /* This is a bit of a hack to adapt NOTIFY lifetime tracking.
+ * When NOTIFY event enters handler, it shouldn't be sent immediately.
+ * To accomodate for this, <0, 5>s random delay is set on
+ * event startup, so the first query fires when this timer
+ * expires. */
+ fdset_set_watchdog(set, id, (int)(tls_rand() * 5));
return KNOT_EOK;
case XFR_TYPE_SOA:
case XFR_TYPE_FORWARD:
- fdset_set_watchdog(w->pool.fds, rq->session, conf()->max_conn_reply);
+ fdset_set_watchdog(set, id, conf()->max_conn_reply);
break;
default:
break;
}
if (ret == KNOT_EOK) {
- xfr_task_set(w, rq->session, rq);
- log_server_info("%s %s.\n", rq->msg, msg);
- } else if (bootstrap_fail){
- int tmr_s = AXFR_BOOTSTRAP_RETRY * tls_rand();
- event_t *ev = zd->xfr_in.timer;
- if (ev) {
- evsched_cancel(ev->parent, ev);
- evsched_schedule(ev->parent, ev, tmr_s);
- }
- log_zone_notice("%s Bootstrap failed, next "
- "attempt in %d seconds.\n",
- rq->msg, tmr_s / 1000);
+ log_server_info("%s %s\n", rq->msg, msg);
} else {
- log_server_error("%s %s.\n", rq->msg, msg);
+ log_server_error("%s %s\n", rq->msg, msg);
}
return ret;
@@ -745,16 +800,11 @@ static int xfr_task_xfer(xfrworker_t *w, knot_ns_xfr_t *rq)
/* Only for successful xfers. */
if (ret > 0) {
ret = xfr_task_finalize(w, rq);
- if (ret != KNOT_EOK && !knot_zone_contents(rq->zone)) {
-
- /* AXFR bootstrap timeout. */
- zonedata_t *zd = (zonedata_t *)knot_zone_data(rq->zone);
- int tmr_s = AXFR_BOOTSTRAP_RETRY * tls_rand();
- zd->xfr_in.bootstrap_retry = tmr_s;
- log_zone_info("%s Next attempt to bootstrap "
- "in %d seconds.\n",
- rq->msg, tmr_s / 1000);
- } else if (ret == KNOT_EBUSY && rq->type == XFR_TYPE_IIN) {
+
+ /* EBUSY on incremental transfer has a special meaning and
+ * is caused by a journal not able to free up space for incoming
+ * transfer, thus forcing to start a new full zone transfer. */
+ if (ret == KNOT_EBUSY && rq->type == XFR_TYPE_IIN) {
return xfr_start_axfr(w, rq, diff_nospace_msg);
} else {
@@ -763,7 +813,7 @@ static int xfr_task_xfer(xfrworker_t *w, knot_ns_xfr_t *rq)
}
/* Update REFRESH/RETRY */
- zones_schedule_refresh(rq->zone, 0);
+ zones_schedule_refresh(rq->zone, REFRESH_DEFAULT);
ret = KNOT_ECONNREFUSED; /* Disconnect */
}
@@ -801,37 +851,36 @@ static int xfr_process_event(xfrworker_t *w, knot_ns_xfr_t *rq)
}
}
-/*! \brief Sweep non-replied connection. */
-static void xfr_sweep(fdset_t *set, int fd, void *data)
+/*! \brief Sweep inactive connection. */
+static enum fdset_sweep_state xfr_sweep(fdset_t *set, int i, void *data)
{
- dbg_xfr("xfr: sweeping fd=%d\n", fd);
- if (!set || !data) {
- dbg_xfr("xfr: invalid sweep operation on NULL worker or set\n");
- return;
- }
- xfrworker_t *w = (xfrworker_t *)data;
- knot_ns_xfr_t *rq = xfr_task_get(w, fd);
- if (!rq) {
- dbg_xfr("xfr: NULL data to sweep\n");
- return;
- }
+ assert(set && i < set->n && i >= 0);
+
+ knot_ns_xfr_t *rq = set->ctx[i];
+ xfrhandler_t *xfr = (xfrhandler_t *)data;
- /* Skip non-sweepable types. */
+ /* Expire only UDP requests. */
int ret = KNOT_ECONNREFUSED;
switch(rq->type) {
case XFR_TYPE_SOA:
case XFR_TYPE_NOTIFY:
case XFR_TYPE_FORWARD:
- ret = xfr_task_expire(set, rq);
+ ret = xfr_task_expire(set, i, rq);
break;
default:
break;
}
+ /* Close if not valid anymore. */
if (ret != KNOT_EOK) {
- xfr_task_close(w, fd);
- --w->pending;
+ if (xfr_task_is_transfer(rq))
+ xfr_pending_decr(xfr);
+ xfr_task_close(rq);
+ socket_close(set->pfd[i].fd);
+ return FDSET_SWEEP;
}
+
+ return FDSET_KEEP;
}
/*! \brief Check TSIG if exists. */
@@ -969,7 +1018,7 @@ int xfr_worker(dthread_t *thread)
xfrhandler_t *xfr = w->master;
/* Buffer for answering. */
- size_t buflen = XFR_BUFFER_SIZE;
+ size_t buflen = SOCKET_MTU_SZ;
uint8_t* buf = malloc(buflen);
if (buf == NULL) {
dbg_xfr("xfr: failed to allocate buffer for XFR worker\n");
@@ -981,84 +1030,113 @@ int xfr_worker(dthread_t *thread)
time_now(&next_sweep);
next_sweep.tv_sec += XFR_SWEEP_INTERVAL;
- int limit = XFR_CHUNKLEN * 3;
- if (conf() && conf()->xfers > 0) {
- limit = conf()->xfers;
+ /* Approximate thread capacity limits. */
+ unsigned threads = w->master->unit->size;
+ unsigned thread_capacity = XFR_MAX_TASKS / threads;
+
+ /* Set of connections. */
+ fdset_t set;
+ int ret = fdset_init(&set, thread_capacity);
+ if (ret != KNOT_EOK) {
+ free(buf);
+ return ret;
}
- unsigned thread_capacity = limit / w->master->unit->size;
- if (thread_capacity < 1) thread_capacity = 1;
- w->pool.fds = fdset_new();
- w->pool.t = ahtable_create();
- w->pending = 0;
/* Accept requests. */
- int ret = 0;
dbg_xfr_verb("xfr: worker=%p starting\n", w);
for (;;) {
/* Populate pool with new requests. */
- if (w->pending <= thread_capacity) {
- pthread_mutex_lock(&xfr->mx);
- unsigned was_pending = w->pending;
- while (!EMPTY_LIST(xfr->queue)) {
- knot_ns_xfr_t *rq = HEAD(xfr->queue);
- rem_node(&rq->n);
+ unsigned newconns = 0;
+ for (;;) {
+ /* Do not exceed thread capacity. */
+ if (set.n >= thread_capacity || newconns > XFR_CHUNKLEN)
+ break;
- /* Unlock queue and process request. */
+ /* Tak first request. */
+ pthread_mutex_lock(&xfr->mx);
+ if (EMPTY_LIST(xfr->queue)) {
pthread_mutex_unlock(&xfr->mx);
- ret = xfr_task_process(w, rq, buf, buflen);
- if (ret == KNOT_EOK) ++w->pending;
- else xfr_task_free(rq);
- pthread_mutex_lock(&xfr->mx);
+ break;
+ }
- if (w->pending - was_pending > XFR_CHUNKLEN)
- break;
+
+ /* Limit number of transfers. */
+ knot_ns_xfr_t *rq = HEAD(xfr->queue);
+ unsigned is_transfer = xfr_task_is_transfer(rq);
+ if (is_transfer && !xfr_pending_incr(xfr)) {
+ pthread_mutex_unlock(&xfr->mx);
+ break;
}
+
+ rem_node(&rq->n);
pthread_mutex_unlock(&xfr->mx);
+
+ /* Start asynchronous connect. */
+ xfr_async_setbuf(rq, buf, buflen);
+ if (xfr_async_start(&set, rq) != KNOT_EOK) {
+ if (is_transfer)
+ xfr_pending_decr(xfr);
+ xfr_task_close(rq);
+ break;
+ }
+
+ ++newconns;
}
/* Check pending threads. */
- if (dt_is_cancelled(thread) || w->pending == 0) {
+ if (dt_is_cancelled(thread) || set.n == 0) {
break;
}
/* Poll fdset. */
- int nfds = fdset_wait(w->pool.fds, (XFR_SWEEP_INTERVAL/2) * 1000);
+ int nfds = poll(set.pfd, set.n, XFR_SWEEP_INTERVAL * 1000);
if (nfds < 0) {
- if (errno == EINTR) continue;
+ if (errno == EINTR)
+ continue;
break;
}
/* Iterate fdset. */
- fdset_it_t it;
- fdset_begin(w->pool.fds, &it);
- while(nfds > 0) {
-
- /* Find data. */
- knot_ns_xfr_t *rq = xfr_task_get(w, it.fd);
- dbg_xfr_verb("xfr: worker=%p processing event on "
- "fd=%d data=%p.\n",
- w, it.fd, rq);
- if (rq) {
+ unsigned i = 0;
+ while (nfds > 0 && i < set.n && !dt_is_cancelled(thread)) {
+
+ if (!(set.pfd[i].revents & set.pfd[i].events)) {
+ /* Skip inactive. */
+ ++i;
+ continue;
+ } else {
+ /* One less active event. */
+ --nfds;
+ }
+
+ /* Process pending tasks. */
+ knot_ns_xfr_t *rq = (knot_ns_xfr_t *)set.ctx[i];
+ if (rq->flags & XFR_FLAG_CONNECTING) {
+ ret = xfr_async_finish(&set, i);
+ } else {
ret = xfr_process_event(w, rq);
- if (ret != KNOT_EOK) {
- xfr_task_close(w, it.fd);
- --w->pending;
- --it.pos; /* Reset iterator */
- }
}
- /* Next fd. */
- if (fdset_next(w->pool.fds, &it) < 0) {
- break;
+ /* Check task state. */
+ if (ret != KNOT_EOK) {
+ if (xfr_task_is_transfer(rq))
+ xfr_pending_decr(xfr);
+ xfr_task_close(rq);
+ socket_close(set.pfd[i].fd);
+ fdset_remove(&set, i);
+ continue; /* Stay on the same index. */
}
+
+ /* Next active. */
+ ++i;
}
/* Sweep inactive. */
timev_t now;
if (time_now(&now) == 0) {
if (now.tv_sec >= next_sweep.tv_sec) {
- fdset_sweep(w->pool.fds, &xfr_sweep, w);
+ fdset_sweep(&set, &xfr_sweep, xfr);
memcpy(&next_sweep, &now, sizeof(next_sweep));
next_sweep.tv_sec += XFR_SWEEP_INTERVAL;
}
@@ -1066,22 +1144,17 @@ int xfr_worker(dthread_t *thread)
}
/* Cancel existing connections. */
- size_t keylen = 0;
- ahtable_iter_t i;
- ahtable_iter_begin(w->pool.t, &i, false);
- while (!ahtable_iter_finished(&i)) {
- int *key = (int *)ahtable_iter_key(&i, &keylen);
- xfr_task_close(w, *key);
- ahtable_iter_next(&i);
- }
- ahtable_iter_free(&i);
-
- /* Destroy data structures. */
- fdset_destroy(w->pool.fds);
- ahtable_free(w->pool.t);
- free(buf);
+ for (unsigned i = 0; i < set.n; ++i) {
+ knot_ns_xfr_t *rq = (knot_ns_xfr_t *)set.ctx[i];
+ socket_close(set.pfd[i].fd);
+ if (xfr_task_is_transfer(rq))
+ xfr_pending_decr(xfr);
+ xfr_task_free(rq);
+ }
dbg_xfr_verb("xfr: worker=%p finished.\n", w);
+ fdset_clear(&set);
+ free(buf);
return KNOT_EOK;
}
@@ -1115,6 +1188,7 @@ xfrhandler_t *xfr_create(size_t thrcount, knot_nameserver_t *ns)
/* Create tasks structure and mutex. */
pthread_mutex_init(&xfr->mx, 0);
+ pthread_mutex_init(&xfr->pending_mx, 0);
init_list(&xfr->queue);
/* Assign worker threads. */
@@ -1133,6 +1207,7 @@ int xfr_free(xfrhandler_t *xfr)
}
/* Free RR mutex. */
+ pthread_mutex_destroy(&xfr->pending_mx);
pthread_mutex_destroy(&xfr->mx);
/* Free pending queue. */
diff --git a/src/knot/server/xfr-handler.h b/src/knot/server/xfr-handler.h
index 2042605..f0b0487 100644
--- a/src/knot/server/xfr-handler.h
+++ b/src/knot/server/xfr-handler.h
@@ -48,11 +48,6 @@ enum xfrstate_t {
*/
typedef struct xfrworker_t
{
- struct {
- ahtable_t *t;
- fdset_t *fds;
- } pool;
- unsigned pending;
struct xfrhandler_t *master; /*! \brief Worker master. */
} xfrworker_t;
@@ -62,6 +57,8 @@ typedef struct xfrworker_t
typedef struct xfrhandler_t
{
list queue;
+ unsigned pending; /*!< \brief Pending transfers. */
+ pthread_mutex_t pending_mx;
pthread_mutex_t mx; /*!< \brief Tasks synchronisation. */
knot_nameserver_t *ns;
dt_unit_t *unit; /*!< \brief Threading unit. */
diff --git a/src/knot/server/zones.c b/src/knot/server/zones.c
index d1a3bf6..e1c295f 100644
--- a/src/knot/server/zones.c
+++ b/src/knot/server/zones.c
@@ -449,27 +449,33 @@ static int zones_zonefile_sync_ev(event_t *e)
return KNOT_EINVAL;
}
- /* Execute zonefile sync. */
- journal_t *j = journal_retain(zd->ixfr_db);
- int ret = zones_zonefile_sync(zone, j);
- journal_release(j);
+ /* Only on zones with valid contents (non empty). */
+ int ret = KNOT_EOK;
+ if (knot_zone_contents(zone)) {
+ /* Synchronize journal. */
+ journal_t *j = journal_retain(zd->ixfr_db);
+ ret = zones_zonefile_sync(zone, j);
+ journal_release(j);
- rcu_read_lock();
- if (ret == KNOT_EOK) {
- log_zone_info("Applied differences of '%s' to zonefile.\n",
- zd->conf->name);
- } else if (ret != KNOT_ERANGE) {
- log_zone_warning("Failed to apply differences of '%s' "
- "to zonefile.\n",
- zd->conf->name);
+ rcu_read_lock();
+ if (ret == KNOT_EOK) {
+ log_zone_info("Applied differences of '%s' to zonefile.\n",
+ zd->conf->name);
+ } else if (ret != KNOT_ERANGE) {
+ log_zone_warning("Failed to apply differences of '%s' "
+ "to zonefile.\n", zd->conf->name);
+ }
+ rcu_read_unlock();
}
/* Reschedule. */
- evsched_schedule(e->parent, e, zd->conf->dbsync_timeout * 1000);
+ rcu_read_lock();
+ int next_timeout = zd->conf->dbsync_timeout * 1000;
dbg_zones("zones: next IXFR database SYNC of '%s' in %d seconds\n",
- zd->conf->name, zd->conf->dbsync_timeout);
+ zd->conf->name, next_timeout / 1000);
rcu_read_unlock();
+ evsched_schedule(e->parent, e, next_timeout);
return ret;
}
@@ -2495,7 +2501,7 @@ int zones_process_response(knot_nameserver_t *nameserver,
/* No updates available. */
if (ret == 0) {
- zones_schedule_refresh(zone, 0);
+ zones_schedule_refresh(zone, REFRESH_DEFAULT);
rcu_read_unlock();
return KNOT_EUPTODATE;
}
@@ -2698,8 +2704,7 @@ int zones_ns_conf_hook(const struct conf_t *conf, void *data)
/* REFRESH zones. */
for (unsigned i = 0; i < knot_zonedb_zone_count(ns->zone_db); ++i) {
- /* Refresh new slave zones (almost) immediately. */
- zones_schedule_refresh(zones[i], tls_rand() * 500 + i/2);
+ zones_schedule_refresh(zones[i], 0); /* Now. */
zones_schedule_notify(zones[i]);
}
@@ -3177,7 +3182,7 @@ int zones_schedule_notify(knot_zone_t *zone)
return KNOT_EOK;
}
-int zones_schedule_refresh(knot_zone_t *zone, unsigned time)
+int zones_schedule_refresh(knot_zone_t *zone, int64_t time)
{
if (!zone || !zone->data) {
return KNOT_EINVAL;
@@ -3206,18 +3211,17 @@ int zones_schedule_refresh(knot_zone_t *zone, unsigned time)
if (zd->xfr_in.has_master) {
/* Schedule REFRESH timer. */
- uint32_t refresh_tmr = time;
- if (refresh_tmr == 0) {
- if (knot_zone_contents(zone)) {
- refresh_tmr = zones_jitter(zones_soa_refresh(zone));
- } else {
- refresh_tmr = zd->xfr_in.bootstrap_retry;
- }
+ if (time < 0) {
+ if (knot_zone_contents(zone))
+ time = zones_jitter(zones_soa_refresh(zone));
+ else
+ time = zd->xfr_in.bootstrap_retry;
}
+
zd->xfr_in.timer = evsched_schedule_cb(sch, zones_refresh_ev,
- zone, refresh_tmr);
+ zone, time);
dbg_zones("zone: REFRESH '%s' set to %u\n",
- zd->conf->name, refresh_tmr);
+ zd->conf->name, time);
zd->xfr_in.state = XFR_SCHED;
}
rcu_read_unlock();
diff --git a/src/knot/server/zones.h b/src/knot/server/zones.h
index 5045d50..2260e01 100644
--- a/src/knot/server/zones.h
+++ b/src/knot/server/zones.h
@@ -46,6 +46,10 @@
#define IXFR_DBSYNC_TIMEOUT (60*1000) /*!< Database sync timeout = 60s. */
#define AXFR_BOOTSTRAP_RETRY (30*1000) /*!< Interval between AXFR BS retries. */
+enum {
+ REFRESH_DEFAULT = -1 /* Use time value from zone structure. */
+};
+
/*!
* \brief Zone-related data.
*/
@@ -302,13 +306,13 @@ int zones_store_and_apply_chgsets(knot_changesets_t *chs,
* REFRESH/RETRY/EXPIRE timers are updated according to SOA.
*
* \param zone Related zone.
- * \param time Specific time or 0 for default.
+ * \param time Specific time or REFRESH_DEFAULT for default.
*
* \retval KNOT_EOK
* \retval KNOT_EINVAL
* \retval KNOT_ERROR
*/
-int zones_schedule_refresh(knot_zone_t *zone, unsigned time);
+int zones_schedule_refresh(knot_zone_t *zone, int64_t time);
/*!
* \brief Schedule NOTIFY after zone update.
diff --git a/src/knot/zone/semantic-check.c b/src/knot/zone/semantic-check.c
index 1d3c5c4..efbe953 100644
--- a/src/knot/zone/semantic-check.c
+++ b/src/knot/zone/semantic-check.c
@@ -606,6 +606,7 @@ static int check_nsec3_node_in_zone(knot_zone_contents_t *zone,
err_handler_handle_error(handler, node,
ZC_ERR_NSEC3_UNSECURED_DELEGATION,
NULL);
+ return KNOT_EOK;
} else {
/* Unsecured delegation, check whether it is part of
* opt-out span */
@@ -623,7 +624,7 @@ static int check_nsec3_node_in_zone(knot_zone_contents_t *zone,
if (nsec3_node == NULL) {
/* Probably should not ever happen */
- return ZC_ERR_NSEC3_NOT_FOUND;
+ return KNOT_ERROR;
}
assert(nsec3_previous);
@@ -643,6 +644,8 @@ static int check_nsec3_node_in_zone(knot_zone_contents_t *zone,
err_handler_handle_error(handler, node,
ZC_ERR_NSEC3_UNSECURED_DELEGATION_OPT,
NULL);
+ /* We cannot continue from here. */
+ return KNOT_EOK;
}
}
}
diff --git a/src/knot/zone/zone-load.c b/src/knot/zone/zone-load.c
index ac414f1..ec8375a 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(&current_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);
file_loader_process(loader->file_loader);
@@ -676,7 +676,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",
@@ -686,7 +686,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");
@@ -695,13 +695,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 =
@@ -724,7 +724,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;
}
@@ -733,9 +733,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/libknot/nameserver/name-server.c b/src/libknot/nameserver/name-server.c
index 4a95240..ee956e7 100644
--- a/src/libknot/nameserver/name-server.c
+++ b/src/libknot/nameserver/name-server.c
@@ -1753,7 +1753,7 @@ static inline int ns_referral(const knot_node_t *node,
&& knot_query_dnssec_requested(
knot_packet_query(resp))) {
ret = ns_add_rrsigs(ds_rrset, resp, node->owner,
- knot_response_add_rrset_authority,
+ knot_response_add_rrset_answer,
1);
}
} else {
@@ -1919,7 +1919,6 @@ static int ns_answer_from_node(const knot_node_t *node,
}
}
} else { // else put authority NS
- assert(previous == NULL);
assert(closest_encloser == knot_node_parent(node)
|| !knot_dname_is_wildcard(knot_node_owner(node))
|| knot_dname_compare(qname, knot_node_owner(node)) == 0);
@@ -2141,14 +2140,19 @@ static int ns_answer_from_zone(const knot_zone_contents_t *zone,
uint16_t qtype = knot_packet_qtype(resp);
search:
- find_ret = knot_zone_contents_find_dname(zone, qname, &node,
- &closest_encloser, &previous);
-// node = knot_node_current(node);
-// closest_encloser = knot_node_current(closest_encloser);
-// previous = knot_node_current(previous);
- previous = NULL; // TODO REVIEW LS
+ // Searching for a name directly is faster than when we need previous dname
+ node = knot_zone_contents_find_node(zone, qname);
+ if (node != NULL) {
+ // If node is found, closest_encloser is equal to node itself
+ closest_encloser = node;
+ find_ret = KNOT_ZONE_NAME_FOUND;
+ } else {
+ // We need previous and closest encloser, full search has to be done
+ find_ret = knot_zone_contents_find_dname(zone, qname, &node,
+ &closest_encloser, &previous);
if (find_ret == KNOT_EINVAL) {
- return NS_ERR_SERVFAIL;
+ return NS_ERR_SERVFAIL;
+ }
}
dbg_ns_exec_verb(
diff --git a/src/libknot/nameserver/name-server.h b/src/libknot/nameserver/name-server.h
index 58ea212..6574539 100644
--- a/src/libknot/nameserver/name-server.h
+++ b/src/libknot/nameserver/name-server.h
@@ -159,7 +159,8 @@ static const size_t KNOT_NS_TSIG_DATA_MAX_SIZE = 100 * 64 * 1024;
enum knot_ns_xfr_flag_t {
XFR_FLAG_TCP = 1 << 0, /*!< XFR request is on TCP. */
XFR_FLAG_UDP = 1 << 1, /*!< XFR request is on UDP. */
- XFR_FLAG_AXFR_FINISHED = 1 << 2 /*!< Transfer is finished. */
+ XFR_FLAG_AXFR_FINISHED = 1 << 2, /*!< Transfer is finished. */
+ XFR_FLAG_CONNECTING = 1 << 3 /*!< In connecting phase. */
};
typedef enum knot_ns_transport {
@@ -173,8 +174,8 @@ typedef enum knot_ns_transport {
typedef enum knot_ns_xfr_type_t {
/* DNS events. */
XFR_TYPE_AIN = 0, /*!< AXFR-IN request (start transfer). */
- XFR_TYPE_AOUT, /*!< AXFR-OUT request (incoming transfer). */
XFR_TYPE_IIN, /*!< IXFR-IN request (start transfer). */
+ XFR_TYPE_AOUT, /*!< AXFR-OUT request (incoming transfer). */
XFR_TYPE_IOUT, /*!< IXFR-OUT request (incoming transfer). */
XFR_TYPE_SOA, /*!< Pending SOA request. */
XFR_TYPE_NOTIFY, /*!< Pending NOTIFY query. */
diff --git a/src/libknot/rrset-dump.c b/src/libknot/rrset-dump.c
index e22a629..c8c7fe7 100644
--- a/src/libknot/rrset-dump.c
+++ b/src/libknot/rrset-dump.c
@@ -549,9 +549,9 @@ static void wire_text_to_str(rrset_dump_params_t *p)
// Loop over all characters.
for (size_t i = 0; i < in_len; i++) {
- char ch = (char)(p->in)[i];
+ uint8_t ch = p->in[i];
- if (isprint((unsigned char)(ch)) != 0) {
+ if (isprint(ch) != 0) {
// For special character print leading slash.
if (ch == '\\' || ch == '"') {
dump_string(p, "\\");
diff --git a/src/libknot/zone/zone-contents.c b/src/libknot/zone/zone-contents.c
index ff1a1d4..fbf4ab3 100644
--- a/src/libknot/zone/zone-contents.c
+++ b/src/libknot/zone/zone-contents.c
@@ -2515,6 +2515,12 @@ int knot_zone_contents_integrity_check(const knot_zone_contents_t *contents)
data.children = 0;
data.contents = contents;
+ if (contents == NULL) {
+ log_zone_warning("Zone to be integrity-checked does "
+ "not exist. Skipping...\n");
+ return 1;
+ }
+
int ret = knot_zone_contents_tree_apply_inorder(
(knot_zone_contents_t *)contents,
knot_zc_integrity_check_node, (void *)&data);
diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am
index 29733b7..bb381dc 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
@@ -63,12 +62,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/Makefile.in b/src/tests/Makefile.in
index df605b8..fefb224 100644
--- a/src/tests/Makefile.in
+++ b/src/tests/Makefile.in
@@ -50,10 +50,10 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-check_PROGRAMS = unittests$(EXEEXT) unittests_xfr$(EXEEXT)
+check_PROGRAMS = unittests$(EXEEXT)
TESTS = unittests$(EXEEXT)
subdir = src/tests
-DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_compile_flag.m4 \
$(top_srcdir)/m4/ax_ext.m4 \
@@ -88,10 +88,6 @@ unittests_DEPENDENCIES = ../libknotd.la ../libknots.la @LIBOBJS@
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
-am_unittests_xfr_OBJECTS = xfr_tests.$(OBJEXT)
-unittests_xfr_OBJECTS = $(am_unittests_xfr_OBJECTS)
-unittests_xfr_DEPENDENCIES = ../libknotd.la ../libknot.la \
- ../libknots.la @LIBOBJS@
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@@ -118,9 +114,8 @@ am__v_CCLD_0 = @echo " CCLD " $@;
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
-SOURCES = $(unittests_SOURCES) $(nodist_unittests_SOURCES) \
- $(unittests_xfr_SOURCES)
-DIST_SOURCES = $(unittests_SOURCES) $(unittests_xfr_SOURCES)
+SOURCES = $(unittests_SOURCES) $(nodist_unittests_SOURCES)
+DIST_SOURCES = $(unittests_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
@@ -198,6 +193,7 @@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
RAGEL = @RAGEL@
RANLIB = @RANLIB@
+RELEASE_DATE = @RELEASE_DATE@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -225,6 +221,7 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+config_dir = @config_dir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
@@ -321,12 +318,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@
all: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) all-am
@@ -438,9 +430,6 @@ libknot/sign_tests.$(OBJEXT): libknot/$(am__dirstamp) \
unittests$(EXEEXT): $(unittests_OBJECTS) $(unittests_DEPENDENCIES) $(EXTRA_unittests_DEPENDENCIES)
@rm -f unittests$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(unittests_OBJECTS) $(unittests_LDADD) $(LIBS)
-unittests_xfr$(EXEEXT): $(unittests_xfr_OBJECTS) $(unittests_xfr_DEPENDENCIES) $(EXTRA_unittests_xfr_DEPENDENCIES)
- @rm -f unittests_xfr$(EXEEXT)
- $(AM_V_CCLD)$(LINK) $(unittests_xfr_OBJECTS) $(unittests_xfr_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -469,7 +458,6 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unittests_main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfr_tests.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/acl_tests.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/base32hex_tests.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@common/$(DEPDIR)/base64_tests.Po@am__quote@
diff --git a/src/tests/README b/src/tests/README
deleted file mode 100644
index 1d9748b..0000000
--- 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/common/fdset_tests.c b/src/tests/common/fdset_tests.c
index d7b29fa..e8b9d73 100644
--- a/src/tests/common/fdset_tests.c
+++ b/src/tests/common/fdset_tests.c
@@ -98,22 +98,21 @@ static int fdset_tests_count(int argc, char *argv[])
static int fdset_tests_run(int argc, char *argv[])
{
- diag("fdset: implements '%s'", fdset_method());
-
/* 1. Create fdset. */
- fdset_t *set = fdset_new();
- ok(set != 0, "fdset: new");
+ fdset_t set;
+ int ret = fdset_init(&set, 32);
+ ok(ret == 0, "fdset: init");
/* 2. Create pipe. */
int fds[2], tmpfds[2];
- int ret = pipe(fds);
+ ret = pipe(fds);
ok(ret >= 0, "fdset: pipe() works");
ret = pipe(tmpfds);
/* 3. Add fd to set. */
- ret = fdset_add(set, fds[0], OS_EV_READ);
+ ret = fdset_add(&set, fds[0], POLLIN, NULL);
ok(ret == 0, "fdset: add to set works");
- fdset_add(set, tmpfds[0], OS_EV_READ);
+ fdset_add(&set, tmpfds[0], POLLIN, NULL);
/* Schedule write. */
struct timeval ts, te;
@@ -122,54 +121,44 @@ static int fdset_tests_run(int argc, char *argv[])
pthread_create(&t, 0, thr_action, &fds[1]);
/* 4. Watch fdset. */
- ret = fdset_wait(set, OS_EV_FOREVER);
+ int nfds = poll(set.pfd, set.n, 2000);
gettimeofday(&te, 0);
size_t diff = timeval_diff(&ts, &te);
- ok(ret > 0 && diff > 99 && diff < 10000,
- "fdset: poll returned events in %zu ms", diff);
+ ok(nfds > 0 && diff > 99 && diff < 10000,
+ "fdset: poll returned %d events in %zu ms", nfds, diff);
/* 5. Prepare event set. */
- fdset_it_t it;
- ret = fdset_begin(set, &it);
- ok(ret == 0 && it.fd == fds[0], "fdset: begin is valid, ret=%d", ret);
+ ok(set.pfd[0].revents & POLLIN, "fdset: pipe is active");
/* 6. Receive data. */
char buf = 0x00;
- ret = read(it.fd, &buf, WRITE_PATTERN_LEN);
- ok(ret >= 0 && buf == WRITE_PATTERN, "fdset: contains valid data, fd=%d", it.fd);
-
- /* 7. Iterate event set. */
- ret = fdset_next(set, &it);
- ok(ret < 0, "fdset: boundary check works");
+ ret = read(set.pfd[0].fd, &buf, WRITE_PATTERN_LEN);
+ ok(ret >= 0 && buf == WRITE_PATTERN, "fdset: contains valid data");
- /* 8. Remove from event set. */
- ret = fdset_remove(set, fds[0]);
+ /* 7-9. Remove from event set. */
+ ret = fdset_remove(&set, 0);
ok(ret == 0, "fdset: remove from fdset works");
close(fds[0]);
close(fds[1]);
- ret = fdset_remove(set, tmpfds[0]);
+ ret = fdset_remove(&set, 0);
close(tmpfds[1]);
close(tmpfds[1]);
-
- /* 9. Poll empty fdset. */
- ret = fdset_wait(set, OS_EV_FOREVER);
- ok(ret <= 0, "fdset: polling empty fdset returns -1 (ret=%d)", ret);
+ ok(ret == 0, "fdset: remove from fdset works (2)");
+ ret = fdset_remove(&set, 0);
+ ok(ret != 0, "fdset: removing nonexistent item");
/* 10. Crash test. */
lives_ok({
- fdset_destroy(0);
- fdset_add(0, -1, 0);
- fdset_remove(0, -1);
- fdset_wait(0, OS_EV_NOWAIT);
- fdset_begin(0, 0);
- fdset_end(0, 0);
- fdset_next(0, 0);
- fdset_method();
+ fdset_init(0, 0);
+ fdset_add(0, 1, 1, 0);
+ fdset_add(0, 0, 1, 0);
+ fdset_remove(0, 1);
+ fdset_remove(0, 0);
}, "fdset: crash test successful");
/* 11. Destroy fdset. */
- ret = fdset_destroy(set);
+ ret = fdset_clear(&set);
ok(ret == 0, "fdset: destroyed");
/* Cleanup. */
diff --git a/src/tests/xfr_tests.c b/src/tests/xfr_tests.c
deleted file mode 100644
index fee09f2..0000000
--- 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 29de11d..0000000
--- 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
diff --git a/src/utils/common/params.c b/src/utils/common/params.c
index 56dc662..86b930d 100644
--- a/src/utils/common/params.c
+++ b/src/utils/common/params.c
@@ -168,7 +168,7 @@ int params_parse_type(const char *value, uint16_t *rtype, uint32_t *xfr_serial)
char *end;
// Convert string to serial.
- unsigned long serial = strtoul(param_str, &end, 10);
+ unsigned long long serial = strtoull(param_str, &end, 10);
// Check for bad serial string.
if (end == param_str || *end != '\0' ||
@@ -217,7 +217,7 @@ int params_parse_wait(const char *value, int32_t *dst)
}
/* Convert string to number. */
- long num = strtol(value, &end, 10);
+ long long num = strtoll(value, &end, 10);
/* Check for bad string (empty or incorrect). */
if (end == value || *end != '\0') {
@@ -225,11 +225,11 @@ int params_parse_wait(const char *value, int32_t *dst)
return KNOT_EINVAL;
} else if (num < 1) {
num = 1;
- WARN("time %s is too short, using %ld instead\n", value, num);
+ WARN("time %s is too short, using %lld instead\n", value, num);
/* Reduce maximal value. Poll takes signed int in milliseconds. */
} else if (num > INT32_MAX) {
num = INT32_MAX / 1000;
- WARN("time %s is too big, using %ld instead\n", value, num);
+ WARN("time %s is too big, using %lld instead\n", value, num);
}
*dst = num;
@@ -247,7 +247,7 @@ int params_parse_num(const char *value, uint32_t *dst)
}
// Convert string to number.
- unsigned long num = strtoul(value, &end, 10);
+ unsigned long long num = strtoull(value, &end, 10);
// Check for bad string.
if (end == value || *end != '\0') {
@@ -257,7 +257,7 @@ int params_parse_num(const char *value, uint32_t *dst)
if (num > UINT32_MAX) {
num = UINT32_MAX;
- WARN("number %s is too big, using %lu instead\n", value, num);
+ WARN("number %s is too big, using %llu instead\n", value, num);
}
*dst = num;
@@ -275,7 +275,7 @@ int params_parse_bufsize(const char *value, int32_t *dst)
}
// Convert string to number.
- unsigned long num = strtoul(value, &end, 10);
+ unsigned long long num = strtoull(value, &end, 10);
// Check for bad string.
if (end == value || *end != '\0') {
@@ -285,7 +285,7 @@ int params_parse_bufsize(const char *value, int32_t *dst)
if (num > UINT16_MAX) {
num = UINT16_MAX;
- WARN("size %s is too big, using %lu instead\n", value, num);
+ WARN("size %s is too big, using %llu instead\n", value, num);
}
*dst = num;
diff --git a/src/utils/dig/dig_params.c b/src/utils/dig/dig_params.c
index 54361c8..d3b3d71 100644
--- a/src/utils/dig/dig_params.c
+++ b/src/utils/dig/dig_params.c
@@ -512,7 +512,7 @@ static void dig_help(void)
" +[no]cl Show DNS class.\n"
" +[no]ttl Show TTL value.\n"
" +time=T Set wait for reply interval in seconds.\n"
- " +retries=N Set number of retries.\n"
+ " +retry=N Set number of retries.\n"
" +bufsize=B Set EDNS buffer size.\n"
" +[no]tcp Use TCP protocol.\n"
" +[no]fail Stop if SERVFAIL.\n"
@@ -855,8 +855,8 @@ static int parse_opt2(const char *value, dig_params_t *params)
return KNOT_EINVAL;
}
}
- else if (strncmp(value, "retries=", 8) == 0) {
- if (params_parse_num(value + 8, &query->retries)
+ else if (strncmp(value, "retry=", 6) == 0) {
+ if (params_parse_num(value + 6, &query->retries)
!= KNOT_EOK) {
return KNOT_EINVAL;
}
diff --git a/src/utils/host/host_params.c b/src/utils/host/host_params.c
index 0b32893..66fe67a 100644
--- a/src/utils/host/host_params.c
+++ b/src/utils/host/host_params.c
@@ -179,7 +179,7 @@ static void host_help(void)
" -d Allow debug messages.\n"
" -h, --help Print help.\n"
" -r Disable recursion.\n"
- " -s Stop if servfail.\n"
+ " -s Stop if SERVFAIL.\n"
" -T Use TCP procotol.\n"
" -v Verbose output.\n"
" -V, --version Print program version.\n"
diff --git a/src/zscanner/test/cases/06-0_INCLUDE.in b/src/zscanner/test/cases/06-0_INCLUDE.in
index 65ed38c..d8f4d27 100644
--- a/src/zscanner/test/cases/06-0_INCLUDE.in
+++ b/src/zscanner/test/cases/06-0_INCLUDE.in
@@ -19,10 +19,10 @@ $INCLUDE \./includes/include2 _a_.-b-c-./d/. ; Slashed character in file name,
$INCLUDE ./includes/include2 \0320\ \\\"\.\@\*.tld. ; Origin with special chars
5. NS @
-$INCLUDE /home/ondrej/Projects/knot/build/src/zscanner/test/cases/includes/include2 ; Absolute path without origin
+$INCLUDE /home/ondrej/Projects/knot/src/zscanner/test/cases/includes/include2 ; Absolute path without origin
6. NS @
-$INCLUDE /home/ondrej/Projects/knot/build/src/zscanner/test/cases/includes/include2 tld. ; Absolute path with origin
+$INCLUDE /home/ondrej/Projects/knot/src/zscanner/test/cases/includes/include2 tld. ; Absolute path with origin
7. NS @
; KO
diff --git a/src/zscanner/test/cases/06-3_INCLUDE.in b/src/zscanner/test/cases/06-3_INCLUDE.in
index 963e44d..3dc9ba8 100644
--- a/src/zscanner/test/cases/06-3_INCLUDE.in
+++ b/src/zscanner/test/cases/06-3_INCLUDE.in
@@ -2,4 +2,4 @@ $ORIGIN .
$TTL 1
; KO
-$INCLUDE /home/ondrej/Projects/knot/build/src/zscanner/test/cases/ ; Given file is a directory
+$INCLUDE /home/ondrej/Projects/knot/src/zscanner/test/cases/ ; Given file is a directory
diff --git a/src/zscanner/test/cases/06-4_INCLUDE.in b/src/zscanner/test/cases/06-4_INCLUDE.in
index 438933a..f4e3c51 100644
--- a/src/zscanner/test/cases/06-4_INCLUDE.in
+++ b/src/zscanner/test/cases/06-4_INCLUDE.in
@@ -2,4 +2,4 @@ $ORIGIN .
$TTL 1
; KO
-$INCLUDE /home/ondrej/Projects/knot/build/src/zscanner/test/cases/zscanner_tests/file-doesnt-exist ; File doesn't exist
+$INCLUDE /home/ondrej/Projects/knot/src/zscanner/test/cases/zscanner_tests/file-doesnt-exist ; File doesn't exist
diff --git a/src/zscanner/test/run_tests.sh b/src/zscanner/test/run_tests.sh
index 2bbdad8..ccac549 100644
--- a/src/zscanner/test/run_tests.sh
+++ b/src/zscanner/test/run_tests.sh
@@ -1,7 +1,7 @@
#!/bin/sh
-TESTS_DIR="/home/ondrej/Projects/knot/build/../src/zscanner/test/cases"
-OUTS_DIR="/home/ondrej/Projects/knot/build/src/zscanner/test/.out"
+TESTS_DIR="/home/ondrej/Projects/knot/src/zscanner/test/cases"
+OUTS_DIR="/home/ondrej/Projects/knot/src/zscanner/test/.out"
TEST_BIN="./../zscanner-tool -m 2"
# Delete temporary output directory at exit.