summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2013-07-15 15:08:40 +0200
committerOndřej Surý <ondrej@sury.org>2013-07-15 15:08:40 +0200
commit93f582ba0ad3d1f69b796b70660ccfd1530303f1 (patch)
tree0481b211d97122e6c6c2ff35ec3a5b74b88b9dfc /src
parent124965832295a277b9ca6ae9fac4f45a74a36b2a (diff)
downloadknot-upstream/1.3.0_rc4.tar.gz
New upstream version 1.3.0~rc4upstream/1.3.0_rc4
Diffstat (limited to 'src')
-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
52 files changed, 1038 insertions, 2668 deletions
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.