summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2012-04-13 17:14:49 +0200
committerOndřej Surý <ondrej@sury.org>2012-04-13 17:14:49 +0200
commitc5e123fb66dfd412a0d89293f893871f9a2e7d12 (patch)
treee4351340a850ae861ce99a4e7824f2f1bd0660a6 /src
parentb5c64fe14e2b779a715756d47d7d4c7e8e5729ea (diff)
downloadknot-c5e123fb66dfd412a0d89293f893871f9a2e7d12.tar.gz
Imported Upstream version 1.0.2upstream/1.0.2
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am10
-rw-r--r--src/Makefile.in52
-rw-r--r--src/common/acl.c41
-rw-r--r--src/common/fdset.c6
-rw-r--r--src/common/fdset.h1
-rw-r--r--src/common/fdset_epoll.c55
-rw-r--r--src/common/fdset_kqueue.c99
-rw-r--r--src/common/fdset_poll.c45
-rw-r--r--src/common/log.c (renamed from src/knot/other/log.c)34
-rw-r--r--src/common/log.h (renamed from src/knot/other/log.h)0
-rw-r--r--src/common/mempattern.c (renamed from src/common/slab/malloc.c)28
-rw-r--r--src/common/mempattern.h (renamed from src/common/slab/malloc.h)29
-rw-r--r--src/common/sockaddr.c18
-rw-r--r--src/common/sockaddr.h25
-rw-r--r--src/config.h.in3
-rw-r--r--src/knot/common.h2
-rw-r--r--src/knot/conf/cf-lex.l4
-rw-r--r--src/knot/conf/cf-parse.y17
-rw-r--r--src/knot/conf/conf.h5
-rw-r--r--src/knot/conf/logconf.c2
-rw-r--r--src/knot/ctl/knotc_main.c129
-rw-r--r--src/knot/other/debug.h88
-rw-r--r--src/knot/other/error.c2
-rw-r--r--src/knot/server/dthreads.c82
-rw-r--r--src/knot/server/dthreads.h9
-rw-r--r--src/knot/server/journal.c548
-rw-r--r--src/knot/server/journal.h94
-rw-r--r--src/knot/server/notify.c2
-rw-r--r--src/knot/server/server.c2
-rw-r--r--src/knot/server/tcp-handler.c11
-rw-r--r--src/knot/server/udp-handler.c4
-rw-r--r--src/knot/server/xfr-handler.c276
-rw-r--r--src/knot/server/zones.c619
-rw-r--r--src/knot/server/zones.h38
-rw-r--r--src/knot/stat/gatherer.c4
-rw-r--r--src/knot/zone/semantic-check.c115
-rw-r--r--src/knot/zone/semantic-check.h3
-rw-r--r--src/knot/zone/zone-dump.c710
-rw-r--r--src/knot/zone/zone-dump.h22
-rw-r--r--src/knot/zone/zone-load.c388
-rw-r--r--src/libknot/dname.c55
-rw-r--r--src/libknot/dname.h3
-rw-r--r--src/libknot/hash/cuckoo-hash-table.c18
-rw-r--r--src/libknot/nameserver/name-server.c2
-rw-r--r--src/libknot/nameserver/name-server.h1
-rw-r--r--src/libknot/updates/xfr-in.c108
-rw-r--r--src/libknot/util/debug.h183
-rw-r--r--src/tests/common/acl_tests.c13
-rw-r--r--src/tests/files/sample_conf2
-rw-r--r--src/tests/knot/dthreads_tests.c1
-rw-r--r--src/tests/knot/journal_tests.c90
-rw-r--r--src/tests/libknot/libknot/dname_tests.c83
-rw-r--r--src/tests/libknot/libknot/packet_tests.c4
-rw-r--r--src/tests/unittests_main.c2
-rw-r--r--src/tests/xfr_tests.c13
-rw-r--r--src/zcompile/parser-descriptor.c7
-rw-r--r--src/zcompile/parser-util.c143
-rw-r--r--src/zcompile/zcompile.c173
-rw-r--r--src/zcompile/zcompile_main.c17
-rw-r--r--src/zcompile/zparser.y75
60 files changed, 3072 insertions, 1543 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index e73b2bf..a1bb196 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -217,12 +217,12 @@ libknot_la_SOURCES = \
libknots_la_SOURCES = \
common/slab/slab.c \
- common/slab/malloc.c \
common/slab/slab.h \
- common/slab/malloc.h \
common/libtap/tap.c \
common/libtap/tap.h \
common/libtap/tap_unit.h \
+ common/mempattern.h \
+ common/mempattern.c \
common/lists.c \
common/base32.c \
common/lists.h \
@@ -265,7 +265,9 @@ libknots_la_SOURCES = \
common/fdset_kqueue.h \
common/fdset_kqueue.c \
common/fdset_epoll.h \
- common/fdset_epoll.c
+ common/fdset_epoll.c \
+ common/log.c \
+ common/log.h
libknotd_la_SOURCES = \
knot/stat/gatherer.c \
@@ -273,8 +275,6 @@ libknotd_la_SOURCES = \
knot/stat/gatherer.h \
knot/stat/stat.h \
knot/common.h \
- knot/other/log.c \
- knot/other/log.h \
knot/other/debug.h \
knot/other/error.h \
knot/other/error.c \
diff --git a/src/Makefile.in b/src/Makefile.in
index f2d122c..bc8db39 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -69,7 +69,7 @@ am_libknot_la_OBJECTS = libknot_error.lo utils.lo debug.lo conv.lo \
tsig-op.lo
libknot_la_OBJECTS = $(am_libknot_la_OBJECTS)
libknotd_la_DEPENDENCIES = libknot.la libknots.la @LIBOBJS@
-am_libknotd_la_OBJECTS = gatherer.lo stat.lo log.lo error.lo \
+am_libknotd_la_OBJECTS = gatherer.lo stat.lo error.lo \
libknotd_la-cf-parse.lo libknotd_la-cf-lex.lo conf.lo \
logconf.lo process.lo dthreads.lo journal.lo socket.lo \
server.lo udp-handler.lo tcp-handler.lo xfr-handler.lo \
@@ -77,11 +77,11 @@ am_libknotd_la_OBJECTS = gatherer.lo stat.lo log.lo error.lo \
zone-dump-text.lo
libknotd_la_OBJECTS = $(am_libknotd_la_OBJECTS)
libknots_la_DEPENDENCIES = @LIBOBJS@
-am_libknots_la_OBJECTS = slab.lo malloc.lo tap.lo lists.lo base32.lo \
- print.lo dynamic-array.lo skip-list.lo base32hex.lo \
+am_libknots_la_OBJECTS = slab.lo tap.lo mempattern.lo lists.lo \
+ base32.lo print.lo dynamic-array.lo skip-list.lo base32hex.lo \
general-tree.lo evqueue.lo evsched.lo acl.lo sockaddr.lo \
crc.lo ref.lo errors.lo dSFMT.lo prng.lo fdset.lo \
- fdset_poll.lo fdset_kqueue.lo fdset_epoll.lo
+ fdset_poll.lo fdset_kqueue.lo fdset_epoll.lo log.lo
libknots_la_OBJECTS = $(am_libknots_la_OBJECTS)
am__installdirs = "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(sbindir)" \
"$(DESTDIR)$(man8dir)"
@@ -220,7 +220,6 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
-DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -248,7 +247,6 @@ LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
-MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
@@ -277,7 +275,6 @@ abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
-ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
@@ -310,6 +307,7 @@ libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
@@ -540,12 +538,12 @@ libknot_la_SOURCES = \
libknots_la_SOURCES = \
common/slab/slab.c \
- common/slab/malloc.c \
common/slab/slab.h \
- common/slab/malloc.h \
common/libtap/tap.c \
common/libtap/tap.h \
common/libtap/tap_unit.h \
+ common/mempattern.h \
+ common/mempattern.c \
common/lists.c \
common/base32.c \
common/lists.h \
@@ -588,7 +586,9 @@ libknots_la_SOURCES = \
common/fdset_kqueue.h \
common/fdset_kqueue.c \
common/fdset_epoll.h \
- common/fdset_epoll.c
+ common/fdset_epoll.c \
+ common/log.c \
+ common/log.h
libknotd_la_SOURCES = \
knot/stat/gatherer.c \
@@ -596,8 +596,6 @@ libknotd_la_SOURCES = \
knot/stat/gatherer.h \
knot/stat/stat.h \
knot/common.h \
- knot/other/log.c \
- knot/other/log.h \
knot/other/debug.h \
knot/other/error.h \
knot/other/error.c \
@@ -892,7 +890,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logconf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/malloc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mempattern.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/name-server.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/node.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/node_tests.Po@am__quote@
@@ -1203,13 +1201,6 @@ stat.lo: knot/stat/stat.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o stat.lo `test -f 'knot/stat/stat.c' || echo '$(srcdir)/'`knot/stat/stat.c
-log.lo: knot/other/log.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT log.lo -MD -MP -MF $(DEPDIR)/log.Tpo -c -o log.lo `test -f 'knot/other/log.c' || echo '$(srcdir)/'`knot/other/log.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/log.Tpo $(DEPDIR)/log.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='knot/other/log.c' object='log.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o log.lo `test -f 'knot/other/log.c' || echo '$(srcdir)/'`knot/other/log.c
-
error.lo: knot/other/error.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT error.lo -MD -MP -MF $(DEPDIR)/error.Tpo -c -o error.lo `test -f 'knot/other/error.c' || echo '$(srcdir)/'`knot/other/error.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/error.Tpo $(DEPDIR)/error.Plo
@@ -1336,13 +1327,6 @@ slab.lo: common/slab/slab.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o slab.lo `test -f 'common/slab/slab.c' || echo '$(srcdir)/'`common/slab/slab.c
-malloc.lo: common/slab/malloc.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT malloc.lo -MD -MP -MF $(DEPDIR)/malloc.Tpo -c -o malloc.lo `test -f 'common/slab/malloc.c' || echo '$(srcdir)/'`common/slab/malloc.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/malloc.Tpo $(DEPDIR)/malloc.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/slab/malloc.c' object='malloc.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o malloc.lo `test -f 'common/slab/malloc.c' || echo '$(srcdir)/'`common/slab/malloc.c
-
tap.lo: common/libtap/tap.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tap.lo -MD -MP -MF $(DEPDIR)/tap.Tpo -c -o tap.lo `test -f 'common/libtap/tap.c' || echo '$(srcdir)/'`common/libtap/tap.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tap.Tpo $(DEPDIR)/tap.Plo
@@ -1350,6 +1334,13 @@ tap.lo: common/libtap/tap.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tap.lo `test -f 'common/libtap/tap.c' || echo '$(srcdir)/'`common/libtap/tap.c
+mempattern.lo: common/mempattern.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mempattern.lo -MD -MP -MF $(DEPDIR)/mempattern.Tpo -c -o mempattern.lo `test -f 'common/mempattern.c' || echo '$(srcdir)/'`common/mempattern.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/mempattern.Tpo $(DEPDIR)/mempattern.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/mempattern.c' object='mempattern.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mempattern.lo `test -f 'common/mempattern.c' || echo '$(srcdir)/'`common/mempattern.c
+
lists.lo: common/lists.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lists.lo -MD -MP -MF $(DEPDIR)/lists.Tpo -c -o lists.lo `test -f 'common/lists.c' || echo '$(srcdir)/'`common/lists.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/lists.Tpo $(DEPDIR)/lists.Plo
@@ -1490,6 +1481,13 @@ fdset_epoll.lo: common/fdset_epoll.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fdset_epoll.lo `test -f 'common/fdset_epoll.c' || echo '$(srcdir)/'`common/fdset_epoll.c
+log.lo: common/log.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT log.lo -MD -MP -MF $(DEPDIR)/log.Tpo -c -o log.lo `test -f 'common/log.c' || echo '$(srcdir)/'`common/log.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/log.Tpo $(DEPDIR)/log.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/log.c' object='log.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o log.lo `test -f 'common/log.c' || echo '$(srcdir)/'`common/log.c
+
zcompile_main.o: zcompile/zcompile_main.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT zcompile_main.o -MD -MP -MF $(DEPDIR)/zcompile_main.Tpo -c -o zcompile_main.o `test -f 'zcompile/zcompile_main.c' || echo '$(srcdir)/'`zcompile/zcompile_main.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/zcompile_main.Tpo $(DEPDIR)/zcompile_main.Po
diff --git a/src/common/acl.c b/src/common/acl.c
index d739319..a3cabd4 100644
--- a/src/common/acl.c
+++ b/src/common/acl.c
@@ -52,34 +52,29 @@ static int acl_compare(void *k1, void *k2)
}
/* Compare integers if IPv4. */
- if (a1->len == sizeof(struct sockaddr_in)) {
+ if (a1->family == AF_INET) {
/* Compute mask .*/
uint32_t mask = acl_fill_mask32(a1->prefix);
/* Compare address. */
- ldiff = (int)((acl_sa_ipv4(a1) & mask) - (acl_sa_ipv4(a2) & mask));
- if (ldiff < 0) {
- return -1;
- } else if (ldiff > 0) {
- return 1;
- } else {
- return 0;
- }
-
+ int cmp1 = (acl_sa_ipv4(a1) & mask);
+ int cmp2 = (acl_sa_ipv4(a2) & mask);
+ if (cmp1 > cmp2) return 1;
+ if (cmp1 < cmp2) return -1;
return 0;
}
/* IPv6 matching. */
#ifndef DISABLE_IPV6
- if (a1->len == sizeof(struct sockaddr_in6)) {
+ if (a1->family == AF_INET6) {
/* Get mask .*/
short chunk = a1->prefix;
/* Compare address by 32bit chunks. */
- uint32_t* a1p = (uint32_t*)&a1->addr6.sin6_addr;
- uint32_t* a2p = (uint32_t*)&a2->addr6.sin6_addr;
+ uint32_t* a1p = (uint32_t *)(&a1->addr6.sin6_addr);
+ uint32_t* a2p = (uint32_t *)(&a2->addr6.sin6_addr);
/* Mask 0 = 0 bits to compare from LO->HO (in big-endian).
* Mask 128 = 128 bits to compare.
@@ -93,12 +88,10 @@ static int acl_compare(void *k1, void *k2)
chunk = 0;
}
- ldiff = (*(a1p++) & mask) ^ (*(a2p++) & mask);
- if (ldiff < 0) {
- return -1;
- } else if (ldiff > 0) {
- return 1;
- }
+ int cmp1 = (*(a1p++) & mask);
+ int cmp2 = (*(a2p++) & mask);
+ if (cmp1 > cmp2) return 1;
+ if (cmp1 < cmp2) return -1;
}
return 0;
@@ -157,9 +150,8 @@ void acl_delete(acl_t **acl)
}
/* Truncate rules. */
- if (acl_truncate(*acl) != ACL_ACCEPT) {
- return;
- }
+ skip_destroy_list(&(*acl)->rules, 0, free);
+ skip_destroy_list(&(*acl)->rules_pref, 0, free);
/* Free ACL. */
free(*acl);
@@ -227,6 +219,11 @@ int acl_truncate(acl_t *acl)
/* Destroy all rules. */
skip_destroy_list(&acl->rules, 0, free);
skip_destroy_list(&acl->rules_pref, 0, free);
+ acl->rules = skip_create_list(acl_compare);
+ acl->rules_pref = skip_create_list(acl_compare);
+ if (acl->rules == NULL || acl->rules_pref == NULL) {
+ return ACL_ERROR;
+ }
return ACL_ACCEPT;
}
diff --git a/src/common/fdset.c b/src/common/fdset.c
index d674d4a..c915e01 100644
--- a/src/common/fdset.c
+++ b/src/common/fdset.c
@@ -103,10 +103,10 @@ void __attribute__ ((constructor)) fdset_init()
* \retval 0 if a == b
* \retval 1 if a > b
*/
-static int fdset_compare(void *a, void *b)
+static inline int fdset_compare(void *a, void *b)
{
- if ((size_t)a < (size_t)b) return -1;
- if ((size_t)a > (size_t)b) return 1;
+ if (a > b) return 1;
+ if (a < b) return -1;
return 0;
}
diff --git a/src/common/fdset.h b/src/common/fdset.h
index ead4d5b..4fbd9bc 100644
--- a/src/common/fdset.h
+++ b/src/common/fdset.h
@@ -34,6 +34,7 @@
#include <stddef.h>
#include "skip-list.h"
+#include "mempattern.h"
/*! \brief Waiting for completion constants. */
enum fdset_wait_t {
diff --git a/src/common/fdset_epoll.c b/src/common/fdset_epoll.c
index dbd803f..f6f42f0 100644
--- a/src/common/fdset_epoll.c
+++ b/src/common/fdset_epoll.c
@@ -27,7 +27,6 @@
#include "skip-list.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;
@@ -41,22 +40,20 @@ struct fdset_t {
fdset_t *fdset_epoll_new()
{
fdset_t *set = malloc(sizeof(fdset_t));
- if (!set) {
- return NULL;
+ if (set) {
+ /* Blank memory. */
+ memset(set, 0, sizeof(fdset_t));
+
+ /* Create epoll fd. */
+ set->epfd = epoll_create(OS_FDS_CHUNKSIZE);
}
-
- /* 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) {
+ if(fdset == NULL) {
return -1;
}
@@ -71,27 +68,14 @@ int fdset_epoll_destroy(fdset_t * fdset)
int fdset_epoll_add(fdset_t *fdset, int fd, int events)
{
- if (!fdset || fd < 0 || events <= 0) {
+ if (fdset == NULL || fd < 0 || events <= 0) {
return -1;
}
/* Realloc needed. */
- if (fdset->nfds == fdset->reserved) {
- const size_t chunk = OS_FDS_CHUNKSIZE;
- const size_t nsize = (fdset->reserved + chunk) *
- sizeof(struct epoll_event);
- struct epoll_event *events_n = malloc(nsize);
- if (!events_n) {
- return -1;
- }
-
- /* Clear and copy old fdset data. */
- memset(events_n, 0, nsize);
- memcpy(events_n, fdset->events,
- fdset->nfds * sizeof(struct epoll_event));
- free(fdset->events);
- fdset->events = events_n;
- fdset->reserved += chunk;
+ if (mreserve((char **)&fdset->events, sizeof(struct epoll_event),
+ fdset->nfds + 1, OS_FDS_CHUNKSIZE, &fdset->reserved) < 0) {
+ return -1;
}
/* Add to epoll set. */
@@ -109,7 +93,7 @@ int fdset_epoll_add(fdset_t *fdset, int fd, int events)
int fdset_epoll_remove(fdset_t *fdset, int fd)
{
- if (!fdset || fd < 0) {
+ if (fdset == NULL || fd < 0) {
return -1;
}
@@ -123,13 +107,16 @@ int fdset_epoll_remove(fdset_t *fdset, int fd)
/* Overwrite current item. */
--fdset->nfds;
- /*! \todo Return memory if unused (issue #1582). */
+ /* Trim excessive memory if possible (retval is not interesting). */
+ mreserve((char **)&fdset->events, sizeof(struct epoll_event), fdset->nfds,
+ OS_FDS_CHUNKSIZE, &fdset->reserved);
+
return 0;
}
int fdset_epoll_wait(fdset_t *fdset, int timeout)
{
- if (!fdset || fdset->nfds < 1 || !fdset->events) {
+ if (fdset == NULL || fdset->nfds < 1 || fdset->events == NULL) {
return -1;
}
@@ -149,7 +136,7 @@ int fdset_epoll_wait(fdset_t *fdset, int timeout)
int fdset_epoll_begin(fdset_t *fdset, fdset_it_t *it)
{
- if (!fdset || !it) {
+ if (fdset == NULL || it == NULL) {
return -1;
}
@@ -160,7 +147,7 @@ int fdset_epoll_begin(fdset_t *fdset, fdset_it_t *it)
int fdset_epoll_end(fdset_t *fdset, fdset_it_t *it)
{
- if (!fdset || !it || fdset->nfds < 1) {
+ if (fdset == NULL || it == NULL || fdset->nfds < 1) {
return -1;
}
@@ -181,7 +168,7 @@ int fdset_epoll_end(fdset_t *fdset, fdset_it_t *it)
int fdset_epoll_next(fdset_t *fdset, fdset_it_t *it)
{
- if (!fdset || !it || fdset->nfds < 1) {
+ if (fdset == NULL || it == NULL || fdset->nfds < 1) {
return -1;
}
diff --git a/src/common/fdset_kqueue.c b/src/common/fdset_kqueue.c
index b9f639d..2c7dd52 100644
--- a/src/common/fdset_kqueue.c
+++ b/src/common/fdset_kqueue.c
@@ -37,32 +37,31 @@ struct fdset_t {
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) {
- return 0;
- }
-
- /* Blank memory. */
- memset(set, 0, sizeof(fdset_t));
-
- /* Create kqueue fd. */
- set->kq = kqueue();
- if (set->kq < 0) {
- free(set);
- set = 0;
+ 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) {
+ if(fdset == NULL) {
return -1;
}
@@ -76,45 +75,20 @@ int fdset_kqueue_destroy(fdset_t * fdset)
return 0;
}
-int fdset_kqueue_realloc(struct kevent **old, size_t oldsize, size_t nsize)
-{
- void *nmem = malloc(nsize);
- if (!nmem) {
- return -1;
- }
-
- /* Clear and copy old fdset data. */
- memset(nmem, 0, nsize);
- if (oldsize > 0) {
- memcpy(nmem, *old, oldsize);
- free(*old);
- }
-
- *old = nmem;
- return 0;
-}
-
int fdset_kqueue_add(fdset_t *fdset, int fd, int events)
{
- if (!fdset || fd < 0 || events <= 0) {
+ if (fdset == NULL || fd < 0 || events <= 0) {
return -1;
}
/* Realloc needed. */
- if (fdset->nfds == fdset->reserved) {
- size_t chunk = OS_FDS_CHUNKSIZE;
- size_t nsize = (fdset->reserved + chunk) *
- sizeof(struct kevent);
- size_t oldsize = fdset->nfds * sizeof(struct kevent);
-
- if (fdset_kqueue_realloc(&fdset->events, oldsize, nsize) < 0) {
- return -1;
- }
-
- if (fdset_kqueue_realloc(&fdset->revents, oldsize, nsize) < 0) {
- return -1;
- }
-
+ 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. */
@@ -128,7 +102,7 @@ int fdset_kqueue_add(fdset_t *fdset, int fd, int events)
int fdset_kqueue_remove(fdset_t *fdset, int fd)
{
- if (!fdset || fd < 0) {
+ if (fdset == NULL || fd < 0) {
return -1;
}
@@ -153,16 +127,35 @@ int fdset_kqueue_remove(fdset_t *fdset, int fd)
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;
- /*! \todo Return memory if unused (issue #1582). */
+ /* 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 || fdset->nfds < 1 || !fdset->events) {
+ if (fdset == NULL || fdset->nfds < 1 || fdset->events == NULL) {
return -1;
}
@@ -196,7 +189,7 @@ int fdset_kqueue_wait(fdset_t *fdset, int timeout)
int fdset_kqueue_begin(fdset_t *fdset, fdset_it_t *it)
{
- if (!fdset || !it) {
+ if (fdset == NULL || it == NULL) {
return -1;
}
@@ -207,7 +200,7 @@ int fdset_kqueue_begin(fdset_t *fdset, fdset_it_t *it)
int fdset_kqueue_end(fdset_t *fdset, fdset_it_t *it)
{
- if (!fdset || !it || fdset->nfds < 1) {
+ if (fdset == NULL || it == NULL || fdset->nfds < 1) {
return -1;
}
@@ -228,7 +221,7 @@ int fdset_kqueue_end(fdset_t *fdset, fdset_it_t *it)
int fdset_kqueue_next(fdset_t *fdset, fdset_it_t *it)
{
- if (!fdset || !it || fdset->nfds < 1) {
+ if (fdset == NULL || it == NULL || fdset->nfds < 1) {
return -1;
}
diff --git a/src/common/fdset_poll.c b/src/common/fdset_poll.c
index 02ed8d4..19804f5 100644
--- a/src/common/fdset_poll.c
+++ b/src/common/fdset_poll.c
@@ -26,7 +26,6 @@
#include "common/fdset_poll.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;
@@ -40,18 +39,16 @@ struct fdset_t {
fdset_t *fdset_poll_new()
{
fdset_t *set = malloc(sizeof(fdset_t));
- if (!set) {
- return 0;
+ if (set != NULL) {
+ memset(set, 0, sizeof(fdset_t));
}
- /* Blank memory. */
- memset(set, 0, sizeof(fdset_t));
return set;
}
int fdset_poll_destroy(fdset_t * fdset)
{
- if(!fdset) {
+ if(fdset == NULL) {
return -1;
}
@@ -63,29 +60,18 @@ int fdset_poll_destroy(fdset_t * fdset)
int fdset_poll_add(fdset_t *fdset, int fd, int events)
{
- if (!fdset || fd < 0 || events <= 0) {
+ if (fdset == NULL || fd < 0 || events <= 0) {
return -1;
}
/* Realloc needed. */
- if (fdset->nfds == fdset->reserved) {
- const size_t chunk = OS_FDS_CHUNKSIZE;
- const size_t nsize = sizeof(struct pollfd) * (fdset->reserved + chunk);
- struct pollfd *fds_n = malloc(nsize);
- if (!fds_n) {
- return -1;
- }
-
- /* Clear and copy old fdset data. */
- memset(fds_n, 0, nsize);
- memcpy(fds_n, fdset->fds, fdset->nfds * sizeof(struct pollfd));
- free(fdset->fds);
- fdset->fds = fds_n;
- fdset->reserved += chunk;
+ if (mreserve((char **)&fdset->fds, sizeof(struct pollfd),
+ fdset->nfds + 1, OS_FDS_CHUNKSIZE, &fdset->reserved) < 0) {
+ return -1;
}
/* Append. */
- int nid = fdset->nfds++;
+ int nid = fdset->nfds++;;
fdset->fds[nid].fd = fd;
fdset->fds[nid].events = POLLIN;
return 0;
@@ -93,7 +79,7 @@ int fdset_poll_add(fdset_t *fdset, int fd, int events)
int fdset_poll_remove(fdset_t *fdset, int fd)
{
- if (!fdset || fd < 0) {
+ if (fdset == NULL || fd < 0) {
return -1;
}
@@ -118,13 +104,16 @@ int fdset_poll_remove(fdset_t *fdset, int fd)
memmove(fdset->fds + pos, fdset->fds + (pos + 1), remaining);
--fdset->nfds;
- /*! \todo Return memory if unused (issue #1582). */
+ /* 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 || fdset->nfds < 1 || !fdset->fds) {
+ if (fdset == NULL || fdset->nfds < 1 || fdset->fds == NULL) {
return -1;
}
@@ -146,7 +135,7 @@ int fdset_poll_wait(fdset_t *fdset, int timeout)
int fdset_poll_begin(fdset_t *fdset, fdset_it_t *it)
{
- if (!fdset || !it) {
+ if (fdset == NULL || it == NULL) {
return -1;
}
@@ -157,7 +146,7 @@ int fdset_poll_begin(fdset_t *fdset, fdset_it_t *it)
int fdset_poll_end(fdset_t *fdset, fdset_it_t *it)
{
- if (!fdset || !it || fdset->nfds < 1) {
+ if (fdset == NULL || it == NULL || fdset->nfds < 1) {
return -1;
}
@@ -186,7 +175,7 @@ int fdset_poll_end(fdset_t *fdset, fdset_it_t *it)
int fdset_poll_next(fdset_t *fdset, fdset_it_t *it)
{
- if (!fdset || !it || fdset->nfds < 1) {
+ if (fdset == NULL || it == NULL || fdset->nfds < 1) {
return -1;
}
diff --git a/src/knot/other/log.c b/src/common/log.c
index 488763d..6d77ccb 100644
--- a/src/knot/other/log.c
+++ b/src/common/log.c
@@ -20,10 +20,10 @@
#include <string.h>
#include <stdlib.h>
+#include "common/log.h"
+#include "common/lists.h"
#include "knot/common.h"
#include "knot/other/error.h"
-#include "knot/other/log.h"
-#include "common/lists.h"
#include "knot/conf/conf.h"
/*! Log source table. */
@@ -208,6 +208,20 @@ static int _log_msg(logsrc_t src, int level, const char *msg)
// Convert level to mask
level = LOG_MASK(level);
+
+ /* Prefix date and time. */
+ char tstr[128] = {0};
+ int tlen = 0;
+ time_t t = time(NULL);
+ struct tm *lt = localtime(&t);
+ if (lt != NULL) {
+ tlen = strftime(tstr, sizeof(tstr) - 1,
+ "%d-%m-%Y %H:%M:%S", lt);
+ if (tlen > 0) {
+ tstr[tlen] = ' ';
+ tstr[tlen + 1] = '\0';
+ }
+ }
// Log streams
for (int i = LOGT_STDERR; i < LOGT_FILE + LOG_FDS_OPEN; ++i) {
@@ -224,7 +238,7 @@ static int _log_msg(logsrc_t src, int level, const char *msg)
}
// Print
- ret = fprintf(stream, "%s", msg);
+ ret = fprintf(stream, "%s%s", tstr, msg);
if (stream == stdout) {
fflush(stream);
}
@@ -248,15 +262,15 @@ int log_msg(logsrc_t src, int level, const char *msg, ...)
/* Prefix error level. */
const char *prefix = "";
switch (level) {
- case LOG_DEBUG: break;
- case LOG_INFO: break;
- case LOG_NOTICE: prefix = "notice: "; break;
- case LOG_WARNING: prefix = "warning: "; break;
- case LOG_ERR: prefix = "error: "; break;
- case LOG_FATAL: prefix = "fatal: "; break;
+ case LOG_DEBUG: prefix = "[debug] "; break;
+ case LOG_INFO: prefix = ""; break;
+ case LOG_NOTICE: prefix = "[notice] "; break;
+ case LOG_WARNING: prefix = "[warning] "; break;
+ case LOG_ERR: prefix = "[error] "; break;
+ case LOG_FATAL: prefix = "[fatal] "; break;
default: break;
}
-
+
/* Prepend prefix. */
int plen = strlen(prefix);
if (plen > buflen) {
diff --git a/src/knot/other/log.h b/src/common/log.h
index 305020c..305020c 100644
--- a/src/knot/other/log.h
+++ b/src/common/log.h
diff --git a/src/common/slab/malloc.c b/src/common/mempattern.c
index ec5a68d..5982e18 100644
--- a/src/common/slab/malloc.c
+++ b/src/common/mempattern.c
@@ -14,17 +14,37 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <config.h>
-/*
- * Skip unit if not debugging memory.
- */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/resource.h>
+#include <config.h>
#include "common/slab/alloc-common.h"
+
+int mreserve(char **p, size_t tlen, size_t min, size_t allow, size_t *reserved)
+{
+ /* Trim excessive memory if possible. */
+ size_t maxlen = min + allow;
+ if (maxlen < min) {
+ return -2; /* size_t overflow */
+ }
+
+ /* Meet target size but trim excessive amounts. */
+ if (*reserved < min || *reserved > maxlen) {
+ void *trimmed = realloc(*p, maxlen * tlen);
+ if (trimmed != NULL) {
+ *p = trimmed;
+ *reserved = maxlen;
+ } else {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
#ifdef MEM_DEBUG
/*
* ((destructor)) attribute executes this function after main().
diff --git a/src/common/slab/malloc.h b/src/common/mempattern.h
index 8ca9f58..ae1fa78 100644
--- a/src/common/slab/malloc.h
+++ b/src/common/mempattern.h
@@ -14,7 +14,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*!
- * \file malloc.h
+ * \file mempattern.h
*
* \author Marek Vavrusa <marek.vavrusa@nic.cz>
*
@@ -27,7 +27,32 @@
#ifndef _KNOTD_COMMON_MALLOC_H_
#define _KNOTD_COMMON_MALLOC_H_
-#include <stdlib.h>
+/*!
+ * \brief Reserve new or trim excessive memory.
+ *
+ * \param p Double-pointer to memory region.
+ * \param tlen Memory unit (f.e. sizeof(int) for int* array)
+ * \param min Minimum number of items required.
+ * \param allow Maximum extra items to keep (for trimming).
+ * \param reserved Pointer to number of already reserved items.
+ *
+ * \note Example usage:
+ * char *buf = NULL; size_t len = 0;
+ * if (mreserve(&buf, sizeof(char), 6, 0, &len) == 0) {
+ * memcpy(buf, "hello", strlen("hello");
+ * if (mreserve(&buf, sizeof(char), 20, 0, &len) == 0) {
+ * strncat(buf, "!", 1);
+ * mreserve(&buf, sizeof(char), strlen("hello!")+1, 0, &len);
+ * }
+ * }
+ * free(buf);
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ *
+ * \note Memory region will be left untouched if function fails.
+ */
+int mreserve(char **p, size_t tlen, size_t min, size_t allow, size_t *reserved);
/*! \brief Print usage statistics.
*
diff --git a/src/common/sockaddr.c b/src/common/sockaddr.c
index 48551bc..b4e75ee 100644
--- a/src/common/sockaddr.c
+++ b/src/common/sockaddr.c
@@ -49,6 +49,20 @@ int sockaddr_init(sockaddr_t *addr, int af)
return sockaddr_update(addr);
}
+int sockaddr_isvalid(sockaddr_t *addr)
+{
+ return addr && addr->family > -1;
+}
+
+int sockaddr_copy(sockaddr_t *dst, const sockaddr_t *src)
+{
+ if (memcpy(dst, src, sizeof(sockaddr_t)) != NULL) {
+ return sockaddr_update(dst);
+ }
+
+ return -1;
+}
+
int sockaddr_update(sockaddr_t *addr)
{
/* Update internal pointer. */
@@ -117,7 +131,7 @@ int sockaddr_setprefix(sockaddr_t *dst, int prefix)
return dst->prefix = prefix;
}
-int sockaddr_tostr(sockaddr_t *addr, char *dst, size_t size)
+int sockaddr_tostr(const sockaddr_t *addr, char *dst, size_t size)
{
if (!addr || !dst || size == 0) {
return -1;
@@ -159,7 +173,7 @@ int sockaddr_tostr(sockaddr_t *addr, char *dst, size_t size)
return 0;
}
-int sockaddr_portnum(sockaddr_t *addr)
+int sockaddr_portnum(const sockaddr_t *addr)
{
if (!addr) {
return -1;
diff --git a/src/common/sockaddr.h b/src/common/sockaddr.h
index b2725c0..52e621c 100644
--- a/src/common/sockaddr.h
+++ b/src/common/sockaddr.h
@@ -74,6 +74,16 @@ typedef struct sockaddr_t {
int sockaddr_init(sockaddr_t *addr, int af);
/*!
+ * \brief Return true value if sockaddr is valid.
+ *
+ * \param addr Socket address structure.
+ *
+ * \retval true on succes.
+ * \retval false otherwise.
+ */
+int sockaddr_isvalid(sockaddr_t *addr);
+
+/*!
* \brief Update internal pointers according to length.
*
* \param addr Socket address structure.
@@ -84,6 +94,17 @@ int sockaddr_init(sockaddr_t *addr, int af);
int sockaddr_update(sockaddr_t *addr);
/*!
+ * \brief Copy socket address structure.
+ *
+ * \param dst Target address structure.
+ * \param src Source address structure.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+int sockaddr_copy(sockaddr_t *dst, const sockaddr_t *src);
+
+/*!
* \brief Set address and port.
*
* \param dst Target address structure.
@@ -119,7 +140,7 @@ int sockaddr_setprefix(sockaddr_t *dst, int prefix);
* \retval 0 on success.
* \retval -1 on invalid parameters.
*/
-int sockaddr_tostr(sockaddr_t *addr, char *dst, size_t size);
+int sockaddr_tostr(const sockaddr_t *addr, char *dst, size_t size);
/*!
* \brief Return port number from address.
@@ -129,7 +150,7 @@ int sockaddr_tostr(sockaddr_t *addr, char *dst, size_t size);
* \retval Port number on success.
* \retval -1 on errors.
*/
-int sockaddr_portnum(sockaddr_t *addr);
+int sockaddr_portnum(const sockaddr_t *addr);
#endif /* _KNOTD_SOCKADDR_H_ */
diff --git a/src/config.h.in b/src/config.h.in
index dfcea86..905e327 100644
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -63,6 +63,9 @@
/* Define to 1 if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
+/* Define to 1 if you have the `madvise' function. */
+#undef HAVE_MADVISE
+
/* Define to 1 if you have the <malloc.h> header file. */
#undef HAVE_MALLOC_H
diff --git a/src/knot/common.h b/src/knot/common.h
index 027962a..c321b94 100644
--- a/src/knot/common.h
+++ b/src/knot/common.h
@@ -79,7 +79,7 @@ typedef unsigned int uint; /*!< \brief Unsigned. */
#include "common/latency.h"
#include "common/print.h"
-#include "knot/other/log.h"
+#include "common/log.h"
#include "knot/other/debug.h"
/*! \brief Eliminate compiler warning with unused parameters. */
diff --git a/src/knot/conf/cf-lex.l b/src/knot/conf/cf-lex.l
index 6683edc..dfd0ac7 100644
--- a/src/knot/conf/cf-lex.l
+++ b/src/knot/conf/cf-lex.l
@@ -15,7 +15,7 @@
#include "common/sockaddr.h"
#include "knot/conf/conf.h"
-#include "knot/other/log.h"
+#include "common/log.h"
#include "libknotd_la-cf-parse.h" /* Automake generated header. */
/* Imported symbols. */
@@ -65,7 +65,6 @@ BLANK [ \t\n]
%%
\#.*\n /* Ignore comments */;
{BLANK}+ /* Ignore whitespace */;
-: /* Optional : in assignments. */;
[\!\$\%\^\&\*\(\)\/\+\-\@\{\}\;\,] { return yytext[0]; }
system { lval.t = yytext; return SYSTEM; }
identity { lval.t = yytext; return IDENTITY; }
@@ -255,6 +254,7 @@ hmac-sha512 { lval.alg = KNOT_TSIG_ALG_HMAC_SHA512; return TSIG_ALGO_NAME; }
return TEXT /* Last resort, alphanumeric word. */;
}
+: /* Optional : in assignments. */;
<<EOF>> return END;
%%
diff --git a/src/knot/conf/cf-parse.y b/src/knot/conf/cf-parse.y
index c7efa10..4981606 100644
--- a/src/knot/conf/cf-parse.y
+++ b/src/knot/conf/cf-parse.y
@@ -52,6 +52,7 @@ static void conf_start_remote(void *scanner, char *remote)
memset(this_remote, 0, sizeof(conf_iface_t));
this_remote->name = remote;
add_tail(&new_config->remotes, &this_remote->n);
+ sockaddr_init(&this_remote->via, -1);
++new_config->remotes_count;
}
@@ -71,7 +72,7 @@ static void conf_remote_set_via(void *scanner, char *item) {
snprintf(buf, sizeof(buf), "remote '%s' is not defined", item);
cf_error(scanner, buf);
} else {
- this_remote->via = found;
+ sockaddr_set(&this_remote->via, found->family, found->address, 0);
}
}
@@ -541,13 +542,17 @@ remote:
}
free($3.t);
}
+ | remote VIA IPA ';' {
+ sockaddr_set(&this_remote->via, AF_INET, $3.t, 0);
+ free($3.t);
+ }
+ | remote VIA IPA6 ';' {
+ sockaddr_set(&this_remote->via, AF_INET6, $3.t, 0);
+ free($3.t);
+ }
| remote VIA TEXT ';' {
- if (this_remote->key != 0) {
- cf_error(scanner, "only one 'via' definition is allowed in remote section\n");
- } else {
conf_remote_set_via(scanner, $3.t);
- }
- free($3.t);
+ free($3.t);
}
;
diff --git a/src/knot/conf/conf.h b/src/knot/conf/conf.h
index 1e6644e..40cd1cc 100644
--- a/src/knot/conf/conf.h
+++ b/src/knot/conf/conf.h
@@ -37,7 +37,8 @@
#include "libknot/util/descriptor.h"
#include "libknot/tsig.h"
#include "common/lists.h"
-#include "knot/other/log.h"
+#include "common/log.h"
+#include "common/sockaddr.h"
/* Constants. */
#define CONFIG_DEFAULT_PORT 53
@@ -60,7 +61,7 @@ typedef struct conf_iface_t {
int port; /*!< Port number for this interface */
int family; /*!< Address family. */
knot_key_t *key; /*!< TSIG key (only valid for remotes). */
- struct conf_iface_t *via; /*!< Used for remotes to specify qry endpoint.*/
+ sockaddr_t via; /*!< Used for remotes to specify qry endpoint.*/
} conf_iface_t;
/*!
diff --git a/src/knot/conf/logconf.c b/src/knot/conf/logconf.c
index a57afd9..4d7334f 100644
--- a/src/knot/conf/logconf.c
+++ b/src/knot/conf/logconf.c
@@ -23,7 +23,7 @@
#include "knot/other/debug.h"
#include "knot/conf/logconf.h"
#include "knot/conf/conf.h"
-#include "knot/other/log.h"
+#include "common/log.h"
#include "knot/other/error.h"
#include "common/lists.h"
#include "knot/common.h"
diff --git a/src/knot/ctl/knotc_main.c b/src/knot/ctl/knotc_main.c
index 814fbc3..436cc5e 100644
--- a/src/knot/ctl/knotc_main.c
+++ b/src/knot/ctl/knotc_main.c
@@ -71,7 +71,8 @@ void help(int argc, char **argv)
" stop Stop %s server (no-op if not running).\n"
" restart Stops and then starts %s server.\n"
" reload Reload %s configuration and compiled zones.\n"
- " running check if server is running.\n"
+ " running Check if server is running.\n"
+ " checkconf Check server configuration.\n"
"\n"
" compile Compile zone file.\n",
PACKAGE_NAME, PACKAGE_NAME, PACKAGE_NAME, PACKAGE_NAME);
@@ -105,8 +106,7 @@ int check_zone(const char *db, const char* source)
break;
}
- fprintf(stderr, "error: ");
- fprintf(stderr, emsg, source);
+ log_zone_error(emsg, source);
return KNOTD_ENOENT;
}
@@ -161,7 +161,7 @@ pid_t start_cmd(const char *argv[], int argc)
execvp(args[0], args);
/* Execute failed. */
- fprintf(stderr, "Failed to run executable '%s'\n", args[0]);
+ log_server_error("Failed to run executable '%s'\n", args[0]);
for (int i = 0; i < argc; ++i) {
free(args[i]);
}
@@ -222,23 +222,23 @@ int zctask_wait(knotc_zctask_t *tasks, int count)
}
if (z == 0) {
- fprintf(stderr, "error: Failed to find zone for finished "
- "zone compilation process.\n");
+ log_server_error("Failed to find zone for finished "
+ "zone compilation process.\n");
return 1;
}
/* Evaluate. */
if (!WIFEXITED(rc)) {
- fprintf(stderr, "error: Compilation of '%s' "
- "failed, process was killed.\n",
- z->name);
+ log_server_error("Compilation of '%s' "
+ "failed, process was killed.\n",
+ z->name);
return 1;
} else {
if (rc < 0 || WEXITSTATUS(rc) != 0) {
- fprintf(stderr, "error: Compilation of "
- "'%s' failed, knot-zcompile "
- "return code was '%d'\n",
- z->name, WEXITSTATUS(rc));
+ log_server_error("Compilation of "
+ "'%s' failed, knot-zcompile "
+ "return code was '%d'\n",
+ z->name, WEXITSTATUS(rc));
return 1;
}
}
@@ -289,7 +289,8 @@ int execute(const char *action, char **argv, int argc, pid_t pid,
// Check pidfile for w+
FILE* chkf = fopen(pidfile, "w+");
if (chkf == NULL) {
- fprintf(stderr, "control: PID file '%s' is not writeable, refusing to start\n", pidfile);
+ log_server_error("PID file '%s' is not writeable, "
+ "refusing to start\n", pidfile);
return 1;
} else {
fclose(chkf);
@@ -305,15 +306,15 @@ int execute(const char *action, char **argv, int argc, pid_t pid,
// }
if (pid > 0 && pid_running(pid)) {
- fprintf(stderr, "control: Server PID found, "
- "already running.\n");
+ log_server_error("Server PID found, "
+ "already running.\n");
if (!has_flag(flags, F_FORCE)) {
return 1;
} else {
- fprintf(stderr, "control: forcing "
- "server start, killing old pid=%ld.\n",
- (long)pid);
+ log_server_info("Forcing server start, "
+ "killing old pid=%ld.\n",
+ (long)pid);
kill(pid, SIGKILL);
pid_remove(pidfile);
}
@@ -344,7 +345,7 @@ int execute(const char *action, char **argv, int argc, pid_t pid,
// Execute command
if (has_flag(flags, F_INTERACTIVE)) {
- printf("control: Running in interactive mode.\n");
+ log_server_info("Running in interactive mode.\n");
fflush(stderr);
fflush(stdout);
}
@@ -358,8 +359,7 @@ int execute(const char *action, char **argv, int argc, pid_t pid,
// Wait for finish
if (has_flag(flags, F_WAIT) && !has_flag(flags, F_INTERACTIVE)) {
if (has_flag(flags, F_VERBOSE)) {
- fprintf(stdout, "control: waiting for server "
- "to load.\n");
+ log_server_info("Waiting for server to load.\n");
}
/* Periodically read pidfile and wait for
* valid result. */
@@ -379,14 +379,13 @@ int execute(const char *action, char **argv, int argc, pid_t pid,
valid_cmd = 1;
rc = 0;
if (pid <= 0 || !pid_running(pid)) {
- fprintf(stderr, "Server PID not found, "
- "probably not running.\n");
+ log_server_warning("Server PID not found, "
+ "probably not running.\n");
if (!has_flag(flags, F_FORCE)) {
rc = 1;
} else {
- fprintf(stderr, "control: forcing "
- "server stop.\n");
+ log_server_info("Forcing server stop.\n");
}
}
@@ -401,8 +400,8 @@ int execute(const char *action, char **argv, int argc, pid_t pid,
// Wait for finish
if (rc == 0 && has_flag(flags, F_WAIT)) {
if (has_flag(flags, F_VERBOSE)) {
- fprintf(stdout, "control: waiting for server "
- "to stop.\n");
+ log_server_info("Waiting for server "
+ "to stop.\n");
}
/* Periodically read pidfile and wait for
* valid result. */
@@ -426,8 +425,8 @@ int execute(const char *action, char **argv, int argc, pid_t pid,
break;
}
if (i == WAITPID_TIMEOUT) {
- fprintf(stderr, "Timeout while "
- "waiting for the server to finish.\n");
+ log_server_error("Timeout while waiting for "
+ "the server to finish.\n");
//pid_remove(pidfile);
break;
} else {
@@ -436,7 +435,7 @@ int execute(const char *action, char **argv, int argc, pid_t pid,
}
}
- printf("Restarting server.\n");
+ log_server_info("Restarting server.\n");
rc = execute("start", argv, argc, -1, flags, jobs, pidfile);
}
if (strcmp(action, "reload") == 0) {
@@ -444,12 +443,11 @@ int execute(const char *action, char **argv, int argc, pid_t pid,
// Check PID
valid_cmd = 1;
if (pid <= 0 || !pid_running(pid)) {
- fprintf(stderr, "Server PID not found, "
- "probably not running.\n");
+ log_server_warning("Server PID not found, "
+ "probably not running.\n");
if (has_flag(flags, F_FORCE)) {
- fprintf(stderr, "control: forcing "
- "server stop.\n");
+ log_server_info("Forcing server stop.\n");
} else {
return 1;
}
@@ -472,29 +470,33 @@ int execute(const char *action, char **argv, int argc, pid_t pid,
// Check PID
valid_cmd = 1;
if (pid <= 0) {
- printf("Server PID not found, "
- "probably not running.\n");
+ log_server_info("Server PID not found, "
+ "probably not running.\n");
rc = 1;
} else {
if (!pid_running(pid)) {
- printf("Server PID not found, "
- "probably not running.\n");
- fprintf(stderr,
- "warning: PID file is stale.\n");
+ log_server_info("Server PID not found, "
+ "probably not running.\n");
+ log_server_warning("PID file is stale.\n");
} else {
- printf("Server running as PID %ld.\n",
- (long)pid);
+ log_server_info("Server running as PID %ld.\n",
+ (long)pid);
}
rc = 0;
}
}
+ if (strcmp(action, "checkconf") == 0) {
+ log_server_info("OK, configuration is valid.\n");
+ rc = 0;
+ valid_cmd = 1;
+ }
if (strcmp(action, "compile") == 0) {
// Print job count
if (jobs > 1) {
- printf("warning: Will attempt to compile %d zones "
- "in parallel, this increases memory consumption "
- "for large zones.\n", jobs);
+ log_server_warning("Will attempt to compile %d zones "
+ "in parallel, this increases memory "
+ "consumption for large zones.\n", jobs);
}
// Check zone
@@ -515,12 +517,12 @@ int execute(const char *action, char **argv, int argc, pid_t pid,
// Check source files and mtime
int zone_status = check_zone(zone->db, zone->file);
if (zone_status == KNOTD_EOK) {
- printf("Zone '%s' is up-to-date.\n",
- zone->name);
+ log_zone_info("Zone '%s' is up-to-date.\n",
+ zone->name);
if (has_flag(flags, F_FORCE)) {
- fprintf(stderr, "control: forcing "
- "zone recompilation.\n");
+ log_zone_info("Forcing zone "
+ "recompilation.\n");
} else {
continue;
}
@@ -533,7 +535,7 @@ int execute(const char *action, char **argv, int argc, pid_t pid,
/* Evaluate space for new task. */
if (running == jobs) {
- zctask_wait(tasks, jobs);
+ rc |= zctask_wait(tasks, jobs);
--running;
}
@@ -549,8 +551,8 @@ int execute(const char *action, char **argv, int argc, pid_t pid,
// Execute command
if (has_flag(flags, F_VERBOSE)) {
- printf("Compiling '%s' as '%s'...\n",
- zone->name, zone->db);
+ log_zone_info("Compiling '%s' as '%s'...\n",
+ zone->name, zone->db);
}
fflush(stdout);
fflush(stderr);
@@ -570,13 +572,13 @@ int execute(const char *action, char **argv, int argc, pid_t pid,
conf_read_unlock();
}
if (!valid_cmd) {
- fprintf(stderr, "Invalid command: '%s'\n", action);
+ log_server_error("Invalid command: '%s'\n", action);
return 1;
}
// Log
if (has_flag(flags, F_VERBOSE)) {
- printf("'%s' finished (return code %d)\n", action, rc);
+ log_server_info("'%s' finished (return code %d)\n", action, rc);
}
return rc;
}
@@ -640,11 +642,8 @@ int main(int argc, char **argv)
return 1;
}
- // Initialize log (no output)
+ // Initialize log
log_init();
- log_levels_set(LOGT_SYSLOG, LOG_ANY, 0);
- log_levels_set(LOGT_STDOUT, LOG_ANY, 0);
- closelog();
// Find implicit configuration file
char *default_fn = 0;
@@ -657,11 +656,11 @@ int main(int argc, char **argv)
int conf_ret = conf_open(config_fn);
if (conf_ret != KNOTD_EOK) {
if (conf_ret == KNOTD_ENOENT) {
- fprintf(stderr, "Couldn't open configuration file "
- "'%s'.\n", config_fn);
+ log_server_error("Couldn't open configuration file "
+ "'%s'.\n", config_fn);
} else {
- fprintf(stderr, "Failed to parse configuration '%s'.\n",
- config_fn);
+ log_server_error("Failed to parse configuration '%s'.\n",
+ config_fn);
}
free(default_fn);
return 1;
@@ -679,8 +678,8 @@ int main(int argc, char **argv)
// Fetch PID
char* pidfile = pid_filename();
if (!pidfile) {
- fprintf(stderr, "No configuration found, "
- "please specify with '-c' parameter.\n");
+ log_server_error("No configuration found, "
+ "please specify with '-c' parameter.\n");
log_close();
return 1;
}
diff --git a/src/knot/other/debug.h b/src/knot/other/debug.h
index 7768d22..1a8698e 100644
--- a/src/knot/other/debug.h
+++ b/src/knot/other/debug.h
@@ -47,9 +47,11 @@
#ifdef KNOT_COMPILER_DEBUG
#define KNOTD_ZDUMP_DEBUG
#define KNOTD_ZLOAD_DEBUG
+ #define KNOTD_SEMCHECK_DEBUG
+ #define KNOTD_COMPILE_DEBUG
#endif
-#include "knot/other/log.h"
+#include "common/log.h"
#include "common/print.h"
/******************************************************************************/
@@ -434,6 +436,90 @@
#define dbg_zload_exec_detail(cmds)
#endif
+#ifdef KNOTD_COMPILER_DEBUG
+
+/* Brief messages. */
+#ifdef DEBUG_ENABLE_BRIEF
+#define dbg_zp(msg...) log_msg(LOG_SERVER, LOG_DEBUG, msg)
+#define dbg_zp_hex(data, len) hex_log(LOG_SERVER, (data), (len))
+#else
+#define dbg_zp(msg...)
+#define dbg_zp_hex(data, len)
+#endif
+
+/* Verbose messages. */
+#ifdef DEBUG_ENABLE_VERBOSE
+#define dbg_zp_verb(msg...) log_msg(LOG_SERVER, LOG_DEBUG, msg)
+#define dbg_zp_hex_verb(data, len) hex_log(LOG_SERVER, (data), (len))
+#else
+#define dbg_zp_verb(msg...)
+#define dbg_zp_hex_verb(data, len)
+#endif
+
+/* Detail messages. */
+#ifdef DEBUG_ENABLE_DETAILS
+#define dbg_zp_detail(msg...) log_msg(LOG_SERVER, LOG_DEBUG, msg)
+#define dbg_zp_hex_detail(data, len) hex_log(LOG_SERVER, (data), (len))
+#define dbg_zp_exec_detail(cmds) do { cmds } while (0)
+#else
+#define dbg_zp_detail(msg...)
+#define dbg_zp_hex_detail(data, len)
+#define dbg_zp_exec_detail(cmds)
+#endif
+
+/* No messages. */
+#else
+#define dbg_zp(msg...)
+#define dbg_zp_hex(data, len)
+#define dbg_zp_verb(msg...)
+#define dbg_zp_hex_verb(data, len)
+#define dbg_zp_detail(msg...)
+#define dbg_zp_hex_detail(data, len)
+#define dbg_zp_exec_detail(cmds)
+#endif
+
+#ifdef KNOTD_SEMCHECK_DEBUG
+
+/* Brief messages. */
+#ifdef DEBUG_ENABLE_BRIEF
+#define dbg_semcheck(msg...) log_msg(LOG_SERVER, LOG_DEBUG, msg)
+#define dbg_semcheck_hex(data, len) hex_log(LOG_SERVER, (data), (len))
+#else
+#define dbg_semcheck(msg...)
+#define dbg_semcheck_hex(data, len)
+#endif
+
+/* Verbose messages. */
+#ifdef DEBUG_ENABLE_VERBOSE
+#define dbg_semcheck_verb(msg...) log_msg(LOG_SERVER, LOG_DEBUG, msg)
+#define dbg_semcheck_hex_verb(data, len) hex_log(LOG_SERVER, (data), (len))
+#else
+#define dbg_semcheck_verb(msg...)
+#define dbg_semcheck_hex_verb(data, len)
+#endif
+
+/* Detail messages. */
+#ifdef DEBUG_ENABLE_DETAILS
+#define dbg_semcheck_detail(msg...) log_msg(LOG_SERVER, LOG_DEBUG, msg)
+#define dbg_semcheck_hex_detail(data, len) hex_log(LOG_SERVER, (data), (len))
+#define dbg_semcheck_exec_detail(cmds) do { cmds } while (0)
+#else
+#define dbg_semcheck_detail(msg...)
+#define dbg_semcheck_hex_detail(data, len)
+#define dbg_semcheck_exec_detail(cmds)
+#endif
+
+/* No messages. */
+#else
+#define dbg_semcheck(msg...)
+#define dbg_semcheck_hex(data, len)
+#define dbg_semcheck_verb(msg...)
+#define dbg_semcheck_hex_verb(data, len)
+#define dbg_semcheck_detail(msg...)
+#define dbg_semcheck_hex_detail(data, len)
+#define dbg_semcheck_exec_detail(cmds)
+#endif
+
/******************************************************************************/
#endif /* _KNOTD_DEBUG_H_ */
diff --git a/src/knot/other/error.c b/src/knot/other/error.c
index 0ab7568..70c84a3 100644
--- a/src/knot/other/error.c
+++ b/src/knot/other/error.c
@@ -26,7 +26,7 @@ const error_table_t knotd_error_msgs[] = {
{KNOTD_ENOTSUP, "Parameter not supported."},
{KNOTD_EBUSY, "Requested resource is busy."},
{KNOTD_EAGAIN, "The system lacked the necessary resource, try again."},
- {KNOTD_EACCES, "Permission to perform requested operation is denied."},
+ {KNOTD_EACCES, "Operation not permitted."},
{KNOTD_ECONNREFUSED, "Connection refused."},
{KNOTD_EISCONN, "Already connected."},
{KNOTD_EADDRINUSE, "Address already in use."},
diff --git a/src/knot/server/dthreads.c b/src/knot/server/dthreads.c
index be6fc24..4e2b490 100644
--- a/src/knot/server/dthreads.c
+++ b/src/knot/server/dthreads.c
@@ -27,7 +27,7 @@
#include "knot/common.h"
#include "knot/server/dthreads.h"
-#include "knot/other/log.h"
+#include "common/log.h"
#include "knot/other/error.h"
/*! \brief Lock thread state for R/W. */
@@ -124,6 +124,7 @@ static void *thread_ep(void *data)
sigaddset(&ignset, SIGTERM);
sigaddset(&ignset, SIGHUP);
sigaddset(&ignset, SIGPIPE);
+ sigaddset(&ignset, SIGUSR1);
pthread_sigmask(SIG_BLOCK, &ignset, 0); /*! \todo Review under BSD (issue #1441). */
dbg_dt("dthreads: [%p] entered ep\n", thread);
@@ -236,8 +237,9 @@ static dthread_t *dt_create_thread(dt_unit_t *unit)
// Initialize attribute
pthread_attr_t *attr = &thread->_attr;
pthread_attr_init(attr);
- pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED);
- pthread_attr_setschedpolicy(attr, SCHED_OTHER);
+ //pthread_attr_setinheritsched(attr, PTHREAD_INHERIT_SCHED);
+ //pthread_attr_setschedpolicy(attr, SCHED_OTHER);
+ pthread_attr_setstacksize(attr, 1024*1024);
return thread;
}
@@ -814,43 +816,43 @@ int dt_stop(dt_unit_t *unit)
return KNOTD_EOK;
}
-int dt_setprio(dthread_t *thread, int prio)
-{
- // Check input
- if (thread == 0) {
- return KNOTD_EINVAL;
- }
-
- // Clamp priority
- int policy = SCHED_FIFO;
- prio = MIN(MAX(sched_get_priority_min(policy), prio),
- sched_get_priority_max(policy));
-
- // Update scheduler policy
- int ret = pthread_attr_setschedpolicy(&thread->_attr, policy);
-
- // Update priority
- if (ret == 0) {
- struct sched_param sp;
- sp.sched_priority = prio;
- ret = pthread_attr_setschedparam(&thread->_attr, &sp);
- }
-
- /* Map error codes. */
- if (ret != 0) {
- dbg_dt("dthreads: [%p] %s(%d): failed",
- thread, __func__, prio);
-
- /* Map "not supported". */
- if (errno == ENOTSUP) {
- return KNOTD_ENOTSUP;
- }
-
- return KNOTD_EINVAL;
- }
-
- return KNOTD_EOK;
-}
+//int dt_setprio(dthread_t *thread, int prio)
+//{
+// // Check input
+// if (thread == 0) {
+// return KNOTD_EINVAL;
+// }
+
+// // Clamp priority
+// int policy = SCHED_FIFO;
+// prio = MIN(MAX(sched_get_priority_min(policy), prio),
+// sched_get_priority_max(policy));
+
+// // Update scheduler policy
+// int ret = pthread_attr_setschedpolicy(&thread->_attr, policy);
+
+// // Update priority
+// if (ret == 0) {
+// struct sched_param sp;
+// sp.sched_priority = prio;
+// ret = pthread_attr_setschedparam(&thread->_attr, &sp);
+// }
+
+// /* Map error codes. */
+// if (ret != 0) {
+// dbg_dt("dthreads: [%p] %s(%d): failed",
+// thread, __func__, prio);
+
+// /* Map "not supported". */
+// if (errno == ENOTSUP) {
+// return KNOTD_ENOTSUP;
+// }
+
+// return KNOTD_EINVAL;
+// }
+
+// return KNOTD_EOK;
+//}
int dt_repurpose(dthread_t *thread, runnable_t runnable, void *data)
{
diff --git a/src/knot/server/dthreads.h b/src/knot/server/dthreads.h
index 8a5e2b4..2347e1d 100644
--- a/src/knot/server/dthreads.h
+++ b/src/knot/server/dthreads.h
@@ -45,6 +45,9 @@
struct dthread_t;
struct dt_unit_t;
+/* Constants. */
+#define DTHREADS_STACKSIZE (1024*1024) /* 1M lightweight stack size. */
+
/*!
* \brief Thread state enumeration.
*/
@@ -238,10 +241,14 @@ int dt_stop(dt_unit_t *unit);
* \param thread Target thread instance.
* \param prio Requested priority (positive integer, default is 0).
*
+ * \warning Thread priority setting is disabled as the compatible scheduler
+ * has significant performance deficiencies (SCHED_OTHER).
+ * (issue #1809)
+ *
* \retval KNOTD_EOK on success.
* \retval KNOTD_EINVAL on invalid parameters.
*/
-int dt_setprio(dthread_t *thread, int prio);
+//int dt_setprio(dthread_t *thread, int prio);
/*!
* \brief Set thread to execute another runnable.
diff --git a/src/knot/server/journal.c b/src/knot/server/journal.c
index 6b566f6..fc8ec5c 100644
--- a/src/knot/server/journal.c
+++ b/src/knot/server/journal.c
@@ -14,13 +14,16 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <config.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
-#include <sys/stat.h>
#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include "common/crc.h"
#include "knot/other/error.h"
#include "knot/other/debug.h"
#include "knot/zone/zone-dump.h"
@@ -51,15 +54,9 @@ static inline int sfwrite(const void *src, size_t len, int fd)
/*! \brief Equality compare function. */
static inline int journal_cmp_eq(uint64_t k1, uint64_t k2)
{
- if (k1 == k2) {
- return 0;
- }
-
- if (k1 < k2) {
- return -1;
- }
-
- return 1;
+ if (k1 > k2) return 1;
+ if (k1 < k2) return -1;
+ return 0;
}
/*! \brief Recover metadata from journal. */
@@ -132,6 +129,183 @@ static int journal_recover(journal_t *j)
return KNOTD_EOK;
}
+int journal_write_in(journal_t *j, journal_node_t **rn, uint64_t id, size_t len)
+{
+ const size_t node_len = sizeof(journal_node_t);
+ *rn = NULL;
+
+ /* Find next free node. */
+ uint16_t jnext = (j->qtail + 1) % j->max_nodes;
+
+ dbg_journal("journal: will write id=%llu, node=%u, size=%zu, fsize=%zu\n",
+ (unsigned long long)id, j->qtail, len, j->fsize);
+
+ /* Calculate remaining bytes to reach file size limit. */
+ size_t fs_remaining = j->fslimit - j->fsize;
+
+ /* Increase free segment if on the end of file. */
+ journal_node_t *n = j->nodes + j->qtail;
+ if (j->free.pos + j->free.len == j->fsize) {
+
+ dbg_journal_verb("journal: * is last node\n");
+
+ /* Grow journal file until the size limit. */
+ if(j->free.len < len && len <= fs_remaining) {
+ size_t diff = len - j->free.len;
+ dbg_journal("journal: * growing by +%zu, pos=%u, "
+ "new fsize=%zu\n",
+ diff, j->free.pos,
+ j->fsize + diff);
+ j->fsize += diff; /* Appending increases file size. */
+ j->free.len += diff;
+
+ }
+
+ /* Rewind if resize is needed, but the limit is reached. */
+ if(j->free.len < len && len > fs_remaining) {
+ journal_node_t *head = j->nodes + j->qhead;
+ j->fsize = j->free.pos;
+ j->free.pos = head->pos;
+ j->free.len = 0;
+ dbg_journal_verb("journal: * fslimit reached, "
+ "rewinding to %u\n",
+ head->pos);
+ dbg_journal_verb("journal: * file size trimmed to %zu\n",
+ j->fsize);
+ }
+ }
+
+ /* Evict occupied nodes if necessary. */
+ while (j->free.len < len ||
+ j->nodes[jnext].flags > JOURNAL_FREE) {
+
+ /* Evict least recent node if not empty. */
+ journal_node_t *head = j->nodes + j->qhead;
+
+ /* Check if it has been synced to disk. */
+ if (head->flags & JOURNAL_DIRTY) {
+ return KNOTD_EAGAIN;
+ }
+
+ /* Write back evicted node. */
+ head->flags = JOURNAL_FREE;
+ lseek(j->fd, JOURNAL_HSIZE + (j->qhead + 1) * node_len, SEEK_SET);
+ if (!sfwrite(head, node_len, j->fd)) {
+ return KNOTD_ERROR;
+ }
+
+ dbg_journal("journal: * evicted node=%u, growing by +%u\n",
+ j->qhead, head->len);
+
+ /* Write back query state. */
+ j->qhead = (j->qhead + 1) % j->max_nodes;
+ uint16_t qstate[2] = {j->qhead, j->qtail};
+ lseek(j->fd, JOURNAL_HSIZE - 2 * sizeof(uint16_t), SEEK_SET);
+ if (!sfwrite(qstate, 2 * sizeof(uint16_t), j->fd)) {
+ return KNOTD_ERROR;
+ }
+
+ /* Increase free segment. */
+ j->free.len += head->len;
+ }
+
+ /* Invalidate node and write back. */
+ n->id = id;
+ n->pos = j->free.pos;
+ n->len = len;
+ n->flags = JOURNAL_FREE;
+ n->next = jnext;
+ journal_update(j, n);
+ *rn = n;
+ return KNOTD_EOK;
+}
+
+int journal_write_out(journal_t *journal, journal_node_t *n)
+{
+ /* Mark node as valid and write back. */
+ uint16_t jnext = n->next;
+ size_t size = n->len;
+ const size_t node_len = sizeof(journal_node_t);
+ n->flags = JOURNAL_VALID | journal->bflags;
+ n->next = 0;
+ journal_update(journal, n);
+
+ /* Handle free segment on node rotation. */
+ if (journal->qtail > jnext && journal->fslimit == FSLIMIT_INF) {
+ /* Trim free space. */
+ journal->fsize -= journal->free.len;
+ dbg_journal_verb("journal: * trimmed filesize to %zu\n",
+ journal->fsize);
+
+ /* Rewind free segment. */
+ journal_node_t *n = journal->nodes + jnext;
+ journal->free.pos = n->pos;
+ journal->free.len = 0;
+
+ } else {
+ /* Mark used space. */
+ journal->free.pos += size;
+ journal->free.len -= size;
+ }
+
+ dbg_journal("journal: finishing node=%u id=%llu flags=0x%x, "
+ "data=<%u, %u> free=<%u, %u>\n",
+ journal->qtail, (unsigned long long)n->id,
+ n->flags, n->pos, n->pos + n->len,
+ journal->free.pos,
+ journal->free.pos + journal->free.len);
+
+ /* Write back free segment state. */
+ lseek(journal->fd, JOURNAL_HSIZE, SEEK_SET);
+ if (!sfwrite(&journal->free, node_len, journal->fd)) {
+ /* Node is marked valid and failed to shrink free space,
+ * node will be overwritten on the next write. Return error.
+ */
+ dbg_journal("journal: failed to write back "
+ "free segment descriptor\n");
+ return KNOTD_ERROR;
+ }
+
+ /* Node write successful. */
+ journal->qtail = jnext;
+
+ /* Write back queue state, not essential as it may be recovered.
+ * qhead - lowest valid node identifier (least recent)
+ * qtail - highest valid node identifier (most recently used)
+ */
+ uint16_t qstate[2] = {journal->qhead, journal->qtail};
+ lseek(journal->fd, JOURNAL_HSIZE - 2 * sizeof(uint16_t), SEEK_SET);
+ if (!sfwrite(qstate, 2 * sizeof(uint16_t), journal->fd)) {
+ dbg_journal("journal: failed to write back queue state\n");
+ return KNOTD_ERROR;
+ }
+
+ return KNOTD_EOK;
+}
+
+/* Recalculate CRC. */
+int journal_update_crc(int fd)
+{
+ if (fcntl(fd, F_GETFL) < 0) {
+ return KNOTD_EINVAL;
+ }
+
+ char buf[4096];
+ ssize_t rb = 0;
+ crc_t crc = crc_init();
+ lseek(fd, MAGIC_LENGTH + sizeof(crc_t), SEEK_SET);
+ while((rb = read(fd, buf, sizeof(buf))) > 0) {
+ crc = crc_update(crc, (const unsigned char *)buf, rb);
+ }
+ lseek(fd, MAGIC_LENGTH, SEEK_SET);
+ if (!sfwrite(&crc, sizeof(crc_t), fd)) {
+ dbg_journal("journal: couldn't write CRC to fd=%d\n", fd);
+ return KNOTD_ERROR;
+ }
+
+ return KNOTD_EOK;
+}
+
int journal_create(const char *fn, uint16_t max_nodes)
{
if (fn == NULL) {
@@ -151,7 +325,7 @@ int journal_create(const char *fn, uint16_t max_nodes)
int fd = open(fn, O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
if (fd < 0) {
dbg_journal("journal: failed to create file '%s'\n", fn);
- return KNOTD_EINVAL;
+ return knot_map_errno(errno);
}
/* Lock. */
@@ -160,13 +334,20 @@ int journal_create(const char *fn, uint16_t max_nodes)
/* Create journal header. */
dbg_journal("journal: creating header\n");
- const char magic[MAGIC_LENGTH] = MAGIC_BYTES;
+ const char magic[MAGIC_LENGTH] = JOURNAL_MAGIC;
if (!sfwrite(magic, MAGIC_LENGTH, fd)) {
fcntl(fd, F_SETLK, &fl);
close(fd);
remove(fn);
return KNOTD_ERROR;
}
+ crc_t crc = crc_init();
+ if (!sfwrite(&crc, sizeof(crc_t), fd)) {
+ fcntl(fd, F_SETLK, &fl);
+ close(fd);
+ remove(fn);
+ return KNOTD_ERROR;
+ }
if (!sfwrite(&max_nodes, sizeof(uint16_t), fd)) {
fcntl(fd, F_SETLK, &fl);
close(fd);
@@ -222,6 +403,14 @@ int journal_create(const char *fn, uint16_t max_nodes)
}
}
+ /* Recalculate CRC. */
+ if (journal_update_crc(fd) != KNOTD_EOK) {
+ fcntl(fd, F_SETLK, &fl);
+ close(fd);
+ remove(fn);
+ return KNOTD_ERROR;
+ }
+
/* Unlock and close. */
fcntl(fd, F_SETLK, &fl);
close(fd);
@@ -241,7 +430,6 @@ journal_t* journal_open(const char *fn, size_t fslimit, int mode, uint16_t bflag
/* Open journal file for r/w (returns error if not exists). */
int fd = open(fn, O_RDWR);
if (fd < 0) {
- dbg_journal("journal: failed to open file '%s'\n", fn);
return NULL;
}
@@ -274,7 +462,7 @@ journal_t* journal_open(const char *fn, size_t fslimit, int mode, uint16_t bflag
/* Read magic bytes. */
dbg_journal("journal: reading magic bytes\n");
- const char magic_req[MAGIC_LENGTH] = MAGIC_BYTES;
+ const char magic_req[MAGIC_LENGTH] = JOURNAL_MAGIC;
char magic[MAGIC_LENGTH];
if (!sfread(magic, MAGIC_LENGTH, fd)) {
dbg_journal_detail("journal: cannot read magic bytes\n");
@@ -289,6 +477,32 @@ journal_t* journal_open(const char *fn, size_t fslimit, int mode, uint16_t bflag
close(fd);
return NULL;
}
+ crc_t crc = 0;
+ if (!sfread(&crc, sizeof(crc_t), fd)) {
+ dbg_journal_detail("journal: cannot read CRC\n");
+ fcntl(fd, F_SETLK, &fl);
+ close(fd);
+ return NULL;
+ }
+
+ /* Recalculate CRC. */
+ char buf[4096];
+ ssize_t rb = 0;
+ crc_t crc_calc = crc_init();
+ while((rb = read(fd, buf, sizeof(buf))) > 0) {
+ crc_calc = crc_update(crc_calc, (const unsigned char *)buf, rb);
+ }
+
+ /* Compare */
+ if (crc == crc_calc) {
+ lseek(fd, MAGIC_LENGTH + sizeof(crc_t), SEEK_SET); /* Rewind. */
+ } else {
+ log_server_warning("Journal file '%s' CRC error, "
+ "it will be flushed.\n", fn);
+ fcntl(fd, F_SETLK, &fl);
+ close(fd);
+ return NULL;
+ }
/* Check for lazy mode. */
if (mode & JOURNAL_LAZY) {
@@ -452,7 +666,9 @@ int journal_fetch(journal_t *journal, uint64_t id,
size_t i = jnode_prev(journal, journal->qtail);
size_t endp = jnode_prev(journal, journal->qhead);
for(; i != endp; i = jnode_prev(journal, i)) {
- if (cf(journal->nodes[i].id, id) == 0) {
+ /* Ignore nodes in uncommited transaction. */
+ journal_node_t *n = journal->nodes + i;
+ if (!(n->flags & JOURNAL_TRANS) && cf(n->id, id) == 0) {
*dst = journal->nodes + i;
return KNOTD_EOK;
}
@@ -497,156 +713,111 @@ int journal_read(journal_t *journal, uint64_t id, journal_cmp_t cf, char *dst)
int journal_write(journal_t *journal, uint64_t id, const char *src, size_t size)
{
- if (journal == 0 || src == 0) {
+ if (journal == NULL || src == NULL) {
return KNOTD_EINVAL;
}
- const size_t node_len = sizeof(journal_node_t);
-
- /* Find next free node. */
- uint16_t jnext = (journal->qtail + 1) % journal->max_nodes;
-
- dbg_journal("journal: will write id=%llu, node=%u, size=%zu, fsize=%zu\n",
- (unsigned long long)id, journal->qtail, size, journal->fsize);
-
- /* Calculate remaining bytes to reach file size limit. */
- size_t fs_remaining = journal->fslimit - journal->fsize;
-
- /* Increase free segment if on the end of file. */
- journal_node_t *n = journal->nodes + journal->qtail;
- if (journal->free.pos + journal->free.len == journal->fsize) {
-
- dbg_journal_verb("journal: * is last node\n");
-
- /* Grow journal file until the size limit. */
- if(journal->free.len < size && size <= fs_remaining) {
- size_t diff = size - journal->free.len;
- dbg_journal("journal: * growing by +%zu, pos=%u, "
- "new fsize=%zu\n",
- diff, journal->free.pos,
- journal->fsize + diff);
- journal->fsize += diff; /* Appending increases file size. */
- journal->free.len += diff;
-
- }
+ /* Prepare journal write. */
+ journal_node_t *n = NULL;
+ int ret = journal_write_in(journal, &n, id, size);
+ if (ret != KNOTD_EOK) {
+ return ret;
+ }
- /* Rewind if resize is needed, but the limit is reached. */
- if(journal->free.len < size && size > fs_remaining) {
- journal_node_t *head = journal->nodes + journal->qhead;
- journal->fsize = journal->free.pos;
- journal->free.pos = head->pos;
- journal->free.len = 0;
- dbg_journal_verb("journal: * fslimit reached, "
- "rewinding to %u\n",
- head->pos);
- dbg_journal_verb("journal: * file size trimmed to %zu\n",
- journal->fsize);
- }
+ /* Write data to permanent storage. */
+ lseek(journal->fd, n->pos, SEEK_SET);
+ if (!sfwrite(src, size, journal->fd)) {
+ return KNOTD_ERROR;
}
- /* Evict occupied nodes if necessary. */
- while (journal->free.len < size ||
- journal->nodes[jnext].flags > JOURNAL_FREE) {
-
- /* Evict least recent node if not empty. */
- journal_node_t *head = journal->nodes + journal->qhead;
+ /* Finalize journal write. */
+ return journal_write_out(journal, n);
+}
- /* Check if it has been synced to disk. */
- if (head->flags & JOURNAL_DIRTY) {
- return KNOTD_EAGAIN;
- }
+int journal_map(journal_t *journal, uint64_t id, char **dst, size_t size)
+{
+ if (journal == NULL || dst == NULL) {
+ return KNOTD_EINVAL;
+ }
+
+ /* Prepare journal write. */
+ journal_node_t *n = NULL;
+ int ret = journal_write_in(journal, &n, id, size);
+ if (ret != KNOTD_EOK) {
+ return ret;
+ }
- /* Write back evicted node. */
- head->flags = JOURNAL_FREE;
- lseek(journal->fd, JOURNAL_HSIZE + (journal->qhead + 1) * node_len, SEEK_SET);
- if (!sfwrite(head, node_len, journal->fd)) {
- return KNOTD_ERROR;
+ /* Reserve data in permanent storage. */
+ /*! \todo This is only needed when inflating journal file. */
+ lseek(journal->fd, n->pos, SEEK_SET);
+ char nbuf[4096] = {0};
+ size_t wb = sizeof(nbuf);
+ while (size > 0) {
+ if (size < sizeof(nbuf)) {
+ wb = size;
}
-
- dbg_journal("journal: * evicted node=%u, growing by +%u\n",
- journal->qhead, head->len);
-
- /* Write back query state. */
- journal->qhead = (journal->qhead + 1) % journal->max_nodes;
- uint16_t qstate[2] = {journal->qhead, journal->qtail};
- lseek(journal->fd, JOURNAL_HSIZE - 2 * sizeof(uint16_t), SEEK_SET);
- if (!sfwrite(qstate, 2 * sizeof(uint16_t), journal->fd)) {
+ if (!sfwrite(nbuf, wb, journal->fd)) {
return KNOTD_ERROR;
}
-
- /* Increase free segment. */
- journal->free.len += head->len;
+ size -= wb;
}
-
- /* Invalidate node and write back. */
- n->id = id;
- n->pos = journal->free.pos;
- n->len = size;
- n->flags = JOURNAL_FREE;
- journal_update(journal, n);
-
- /* Write data to permanent storage. */
- lseek(journal->fd, n->pos, SEEK_SET);
- if (!sfwrite(src, size, journal->fd)) {
+
+ /* Align offset to page size (required). */
+ const size_t ps = sysconf(_SC_PAGESIZE);
+ off_t ps_delta = (n->pos % ps);
+ off_t off = n->pos - ps_delta;
+
+ /* Map file region. */
+ *dst = mmap(NULL, n->len + ps_delta, PROT_READ | PROT_WRITE, MAP_SHARED,
+ journal->fd, off);
+ if (*dst == ((void*)-1)) {
+ dbg_journal("journal: couldn't mmap() fd=%d <%u,%u> %d\n",
+ journal->fd, n->pos, n->pos+n->len, errno);
return KNOTD_ERROR;
}
+
+ /* Advise usage of memory. */
+#ifdef HAVE_MADVISE
+ madvise(*dst, n->len + ps_delta, MADV_SEQUENTIAL);
+#endif
+ /* Correct dst pointer to alignment. */
+ *dst += ps_delta;
+
+ return KNOTD_EOK;
+}
- /* Mark node as valid and write back. */
- n->flags = JOURNAL_VALID | journal->bflags;
- journal_update(journal, n);
-
- /* Handle free segment on node rotation. */
- if (journal->qtail > jnext && journal->fslimit == FSLIMIT_INF) {
- /* Trim free space. */
- journal->fsize -= journal->free.len;
- dbg_journal_verb("journal: * trimmed filesize to %zu\n",
- journal->fsize);
-
- /* Rewind free segment. */
- journal_node_t *n = journal->nodes + jnext;
- journal->free.pos = n->pos;
- journal->free.len = 0;
-
- } else {
- /* Mark used space. */
- journal->free.pos += size;
- journal->free.len -= size;
+int journal_unmap(journal_t *journal, uint64_t id, void *ptr, int finalize)
+{
+ if (journal == NULL || ptr == NULL) {
+ return KNOTD_EINVAL;
}
- dbg_journal("journal: finished node=%u, data=<%u, %u> free=<%u, %u>\n",
- journal->qtail, n->pos, n->pos + n->len,
- journal->free.pos,
- journal->free.pos + journal->free.len);
-
- /* Write back free segment state. */
- lseek(journal->fd, JOURNAL_HSIZE, SEEK_SET);
- if (!sfwrite(&journal->free, node_len, journal->fd)) {
- /* Node is marked valid and failed to shrink free space,
- * node will be overwritten on the next write. Return error.
- */
- dbg_journal("journal: failed to write back "
- "free segment descriptor\n");
- return KNOTD_ERROR;
+
+ /* Mapped node is on tail. */
+ journal_node_t *n = journal->nodes + journal->qtail;
+ if(n->id != id) {
+ dbg_journal("journal: failed to find mmap node with id=%llu\n",
+ (unsigned long long)id);
+ return KNOTD_ENOENT;
}
- /* Node write successful. */
- journal->qtail = jnext;
-
- /* Write back queue state, not essential as it may be recovered.
- * qhead - lowest valid node identifier (least recent)
- * qtail - highest valid node identifier (most recently used)
- */
- uint16_t qstate[2] = {journal->qhead, journal->qtail};
- lseek(journal->fd, JOURNAL_HSIZE - 2 * sizeof(uint16_t), SEEK_SET);
- if (!sfwrite(qstate, 2 * sizeof(uint16_t), journal->fd)) {
- dbg_journal("journal: failed to write back queue state\n");
+ /* Realign memory. */
+ const size_t ps = sysconf(_SC_PAGESIZE);
+ off_t ps_delta = (n->pos % ps);
+ ptr = ((char*)ptr - ps_delta);
+
+ /* Unmap memory. */
+ if (munmap(ptr, n->len + ps_delta) != 0) {
+ dbg_journal("journal: couldn't munmap() fd=%d <%u,%u> %d\n",
+ journal->fd, n->pos, n->pos+n->len, errno);
return KNOTD_ERROR;
}
-
- /*! \todo Delayed write-back? (issue #964) */
- dbg_journal_verb("journal: write of finished, nqueue=<%u, %u>\n",
- journal->qhead, journal->qtail);
-
- return KNOTD_EOK;
+
+ /* Finalize. */
+ int ret = KNOTD_EOK;
+ if (finalize) {
+ ret = journal_write_out(journal, n);
+ }
+ return ret;
}
int journal_walk(journal_t *journal, journal_apply_t apply)
@@ -677,8 +848,8 @@ int journal_update(journal_t *journal, journal_node_t *n)
/* Calculate node position in permanent storage. */
long jn_fpos = JOURNAL_HSIZE + (i + 1) * node_len;
- dbg_journal("journal: syncing journal node=%zu at %ld\n",
- i, jn_fpos);
+ dbg_journal("journal: syncing journal node=%zu id=%llu flags=0x%x\n",
+ i, (unsigned long long)n->id, n->flags);
/* Write back. */
lseek(journal->fd, jn_fpos, SEEK_SET);
@@ -691,6 +862,82 @@ int journal_update(journal_t *journal, journal_node_t *n)
return KNOTD_EOK;
}
+int journal_trans_begin(journal_t *journal)
+{
+ if (journal == NULL) {
+ return KNOTD_EINVAL;
+ }
+
+ /* Already pending transactions. */
+ if (journal->bflags & JOURNAL_TRANS) {
+ return KNOTD_EBUSY;
+ }
+
+ journal->bflags |= JOURNAL_TRANS;
+ journal->tmark = journal->qtail;
+ dbg_journal("journal: starting transaction at qtail=%hu\n",
+ journal->tmark);
+
+ return KNOTD_EOK;
+}
+
+int journal_trans_commit(journal_t *journal)
+{
+ if (journal == NULL) {
+ return KNOTD_EINVAL;
+ }
+ if ((journal->bflags & JOURNAL_TRANS) == 0) {
+ return KNOTD_ENOENT;
+ }
+
+ /* Mark affected nodes as commited. */
+ int ret = KNOTD_EOK;
+ size_t i = journal->tmark;
+ for(; i != journal->qtail; i = (i + 1) % journal->max_nodes) {
+ journal->nodes[i].flags &= (~JOURNAL_TRANS);
+ ret = journal_update(journal, journal->nodes + i);
+ if (ret != KNOTD_EOK) {
+ dbg_journal("journal: failed to clear TRANS flag from "
+ "node %zu\n", i);
+ return ret;
+ }
+ }
+
+ /* Clear in-transaction flags. */
+ journal->tmark = 0;
+ journal->bflags &= (~JOURNAL_TRANS);
+ return KNOTD_EOK;
+}
+
+int journal_trans_rollback(journal_t *journal)
+{
+ if (journal == NULL) {
+ return KNOTD_EINVAL;
+ }
+ if ((journal->bflags & JOURNAL_TRANS) == 0) {
+ return KNOTD_ENOENT;
+ }
+
+ /* Expand free space and rewind node queue tail. */
+ /*! \note This shouldn't be relied upon and probably shouldn't
+ * be written back to file, as crashing anywhere between
+ * transaction begin and rollback would result in corrupted
+ * journal. Also write function should recognize TRANS nodes.
+ */
+ //journal->free.pos = journal->nodes[journal->tmark].pos;
+ //journal->free.len = 0;
+
+ dbg_journal("journal: rollback transaction id=<%hu,%hu>\n",
+ journal->tmark, journal->qtail);
+ //journal->qtail = journal->tmark;
+
+ /* Clear in-transaction flags. */
+ journal->tmark = 0;
+ journal->bflags &= (~JOURNAL_TRANS);
+
+ return KNOTD_EOK;
+}
+
int journal_close(journal_t *journal)
{
/* Check journal. */
@@ -699,9 +946,13 @@ int journal_close(journal_t *journal)
}
/* Check if lazy. */
+ int ret = KNOTD_EOK;
if (journal->fd < 0) {
free(journal->path);
} else {
+ /* Recalculate CRC. */
+ ret = journal_update_crc(journal->fd);
+
/* Unlock journal file. */
journal->fl.l_type = F_UNLCK;
fcntl(journal->fd, F_SETLK, &journal->fl);
@@ -714,10 +965,9 @@ int journal_close(journal_t *journal)
dbg_journal("journal: closed journal %p\n", journal);
/* Free allocated resources. */
-
free(journal);
- return KNOTD_EOK;
+ return ret;
}
journal_t *journal_retain(journal_t *journal)
diff --git a/src/knot/server/journal.h b/src/knot/server/journal.h
index b12bfc9..d874996 100644
--- a/src/knot/server/journal.h
+++ b/src/knot/server/journal.h
@@ -43,7 +43,6 @@
#include <stdint.h>
#include <fcntl.h>
-#include "knot/zone/zone-dump.h"
/*!
* \brief Journal entry flags.
@@ -52,7 +51,8 @@ typedef enum journal_flag_t {
JOURNAL_NULL = 0 << 0, /*!< Invalid journal entry. */
JOURNAL_FREE = 1 << 0, /*!< Free journal entry. */
JOURNAL_VALID = 1 << 1, /*!< Valid journal entry. */
- JOURNAL_DIRTY = 1 << 2 /*!< Journal entry cannot be evicted. */
+ JOURNAL_DIRTY = 1 << 2, /*!< Journal entry cannot be evicted. */
+ JOURNAL_TRANS = 1 << 3 /*!< Entry is in transaction (uncommited). */
} journal_flag_t;
/*!
@@ -73,6 +73,7 @@ typedef struct journal_node_t
{
uint64_t id; /*!< Node ID. */
uint16_t flags; /*!< Node flags. */
+ uint16_t next; /*!< Next node ptr. */
uint32_t pos; /*!< Position in journal file. */
uint32_t len; /*!< Entry data length. */
} journal_node_t;
@@ -94,6 +95,7 @@ typedef struct journal_t
struct flock fl; /*!< File lock. */
char *path; /*!< Path to journal file. */
int refs; /*!< Number of references. */
+ uint16_t tmark; /*!< Transaction start mark. */
uint16_t max_nodes; /*!< Number of nodes. */
uint16_t qhead; /*!< Node queue head. */
uint16_t qtail; /*!< Node queue tail. */
@@ -125,7 +127,9 @@ typedef int (*journal_apply_t)(journal_t *j, journal_node_t *n);
* Journal defaults and constants.
*/
#define JOURNAL_NCOUNT 1024 /*!< Default node count. */
-#define JOURNAL_HSIZE (MAGIC_LENGTH + sizeof(uint16_t) * 3) /*!< magic, max_entries, qhead, qtail */
+/* HEADER = magic, crc, max_entries, qhead, qtail */
+#define JOURNAL_HSIZE (MAGIC_LENGTH + sizeof(crc_t) + sizeof(uint16_t) * 3)
+#define JOURNAL_MAGIC {'k', 'n', 'o', 't', '1', '0', '2'}
/*!
* \brief Create new journal.
@@ -195,6 +199,36 @@ int journal_read(journal_t *journal, uint64_t id, journal_cmp_t cf, char *dst);
int journal_write(journal_t *journal, uint64_t id, const char *src, size_t size);
/*!
+ * \brief Map journal entry for read/write.
+ *
+ * \warning New nodes shouldn't be created until the entry is unmapped.
+ *
+ * \param journal Associated journal.
+ * \param id Entry identifier.
+ * \param dst Will contain mapped memory.
+ *
+ * \retval KNOTD_EOK if successful.
+ * \retval KNOTD_EAGAIN if no free node is available, need to remove dirty nodes.
+ * \retval KNOTD_ERROR on I/O error.
+ */
+int journal_map(journal_t *journal, uint64_t id, char **dst, size_t size);
+
+/*!
+ * \brief Finalize mapped journal entry.
+ *
+ * \param journal Associated journal.
+ * \param id Entry identifier.
+ * \param ptr Mapped memory.
+ * \param finalize Set to true to finalize node or False to discard it.
+ *
+ * \retval KNOTD_EOK if successful.
+ * \retval KNOTD_ENOENT if the entry cannot be found.
+ * \retval KNOTD_EAGAIN if no free node is available, need to remove dirty nodes.
+ * \retval KNOTD_ERROR on I/O error.
+ */
+int journal_unmap(journal_t *journal, uint64_t id, void *ptr, int finalize);
+
+/*!
* \brief Return least recent node (journal head).
*
* \param journal Associated journal.
@@ -243,6 +277,45 @@ int journal_walk(journal_t *journal, journal_apply_t apply);
int journal_update(journal_t *journal, journal_node_t *n);
/*!
+ * \brief Begin transaction of multiple entries.
+ *
+ * \note Only one transaction at a time is supported.
+ *
+ * \param journal Associated journal.
+ *
+ * \retval KNOTD_EOK on success.
+ * \retval KNOTD_EINVAL on invalid parameters.
+ * \retval KNOTD_EBUSY if transaction is already pending.
+ */
+int journal_trans_begin(journal_t *journal);
+
+/*!
+ * \brief Commit pending transaction.
+ *
+ * \note Only one transaction at a time is supported.
+ *
+ * \param journal Associated journal.
+ *
+ * \retval KNOTD_EOK on success.
+ * \retval KNOTD_EINVAL on invalid parameters.
+ * \retval KNOTD_ENOENT if no transaction is pending.
+ */
+int journal_trans_commit(journal_t *journal);
+
+/*!
+ * \brief Rollback pending transaction.
+ *
+ * \note Only one transaction at a time is supported.
+ *
+ * \param journal Associated journal.
+ *
+ * \retval KNOTD_EOK on success.
+ * \retval KNOTD_EINVAL on invalid parameters.
+ * \retval KNOTD_ENOENT if no transaction is pending.
+ */
+int journal_trans_rollback(journal_t *journal);
+
+/*!
* \brief Close journal file.
*
* \param journal Associated journal.
@@ -270,4 +343,19 @@ journal_t *journal_retain(journal_t *journal);
*/
void journal_release(journal_t *journal);
+/*!
+ * \brief Recompute journal CRC.
+ *
+ * \warning Use only if you altered the journal file somehow
+ * and need it to pass CRC checks. CRC check normally
+ * checks file integrity, so you should not touch it unless
+ * you know what you're doing.
+ *
+ * \param fd Open journal file.
+ *
+ * \retval KNOTD_EOK on success.
+ * \retval KNOTD_EINVAL if not valid fd.
+ */
+int journal_update_crc(int fd);
+
#endif /* _KNOTD_JOURNAL_H_ */
diff --git a/src/knot/server/notify.c b/src/knot/server/notify.c
index 566d66f..d12247b 100644
--- a/src/knot/server/notify.c
+++ b/src/knot/server/notify.c
@@ -193,7 +193,7 @@ static int notify_check_and_schedule(knot_nameserver_t *nameserver,
char straddr[SOCKADDR_STRLEN];
sockaddr_tostr(from, straddr, sizeof(straddr));
log_zone_notice("Unauthorized NOTIFY query "
- "from %s:%d to zone '%s'.\n",
+ "from '%s@%d' to zone '%s'.\n",
straddr, sockaddr_portnum(from),
zd->conf->name);
return KNOT_ERROR;
diff --git a/src/knot/server/server.c b/src/knot/server/server.c
index ceab716..ba7ccd7 100644
--- a/src/knot/server/server.c
+++ b/src/knot/server/server.c
@@ -759,7 +759,7 @@ int server_conf_hook(const struct conf_t *conf, void *data)
h->state = ServerRunning;
ret = dt_start(h->unit);
if (ret < 0) {
- log_server_error("Handler for %s:%d "
+ log_server_error("Handler for '%s@%d' "
"has failed to start.\n",
h->iface->addr,
h->iface->port);
diff --git a/src/knot/server/tcp-handler.c b/src/knot/server/tcp-handler.c
index a59ba7c..e53e286 100644
--- a/src/knot/server/tcp-handler.c
+++ b/src/knot/server/tcp-handler.c
@@ -53,7 +53,7 @@ typedef struct tcp_worker_t {
/*
* Forward decls.
*/
-#define TCP_THROTTLE_LO 10 /*!< Minimum recovery time on errors. */
+#define TCP_THROTTLE_LO 5 /*!< Minimum recovery time on errors. */
#define TCP_THROTTLE_HI 50 /*!< Maximum recovery time on errors. */
/*! \brief Calculate TCP throttle time (random). */
@@ -119,7 +119,7 @@ static void tcp_sweep(fdset_t *set, int fd, void* data)
#endif
}
- log_server_notice("Connection with %s:%d was terminated due to "
+ log_server_notice("Connection with '%s@%d' was terminated due to "
"inactivity.\n", r_addr, r_port);
fdset_remove(set, fd);
close(fd);
@@ -164,9 +164,9 @@ static int tcp_handle(tcp_worker_t *w, int fd, uint8_t *qbuf, size_t qbuf_maxlen
char r_addr[SOCKADDR_STRLEN];
sockaddr_tostr(&addr, r_addr, sizeof(r_addr));
int r_port = sockaddr_portnum(&addr);
- log_server_warning("Couldn't receive query from %s:%d "
- "within the time limit %ds.\n",
- r_addr, r_port, TCP_ACTIVITY_WD);
+ log_server_warning("Couldn't receive query from '%s@%d'"
+ " within the time limit of %ds.\n",
+ r_addr, r_port, TCP_ACTIVITY_WD);
}
return KNOTD_ECONNREFUSED;
}
@@ -290,7 +290,6 @@ static int tcp_accept(int fd)
/* Evaluate connection. */
if (incoming < 0) {
int en = errno;
- /*! \todo Better solution so it doesn't block current connections (issue #1542). */
if (en != EINTR) {
log_server_error("Cannot accept connection "
"(%d).\n", errno);
diff --git a/src/knot/server/udp-handler.c b/src/knot/server/udp-handler.c
index 6e50926..73c557d 100644
--- a/src/knot/server/udp-handler.c
+++ b/src/knot/server/udp-handler.c
@@ -72,7 +72,7 @@ int udp_handle(int fd, uint8_t *qbuf, size_t qbuflen, size_t *resp_len,
#ifdef DEBUG_ENABLE_BRIEF
char strfrom[SOCKADDR_STRLEN];
sockaddr_tostr(addr, strfrom, sizeof(strfrom));
- dbg_net("udp: fd=%d received %zd bytes from %s:%d.\n", fd, qbuflen,
+ dbg_net("udp: fd=%d received %zd bytes from '%s@%d'.\n", fd, qbuflen,
strfrom, sockaddr_portnum(addr));
#endif
@@ -458,8 +458,8 @@ void __attribute__ ((constructor)) udp_master_init()
}
/* Check for sendmmsg() support. */
-#ifdef ENABLE_SENDMMSG
_send_mmsg = udp_sendto;
+#ifdef ENABLE_SENDMMSG
sendmmsg(0, 0, 0, 0); /* Just check if syscall exists */
if (errno != ENOSYS) {
_send_mmsg = udp_sendmmsg;
diff --git a/src/knot/server/xfr-handler.c b/src/knot/server/xfr-handler.c
index 3a1b7da..8e6d6ca 100644
--- a/src/knot/server/xfr-handler.c
+++ b/src/knot/server/xfr-handler.c
@@ -46,6 +46,7 @@
#define XFR_SWEEP_INTERVAL 2 /*! [seconds] between sweeps. */
#define XFR_BUFFER_SIZE 65535 /*! Do not change this - maximum value for UDP packet length. */
+/*! \brief Send interrupt to all workers. */
void xfr_interrupt(xfrhandler_t *h)
{
for(unsigned i = 0; i < h->unit->size; ++i) {
@@ -53,6 +54,7 @@ void xfr_interrupt(xfrhandler_t *h)
}
}
+/*! \brief Deinitialize allocated values from xfer descriptor. */
static void xfr_request_deinit(knot_ns_xfr_t *r)
{
if (r) {
@@ -61,7 +63,7 @@ static void xfr_request_deinit(knot_ns_xfr_t *r)
}
}
-/*! \todo Document me (issue #1586) */
+/*! \brief Free allocated xfer descriptor (also deinitializes). */
static void xfr_free_task(knot_ns_xfr_t *task)
{
if (!task) {
@@ -89,20 +91,29 @@ static void xfr_free_task(knot_ns_xfr_t *task)
pthread_mutex_unlock(&zd->xfr_in.lock);
}
}
-
- /* Remove fd-related data. */
- xfrhandler_t *h = w->master;
- pthread_mutex_lock(&h->tasks_mx);
- skip_remove(h->tasks, (void*)((size_t)task->session), 0, 0);
- pthread_mutex_unlock(&h->tasks_mx);
/* Deinitialize */
xfr_request_deinit(task);
-
- close(task->session);
+ if (!task->session_closed) {
+ /* Remove fd-related data. */
+ xfrhandler_t *h = w->master;
+ pthread_mutex_lock(&h->tasks_mx);
+ skip_remove(h->tasks, (void*)((size_t)task->session), 0, 0);
+ pthread_mutex_unlock(&h->tasks_mx);
+ close(task->session);
+ }
free(task);
}
+/*!
+ * \brief Return xfer descriptor associated with given fd.
+ *
+ * \param w Current worker.
+ * \param fd Requested descriptor.
+ *
+ * \retval xfer descriptor if found.
+ * \retval NULL if no descriptor found.
+ */
static knot_ns_xfr_t *xfr_handler_task(xfrworker_t *w, int fd)
{
xfrhandler_t *h = w->master;
@@ -157,8 +168,8 @@ static int xfr_process_udp_resp(xfrworker_t *w, int fd, knot_ns_xfr_t *data)
udp_handle(fd, data->wire, n, &resp_len, &data->addr, w->ns);
}
- xfr_free_task(data);
- return KNOTD_EOK;
+ /* Invalidate pending query. */
+ return KNOTD_ECONNREFUSED;
}
/*! \brief Sweep non-replied connection. */
@@ -188,8 +199,18 @@ static void xfr_sweep(fdset_t *set, int fd, void *data)
}
}
-/*! \todo Document me (issue #1586) */
-static knot_ns_xfr_t *xfr_register_task(xfrworker_t *w, knot_ns_xfr_t *req)
+/*!
+ * \brief Register task in given worker.
+ *
+ * \warning Must be freed with xfr_free_task() when finished.
+ *
+ * \param w Given worker.
+ * \param req Pointer to template xfer descriptor.
+ *
+ * \retval Newly allocated xfer descriptor if success.
+ * \retval NULL on error.
+ */
+static knot_ns_xfr_t *xfr_register_task(xfrworker_t *w, const knot_ns_xfr_t *req)
{
knot_ns_xfr_t *t = malloc(sizeof(knot_ns_xfr_t));
if (!t) {
@@ -279,19 +300,12 @@ static int xfr_xfrin_cleanup(xfrworker_t *w, knot_ns_xfr_t *data)
*/
static int xfr_xfrin_finalize(xfrworker_t *w, knot_ns_xfr_t *data)
{
- /* CLEANUP */
-// // get the zone name from Question
-// dbg_xfr_verb("Query: %p, response: %p\n", data->query, data->response);
-// const knot_dname_t *qname = knot_packet_qname(data->query);
-// char *zorigin = "(unknown)";
-// if (qname != NULL) {
-// zorigin = knot_dname_to_str(qname);
-// }
-
+
int ret = KNOTD_EOK;
int apply_ret = KNOT_EOK;
int switch_ret = KNOT_EOK;
knot_changesets_t *chs = NULL;
+ journal_t *transaction = NULL;
switch(data->type) {
case XFR_TYPE_AIN:
@@ -319,15 +333,21 @@ static int xfr_xfrin_finalize(xfrworker_t *w, knot_ns_xfr_t *data)
case XFR_TYPE_IIN:
chs = (knot_changesets_t *)data->data;
- /* First, serialize changesets. */
- ret = zones_changesets_to_binary(chs);
+ /* Serialize and store changesets. */
+ dbg_xfr("xfr: IXFR/IN serializing and saving changesets\n");
+ transaction = zones_store_changesets_begin(data);
+ if (transaction != NULL) {
+ ret = zones_store_changesets(data);
+ } else {
+ ret = KNOTD_ERROR;
+ }
if (ret != KNOTD_EOK) {
- log_zone_error("%s Failed to serialize changesets - %s"
- "\n", data->msgpref,
+ log_zone_error("%s Failed to serialize and store "
+ "changesets - %s\n", data->msgpref,
knotd_strerror(ret));
/* Free changesets, but not the data. */
knot_free_changesets(&chs);
- data->data = 0;
+ data->data = NULL;
break;
}
@@ -336,40 +356,30 @@ static int xfr_xfrin_finalize(xfrworker_t *w, knot_ns_xfr_t *data)
&data->new_contents);
if (apply_ret != KNOT_EOK) {
+ zones_store_changesets_rollback(transaction);
log_zone_error("%s Failed to apply changesets - %s\n",
data->msgpref,
knot_strerror(apply_ret));
/* Free changesets, but not the data. */
knot_free_changesets(&chs);
- data->data = 0;
+ data->data = NULL;
ret = KNOTD_ERROR;
break;
}
- /* Save changesets. */
- dbg_xfr("xfr: IXFR/IN saving changesets\n");
-
- /*! \note Here, the changesets may already be modified.
- * Only the 'data' field of each changeset contains the
- * proper serialized changesets. Serials should be
- * OK too.
- */
- ret = zones_store_changesets(data);
+ /* Commit transaction. */
+ ret = zones_store_changesets_commit(transaction);
if (ret != KNOTD_EOK) {
- log_zone_error("%s Failed to save "
- "transferred changesets - %s\n",
- data->msgpref, knotd_strerror(ret));
-
- // Cleanup old and new contents
- xfrin_rollback_update(data->zone->contents,
- &data->new_contents,
- &chs->changes);
- /* Free changesets, but not the data. */
+ log_zone_error("%s Failed to commit stored changesets "
+ "- %s\n",
+ data->msgpref,
+ knot_strerror(apply_ret));
knot_free_changesets(&chs);
- data->data = 0;
+ data->data = NULL;
break;
}
+
/* Switch zone contents. */
switch_ret = xfrin_switch_zone(data->zone, data->new_contents,
data->type);
@@ -386,7 +396,7 @@ static int xfr_xfrin_finalize(xfrworker_t *w, knot_ns_xfr_t *data)
/* Free changesets, but not the data. */
knot_free_changesets(&chs);
- data->data = 0;
+ data->data = NULL;
ret = KNOTD_ERROR;
break;
}
@@ -395,7 +405,7 @@ static int xfr_xfrin_finalize(xfrworker_t *w, knot_ns_xfr_t *data)
/* Free changesets, but not the data. */
knot_free_changesets(&chs);
- data->data = 0;
+ data->data = NULL;
assert(ret == KNOTD_EOK);
log_zone_info("%s Finished.\n", data->msgpref);
break;
@@ -404,11 +414,6 @@ static int xfr_xfrin_finalize(xfrworker_t *w, knot_ns_xfr_t *data)
break;
}
- /* CLEANUP */
-// if (qname != NULL) {
-// free(zorigin);
-// }
-
return ret;
}
@@ -661,11 +666,20 @@ int xfr_process_event(xfrworker_t *w, int fd, knot_ns_xfr_t *data, uint8_t *buf,
data->msgpref, knot_strerror(ret));
}
-
/* Check finished zone. */
int result = KNOTD_EOK;
if (xfer_finished) {
+ /* Close early to free up fd for storing zone. */
+ data->session_closed = 1;
+ close(data->session);
+
+ /* Remove fd-related data. */
+ xfrhandler_t *h = w->master;
+ pthread_mutex_lock(&h->tasks_mx);
+ skip_remove(h->tasks, (void*)((size_t)data->session), 0, 0);
+ pthread_mutex_unlock(&h->tasks_mx);
+
knot_zone_t *zone = (knot_zone_t *)data->zone;
zonedata_t *zd = (zonedata_t *)knot_zone_data(zone);
@@ -714,7 +728,14 @@ int xfr_process_event(xfrworker_t *w, int fd, knot_ns_xfr_t *data, uint8_t *buf,
return result;
}
-/*! \todo Document me (issue #1586)
+/*!
+ * \brief Start incoming transfer (applicable to AXFR/IN or IXFR/IN).
+ *
+ * \warning xfer descriptor will be registered if successful.
+ * \warning data->fd will be duplicated if successful.
+ *
+ * \param w Given worker.
+ * \param data xfer descriptor.
*/
static int xfr_client_start(xfrworker_t *w, knot_ns_xfr_t *data)
{
@@ -759,32 +780,20 @@ static int xfr_client_start(xfrworker_t *w, knot_ns_xfr_t *data)
/* Presume port is already preset. */
ret = bind(fd, data->saddr.ptr, data->saddr.len);
}
+ if (ret < 0) {
+ log_server_warning("%s Failed to create socket.\n",
+ data->msgpref);
+ } else {
+ ret = connect(fd, data->addr.ptr, data->addr.len);
+ }
} else {
- pthread_mutex_unlock(&zd->xfr_in.lock);
- log_server_warning("%s Failed to create socket "
- "(type=%s, family=%s).\n",
- "SOCK_STREAM",
- data->msgpref,
- data->addr.family == AF_INET ?
- "AF_INET" : "AF_INET6");
- return KNOTD_ERROR;
+ ret = -1;
}
- ret = connect(fd, data->addr.ptr, data->addr.len);
if (ret < 0) {
pthread_mutex_unlock(&zd->xfr_in.lock);
- if (!knot_zone_contents(zone)) {
- /* Reschedule request (120 - 240s random delay). */
- int tmr_s = AXFR_BOOTSTRAP_RETRY * 2; /* Malus x2 */
- tmr_s += (int)((120.0 * 1000) * 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",
- data->msgpref, tmr_s / 1000);
+ if (fd >= 0) {
+ close(fd);
}
return KNOTD_ECONNREFUSED;
}
@@ -794,6 +803,12 @@ static int xfr_client_start(xfrworker_t *w, knot_ns_xfr_t *data)
} else {
/* Duplicate existing socket descriptor. */
data->session = dup(data->session);
+ if (data->session < 0) {
+ pthread_mutex_unlock(&zd->xfr_in.lock);
+ log_server_warning("Not enough memory to duplicate \n"
+ "sockets.\n");
+ return KNOTD_ENOMEM;
+ }
}
/* Fetch zone contents. */
@@ -804,6 +819,8 @@ static int xfr_client_start(xfrworker_t *w, knot_ns_xfr_t *data)
rcu_read_unlock();
log_server_warning("%s Refusing to start IXFR/IN on zone with no "
"contents.\n", data->msgpref);
+ close(data->session);
+ data->session = -1;
return KNOTD_EINVAL;
}
@@ -842,8 +859,10 @@ static int xfr_client_start(xfrworker_t *w, knot_ns_xfr_t *data)
/* Handle errors. */
if (ret != KNOT_EOK) {
pthread_mutex_unlock(&zd->xfr_in.lock);
- fprintf(stderr, "xfr: failed to create XFR query type %d: %s\n",
+ dbg_xfr("xfr: failed to create XFR query type %d: %s\n",
data->type, knot_strerror(ret));
+ close(data->session);
+ data->session = -1;
return KNOTD_ERROR;
}
@@ -858,30 +877,39 @@ static int xfr_client_start(xfrworker_t *w, knot_ns_xfr_t *data)
log_server_info("%s Failed to send query (%s).\n",
data->msgpref, buf);
pthread_mutex_unlock(&zd->xfr_in.lock);
+ close(data->session);
+ data->session = -1;
return KNOTD_ECONNREFUSED;
}
/* Add to pending transfers. */
- knot_ns_xfr_t *task = xfr_register_task(w, data);
+ knot_ns_xfr_t *task = xfr_register_task(w, data);
+ if (task == NULL) {
+ log_server_warning("%s Couldn't start connection.\n",
+ data->msgpref);
+ close(data->session);
+ data->session = -1;
+ return KNOTD_ERROR;
+ }
/* Send XFR query. */
- log_server_info("%s Started.\n", task->msgpref);
+ log_server_info("%s Started.\n", data->msgpref);
return KNOTD_EOK;
}
+/*!
+ * \brief Compare file descriptors.
+ *
+ * \note Return values of {-1,0,1} are required by skip-list structure.
+ */
static int xfr_fd_compare(void *k1, void *k2)
{
- if (k1 < k2) {
- return -1;
- }
-
- if (k1 > k2) {
- return 1;
- }
-
+ if (k1 > k2) return 1;
+ if (k1 < k2) return -1;
return 0;
}
+/*! \brief Return I/A character depending on xfer type. */
static inline char xfr_strtype(knot_ns_xfr_t *xfr) {
if (xfr->type == XFR_TYPE_IOUT) {
return 'I';
@@ -890,6 +918,7 @@ static inline char xfr_strtype(knot_ns_xfr_t *xfr) {
}
}
+/*! \brief Wrapper function for answering AXFR/OUT. */
static int xfr_answer_axfr(knot_nameserver_t *ns, knot_ns_xfr_t *xfr)
{
int ret = knot_ns_answer_axfr(ns, xfr);
@@ -897,22 +926,21 @@ static int xfr_answer_axfr(knot_nameserver_t *ns, knot_ns_xfr_t *xfr)
return ret;
}
+/*! \brief Wrapper function for answering IXFR/OUT. */
static int xfr_answer_ixfr(knot_nameserver_t *ns, knot_ns_xfr_t *xfr)
{
/* Check serial differeces. */
int ret = KNOT_EOK;
uint32_t serial_from = 0;
uint32_t serial_to = 0;
- dbg_xfr_verb("Loading serials for IXFR.\n");
ret = ns_ixfr_load_serials(xfr, &serial_from, &serial_to);
- dbg_xfr_detail("Loaded serials: from: %u, to: %u\n",
- serial_from, serial_to);
+ dbg_xfr_verb("xfr: loading changesets for IXFR %u-%u\n",
+ serial_from, serial_to);
if (ret != KNOT_EOK) {
return ret;
}
/* Load changesets from journal. */
- dbg_xfr_verb("Loading changesets from journal.\n");
int chsload = zones_xfr_load_changesets(xfr, serial_from, serial_to);
if (chsload != KNOTD_EOK) {
/* History cannot be reconstructed, fallback to AXFR. */
@@ -943,6 +971,7 @@ static int xfr_answer_ixfr(knot_nameserver_t *ns, knot_ns_xfr_t *xfr)
return ret;
}
+/*! \brief Build string for logging related to given xfer descriptor. */
static int xfr_update_msgpref(knot_ns_xfr_t *req, const char *keytag)
{
/* Check */
@@ -990,22 +1019,22 @@ static int xfr_update_msgpref(knot_ns_xfr_t *req, const char *keytag)
const char *pformat = NULL;
switch (req->type) {
case XFR_TYPE_AIN:
- pformat = "AXFR transfer of '%s/IN' with %s:%d%s:";
+ pformat = "AXFR transfer of '%s/IN' with '%s@%d'%s:";
break;
case XFR_TYPE_IIN:
- pformat = "IXFR transfer of '%s/IN' with %s:%d%s:";
+ pformat = "IXFR transfer of '%s/IN' with '%s@%d'%s:";
break;
case XFR_TYPE_AOUT:
- pformat = "AXFR transfer of '%s/OUT' to %s:%d%s:";
+ pformat = "AXFR transfer of '%s/OUT' to '%s@%d'%s:";
break;
case XFR_TYPE_IOUT:
- pformat = "IXFR transfer of '%s/OUT' to %s:%d%s:";
+ pformat = "IXFR transfer of '%s/OUT' to '%s@%d'%s:";
break;
case XFR_TYPE_NOTIFY:
- pformat = "NOTIFY query of '%s' to %s:%d%s:";
+ pformat = "NOTIFY query of '%s' to '%s@%d'%s:";
break;
case XFR_TYPE_SOA:
- pformat = "SOA query of '%s' to %s:%d%s:";
+ pformat = "SOA query of '%s' to '%s@%d'%s:";
break;
default:
pformat = "";
@@ -1032,10 +1061,7 @@ static int xfr_update_msgpref(knot_ns_xfr_t *req, const char *keytag)
return KNOTD_EOK;
}
-/*
- * Public APIs.
- */
-
+/*! \brief Create XFR worker. */
static xfrworker_t* xfr_worker_create(xfrhandler_t *h, knot_nameserver_t *ns)
{
xfrworker_t *w = malloc(sizeof(xfrworker_t));
@@ -1068,6 +1094,7 @@ static xfrworker_t* xfr_worker_create(xfrhandler_t *h, knot_nameserver_t *ns)
return w;
}
+/*! \brief Free created XFR worker. */
static void xfr_worker_free(xfrworker_t *w) {
if (w) {
evqueue_free(&w->q);
@@ -1076,6 +1103,10 @@ static void xfr_worker_free(xfrworker_t *w) {
}
}
+/*
+ * Public APIs.
+ */
+
xfrhandler_t *xfr_create(size_t thrcount, knot_nameserver_t *ns)
{
/* Create XFR handler data. */
@@ -1243,7 +1274,6 @@ int xfr_answer(knot_nameserver_t *ns, knot_ns_xfr_t *xfr)
// use the QNAME as the zone name to get names also for
// zones that are not in the server
- /*! \todo Update msgpref with zname from query. */
const knot_dname_t *qname = knot_packet_qname(xfr->query);
if (qname != NULL) {
xfr->zname = knot_dname_to_str(qname);
@@ -1348,7 +1378,13 @@ static int xfr_process_request(xfrworker_t *w, uint8_t *buf, size_t buflen)
/* Update XFR message prefix. */
xfr_update_msgpref(&xfr, NULL);
-
+
+ /* Check if not already processing. */
+ zonedata_t *zd = NULL;
+ if (xfr.zone != NULL) {
+ zd = (zonedata_t *)knot_zone_data(xfr.zone);
+ }
+
conf_read_lock();
/* Handle request. */
@@ -1362,8 +1398,22 @@ static int xfr_process_request(xfrworker_t *w, uint8_t *buf, size_t buflen)
/* Report. */
if (ret != KNOTD_EOK && ret != KNOTD_EACCES) {
- log_server_error("%s %s\n",
- xfr.msgpref, knotd_strerror(ret));
+ if (zd != NULL && !knot_zone_contents(xfr.zone)) {
+ /* Reschedule request (120 - 240s random delay). */
+ int tmr_s = AXFR_BOOTSTRAP_RETRY * 2; /* Malus x2 */
+ tmr_s += (int)((120.0 * 1000) * 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",
+ xfr.msgpref, tmr_s / 1000);
+ } else {
+ log_server_error("%s %s\n",
+ xfr.msgpref, knotd_strerror(ret));
+ }
}
break;
@@ -1445,16 +1495,12 @@ int xfr_worker(dthread_t *thread)
int rfd = evqueue_pollfd(w->q);
fdset_it_t it;
fdset_begin(w->fdset, &it);
+ int rfd_event = 0;
while(nfds > 0) {
/* Check if it request. */
if (it.fd == rfd) {
- dbg_xfr_verb("xfr: worker=%p processing request\n",
- w);
- ret = xfr_process_request(w, buf, buflen);
- if (ret == KNOTD_ENOTRUNNING) {
- break;
- }
+ rfd_event = 1; /* Delay new tasks after processing. */
} else {
/* Find data. */
data = xfr_handler_task(w, it.fd);
@@ -1481,6 +1527,12 @@ int xfr_worker(dthread_t *thread)
}
}
+ /* Lazily process new tasks. */
+ if (rfd_event) {
+ dbg_xfr_verb("xfr: worker=%p processing request\n", w);
+ ret = xfr_process_request(w, buf, buflen);
+ }
+
/* Sweep inactive. */
timev_t now;
if (time_now(&now) == 0) {
diff --git a/src/knot/server/zones.c b/src/knot/server/zones.c
index be072e8..ba6340d 100644
--- a/src/knot/server/zones.c
+++ b/src/knot/server/zones.c
@@ -28,7 +28,7 @@
#include "knot/conf/conf.h"
#include "knot/other/debug.h"
#include "knot/other/error.h"
-#include "knot/other/log.h"
+#include "common/log.h"
#include "knot/server/notify.h"
#include "knot/server/server.h"
#include "libknot/updates/xfr-in.h"
@@ -42,6 +42,7 @@
static const size_t XFRIN_CHANGESET_BINARY_SIZE = 100;
static const size_t XFRIN_CHANGESET_BINARY_STEP = 100;
+static const size_t XFRIN_BOOTSTRAP_DELAY = 60; /*!< AXFR bootstrap avg. delay */
/* Forward declarations. */
static int zones_dump_zone_text(knot_zone_contents_t *zone, const char *zf);
@@ -157,7 +158,7 @@ static int zonedata_init(conf_zone_t *cfg, knot_zone_t *zone)
zd->xfr_in.next_id = -1;
zd->xfr_in.acl = 0;
zd->xfr_in.wrkr = 0;
- zd->xfr_in.bootstrap_retry = 0;
+ zd->xfr_in.bootstrap_retry = XFRIN_BOOTSTRAP_DELAY * 1000 * tls_rand();
pthread_mutex_init(&zd->xfr_in.lock, 0);
/* Initialize NOTIFY. */
@@ -169,16 +170,19 @@ static int zonedata_init(conf_zone_t *cfg, knot_zone_t *zone)
if (!zd->ixfr_db) {
int ret = journal_create(cfg->ixfr_db, JOURNAL_NCOUNT);
if (ret != KNOTD_EOK) {
- log_server_error("Failed to create journal file "
- "'%s'\n", cfg->ixfr_db);
+ log_server_warning("Failed to create journal file "
+ "'%s' (%s)\n", cfg->ixfr_db,
+ knotd_strerror(ret));
}
zd->ixfr_db = journal_open(cfg->ixfr_db, cfg->ixfr_fslimit,
JOURNAL_LAZY, JOURNAL_DIRTY);
}
- if (zd->ixfr_db == 0) {
- log_server_error("Failed to open journal file "
- "'%s'\n", cfg->ixfr_db);
+ if (zd->ixfr_db == NULL) {
+ char ebuf[128] = {0};
+ strerror_r(errno, ebuf, sizeof(ebuf));
+ log_server_warning("Couldn't open journal file for zone '%s', "
+ "disabling IXFR/IN. (%s)\n", cfg->name, ebuf);
}
/* Initialize IXFR database syncing event. */
@@ -299,14 +303,32 @@ static int zones_expire_ev(event_t *e)
rcu_read_lock();
dbg_zones("zones: EXPIRE timer event\n");
knot_zone_t *zone = (knot_zone_t *)e->data;
- if (!zone) {
- return KNOTD_EINVAL;
- }
- if (!zone->data) {
+ if (zone == NULL || zone->data == NULL) {
return KNOTD_EINVAL;
}
-
+
zonedata_t *zd = (zonedata_t *)zone->data;
+ rcu_read_lock();
+
+ /* Do not issue SOA query if transfer is pending. */
+ int locked = pthread_mutex_trylock(&zd->xfr_in.lock);
+ if (locked != 0) {
+ dbg_zones("zones: zone '%s' is being transferred, "
+ "deferring EXPIRE\n",
+ zd->conf->name);
+
+ /* Reschedule as EXPIRE timer. */
+ uint32_t exp_tmr = zones_soa_expire(zone);
+ evsched_schedule(e->parent, e, exp_tmr);
+ dbg_zones("zones: EXPIRE of '%s' after %u seconds\n",
+ zd->conf->name, exp_tmr / 1000);
+
+ /* Unlock RCU. */
+ rcu_read_unlock();
+ return KNOTD_EOK;
+ }
+ dbg_zones_verb("zones: zone %s locked, no xfers are running\n",
+ zd->conf->name);
/* Won't accept any pending SOA responses. */
zd->xfr_in.next_id = -1;
@@ -316,23 +338,18 @@ static int zones_expire_ev(event_t *e)
zd->server->nameserver->zone_db, zone->name);
if (contents == NULL) {
+ pthread_mutex_unlock(&zd->xfr_in.lock);
log_server_warning("Non-existent zone expired. Ignoring.\n");
rcu_read_unlock();
return 0;
}
-
+ /* Publish expired zone. */
rcu_read_unlock();
-
- dbg_zones_verb("zones: zone %s expired, waiting for xfers to finish\n",
- zd->conf->name);
- pthread_mutex_lock(&zd->xfr_in.lock);
- dbg_zones_verb("zones: zone %s locked, no xfers are running\n",
- zd->conf->name);
-
synchronize_rcu();
- pthread_mutex_unlock(&zd->xfr_in.lock);
+ rcu_read_lock();
+ /* Log event. */
log_server_info("Zone '%s' expired.\n", zd->conf->name);
/* Early finish this event to prevent lockup during cancellation. */
@@ -353,6 +370,8 @@ static int zones_expire_ev(event_t *e)
}
knot_zone_contents_deep_free(&contents, 0);
+ pthread_mutex_unlock(&zd->xfr_in.lock);
+ rcu_read_unlock();
return 0;
}
@@ -364,20 +383,15 @@ static int zones_refresh_ev(event_t *e)
{
dbg_zones("zones: REFRESH or RETRY timer event\n");
knot_zone_t *zone = (knot_zone_t *)e->data;
- if (!zone) {
+ if (zone == NULL || zone->data == NULL) {
return KNOTD_EINVAL;
}
/* Cancel pending timers. */
zonedata_t *zd = (zonedata_t *)knot_zone_data(zone);
- if (!zd) {
- return KNOTD_EINVAL;
- }
-
- /* Lock RCU. */
- rcu_read_lock();
/* Check for contents. */
+ rcu_read_lock();
if (!knot_zone_contents(zone)) {
/* Bootstrap from XFR master. */
@@ -415,8 +429,8 @@ static int zones_refresh_ev(event_t *e)
return KNOTD_EOK;
}
- log_zone_info("Attempting to bootstrap zone %s from master\n",
- zd->conf->name);
+// log_zone_info("Attempting to bootstrap zone %s from master\n",
+// zd->conf->name);
++zd->xfr_in.scheduled;
pthread_mutex_unlock(&zd->xfr_in.lock);
@@ -483,6 +497,8 @@ static int zones_refresh_ev(event_t *e)
/* Create query. */
int sock = -1;
+ char strbuf[512] = "Generic error.";
+ const char *errstr = strbuf;
sockaddr_t *master = &zd->xfr_in.master;
int ret = xfrin_create_soa_query(zone->name, &xfr_req, &buflen);
if (ret == KNOT_EOK) {
@@ -496,6 +512,10 @@ static int zones_refresh_ev(event_t *e)
if (bind(sock, via->ptr, via->len) < 0) {
socket_close(sock);
sock = -1;
+ char r_addr[SOCKADDR_STRLEN];
+ sockaddr_tostr(via, r_addr, sizeof(r_addr));
+ snprintf(strbuf, sizeof(strbuf),
+ "Couldn't bind to \'%s\'", r_addr);
}
}
@@ -509,6 +529,7 @@ static int zones_refresh_ev(event_t *e)
if (sent == buflen) {
ret = KNOTD_EOK;
} else {
+ strerror_r(errno, strbuf, sizeof(strbuf));
socket_close(sock);
sock = -1;
}
@@ -523,6 +544,7 @@ static int zones_refresh_ev(event_t *e)
}
} else {
ret = KNOTD_ERROR;
+ errstr = "Couldn't create SOA query";
}
@@ -544,8 +566,8 @@ static int zones_refresh_ev(event_t *e)
ret = xfr_request(zd->server->xfr_h, &req);
}
if (ret != KNOTD_EOK) {
- log_server_warning("Failed to issue SOA query for zone '%s'.\n",
- zd->conf->name);
+ log_server_warning("Failed to issue SOA query for zone '%s' (%s).\n",
+ zd->conf->name, errstr);
}
free(qbuf);
@@ -564,9 +586,13 @@ static int zones_notify_send(event_t *e)
dbg_notify("notify: NOTIFY timer event\n");
notify_ev_t *ev = (notify_ev_t *)e->data;
- knot_zone_t *zone = ev->zone;
- if (!zone) {
+ if (ev == NULL) {
log_zone_error("NOTIFY invalid event received\n");
+ return KNOTD_EINVAL;
+ }
+ knot_zone_t *zone = ev->zone;
+ if (zone == NULL || zone->data == NULL) {
+ log_zone_error("NOTIFY invalid event data received\n");
evsched_event_free(e->parent, e);
free(ev);
return KNOTD_EINVAL;
@@ -744,17 +770,18 @@ static int zones_set_acl(acl_t **acl, list* acl_list)
/* Create new ACL. */
*acl = acl_new(ACL_DENY, 0);
- if (!*acl) {
+ if (*acl == NULL) {
return KNOTD_ENOMEM;
}
/* Load ACL rules. */
+ sockaddr_t addr;
conf_remote_t *r = 0;
WALK_LIST(r, *acl_list) {
/* Initialize address. */
/*! Port matching disabled, port = 0. */
- sockaddr_t addr;
+ sockaddr_init(&addr, -1);
conf_iface_t *cfg_if = r->remote;
int ret = sockaddr_set(&addr, cfg_if->family,
cfg_if->address, 0);
@@ -988,7 +1015,7 @@ static inline uint64_t ixfrdb_key_make(uint32_t from, uint32_t to)
/*----------------------------------------------------------------------------*/
-static int zones_changesets_from_binary(knot_changesets_t *chgsets)
+int zones_changesets_from_binary(knot_changesets_t *chgsets)
{
assert(chgsets != NULL);
assert(chgsets->allocated >= chgsets->count);
@@ -1015,14 +1042,14 @@ static int zones_changesets_from_binary(knot_changesets_t *chgsets)
* from journal) the SOA serial should already
* be set, check it.
*/
+ dbg_xfr_verb("xfr: reading RRSets to REMOVE, first RR is %hu\n",
+ knot_rrset_type(rrset));
assert(knot_rrset_type(rrset) == KNOT_RRTYPE_SOA);
assert(chs->serial_from ==
knot_rdata_soa_serial(knot_rrset_rdata(rrset)));
knot_changeset_store_soa(&chs->soa_from, &chs->serial_from,
rrset);
- dbg_xfr_verb("xfr: reading RRSets to REMOVE\n");
-
/* Read remaining RRSets */
int in_remove_section = 1;
while (remaining > 0) {
@@ -1105,8 +1132,6 @@ static int zones_load_changesets(const knot_zone_t *zone,
return KNOTD_EINVAL;
}
- dbg_xfr("Loading changesets from serial %u to %u\n", from, to);
-
/* Fetch zone-specific data. */
zonedata_t *zd = (zonedata_t *)knot_zone_data(zone);
if (!zd->ixfr_db) {
@@ -1114,6 +1139,11 @@ static int zones_load_changesets(const knot_zone_t *zone,
return KNOTD_EINVAL;
}
+ conf_read_lock();
+ dbg_xfr("xfr: loading changesets for zone '%s' from serial %u to %u\n",
+ zd->conf->name, from, to);
+ conf_read_unlock();
+
/* Retain journal for changeset loading. */
journal_t *j = journal_retain(zd->ixfr_db);
@@ -1181,7 +1211,7 @@ static int zones_load_changesets(const knot_zone_t *zone,
/*! \todo Check consistency. */
}
- dbg_xfr_detail("xfr: Journal entries read.\n");
+ dbg_xfr_detail("xfr: finished reading journal entries\n");
journal_release(j);
/* Unpack binary data. */
@@ -1194,12 +1224,12 @@ static int zones_load_changesets(const knot_zone_t *zone,
/* Check for complete history. */
if (to != found_to) {
- dbg_xfr_detail("Returning ERANGE\n");
+ dbg_xfr_detail("xfr: load changesets finished, ERANGE\n");
return KNOTD_ERANGE;
}
/* History reconstructed. */
- dbg_xfr_detail("Returning EOK\n");
+ dbg_xfr_detail("xfr: load changesets finished, EOK\n");
return KNOTD_EOK;
}
@@ -1475,11 +1505,9 @@ static int zones_insert_zones(knot_nameserver_t *ns,
cfg_if->family,
cfg_if->address,
cfg_if->port);
- if (cfg_if->via) {
- sockaddr_set(&zd->xfr_in.via,
- cfg_if->via->family,
- cfg_if->via->address,
- 0);
+ if (sockaddr_isvalid(&cfg_if->via)) {
+ sockaddr_copy(&zd->xfr_in.via,
+ &cfg_if->via);
}
if (cfg_if->key) {
@@ -1488,7 +1516,7 @@ static int zones_insert_zones(knot_nameserver_t *ns,
sizeof(knot_key_t));
}
- dbg_zones("zones: using %s:%d as XFR master "
+ dbg_zones("zones: using '%s@%d' as XFR master "
"for '%s'\n",
cfg_if->address,
cfg_if->port,
@@ -1690,27 +1718,28 @@ static int zones_check_tsig_query(const knot_zone_t *zone,
knot_packet_additional_rrset_count(query) - 1);
if (knot_rrset_type(tsig) == KNOT_RRTYPE_TSIG) {
dbg_zones_verb("found TSIG in normal query\n");
- } else {
- tsig = NULL; /* Invalidate if not TSIG RRTYPE. */
- }
+ } else {
+ tsig = NULL; /* Invalidate if not TSIG RRTYPE. */
+ }
}
if (tsig == NULL) {
// no TSIG, this is completely valid
+ /*! \note This function is (should be) called only in case of
+ normal query, i.e. we do not have to check ACL.
+ */
*tsig_rcode = 0;
return KNOT_EOK;
}
// if there is some TSIG in the query, find the TSIG associated with
// the zone
- //knot_key_t *tsig_key_zone = NULL;
-
dbg_zones_verb("Checking zone and ACL.\n");
int ret = zones_query_check_zone(zone, addr, tsig_key_zone, rcode);
- /*! \todo What if there is TSIG, but no key is configured? */
-
- if (ret == KNOTD_EOK) {
+
+ /* Accept found OR unknown key results. */
+ if (ret == KNOTD_EOK || ret == KNOTD_EACCES) {
if (*tsig_key_zone != NULL) {
// everything OK, so check TSIG
dbg_zones_verb("Verifying TSIG.\n");
@@ -1903,8 +1932,6 @@ int zones_query_check_zone(const knot_zone_t *zone, const sockaddr_t *addr,
/* Check xfr-out ACL */
acl_key_t *match = NULL;
if (acl_match(zd->xfr_out, addr, &match) == ACL_DENY) {
- log_answer_warning("Unauthorized query or request for XFR "
- "'%s/OUT'.\n", zd->conf->name);
*rcode = KNOT_RCODE_REFUSED;
return KNOTD_EACCES;
} else {
@@ -2244,7 +2271,7 @@ int zones_process_response(knot_nameserver_t *nameserver,
char r_addr[SOCKADDR_STRLEN];
int r_port = sockaddr_portnum(from);
sockaddr_tostr(from, r_addr, sizeof(r_addr));
- log_zone_info("SOA query of '%s' to %s:%d: Answered, no "
+ log_zone_info("SOA query of '%s' to '%s@%d': Answered, no "
"transfer needed.\n",
zd->conf->name, r_addr, r_port);
rcu_read_unlock();
@@ -2257,7 +2284,7 @@ int zones_process_response(knot_nameserver_t *nameserver,
assert(ret > 0);
/* Already transferring. */
- int xfrtype = zones_transfer_to_use(contents);
+ int xfrtype = zones_transfer_to_use(zd);
if (pthread_mutex_trylock(&zd->xfr_in.lock) != 0) {
/* Unlock zone contents. */
dbg_zones("zones: SOA response received, but zone is "
@@ -2299,9 +2326,12 @@ int zones_process_response(knot_nameserver_t *nameserver,
/*----------------------------------------------------------------------------*/
-knot_ns_xfr_type_t zones_transfer_to_use(const knot_zone_contents_t *zone)
+knot_ns_xfr_type_t zones_transfer_to_use(zonedata_t *data)
{
- /*! \todo Implement. */
+ if (data == NULL || data->ixfr_db == NULL) {
+ return XFR_TYPE_AIN;
+ }
+
return XFR_TYPE_IIN;
}
@@ -2565,235 +2595,343 @@ int zones_ns_conf_hook(const struct conf_t *conf, void *data)
}
/*----------------------------------------------------------------------------*/
+/* Counting size of changeset in serialized form. */
+/*----------------------------------------------------------------------------*/
-static int zones_check_binary_size(uint8_t **data, size_t *allocated,
- size_t required)
+static inline size_t zones_dname_binary_size(const knot_dname_t *dname)
{
- if (required <= *allocated) {
- return KNOTD_EOK;
+ if (dname == NULL) {
+ return 0;
}
- /* Allocate new memory block. */
- size_t new_count = required;
- uint8_t *new_data = malloc(new_count * sizeof(uint8_t));
- if (new_data == NULL) {
- return KNOTD_ENOMEM;
+ size_t size = 10; // 4B ID, 4B size, 2B label count
+
+ // dname size in wire format
+ size += knot_dname_size(dname);
+ // label array size
+ size += knot_dname_label_count(dname);
+
+ return size;
+}
+
+/*----------------------------------------------------------------------------*/
+
+static size_t zones_rdata_binary_size(const knot_rdata_t *rdata,
+ knot_rrtype_descriptor_t *desc)
+{
+ if (rdata == NULL) {
+ return 0;
}
- /* Clear memory block and copy old data. */
- memset(new_data, 0, new_count * sizeof(uint8_t));
- memcpy(new_data, *data, *allocated);
+ assert(desc != NULL);
- /* Switch pointers and free old pointer. */
- free(*data);
- *data = new_data;
- *allocated = new_count;
+ size_t size = sizeof(unsigned int); // RDATA item count
- return KNOTD_EOK;
+ for (int i = 0; i < rdata->count; ++i) {
+ if (desc->wireformat[i] == KNOT_RDATA_WF_COMPRESSED_DNAME
+ || desc->wireformat[i] == KNOT_RDATA_WF_UNCOMPRESSED_DNAME
+ || desc->wireformat[i] == KNOT_RDATA_WF_LITERAL_DNAME) {
+ size += zones_dname_binary_size(rdata->items[i].dname);
+ size += 2; // flags
+ } else {
+ if (rdata->items[i].raw_data != NULL) {
+ size += rdata->items[i].raw_data[0] + 2;
+ }
+ }
+ }
+
+ return size;
}
/*----------------------------------------------------------------------------*/
-static int zones_changeset_rrset_to_binary(uint8_t **data, size_t *size,
- size_t *allocated,
- knot_rrset_t *rrset)
+static size_t zones_rrset_binary_size(const knot_rrset_t *rrset)
{
- assert(data != NULL);
- assert(size != NULL);
- assert(allocated != NULL);
+ assert(rrset != NULL);
- /*
- * In *data, there is the whole changeset in the binary format,
- * the actual RRSet will be just appended to it
- */
+ size_t size = 0;
+
+ size += 13; // 2B type, 2B class, 4B TTL, 4B RDATA count, 1B flags
+ size += zones_dname_binary_size(rrset->owner);
+
+ knot_rrtype_descriptor_t *desc = knot_rrtype_descriptor_by_type(
+ knot_rrset_type(rrset));
+ assert(desc != NULL);
+
+ const knot_rdata_t *rdata = knot_rrset_rdata(rrset);
+ while (rdata != NULL) {
+ size += zones_rdata_binary_size(rdata, desc);
+ rdata = knot_rrset_rdata_next(rrset, rdata);
+ }
+
+ return size;
+}
+
+/*----------------------------------------------------------------------------*/
- uint8_t *binary = NULL;
- size_t actual_size = 0;
- int ret = knot_zdump_rrset_serialize(rrset, &binary, &actual_size);
- if (ret != KNOT_EOK || binary == NULL) {
+int zones_changeset_binary_size(const knot_changeset_t *chgset, size_t *size)
+{
+ if (chgset == NULL || size == NULL) {
+ return KNOTD_EINVAL;
+ }
+
+ size_t soa_from_size = zones_rrset_binary_size(chgset->soa_from);
+ size_t soa_to_size = zones_rrset_binary_size(chgset->soa_to);
+
+ size_t remove_size = 0;
+ for (int i = 0; i < chgset->remove_count; ++i)
+ {
+ remove_size += zones_rrset_binary_size(chgset->remove[i]);
+ }
+
+ size_t add_size = 0;
+ for (int i = 0; i < chgset->add_count; ++i)
+ {
+ add_size += zones_rrset_binary_size(chgset->add[i]);
+ }
+
+ /*! \todo How is the changeset serialized? Any other parts? */
+ *size += soa_from_size + soa_to_size + remove_size + add_size;
+
+ return KNOT_EOK;
+}
+
+/*----------------------------------------------------------------------------*/
+/* Changeset serialization and storing (new) */
+/*----------------------------------------------------------------------------*/
+
+static int zones_rrset_write_to_mem(const knot_rrset_t *rr, char **entry,
+ size_t *remaining) {
+ size_t written = 0;
+ int ret = knot_zdump_rrset_serialize(rr, *((uint8_t **)entry),
+ *remaining, &written);
+ if (ret == KNOT_EOK) {
+ assert(written <= *remaining);
+ *remaining -= written;
+ *entry += written;
+ }
+
+ return ret;
+}
+
+static int zones_serialize_and_store_chgset(const knot_changeset_t *chs,
+ char *entry, size_t max_size)
+{
+ /* Serialize SOA 'from'. */
+ int ret = zones_rrset_write_to_mem(chs->soa_from, &entry, &max_size);
+ if (ret != KNOT_EOK) {
dbg_zones("knot_zdump_rrset_serialize() returned %s\n",
knot_strerror(ret));
return KNOTD_ERROR; /*! \todo Other code? */
}
- ret = zones_check_binary_size(data, allocated, *size + actual_size);
- if (ret != KNOTD_EOK) {
- free(binary);
- return ret;
+ /* Serialize RRSets from the 'remove' section. */
+ for (int i = 0; i < chs->remove_count; ++i) {
+ ret = zones_rrset_write_to_mem(chs->remove[i], &entry, &max_size);
+ if (ret != KNOT_EOK) {
+ dbg_zones("knot_zdump_rrset_serialize() returned %s\n",
+ knot_strerror(ret));
+ return KNOTD_ERROR; /*! \todo Other code? */
+ }
+ }
+
+ /* Serialize SOA 'to'. */
+ ret = zones_rrset_write_to_mem(chs->soa_to, &entry, &max_size);
+ if (ret != KNOT_EOK) {
+ dbg_zones("knot_zdump_rrset_serialize() returned %s\n",
+ knot_strerror(ret));
+ return KNOTD_ERROR; /*! \todo Other code? */
+ }
+
+ /* Serialize RRSets from the 'add' section. */
+ for (int i = 0; i < chs->add_count; ++i) {
+ ret = zones_rrset_write_to_mem(chs->add[i], &entry, &max_size);
+ if (ret != KNOT_EOK) {
+ dbg_zones("knot_zdump_rrset_serialize() returned %s\n",
+ knot_strerror(ret));
+ return KNOTD_ERROR; /*! \todo Other code? */
+ }
+
}
- memcpy(*data + *size, binary, actual_size);
- *size += actual_size;
- free(binary);
return KNOTD_EOK;
}
/*----------------------------------------------------------------------------*/
-int zones_changesets_to_binary(knot_changesets_t *chgsets)
+static int zones_store_changeset(const knot_changeset_t *chs, journal_t *j,
+ knot_zone_t *zone, zonedata_t *zd)
{
- assert(chgsets != NULL);
- assert(chgsets->allocated >= chgsets->count);
+ assert(chs != NULL);
+ assert(j != NULL);
- /*
- * Converts changesets to the binary format stored in chgsets->data
- * from the changeset_t structures.
- */
- int ret;
+ dbg_xfr("Saving changeset from %u to %u.\n",
+ chs->serial_from, chs->serial_to);
- for (int i = 0; i < chgsets->count; ++i) {
- knot_changeset_t *ch = &chgsets->sets[i];
- assert(ch->data == NULL);
- assert(ch->size == 0);
+ uint64_t k = ixfrdb_key_make(chs->serial_from, chs->serial_to);
- /* 1) origin SOA */
- ret = zones_changeset_rrset_to_binary(&ch->data, &ch->size,
- &ch->allocated, ch->soa_from);
- if (ret != KNOTD_EOK) {
- free(ch->data);
- ch->data = NULL;
- dbg_zones("zones_changeset_rrset_to_binary(): %s\n",
- knot_strerror(ret));
- return ret;
- }
+ /* Count the size of the entire changeset in serialized form. */
+ size_t entry_size = 0;
- int j;
-
- /* 2) remove RRsets */
- assert(ch->remove_allocated >= ch->remove_count);
- for (j = 0; j < ch->remove_count; ++j) {
- ret = zones_changeset_rrset_to_binary(&ch->data,
- &ch->size,
- &ch->allocated,
- ch->remove[j]);
- if (ret != KNOTD_EOK) {
- free(ch->data);
- ch->data = NULL;
- dbg_zones("zones_changeset_rrset_to_binary(): %s\n",
- knot_strerror(ret));
- return ret;
- }
+ int ret = zones_changeset_binary_size(chs, &entry_size);
+ assert(ret == KNOTD_EOK);
+
+ dbg_xfr_verb("Size in serialized form: %zu\n", entry_size);
+
+ /* Reserve space for the journal entry. */
+ char *journal_entry = NULL;
+ ret = journal_map(j, k, &journal_entry, entry_size);
+
+ /* Sync to zonefile may be needed. */
+ while (ret == KNOTD_EAGAIN) {
+ /* Cancel sync timer. */
+ event_t *tmr = zd->ixfr_dbsync;
+ if (tmr) {
+ dbg_xfr_verb("xfr: cancelling zonefile "
+ "SYNC timer of '%s'\n",
+ zd->conf->name);
+ evsched_cancel(tmr->parent, tmr);
}
- /* 3) new SOA */
- ret = zones_changeset_rrset_to_binary(&ch->data, &ch->size,
- &ch->allocated, ch->soa_to);
- if (ret != KNOTD_EOK) {
- free(ch->data);
- ch->data = NULL;
- dbg_zones("zones_changeset_rrset_to_binary(): %s\n",
- knot_strerror(ret));
- return ret;
+ /* Synchronize. */
+ dbg_xfr_verb("xfr: forcing zonefile SYNC "
+ "of '%s'\n",
+ zd->conf->name);
+ ret = zones_zonefile_sync(zone, j);
+ if (ret != KNOTD_EOK && ret != KNOTD_ERANGE) {
+ continue;
}
- /* 4) add RRsets */
- assert(ch->add_allocated >= ch->add_count);
- for (j = 0; j < ch->add_count; ++j) {
- ret = zones_changeset_rrset_to_binary(&ch->data,
- &ch->size,
- &ch->allocated,
- ch->add[j]);
- if (ret != KNOTD_EOK) {
- free(ch->data);
- ch->data = NULL;
- dbg_zones("zones_changeset_rrset_to_binary(): %s\n",
- knot_strerror(ret));
- return ret;
- }
+ /* Reschedule sync timer. */
+ if (tmr) {
+ /* Fetch sync timeout. */
+ conf_read_lock();
+ int timeout = zd->conf->dbsync_timeout;
+ timeout *= 1000; /* Convert to ms. */
+ conf_read_unlock();
+
+ /* Reschedule. */
+ dbg_xfr_verb("xfr: resuming SYNC "
+ "of '%s'\n",
+ zd->conf->name);
+ evsched_schedule(tmr->parent, tmr,
+ timeout);
+
}
+
+ /* Attempt to map again. */
+ ret = journal_map(j, k, &journal_entry, entry_size);
}
- return KNOTD_EOK;
+ if (ret != KNOTD_EOK) {
+ dbg_xfr("Failed to map space for journal entry: %s.\n",
+ knotd_strerror(ret));
+ return ret;
+ }
+
+ assert(journal_entry != NULL);
+
+ /* Serialize changeset, saving it bit by bit. */
+ ret = zones_serialize_and_store_chgset(chs, journal_entry, entry_size);
+
+ if (ret != KNOTD_EOK) {
+ dbg_xfr("Failed to serialize and store changeset: %s\n",
+ knotd_strerror(ret));
+ }
+
+ /* Unmap the journal entry.
+ If successfuly written changeset to journal, validate the entry. */
+ ret = journal_unmap(j, k, journal_entry, ret == KNOTD_EOK);
+
+ return ret;
}
/*----------------------------------------------------------------------------*/
-int zones_store_changesets(knot_ns_xfr_t *xfr)
+journal_t *zones_store_changesets_begin(knot_ns_xfr_t *xfr)
{
if (xfr == NULL || xfr->data == NULL || xfr->zone == NULL) {
- return KNOTD_EINVAL;
+ return NULL;
}
-
- knot_zone_t *zone = xfr->zone;
- knot_changesets_t *src = (knot_changesets_t *)xfr->data;
/* Fetch zone-specific data. */
+ knot_zone_t *zone = xfr->zone;
zonedata_t *zd = (zonedata_t *)zone->data;
if (!zd->ixfr_db) {
- return KNOTD_EINVAL;
+ return NULL;
}
- /* Retain journal for changeset loading. */
+ /* Begin transaction, will be release on commit/rollback. */
journal_t *j = journal_retain(zd->ixfr_db);
+ if (journal_trans_begin(j) != KNOTD_EOK) {
+ journal_release(j);
+ j = NULL;
+ }
- /* Begin writing to journal. */
- for (unsigned i = 0; i < src->count; ++i) {
+ return j;
+}
- /* Make key from serials. */
- knot_changeset_t* chs = src->sets + i;
- uint64_t k = ixfrdb_key_make(chs->serial_from, chs->serial_to);
+/*----------------------------------------------------------------------------*/
- /* Write entry. */
- int ret = journal_write(j, k, (const char*)chs->data, chs->size);
+int zones_store_changesets_commit(journal_t *j)
+{
+ if (j == NULL) {
+ return KNOTD_EINVAL;
+ }
+
+ int ret = journal_trans_commit(j);
+ journal_release(j);
+ return ret;
+}
- /* Check for errors. */
- while (ret != KNOTD_EOK) {
+/*----------------------------------------------------------------------------*/
- /* Sync to zonefile may be needed. */
- if (ret == KNOTD_EAGAIN) {
+int zones_store_changesets_rollback(journal_t *j)
+{
+ if (j == NULL) {
+ return KNOTD_EINVAL;
+ }
+
+ int ret = journal_trans_rollback(j);
+ journal_release(j);
+ return ret;
+}
- /* Cancel sync timer. */
- event_t *tmr = zd->ixfr_dbsync;
- if (tmr) {
- dbg_xfr_verb("xfr: cancelling zonefile "
- "SYNC timer of '%s'\n",
- zd->conf->name);
- evsched_cancel(tmr->parent, tmr);
- }
+/*----------------------------------------------------------------------------*/
- /* Synchronize. */
- dbg_xfr_verb("xfr: forcing zonefile SYNC "
- "of '%s'\n",
- zd->conf->name);
- ret = zones_zonefile_sync(zone, j);
- if (ret != KNOTD_EOK && ret != KNOTD_ERANGE) {
- continue;
- }
+int zones_store_changesets(knot_ns_xfr_t *xfr)
+{
+ if (xfr == NULL || xfr->data == NULL || xfr->zone == NULL) {
+ return KNOTD_EINVAL;
+ }
- /* Reschedule sync timer. */
- if (tmr) {
- /* Fetch sync timeout. */
- conf_read_lock();
- int timeout = zd->conf->dbsync_timeout;
- timeout *= 1000; /* Convert to ms. */
- conf_read_unlock();
-
- /* Reschedule. */
- dbg_xfr_verb("xfr: resuming SYNC "
- "of '%s'\n",
- zd->conf->name);
- evsched_schedule(tmr->parent, tmr,
- timeout);
+ knot_zone_t *zone = xfr->zone;
+ knot_changesets_t *src = (knot_changesets_t *)xfr->data;
- }
+ /* Fetch zone-specific data. */
+ zonedata_t *zd = (zonedata_t *)zone->data;
+ if (!zd->ixfr_db) {
+ return KNOTD_EINVAL;
+ }
- /* Attempt to write again. */
- ret = journal_write(j, k, (const char*)chs->data,
- chs->size);
- } else {
- /* Other errors. */
- journal_release(j);
- return KNOTD_ERROR;
- }
- }
+ /* Retain journal for changeset writing. */
+ journal_t *j = journal_retain(zd->ixfr_db);
+
+ int ret = 0;
+
+ /* Begin writing to journal. */
+ for (unsigned i = 0; i < src->count; ++i) {
+ /* Make key from serials. */
+ knot_changeset_t* chs = src->sets + i;
- /* Free converted binary data. */
- free(chs->data);
- chs->data = 0;
- chs->size = 0;
+ ret = zones_store_changeset(chs, j, zone, zd);
+ if (ret != KNOTD_EOK) {
+ journal_release(j);
+ return ret;
+ }
}
-
+
/* Release journal. */
journal_release(j);
@@ -2825,13 +2963,12 @@ int zones_xfr_load_changesets(knot_ns_xfr_t *xfr, uint32_t serial_from,
return KNOTD_EOK;
}
- dbg_zones("Loading changesets...\n");
-
+ dbg_xfr_verb("xfr: loading changesets\n");
ret = zones_load_changesets(xfr->zone, chgsets,
serial_from, serial_to);
if (ret != KNOTD_EOK) {
- dbg_zones_verb("Loading changesets failed: %s\n",
- knotd_strerror(ret));
+ dbg_xfr("xfr: failed to load changesets: %s\n",
+ knotd_strerror(ret));
knot_free_changesets(&chgsets);
return ret;
}
@@ -2934,15 +3071,17 @@ int zones_timers_update(knot_zone_t *zone, conf_zone_t *cfzone, evsched_t *sch)
int ret = sockaddr_set(&ev->addr, cfg_if->family,
cfg_if->address,
cfg_if->port);
- conf_iface_t *via = cfg_if->via;
- if (ret > 0 && via != NULL) {
- ret = sockaddr_set(&ev->saddr, via->family,
- via->address, 0);
- }
- if (ret < 1) {
+ sockaddr_t *via = &cfg_if->via;
+ if (ret > 0) {
+ if (sockaddr_isvalid(via)) {
+ sockaddr_copy(&ev->saddr, via);
+ }
+ } else {
free(ev);
- dbg_zones("notify: NOTIFY slave %s has invalid "
- "address\n", cfg_if->name);
+ log_server_warning("NOTIFY slave '%s' has invalid "
+ "address '%s@%d', couldn't create"
+ "query.\n", cfg_if->name,
+ cfg_if->address, cfg_if->port);
continue;
}
@@ -2961,7 +3100,7 @@ int zones_timers_update(knot_zone_t *zone, conf_zone_t *cfzone, evsched_t *sch)
pthread_mutex_unlock(&zd->lock);
log_server_info("Scheduled '%s' NOTIFY query "
- "after %d s to %s:%d\n", zd->conf->name,
+ "after %d s to '%s@%d'.\n", zd->conf->name,
tmr_s, cfg_if->address, cfg_if->port);
}
diff --git a/src/knot/server/zones.h b/src/knot/server/zones.h
index 8421f30..08f9df6 100644
--- a/src/knot/server/zones.h
+++ b/src/knot/server/zones.h
@@ -174,13 +174,12 @@ int zones_process_response(knot_nameserver_t *nameserver,
/*!
* \brief Decides what type of transfer should be used to update the given zone.
- *
- * \param nameserver Name server structure that uses the zone.
- * \param zone Zone to be updated by the transfer.
+ *.
+ * \param data Zone data for associated zone.
*
* \retval
*/
-knot_ns_xfr_type_t zones_transfer_to_use(const knot_zone_contents_t *zone);
+knot_ns_xfr_type_t zones_transfer_to_use(zonedata_t *data);
int zones_save_zone(const knot_ns_xfr_t *xfr);
@@ -212,9 +211,40 @@ int zones_ns_conf_hook(const struct conf_t *conf, void *data);
* \retval KNOTD_EAGAIN if journal needs to be synced with zonefile first.
*
* \todo Expects the xfr structure to be initialized in some way.
+ * \todo Update documentation!!!
*/
int zones_store_changesets(knot_ns_xfr_t *xfr);
+/*!
+ * \brief Begin changesets storing transaction.
+ *
+ * \retval pointer to journal if successful
+ * \retval NULL on failure.
+ */
+journal_t *zones_store_changesets_begin(knot_ns_xfr_t *xfr);
+
+/*!
+ * \brief Commit stored changesets.
+ *
+ * \retval KNOTD_EOK on success.
+ * \retval KNOTD_EINVAL on invalid parameters.
+ * \retval KNOTD_ENOENT when no transaction is pending.
+ */
+int zones_store_changesets_commit(journal_t *j);
+
+/*!
+ * \brief Rollback stored changesets.
+ *
+ * \retval KNOTD_EOK on success.
+ * \retval KNOTD_EINVAL on invalid parameters.
+ * \retval KNOTD_ENOENT when no transaction is pending.
+ */
+int zones_store_changesets_rollback(journal_t *j);
+
+/*! \todo Document me. */
+int zones_changesets_from_binary(knot_changesets_t *chgsets);
+
+/*! \todo Document me. */
int zones_changesets_to_binary(knot_changesets_t *chgsets);
/*!
diff --git a/src/knot/stat/gatherer.c b/src/knot/stat/gatherer.c
index e8048a1..5b8eab6 100644
--- a/src/knot/stat/gatherer.c
+++ b/src/knot/stat/gatherer.c
@@ -16,9 +16,11 @@
#include <config.h>
#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
#include "knot/stat/stat-common.h"
-#include "common/slab/malloc.h"
+#include "common/mempattern.h"
#include "knot/stat/gatherer.h"
gatherer_t *new_gatherer()
diff --git a/src/knot/zone/semantic-check.c b/src/knot/zone/semantic-check.c
index f900951..fc20c29 100644
--- a/src/knot/zone/semantic-check.c
+++ b/src/knot/zone/semantic-check.c
@@ -5,6 +5,7 @@
#include "knot/common.h"
#include "knot/zone/zone-dump.h"
#include "knot/other/error.h"
+#include "knot/other/debug.h"
#include "libknot/libknot.h"
#include "common/base32hex.h"
#include "common/crc.h"
@@ -15,6 +16,8 @@ static char *error_messages[(-ZC_ERR_ALLOC) + 1] = {
[-ZC_ERR_ALLOC] = "Memory allocation error!\n",
[-ZC_ERR_MISSING_SOA] = "SOA record missing in zone!\n",
+ [-ZC_ERR_MISSING_NS_DEL_POINT] = "NS record missing in zone apex or in "
+ "delegation point!\n",
[-ZC_ERR_RRSIG_RDATA_TYPE_COVERED] =
"RRSIG: Type covered rdata field is wrong!\n",
@@ -63,6 +66,9 @@ static char *error_messages[(-ZC_ERR_ALLOC) + 1] = {
"NSEC3: NSEC3 chain is not coherent!\n",
[-ZC_ERR_NSEC3_RDATA_BITMAP] =
"NSEC3: NSEC3 bitmap error!\n",
+ [-ZC_ERR_NSEC3_EXTRA_RECORD] =
+ "NSEC3: NSEC3 node contains extra record. This is valid, however Knot "
+ "will not serve this record properly.\n",
[-ZC_ERR_CNAME_CYCLE] =
"CNAME: CNAME cycle!\n",
@@ -90,9 +96,9 @@ static char *error_messages[(-ZC_ERR_ALLOC) + 1] = {
specified otherwise */
[-ZC_ERR_GLUE_NODE] =
- "GLUE: Node with Glue record missing!\n",
+ "GLUE: Node with glue record missing!\n",
[-ZC_ERR_GLUE_RECORD] =
- "GLUE: Record with Glue address missing\n",
+ "GLUE: Record with glue address missing\n",
};
static const uint MAX_CNAME_CYCLE_DEPTH = 15;
@@ -140,7 +146,11 @@ static void log_error_from_node(err_handler_t *handler,
char *name =
knot_dname_to_str(knot_node_owner(node));
fprintf(stderr, "Semantic warning in node: %s: ", name);
- fprintf(stderr, "%s", error_messages[-error]);
+ if (error_messages[-error] != NULL) {
+ fprintf(stderr, "%s", error_messages[-error]);
+ } else {
+ fprintf(stderr, "Unknown error (%d).\n", error);
+ }
free(name);
} else {
fprintf(stderr, "Total number of warnings is: %d for error: %s",
@@ -171,6 +181,7 @@ int err_handler_handle_error(err_handler_t *handler,
(error < ZC_ERR_GENERIC_GENERAL_ERROR)) {
/* The two errors before SOA were handled */
log_error_from_node(handler, node, error);
+ return KNOT_EOK;
} else if ((error < ZC_ERR_RRSIG_GENERAL_ERROR) &&
((handler->errors[-error] == 0) ||
@@ -310,12 +321,19 @@ static int check_cname_cycles_in_zone(knot_zone_contents_t *zone,
knot_dname_t *tmp_chopped =
knot_dname_left_chop(next_dname_copy);
- knot_dname_free(&next_dname_copy);
- if (!tmp_chopped) {
+ if (!tmp_chopped &&
+ !(knot_dname_is_fqdn(next_dname_copy) &&
+ knot_dname_label_count(next_dname_copy) == 0)) {
knot_dname_free(&chopped_wc);
knot_dname_free(&next_dname_copy);
return KNOT_ERROR;
+ } else if ((knot_dname_is_fqdn(next_dname_copy) &&
+ knot_dname_label_count(next_dname_copy) == 0)) {
+ knot_dname_free(&next_dname_copy);
+ /* Root domain, end of search. */
+ break;
}
+ knot_dname_free(&next_dname_copy);
cut_offs++;
@@ -973,7 +991,8 @@ static int check_nsec3_node_in_zone(knot_zone_contents_t *zone, knot_node_t *nod
/* Directly discard. */
knot_dname_free(&next_dname);
-
+
+ /*!< \todo These comments are not accurate anymore. */
/* This is probably not sufficient, but again, it is covered in
* zone load time */
@@ -999,14 +1018,21 @@ static int check_nsec3_node_in_zone(knot_zone_contents_t *zone, knot_node_t *nod
type) == NULL) {
err_handler_handle_error(handler, node,
ZC_ERR_NSEC3_RDATA_BITMAP);
-/* char *name =
- knot_dname_to_str(
- log_zone_error("Node %s does "
- "not contain RRSet of type %s "
- "but NSEC bitmap says "
- "it does!\n", name,
- knot_rrtype_to_string(type));
- free(name); */
+ }
+ }
+
+ /* Check that the node only contains NSEC3 and RRSIG. */
+ const knot_rrset_t **rrsets = knot_node_rrsets(nsec3_node);
+ if (rrsets == NULL) {
+ return KNOT_ENOMEM;
+ }
+
+ for (int i = 0; i < knot_node_rrset_count(nsec3_node); i++) {
+ uint16_t type = knot_rrset_type(rrsets[i]);
+ if (!(type == KNOT_RRTYPE_NSEC3 ||
+ type == KNOT_RRTYPE_RRSIG)) {
+ err_handler_handle_error(handler, nsec3_node,
+ ZC_ERR_NSEC3_EXTRA_RECORD);
}
}
@@ -1143,15 +1169,21 @@ static int semantic_checks_plain(knot_zone_contents_t *zone,
return KNOT_EOK;
}
+ /*!< \todo Good Lord, move this to ist own function. */
- /* check for glue records at zone cuts */
- if (knot_node_is_deleg_point(node)) {
+ /* check for glue records at zone cuts and in apex. */
+ if (knot_node_is_deleg_point(node) || knot_zone_contents_apex(zone) ==
+ node) {
const knot_rrset_t *ns_rrset =
knot_node_rrset(node, KNOT_RRTYPE_NS);
- assert(ns_rrset);
+ if (ns_rrset == NULL) {
+ err_handler_handle_error(handler, node,
+ ZC_ERR_MISSING_NS_DEL_POINT);
+ return KNOT_EOK;
+ }
//FIXME this should be an error as well ! (i guess)
- const knot_dname_t *ns_dname =
+ knot_dname_t *ns_dname =
knot_rdata_get_item(knot_rrset_rdata
(ns_rrset), 0)->dname;
@@ -1159,12 +1191,41 @@ static int semantic_checks_plain(knot_zone_contents_t *zone,
const knot_node_t *glue_node =
knot_zone_contents_find_node(zone, ns_dname);
-
+
if (knot_dname_is_subdomain(ns_dname,
knot_node_owner(knot_zone_contents_apex(zone)))) {
if (glue_node == NULL) {
- err_handler_handle_error(handler, node,
+ /* Try wildcard. */
+ knot_dname_t *wildcard =
+ knot_dname_new_from_str("*", 1, NULL);
+ if (wildcard == NULL) {
+ return KNOT_ENOMEM;
+ }
+
+ knot_dname_left_chop_no_copy(ns_dname);
+
+ if (knot_dname_cat(wildcard,
+ ns_dname) == NULL) {
+ knot_dname_free(&wildcard);
+ return KNOT_ENOMEM;
+ }
+
+ const knot_node_t *wildcard_node =
+ knot_zone_contents_find_node(zone,
+ wildcard);
+ if (wildcard_node == NULL) {
+ err_handler_handle_error(handler, node,
ZC_ERR_GLUE_NODE);
+ } else {
+ /* Look for A or AAAA. */
+ if ((knot_node_rrset(wildcard_node,
+ KNOT_RRTYPE_A) == NULL) &&
+ (knot_node_rrset(wildcard_node,
+ KNOT_RRTYPE_AAAA) == NULL)) {
+ err_handler_handle_error(handler, node,
+ ZC_ERR_GLUE_RECORD);
+ }
+ }
} else {
if ((knot_node_rrset(glue_node,
KNOT_RRTYPE_A) == NULL) &&
@@ -1276,15 +1337,6 @@ static int semantic_checks_dnssec(knot_zone_contents_t *zone,
err_handler_handle_error(handler,
node,
ZC_ERR_NSEC_RDATA_MULTIPLE);
- /* CLEANUP */
-/* char *name =
- knot_dname_to_str(
- knot_node_owner(node));
- log_zone_error("Node %s contains more "
- "than one NSEC "
- "record!\n", name);
- knot_rrset_dump(nsec_rrset, 0);
- free(name); */
}
/*
@@ -1308,9 +1360,6 @@ static int semantic_checks_dnssec(knot_zone_contents_t *zone,
err_handler_handle_error(handler,
node,
ZC_ERR_NSEC_RDATA_CHAIN);
- /* CLEANUP */
-/* log_zone_error("NSEC chain is not "
- "coherent!\n"); */
}
if (knot_dname_compare(next_domain,
@@ -1344,6 +1393,8 @@ static int semantic_checks_dnssec(knot_zone_contents_t *zone,
*/
static void do_checks_in_tree(knot_node_t *node, void *data)
{
+ dbg_semcheck_verb("semcheck: do_check_in_tree: Checking node: %s\n",
+ knot_dname_to_str(node->owner));
assert(data != NULL);
arg_t *args = (arg_t *)data;
diff --git a/src/knot/zone/semantic-check.h b/src/knot/zone/semantic-check.h
index 08396c8..17b774f 100644
--- a/src/knot/zone/semantic-check.h
+++ b/src/knot/zone/semantic-check.h
@@ -36,6 +36,7 @@ enum zonechecks_errors {
ZC_ERR_UNKNOWN,
ZC_ERR_MISSING_SOA,
+ ZC_ERR_MISSING_NS_DEL_POINT,
ZC_ERR_GENERIC_GENERAL_ERROR, /* isn't there a better name? */
@@ -67,6 +68,7 @@ enum zonechecks_errors {
ZC_ERR_NSEC3_RDATA_TTL,
ZC_ERR_NSEC3_RDATA_CHAIN,
ZC_ERR_NSEC3_RDATA_BITMAP,
+ ZC_ERR_NSEC3_EXTRA_RECORD,
ZC_ERR_NSEC3_GENERAL_ERROR,
@@ -101,6 +103,7 @@ struct arg {
void *arg5; /* last node */
void *arg6; /* error handler */
void *arg7; /* CRC */
+ int error_code; /* Error code. */
};
typedef struct arg arg_t;
diff --git a/src/knot/zone/zone-dump.c b/src/knot/zone/zone-dump.c
index 6ca969f..64b743c 100644
--- a/src/knot/zone/zone-dump.c
+++ b/src/knot/zone/zone-dump.c
@@ -55,9 +55,12 @@ static inline int write_to_file_crc(const void *src,
size_t size, size_t n, int fd,
crc_t *crc)
{
+ if (src == NULL || fd < 0) {
+ return KNOT_EBADARG;
+ }
ssize_t rc = write(fd, src, size * n);
if (rc != size * n) {
- fprintf(stderr, "fwrite: invalid write %zu (expected %zu)\n", rc,
+ fprintf(stderr, "write: invalid write %zu (expected %zu)\n", rc,
n);
}
@@ -67,48 +70,66 @@ static inline int write_to_file_crc(const void *src,
size * n);
}
- /*
- * It was meant differtely, caller function does not
- * care how many bytes had been written, it just cares about
- * success/fail (not that it is checked anyway) (#1684).
- */
- return rc == n;
-
+ return rc == size * n;
}
static inline int write_to_stream(const void *src,
- size_t size, size_t n,
- uint8_t **stream,
- size_t *stream_size)
+ size_t size, size_t n,
+ uint8_t *stream,
+ size_t max_size,
+ size_t *written_bytes)
{
- /* Resize the stream */
- void *tmp = realloc(*stream,
- (*stream_size + (size * n)) * sizeof(uint8_t));
- if (tmp != NULL) {
- *stream = tmp;
- memcpy(*stream + *stream_size, src,
- size * n);
- *stream_size += (size * n) * sizeof(uint8_t);
- return KNOT_EOK;
- } else {
- free(*stream);
- *stream = NULL;
- return KNOT_ENOMEM;
+ if (src == NULL || stream == NULL || written_bytes == NULL) {
+ return KNOT_EBADARG;
}
-
+
+ /* Check that the stream boundary will not be crossed. */
+ if (*written_bytes + (size * n) > max_size) {
+ /* Buffer overflown. */
+ dbg_zdump("zdump: write_to_stream: Cannot write to stream, no "
+ "space left.\n");
+ return KNOT_ERANGE;
+ }
+
+ /* Do the actual write. */
+ memcpy(stream + *written_bytes, src, size * n);
+ /* Expand size. */
+ *written_bytes += (size * n);
+
return KNOT_EOK;
}
static int write_wrapper(const void *src,
- size_t size, size_t n, int fd,
- uint8_t **stream, size_t *stream_size, crc_t *crc)
+ size_t size, size_t n, int fd,
+ uint8_t *stream, size_t max_size,
+ size_t *written_bytes, crc_t *crc)
{
+ if (src == NULL) {
+ dbg_zdump("zdump: write_wrapper: NULL source.\n");
+ return KNOT_EBADARG;
+ }
+
+ dbg_zdump_detail("zdump: write_wrapper: Writing %d bytes to fd: %d.\n",
+ size * n, fd);
+
if (fd < 0) {
- assert(stream && stream_size);
+ assert(stream && written_bytes);
assert(crc == NULL);
- return write_to_stream(src, size, n, stream, stream_size);
+ /*!< \todo To comply with calling convention of write_wrapper,
+ * we have to lose the error. */
+ int ret = write_to_stream(src, size, n, stream, max_size,
+ written_bytes);
+ if (ret != KNOT_EOK) {
+ dbg_zdump("zdump: write_wrapper: Could not write to "
+ "stream. Reason: %s.\n", knot_strerror(ret));
+ /* Intentional! */
+ return 0;
+ } else {
+ /* Intentional! */
+ return 1;
+ }
} else {
- assert(stream == NULL && stream_size == NULL);
+ assert(stream == NULL && written_bytes == NULL);
return write_to_file_crc(src, size, n, fd, crc);
}
}
@@ -119,18 +140,30 @@ static int write_wrapper(const void *src,
* \param dname Dname whose labels are to be dumped.
* \param f Output file.
*/
-static void knot_labels_dump_binary(const knot_dname_t *dname, int fd,
- uint8_t **stream, size_t *stream_size,
- crc_t *crc)
+static int knot_labels_dump_binary(const knot_dname_t *dname, int fd,
+ uint8_t *stream, size_t max_size,
+ size_t *written_bytes, crc_t *crc)
{
- dbg_zdump("label count: %d\n", dname->label_count);
+ if (dname == NULL) {
+ dbg_zdump("zdump: dump_labels: NULL dname.\n");
+ return KNOT_EBADARG;
+ }
+
uint16_t label_count = dname->label_count;
- /*!< \todo #1684 check the return value */
- write_wrapper(&label_count, sizeof(label_count), 1, fd, stream,
- stream_size, crc);
- /*!< \todo #1684 check the return value */
- write_wrapper(dname->labels, sizeof(uint8_t), dname->label_count, fd,
- stream, stream_size, crc);
+ if (!write_wrapper(&label_count, sizeof(label_count), 1, fd, stream,
+ max_size, written_bytes, crc)) {
+ dbg_zdump("zdump: dump_labels: Could not write label count.\n");
+ return KNOT_ERROR;
+ }
+
+ if (!write_wrapper(dname->labels, sizeof(uint8_t), dname->label_count,
+ fd, stream, max_size, written_bytes, crc)) {
+ dbg_zdump("zdump: dump_labels: Could not write labels.\n");
+ return KNOT_ERROR;
+ }
+
+ dbg_zdump_verb("zdump: dump_labels: Labels dumped successfully.\n");
+ return KNOT_EOK;
}
/*!
@@ -139,33 +172,53 @@ static void knot_labels_dump_binary(const knot_dname_t *dname, int fd,
* \param dname Dname to be dumped.
* \param f Output file.
*/
-static void knot_dname_dump_binary(const knot_dname_t *dname, int fd,
- uint8_t **stream, size_t *stream_size,
- crc_t *crc)
+static int knot_dname_dump_binary(const knot_dname_t *dname, int fd,
+ uint8_t *stream, size_t max_size,
+ size_t *written_bytes,
+ crc_t *crc)
{
+ if (dname == NULL) {
+ dbg_zdump("zdump: dump_dname: NULL dname.\n");
+ return KNOT_EBADARG;
+ }
+
+ /*! \todo too big */
uint32_t dname_size = dname->size;
- /*!< \todo #1684 check the return value */
- write_wrapper(&dname_size, sizeof(dname_size), 1, fd, stream,
- stream_size, crc);
- /*!< \todo #1684 check the return value */
- write_wrapper(dname->name, sizeof(uint8_t), dname->size, fd,
- stream, stream_size, crc);
- dbg_zdump("dname size: %d\n", dname->size);
- knot_labels_dump_binary(dname, fd, stream, stream_size, crc);
+ if (!write_wrapper(&dname_size, sizeof(dname_size), 1, fd, stream,
+ max_size, written_bytes, crc)) {
+ dbg_zdump("zdump: dump_dname: Cannot write dname size.\n");
+ return KNOT_ERROR;
+ }
+
+ if (!write_wrapper(dname->name, sizeof(uint8_t), dname->size, fd,
+ stream, max_size, written_bytes, crc)) {
+ dbg_zdump("zdump: dump_dname: Cannot write dname name.\n");
+ return KNOT_ERROR;
+ }
+
+ dbg_zdump_verb("zdump: dump_dname: Dname dumped successfully.\n");
+ return knot_labels_dump_binary(dname, fd, stream, max_size,
+ written_bytes, crc);
}
/*!< \todo #1684 some global variable indicating error! */
-static void dump_dname_with_id(const knot_dname_t *dname, int fd,
- uint8_t **stream, size_t *stream_size,
- crc_t *crc)
+static int dump_dname_with_id(const knot_dname_t *dname, int fd,
+ uint8_t *stream, size_t max_size,
+ size_t *written_bytes, crc_t *crc)
{
+ if (dname == NULL) {
+ dbg_zdump("zdump: dump_dname: NULL dname.\n");
+ return KNOT_EBADARG;
+ }
+
uint32_t id = dname->id;
- /*!< \todo #1684 check the return value */
- write_wrapper(&id, sizeof(id), 1, fd, stream, stream_size, crc);
- knot_dname_dump_binary(dname, fd, stream, stream_size, crc);
-/* if (!write_wrapper_safe(&dname->id, sizeof(dname->id), 1, f)) {
+ if (!write_wrapper(&id, sizeof(id), 1, fd, stream, max_size,
+ written_bytes, crc)) {
+ dbg_zdump("zdump: dump_dname: Cannot write ID.\n");
return KNOT_ERROR;
- } */
+ }
+ return knot_dname_dump_binary(dname, fd, stream, max_size,
+ written_bytes, crc);
}
/*!
@@ -175,32 +228,39 @@ static void dump_dname_with_id(const knot_dname_t *dname, int fd,
* \param type Type of rdata.
* \param data Arguments to be propagated.
*/
-static void knot_rdata_dump_binary(knot_rdata_t *rdata,
- uint32_t type, int fd, int use_ids,
- uint8_t **stream, size_t *stream_size,
- crc_t *crc)
+static int knot_rdata_dump_binary(knot_rdata_t *rdata,
+ uint32_t type, int fd, int use_ids,
+ uint8_t *stream, size_t max_size,
+ size_t *written_bytes,
+ crc_t *crc)
{
+ if (rdata == NULL) {
+ dbg_zdump("zdump: dump_rdata: NULL rdata.\n");
+ return KNOT_EBADARG;
+ }
knot_rrtype_descriptor_t *desc =
knot_rrtype_descriptor_by_type(type);
assert(desc != NULL);
- dbg_zdump("Dumping type: %d\n", type);
-
if (desc->fixed_items) {
assert(desc->length == rdata->count);
}
-
+
/* Write rdata count. */
- /*!< \todo #1684 check the return value */
- write_wrapper(&(rdata->count),
- sizeof(rdata->count), 1, fd, stream, stream_size, crc);
+ if (!write_wrapper(&(rdata->count),
+ sizeof(rdata->count), 1, fd, stream, max_size,
+ written_bytes, crc)) {
+ dbg_zdump("zdump: dump_rdata: Could not write RDATA count.\n");
+ return KNOT_ERROR;
+ }
for (int i = 0; i < rdata->count; i++) {
if (&(rdata->items[i]) == NULL) {
- dbg_zdump("Item n. %d is not set!\n", i);
+ dbg_zdump("zdump: dump_rdata: "
+ "Item n. %d is not set!\n", i);
continue;
}
- dbg_zdump("Item n: %d\n", i);
+ dbg_zdump_detail("zdump: dump_rdata: Dumping item nr: %d\n", i);
if (desc->wireformat[i] == KNOT_RDATA_WF_COMPRESSED_DNAME ||
desc->wireformat[i] == KNOT_RDATA_WF_UNCOMPRESSED_DNAME ||
desc->wireformat[i] == KNOT_RDATA_WF_LITERAL_DNAME ) {
@@ -219,60 +279,105 @@ static void knot_rdata_dump_binary(knot_rdata_t *rdata,
assert(rdata->items[i].dname->id != 0);
uint32_t id = rdata->items[i].dname->id;
- /*!< \todo #1684 check the return value */
- write_wrapper(&id,
- sizeof(id), 1, fd, stream, stream_size,
- crc);
+ if (!write_wrapper(&id,
+ sizeof(id),
+ 1, fd, stream, max_size,
+ written_bytes, crc)) {
+ dbg_zdump("zdump: dump_rdata: Cannot "
+ "write dname ID.\n");
+ return KNOT_ERROR;
+ }
} else {
-// assert(rdata->items[i].dname->id != 0);
- dump_dname_with_id(rdata->items[i].dname,
- fd, stream,
- stream_size, crc);
+ int ret = dump_dname_with_id(
+ rdata->items[i].dname,
+ fd, stream,
+ max_size,
+ written_bytes,
+ crc);
+ if (ret != KNOT_EOK) {
+ dbg_zdump("zdump: dump_rdata: Cannot "
+ "dump dname.\n");
+ return ret;
+ }
}
/* Write in the zone bit */
+ /*! \todo Does not have to be so complex.
+ * Create extra variable. */
if (rdata->items[i].dname->node != NULL && !wildcard) {
- /*!< \todo #1684 check the return value */
- write_wrapper((uint8_t *)"\1",
- sizeof(uint8_t), 1, fd, stream,
- stream_size, crc);
+ if (!write_wrapper((uint8_t *)"\1",
+ sizeof(uint8_t), 1, fd,
+ stream, max_size,
+ written_bytes, crc)) {
+ dbg_zdump("zdump: dump_rdata: Cannot "
+ "write zone bit.\n");
+ return KNOT_ERROR;
+ }
} else {
- /*!< \todo #1684 check the return value */
- write_wrapper((uint8_t *)"\0", sizeof(uint8_t),
- 1, fd, stream, stream_size, crc);
+ if (!write_wrapper((uint8_t *)"\0",
+ sizeof(uint8_t),
+ 1, fd,
+ stream, max_size,
+ written_bytes, crc)) {
+ dbg_zdump("zdump: dump_rdata: Cannot "
+ "write zone bit.\n");
+ return KNOT_ERROR;
+ }
}
if (use_ids && wildcard) {
- /*!< \todo #1684 check the return value */
- write_wrapper((uint8_t *)"\1",
- sizeof(uint8_t), 1, fd, stream,
- stream_size, crc);
+ if (!write_wrapper((uint8_t *)"\1",
+ sizeof(uint8_t), 1,
+ fd, stream, max_size,
+ written_bytes, crc)) {
+ dbg_zdump("zdump: dump_rdata: Cannot "
+ "write wildcard bit.\n");
+ return KNOT_ERROR;
+ }
+
uint32_t wildcard_id = wildcard->id;
- /*!< \todo #1684 check the return value */
- write_wrapper(&wildcard_id,
- sizeof(wildcard_id), 1, fd, stream,
- stream_size, crc);
+ if (!write_wrapper(&wildcard_id,
+ sizeof(wildcard_id), 1,
+ fd, stream, max_size,
+ written_bytes, crc)) {
+ dbg_zdump("zdump: dump_rdata: Cannot "
+ "write wildcard ID.\n");
+ return KNOT_ERROR;
+ }
} else {
- /*!< \todo #1684 check the return value */
- write_wrapper((uint8_t *)"\0", sizeof(uint8_t),
- 1, fd, stream,
- stream_size, crc);
+ if (!write_wrapper((uint8_t *)"\0",
+ sizeof(uint8_t),
+ 1, fd, stream,
+ max_size, written_bytes,
+ crc)) {
+ dbg_zdump("zdump: dump_rdata: Cannot "
+ "write wildcard bit.\n");
+ return KNOT_ERROR;
+ }
}
-
} else {
- dbg_zdump("Writing raw data. Item nr.: %d\n",
+ dbg_zdump_detail("zdump: dump_rdata: "
+ "Writing raw data. Item nr.: %d\n",
i);
assert(rdata->items[i].raw_data != NULL);
- /*!< \todo #1684 check the return value */
- write_wrapper(rdata->items[i].raw_data,
- sizeof(uint8_t),
- rdata->items[i].raw_data[0] + 2, fd,
- stream, stream_size, crc);
-
- dbg_zdump("Written %d long raw data\n",
- rdata->items[i].raw_data[0]);
+ if (!write_wrapper(rdata->items[i].raw_data,
+ sizeof(uint8_t),
+ rdata->items[i].raw_data[0] + 2, fd,
+ stream, max_size,
+ written_bytes, crc)) {
+ dbg_zdump("zdump: dump_rdata: Cannot write raw "
+ "data.\n");
+ return KNOT_ERROR;
+ }
+
+ dbg_zdump_detail("zdump: dump_rdata: "
+ "Written %d long raw data.\n",
+ rdata->items[i].raw_data[0]);
}
}
+
+ dbg_zdump_verb("zdump: dump_rdata: RDATA dumped successfully.\n");
+ return KNOT_EOK;
}
/*!
@@ -280,28 +385,45 @@ static void knot_rdata_dump_binary(knot_rdata_t *rdata,
*
* \param rrsig RRSIG to be dumped.
* \param data Arguments to be propagated.
+ *
+ * \todo This whole function is obsolete. Change after 1.0.2 release.
*/
-static void knot_rrsig_set_dump_binary(knot_rrset_t *rrsig, int fd,
- int use_ids,
- uint8_t **stream, size_t *stream_size,
- crc_t *crc)
+static int knot_rrsig_set_dump_binary(knot_rrset_t *rrsig, int fd,
+ int use_ids,
+ uint8_t *stream, size_t max_size,
+ size_t *written_bytes, crc_t *crc)
{
+ if (rrsig == NULL) {
+ dbg_zdump("zdump: dump_rrsig: NULL RRSIG.\n");
+ return KNOT_EBADARG;
+ }
+
dbg_zdump_exec_detail(
char *name = knot_dname_to_str(knot_rrset_owner(rrsig));
- dbg_zdump("Dumping RRSIG \\w owner: %s\n",
- name);
+ dbg_zdump_detail("zdump: dump_rrsig: Dumping RRSIG \\w owner: %s.\n",
+ name);
free(name);
);
assert(rrsig->type == KNOT_RRTYPE_RRSIG);
assert(rrsig->rdata);
- /*!< \todo #1684 check the return value */
- write_wrapper(&rrsig->type, sizeof(rrsig->type), 1, fd,
- stream, stream_size, crc);
- write_wrapper(&rrsig->rclass, sizeof(rrsig->rclass), 1, fd,
- stream, stream_size, crc);
- write_wrapper(&rrsig->ttl, sizeof(rrsig->ttl), 1, fd,
- stream, stream_size, crc);
-
+ if (!write_wrapper(&rrsig->type, sizeof(rrsig->type), 1, fd,
+ stream, max_size, written_bytes, crc)) {
+ dbg_zdump("zdump: dump_rrsig: Cannot write type.\n");
+ return KNOT_ERROR;
+ }
+
+ if (!write_wrapper(&rrsig->rclass, sizeof(rrsig->rclass), 1, fd,
+ stream, max_size, written_bytes, crc)) {
+ dbg_zdump("zdump: dump_rrsig: Cannot write class.\n");
+ return KNOT_ERROR;
+ }
+
+ if (!write_wrapper(&rrsig->ttl, sizeof(rrsig->ttl), 1, fd,
+ stream, max_size, written_bytes, crc)) {
+ dbg_zdump("zdump: dump_rrsig: Cannot write TTL.\n");
+ return KNOT_ERROR;
+ }
+
uint32_t rdata_count = 1;
/* Calculate rrset rdata count. */
knot_rdata_t *tmp_rdata = rrsig->rdata;
@@ -309,18 +431,30 @@ dbg_zdump_exec_detail(
tmp_rdata = tmp_rdata->next;
rdata_count++;
}
+
+ if (!write_wrapper(&rdata_count, sizeof(rdata_count), 1, fd,
+ stream, max_size, written_bytes, crc)) {
+ dbg_zdump("zdump: dump_rrsig: Cannot write rdata count.\n");
+ return KNOT_ERROR;
+ }
- write_wrapper(&rdata_count, sizeof(rdata_count), 1, fd,
- stream, stream_size, crc);
+ dbg_zdump_verb("zdump: dump_rrsig: Static data dumped.\n");
tmp_rdata = rrsig->rdata;
while (tmp_rdata->next != rrsig->rdata) {
- knot_rdata_dump_binary(tmp_rdata, KNOT_RRTYPE_RRSIG, fd,
- use_ids, stream, stream_size, crc);
+ int ret = knot_rdata_dump_binary(tmp_rdata, KNOT_RRTYPE_RRSIG,
+ fd,
+ use_ids, stream, max_size,
+ written_bytes, crc);
+ if (ret != KNOT_EOK) {
+ dbg_zdump("zdump: rrsig_to_binary: Could not dump "
+ "rdata. Reason: %s.\n", knot_strerror(ret));
+ return ret;
+ }
tmp_rdata = tmp_rdata->next;
}
- knot_rdata_dump_binary(tmp_rdata, KNOT_RRTYPE_RRSIG, fd, use_ids,
- stream, stream_size, crc);
+ return knot_rdata_dump_binary(tmp_rdata, KNOT_RRTYPE_RRSIG, fd, use_ids,
+ stream, max_size, written_bytes, crc);
}
/*!
@@ -329,25 +463,52 @@ dbg_zdump_exec_detail(
* \param rrset RRSSet to be dumped.
* \param data Arguments to be propagated.
*/
-static void knot_rrset_dump_binary(const knot_rrset_t *rrset, int fd,
- int use_ids,
- uint8_t **stream, size_t *stream_size,
- crc_t *crc)
+static int knot_rrset_dump_binary(const knot_rrset_t *rrset, int fd,
+ int use_ids,
+ uint8_t *stream, size_t max_size,
+ size_t *written_bytes,
+ crc_t *crc)
{
- dbg_zdump_detail("zdump: rrset_dump_binary: Dumping rrset to fd=%d\n",
- fd);
-
+ if (rrset == NULL) {
+ dbg_zdump("zdump: dump_rrset: NULL RRSet.\n");
+ return KNOT_EBADARG;
+ }
+
+ dbg_zdump_exec_detail(
+ char *name = knot_dname_to_str(knot_rrset_owner(rrset));
+ dbg_zdump_detail("zdump: dump_rrset: "
+ "Dumping RRSet \\w owner: %s.\n",
+ name);
+ free(name);
+ );
+
if (!use_ids) {
- dump_dname_with_id(rrset->owner, fd, stream, stream_size, crc);
+ /*!< \todo IDs in changeset do no good. Change loading too. */
+ int ret = dump_dname_with_id(rrset->owner,
+ fd, stream, max_size,
+ written_bytes, crc);
+ if (ret != KNOT_EOK) {
+ dbg_zdump("zdump: rrset_dump_binary: Could not dump "
+ "RRSet's owner.\n");
+ return ret;
+ }
}
- /*!< \todo #1684 check the return value */
- write_wrapper(&rrset->type, sizeof(rrset->type), 1, fd,
- stream, stream_size, crc);
- write_wrapper(&rrset->rclass, sizeof(rrset->rclass), 1, fd,
- stream, stream_size, crc);
- write_wrapper(&rrset->ttl, sizeof(rrset->ttl), 1, fd,
- stream, stream_size, crc);
+ if (!write_wrapper(&rrset->type, sizeof(rrset->type), 1, fd,
+ stream, max_size, written_bytes, crc)) {
+ dbg_zdump("zdump: dump_rrset: Cannot write type.\n");
+ return KNOT_ERROR;
+ }
+ if (!write_wrapper(&rrset->rclass, sizeof(rrset->rclass), 1, fd,
+ stream, max_size, written_bytes, crc)) {
+ dbg_zdump("zdump: dump_rrset: Cannot write class.\n");
+ return KNOT_ERROR;
+ }
+ if (!write_wrapper(&rrset->ttl, sizeof(rrset->ttl), 1, fd,
+ stream, max_size, written_bytes, crc)) {
+ dbg_zdump("zdump: dump_rrset: Cannot write TTL.\n");
+ return KNOT_ERROR;
+ }
uint32_t rdata_count = 1;
uint8_t has_rrsig = rrset->rrsigs != NULL;
@@ -359,31 +520,54 @@ static void knot_rrset_dump_binary(const knot_rrset_t *rrset, int fd,
rdata_count++;
}
- write_wrapper(&rdata_count, sizeof(rdata_count), 1, fd,
- stream, stream_size, crc);
- write_wrapper(&has_rrsig, sizeof(has_rrsig), 1, fd,
- stream, stream_size, crc);
+ if (!write_wrapper(&rdata_count, sizeof(rdata_count), 1, fd,
+ stream, max_size, written_bytes, crc)) {
+ dbg_zdump("zdump: dump_rrset: Cannot write rdata count.\n");
+ return KNOT_ERROR;
+ }
- dbg_zdump_detail("zdump: rrset_dump_binary: Static data dumped.\n");
+ if (!write_wrapper(&has_rrsig, sizeof(has_rrsig), 1, fd,
+ stream, max_size, written_bytes, crc)) {
+ return KNOT_ERROR;
+ }
+
+ dbg_zdump_verb("zdump: rrset_dump_binary: Static data dumped.\n");
tmp_rdata = rrset->rdata;
while (tmp_rdata->next != rrset->rdata) {
- knot_rdata_dump_binary(tmp_rdata, rrset->type, fd, use_ids,
- stream, stream_size, crc);
+ int ret = knot_rdata_dump_binary(tmp_rdata, rrset->type,
+ fd, use_ids,
+ stream, max_size,
+ written_bytes, crc);
+ if (ret != KNOT_EOK) {
+ dbg_zdump("zdump: rrset_to_binary: Could not dump "
+ "rdata. Reason: %s.\n", knot_strerror(ret));
+ return ret;
+ }
tmp_rdata = tmp_rdata->next;
}
- knot_rdata_dump_binary(tmp_rdata, rrset->type, fd, use_ids,
- stream, stream_size, crc);
- dbg_zdump_detail("zdump: rrset_dump_binary: Rdata dumped.\n");
+ int ret = knot_rdata_dump_binary(tmp_rdata, rrset->type, fd, use_ids,
+ stream,
+ max_size, written_bytes, crc);
+ if (ret != KNOT_EOK) {
+ dbg_zdump("zdump: rrset_to_binary: Could not dump "
+ "rdata. Reason: %s.\n", knot_strerror(ret));
+ return ret;
+ }
+
+ dbg_zdump_verb("zdump: rrset_dump_binary: Rdata dumped.\n");
/* This is now obsolete, although I'd rather not use recursion - that
* would probably not work */
if (rrset->rrsigs != NULL) {
- knot_rrsig_set_dump_binary(rrset->rrsigs, fd, use_ids,
- stream, stream_size, crc);
+ return knot_rrsig_set_dump_binary(rrset->rrsigs, fd, use_ids,
+ stream,
+ max_size, written_bytes, crc);
+ } else {
+ return KNOT_EOK;
}
}
@@ -393,12 +577,15 @@ static void knot_rrset_dump_binary(const knot_rrset_t *rrset, int fd,
* \param node Node to dumped.
* \param data Arguments to be propagated.
*/
-static void knot_node_dump_binary(knot_node_t *node, int fd,
- uint8_t **stream, size_t *stream_size,
- crc_t *crc)
+static int knot_node_dump_binary(knot_node_t *node, int fd,
+ uint8_t *stream,
+ size_t max_size,
+ size_t *written_bytes,
+ crc_t *crc)
{
if (node == NULL) {
- return;
+ dbg_zdump("zdump: dump_node: NULL node.\n");
+ return KNOT_EBADARG;
}
/* first write dname */
@@ -407,61 +594,93 @@ static void knot_node_dump_binary(knot_node_t *node, int fd,
/* Write owner ID. */
dbg_zdump_exec_detail(
char *name = knot_dname_to_str(knot_node_owner(node));
- dbg_zdump("Dumping node owned by %s\n",
- name);
+ dbg_zdump_detail("zdump: dump_node: Dumping node owned by %s\n",
+ name);
free(name);
);
assert(node->owner->id != 0);
uint32_t owner_id = node->owner->id;
- /*!< \todo #1684 check the return value */
- write_wrapper(&owner_id, sizeof(owner_id), 1, fd, stream, stream_size,
- crc);
+ if (!write_wrapper(&owner_id, sizeof(owner_id), 1, fd, stream,
+ max_size, written_bytes, crc)) {
+ dbg_zdump("zdump: dump_node: Cannot write ID.\n");
+ return KNOT_ERROR;
+ }
+ /*!< \todo Fix after release. */
if (knot_node_parent(node) != NULL) {
uint32_t parent_id = knot_dname_id(
knot_node_owner(knot_node_parent(node)));
- write_wrapper(&parent_id, sizeof(parent_id), 1, fd,
- stream, stream_size, crc);
+ if (!write_wrapper(&parent_id, sizeof(parent_id), 1, fd,
+ stream, max_size, written_bytes, crc)) {
+ dbg_zdump("zdump: dump_node: Cannot write parent "
+ "ID.\n");
+ return KNOT_ERROR;
+ }
} else {
uint32_t parent_id = 0;
- write_wrapper(&parent_id, sizeof(parent_id), 1, fd,
- stream, stream_size, crc);
+ if (!write_wrapper(&parent_id, sizeof(parent_id), 1, fd,
+ stream, max_size, written_bytes, crc)) {
+ dbg_zdump("zdump: dump_node: Cannot write parent "
+ "ID.\n");
+ return KNOT_ERROR;
+ }
}
- write_wrapper(&(node->flags), sizeof(node->flags), 1, fd,
- stream, stream_size, crc);
-
- dbg_zdump("Written flags: %u\n", node->flags);
+ if (!write_wrapper(&(node->flags), sizeof(node->flags), 1, fd,
+ stream, max_size, written_bytes, crc)) {
+ dbg_zdump("zdump: dump_node: Cannot write node flags.\n");
+ return KNOT_ERROR;
+ }
if (knot_node_nsec3_node(node) != NULL) {
uint32_t nsec3_id =
knot_node_owner(knot_node_nsec3_node(node))->id;
- write_wrapper(&nsec3_id, sizeof(nsec3_id), 1, fd,
- stream, stream_size, crc);
- dbg_zdump("Written nsec3 node id: %u\n",
- knot_node_owner(knot_node_nsec3_node(node))->id);
+ if (!write_wrapper(&nsec3_id, sizeof(nsec3_id), 1, fd,
+ stream, max_size, written_bytes, crc)) {
+ dbg_zdump("zdump: dump_node: Cannot write NSEC3 ID.\n");
+ return KNOT_ERROR;
+ }
+
+ dbg_zdump_detail("Written nsec3 node id: %u\n",
+ knot_node_owner(
+ knot_node_nsec3_node(node))->id);
} else {
uint32_t nsec3_id = 0;
- write_wrapper(&nsec3_id, sizeof(nsec3_id), 1, fd,
- stream, stream_size, crc);
+ if (!write_wrapper(&nsec3_id, sizeof(nsec3_id), 1, fd,
+ stream, max_size, written_bytes, crc)) {
+ dbg_zdump("zdump: dump_node: Cannot write NSEC3 ID.\n");
+ return KNOT_ERROR;
+ }
}
/* Now we need (or do we?) count of rrsets to be read
* but that number is yet unknown */
uint16_t rrset_count = node->rrset_count;
- write_wrapper(&rrset_count, sizeof(rrset_count), 1, fd,
- stream, stream_size, crc);
+ if (!write_wrapper(&rrset_count, sizeof(rrset_count), 1, fd,
+ stream, max_size, written_bytes, crc)) {
+ dbg_zdump("zdump: dump_node: Cannot write RRSet count.\n");
+ return KNOT_ERROR;
+ }
const knot_rrset_t **node_rrsets = knot_node_rrsets(node);
for (int i = 0; i < rrset_count; i++)
{
- knot_rrset_dump_binary(node_rrsets[i], fd, 1,
- stream, stream_size, crc);
+ int ret = knot_rrset_dump_binary(node_rrsets[i], fd, 1,
+ stream, max_size,
+ written_bytes, crc);
+ if (ret != KNOT_EOK) {
+ dbg_zdump("zdump: dump_node: Could not dump RRSet. "
+ "Reason: %s.\n", knot_strerror(ret));
+ return ret;
+ }
}
free(node_rrsets);
+
+ dbg_zdump_verb("zdump: dump_node: Node dumped successfully.\n");
+ return KNOT_EOK;
}
int zone_is_secure(knot_zone_contents_t *zone)
@@ -483,17 +702,24 @@ static void dump_dname_from_tree(knot_dname_t *dname,
void *data)
{
arg_t *arg = (arg_t *)data;
+ if (arg->error_code != KNOT_EOK) {
+ dbg_zdump("zdump: dump_dname_from_tree: "
+ "Error occured previously.\n");
+ return;
+ }
+
int *fd_pointer = (int *)arg->arg1;
int fd = -1;
if (fd_pointer != NULL) {
fd = *fd_pointer;
} else {
dbg_zdump("zdump: dump_dname_from_tree: Bad fd.\n");
+ arg->error_code = KNOT_EBADARG;
return;
}
crc_t *crc = (crc_t*)arg->arg2;
- dump_dname_with_id(dname, fd, NULL, NULL, crc);
+ arg->error_code = dump_dname_with_id(dname, fd, NULL, 0, NULL, crc);
}
static int knot_dump_dname_table(const knot_dname_table_t *dname_table,
@@ -502,16 +728,21 @@ static int knot_dump_dname_table(const knot_dname_table_t *dname_table,
arg_t arg;
arg.arg1 = &fd;
arg.arg2 = crc;
+ arg.error_code = KNOT_EOK;
/* Go through the tree and dump each dname along with its ID. */
knot_dname_table_tree_inorder_apply(dname_table,
dump_dname_from_tree, &arg);
- return KNOT_EOK;
+ return arg.error_code;
}
static void save_node_from_tree(knot_node_t *node, void *data)
{
arg_t *arg = (arg_t *)data;
+ if (arg == NULL) {
+ return;
+ }
+
/* Increment node count */
(*((uint32_t *)(arg->arg1)))++;
/* Save the first node only */
@@ -524,13 +755,25 @@ static void save_node_from_tree(knot_node_t *node, void *data)
static void dump_node_to_file(knot_node_t *node, void *data)
{
arg_t *arg = (arg_t *)data;
+ if (arg == NULL) {
+ return;
+ }
+
+ if (arg->error_code != KNOT_EOK) {
+ dbg_zdump("zdump: dump_node_to_file: "
+ "Error occured previously.\n");
+ return;
+ }
+
int *fd_pointer = (int *)arg->arg1;
int fd = -1;
if (fd_pointer != NULL) {
fd = *fd_pointer;
}
- knot_node_dump_binary(node, fd, NULL, NULL, (crc_t *)arg->arg7);
+ arg->error_code =
+ knot_node_dump_binary(node,
+ fd, NULL, 0, NULL, (crc_t *)arg->arg7);
}
char *knot_zdump_crc_file(const char* filename)
@@ -553,6 +796,7 @@ int knot_zdump_binary(knot_zone_contents_t *zone, int fd,
crc_t *crc)
{
if (fd < 0 || sfilename == NULL) {
+ dbg_zdump("zdump: Bad arguments.\n");
return KNOT_EBADARG;
}
@@ -562,8 +806,9 @@ int knot_zdump_binary(knot_zone_contents_t *zone, int fd,
arguments.arg1 = &node_count;
arguments.arg2 = NULL;
- /* Count number of normal nodes. */
- knot_zone_contents_tree_apply_inorder(zone, save_node_from_tree, &arguments);
+ /* Count number of normal nodes. This cannot fail. */
+ knot_zone_contents_tree_apply_inorder(zone, save_node_from_tree,
+ &arguments);
/* arg1 is now count of normal nodes */
uint32_t normal_node_count = *((uint32_t *)arguments.arg1);
@@ -571,8 +816,9 @@ int knot_zdump_binary(knot_zone_contents_t *zone, int fd,
arguments.arg1 = &node_count;
arguments.arg2 = NULL;
- /* Count number of NSEC3 nodes. */
- knot_zone_contents_nsec3_apply_inorder(zone, save_node_from_tree, &arguments);
+ /* Count number of NSEC3 nodes. This cannot fail. */
+ knot_zone_contents_nsec3_apply_inorder(zone,
+ save_node_from_tree, &arguments);
uint32_t nsec3_node_count = *((uint32_t *)arguments.arg1);
/* arg2 is the first NSEC3 node - used in sem checks. */
/* arg3 is the last NSEC3 node - used in sem checks. */
@@ -616,74 +862,112 @@ int knot_zdump_binary(knot_zone_contents_t *zone, int fd,
/* Start writing header - magic bytes. */
static const uint8_t MAGIC[MAGIC_LENGTH] = MAGIC_BYTES;
- write_wrapper(&MAGIC, sizeof(uint8_t), MAGIC_LENGTH, fd, NULL, NULL,
- crc);
+ if (!write_wrapper(&MAGIC, sizeof(uint8_t), MAGIC_LENGTH,
+ fd, NULL, 0, NULL, crc)) {
+ dbg_zdump("zdump: Cannot write magic bytes.\n");
+ return KNOT_ERROR;
+ }
/* Write source file length. */
uint32_t sflen = strlen(sfilename) + 1;
- write_wrapper(&sflen, sizeof(uint32_t), 1, fd, NULL, NULL, crc);
+ if (!write_wrapper(&sflen, sizeof(uint32_t), 1, fd,
+ NULL, 0, NULL, crc)) {
+ dbg_zdump("zdump: Cannot write source file length.\n");
+ return KNOT_ERROR;
+ }
/* Write source file. */
- write_wrapper(sfilename, sflen, 1, fd, NULL, NULL, crc);
+ if (!write_wrapper(sfilename, sflen, 1, fd, NULL, 0, NULL, crc)) {
+ dbg_zdump("zdump: Cannot write source file name.\n");
+ return KNOT_ERROR;
+ }
/* Notice: End of header,
*/
/* Start writing compiled data. */
- write_wrapper(&normal_node_count, sizeof(normal_node_count), 1, fd,
- NULL, NULL, crc);
- write_wrapper(&nsec3_node_count, sizeof(nsec3_node_count), 1, fd,
- NULL, NULL, crc);
+ if (!write_wrapper(&normal_node_count, sizeof(normal_node_count), 1, fd,
+ NULL, 0, NULL, crc)) {
+ dbg_zdump("zdump: Cannot write node count.\n");
+ return KNOT_ERROR;
+ }
+
+ if (!write_wrapper(&nsec3_node_count, sizeof(nsec3_node_count), 1, fd,
+ NULL, 0, NULL, crc)) {
+ dbg_zdump("zdump: Cannot write NSEC3 node count.\n");
+ return KNOT_ERROR;
+ }
uint32_t auth_node_count = zone->node_count;
- write_wrapper(&auth_node_count,
- sizeof(auth_node_count), 1, fd, NULL, NULL, crc);
+ if (!write_wrapper(&auth_node_count,
+ sizeof(auth_node_count),
+ 1, fd, NULL, 0, NULL, crc)) {
+ dbg_zdump("zdump: Cannot write authoritative node count.\n");
+ return KNOT_ERROR;
+ }
/* Write total number of dnames */
assert(zone->dname_table);
uint32_t total_dnames = zone->dname_table->id_counter;
- write_wrapper(&total_dnames,
- sizeof(total_dnames), 1, fd, NULL, NULL, crc);
+ if (!write_wrapper(&total_dnames,
+ sizeof(total_dnames), 1, fd, NULL, 0, NULL, crc)) {
+ dbg_zdump("zdump: Cannot write dname count.\n");
+ return KNOT_ERROR;
+ }
/* Write dname table. */
if (knot_dump_dname_table(zone->dname_table, fd, crc)
!= KNOT_EOK) {
+ dbg_zdump("zdump: Cannot write dname table.\n");
return KNOT_ERROR;
}
arguments.arg1 = &fd;
arguments.arg3 = zone;
arguments.arg7 = crc;
+
+ arguments.error_code = KNOT_EOK;
/*!< \todo #1685 Stop traversal upon error. */
knot_zone_contents_tree_apply_inorder(zone, dump_node_to_file,
(void *)&arguments);
-
+
+ if (arguments.error_code != KNOT_EOK) {
+ dbg_zdump("zdump: Dump of normal tree failed. Reason: %s.\n",
+ knot_strerror(arguments.error_code));
+ return arguments.error_code;
+ }
+
+ arguments.error_code = KNOT_EOK;
knot_zone_contents_nsec3_apply_inorder(zone, dump_node_to_file,
(void *)&arguments);
+
+ if (arguments.error_code != KNOT_EOK) {
+ dbg_zdump("zdump: Dump of NSEC3 tree failed. Reason: %s.\n",
+ knot_strerror(arguments.error_code));
+ return arguments.error_code;
+ }
+
*crc = crc_finalize(*crc);
return KNOT_EOK;
}
-int knot_zdump_rrset_serialize(const knot_rrset_t *rrset, uint8_t **stream,
- size_t *size)
+int knot_zdump_rrset_serialize(const knot_rrset_t *rrset, uint8_t *stream,
+ size_t max_size, size_t *written_bytes)
{
- if (stream == NULL || *stream != NULL || rrset == NULL ||
- size == NULL) {
+ if (stream == NULL || rrset == NULL ||
+ written_bytes == NULL) {
dbg_zdump("zdump: rrset_serialize: Bad arguments.\n");
return KNOT_EBADARG;
}
-
- *size = 0;
- arg_t arguments;
- memset(&arguments, 0, sizeof(arg_t));
+ *written_bytes = 0;
+
/* This fd will signal functions to use streams. */
int fd = -1;
- knot_rrset_dump_binary(rrset, fd, 0, stream, size, NULL);
-
- return KNOT_EOK;
+ return knot_rrset_dump_binary(rrset, fd, 0, stream, max_size,
+ written_bytes, NULL);
}
int knot_zdump_dump(knot_zone_contents_t *zone, int fd, const char *sfilename,
diff --git a/src/knot/zone/zone-dump.h b/src/knot/zone/zone-dump.h
index 975b8e8..46e760e 100644
--- a/src/knot/zone/zone-dump.h
+++ b/src/knot/zone/zone-dump.h
@@ -62,29 +62,15 @@ int knot_zdump_binary(knot_zone_contents_t *zone, int fd,
*
* \param rrset RRSet to be serialized.
* \param stream Stream containing serialized RRSet.
- * \param size Length of created stream.
+ * \param max_size Maximum size of stream.
+ * \param bytes_written Actually written data.
*
* \retval KNOT_EOK on success.
* \retval KNOT_EBADARG if wrong arguments are supplied.
* \retval KNOT_ENOMEM on memory error.
*/
-int knot_zdump_rrset_serialize(const knot_rrset_t *rrset, uint8_t **stream,
- size_t *size);
-
-/*!
- * \brief Serializes RRSet into binary stream. Expects NULL pointer, memory
- * is handled inside function.
- *
- * \param rrset RRSet to be serialized.
- * \param stream Stream containing serialized RRSet.
- * \param size Length of created stream.
- *
- * \retval KNOT_EOK on success.
- * \retval KNOT_EBADARG if wrong arguments are supplied.
- * \retval KNOT_ENOMEM on memory error.
- */
-int knot_zdump_rrset_serialize(const knot_rrset_t *rrset, uint8_t **stream,
- size_t *size);
+int knot_zdump_rrset_serialize(const knot_rrset_t *rrset, uint8_t *stream,
+ size_t max_size, size_t *bytes_written);
/*!
* \brief Checks if zone uses DNSSEC and/or NSEC3
diff --git a/src/knot/zone/zone-load.c b/src/knot/zone/zone-load.c
index 69ea58f..cee138f 100644
--- a/src/knot/zone/zone-load.c
+++ b/src/knot/zone/zone-load.c
@@ -40,26 +40,14 @@
* \param y Second time_t value to be compared.
*
* \retval 0 when times are the some.
- * \retval 1 when y < x.
- * \retval -1 when x > y.
+ * \retval 1 when x > y.
+ * \retval -1 when x < y.
*/
static int timet_cmp(time_t x, time_t y)
{
- /* Calculate difference in the scale of seconds. */
- long diff = x - y;
-
- /* X and Y are equal. */
- if (diff == 0) {
- return 0;
- }
-
- /* X is newer. */
- if (diff > 0) {
- return 1;
- }
-
- /* Y is newer. */
- return -1;
+ if (x > y) return 1;
+ if (x < y) return -1;
+ return 0;
}
/*!
@@ -160,6 +148,9 @@ static void load_rdata_purge(knot_rdata_t *rdata,
static knot_dname_t *read_dname_with_id(FILE *f)
{
+ if (f == NULL) {
+ dbg_zload("zload: read_dname_id: NULL file.\n");
+ }
knot_dname_t *ret = knot_dname_new();
CHECK_ALLOC_LOG(ret, NULL);
@@ -167,16 +158,18 @@ static knot_dname_t *read_dname_with_id(FILE *f)
uint32_t dname_id = 0;
if (!fread_wrapper(&dname_id, sizeof(dname_id), 1, f)) {
knot_dname_release(ret);
+ dbg_zload("zload: read_dname_id: Cannot read dname ID.\n");
return NULL;
}
ret->id = dname_id;
- dbg_zload("loaded: dname id: %u\n", dname_id);
+ dbg_zload_detail("zload: read_dname_id: dname id: %u\n", dname_id);
/* Read size of dname. */
uint32_t dname_size = 0;
if (!fread_wrapper(&dname_size, sizeof(dname_size), 1, f)) {
knot_dname_release(ret);
+ dbg_zload("zload: read_dname_id: Cannot read dname size.\n");
return NULL;
}
ret->size = dname_size;
@@ -194,6 +187,7 @@ static knot_dname_t *read_dname_with_id(FILE *f)
if (!fread_wrapper(ret->name, sizeof(uint8_t), ret->size, f)) {
knot_dname_release(ret);
+ dbg_zload("zload: read_dname_id: Cannot read dname name.\n");
return NULL;
}
@@ -201,6 +195,8 @@ static knot_dname_t *read_dname_with_id(FILE *f)
uint16_t label_count = 0;
if (!fread_wrapper(&label_count, sizeof(label_count), 1, f)) {
knot_dname_release(ret);
+ dbg_zload("zload: read_dname_id: Cannot read "
+ "dname label count.\n");
return NULL;
}
@@ -216,11 +212,16 @@ static knot_dname_t *read_dname_with_id(FILE *f)
if (!fread_wrapper(ret->labels, sizeof(uint8_t), ret->label_count, f)) {
free(ret->name);
free(ret);
+ dbg_zload("zload: read_dname_id: Cannot read dname labels.\n");
return NULL;
}
- dbg_zload("loaded: %s (id: %d)\n", knot_dname_to_str(ret),
+dbg_zload_exec_detail(
+ char *name = knot_dname_to_str(ret);
+ dbg_zload_detail("zload: Loaded dname: %s (id: %d).\n", name,
ret->id);
+ free(name);
+);
return ret;
}
@@ -239,6 +240,7 @@ static knot_rdata_t *knot_load_rdata(uint16_t type, FILE *f,
{
knot_rdata_t *rdata = knot_rdata_new();
if (rdata == NULL) {
+ dbg_zload("zload: load_rdata: Cannot create new rdata.\n");
return NULL;
}
@@ -246,13 +248,13 @@ static knot_rdata_t *knot_load_rdata(uint16_t type, FILE *f,
knot_rrtype_descriptor_by_type(type);
assert(desc != NULL);
-
- /* First, should read rdata count. */
+ /* First we should read rdata count. */
uint32_t rdata_count = 0;
if(!fread_wrapper(&rdata_count, sizeof(rdata_count), 1, f)) {
knot_rdata_free(&rdata);
+ dbg_zload("zload: load_rdata: Cannot read rdata count.\n");
return NULL;
}
@@ -263,11 +265,11 @@ static knot_rdata_t *knot_load_rdata(uint16_t type, FILE *f,
assert(desc->length == rdata_count);
}
- uint16_t raw_data_length;
+ uint16_t raw_data_length = 0;
- dbg_zload("Reading %d items\n", rdata_count);
-
- dbg_zload("current type: %s\n", knot_rrtype_to_string(type));
+ dbg_zload_detail("zload: load_rdata: Reading %d items\n", rdata_count);
+ dbg_zload_detail("zload: load_rdata: Current type: %s\n",
+ knot_rrtype_to_string(type));
for (int i = 0; i < rdata_count; i++) {
if (desc->wireformat[i] == KNOT_RDATA_WF_COMPRESSED_DNAME ||
@@ -283,8 +285,12 @@ static knot_rdata_t *knot_load_rdata(uint16_t type, FILE *f,
uint8_t in_the_zone = 0;
if (use_ids) {
- if(!fread_wrapper(&dname_id, sizeof(dname_id), 1, f)) {
- load_rdata_purge(rdata, items, i, desc, type);
+ if(!fread_wrapper(&dname_id, sizeof(dname_id),
+ 1, f)) {
+ load_rdata_purge(rdata,
+ items, i, desc, type);
+ dbg_zload("zload: load_rdata: "
+ "Cannot read dname ID.\n");
return NULL;
}
@@ -298,12 +304,16 @@ static knot_rdata_t *knot_load_rdata(uint16_t type, FILE *f,
if(!fread_wrapper(&in_the_zone, sizeof(in_the_zone),
1, f)) {
load_rdata_purge(rdata, items, i, desc, type);
+ dbg_zload("zload: load_rdata: "
+ "Cannot read zone bit.\n");
return NULL;
}
if(!fread_wrapper(&has_wildcard, sizeof(uint8_t),
1, f)) {
load_rdata_purge(rdata, items, i, desc, type);
+ dbg_zload("zload: load_rdata: "
+ "Cannot read wildcard bit.\n");
return NULL;
}
@@ -312,11 +322,14 @@ static knot_rdata_t *knot_load_rdata(uint16_t type, FILE *f,
1, f)) {
load_rdata_purge(rdata, items,
i, desc, type);
+ dbg_zload("zload: load_rdata: "
+ "Cannot read wc ID.\n");
return NULL;
}
items[i].dname->node =
- id_array[dname_id]->node;
- } else if (use_ids && !in_the_zone) { /* destroy the node */
+ id_array[dname_id]->node;
+ } else if (use_ids && !in_the_zone) {
+ /* destroy the node */
if (id_array[dname_id]->node != NULL) {
knot_node_free(&id_array[dname_id]->
node, 0);
@@ -328,37 +341,51 @@ static knot_rdata_t *knot_load_rdata(uint16_t type, FILE *f,
if (!fread_wrapper(&raw_data_length,
sizeof(raw_data_length), 1, f)) {
load_rdata_purge(rdata, items, i, desc, type);
+ dbg_zload("zload: load_rdata: Cannot read "
+ "raw data length.\n");
return NULL;
}
/*!< \todo this is not proper fix, see #1678 */
items[i].raw_data = (uint16_t *)
malloc(sizeof(uint8_t) * (raw_data_length + 2));
+ if (items[i].raw_data == NULL) {
+ ERR_ALLOC_FAILED;
+ load_rdata_purge(rdata, items, i + 1, desc,
+ type);
+ return NULL;
+ }
items[i].raw_data[0] = raw_data_length;
- if (!fread_wrapper(items[i].raw_data + 1, sizeof(uint8_t),
+ if (!fread_wrapper(items[i].raw_data + 1,
+ sizeof(uint8_t),
raw_data_length, f)) {
- load_rdata_purge(rdata, items, i + 1, desc, type);
+ load_rdata_purge(rdata, items, i + 1, desc,
+ type);
+ dbg_zload("zload: load_rdata: Cannot read "
+ "raw data.\n");
return NULL;
}
- dbg_zload("read raw_data len %d\n", raw_data_length);
+ dbg_zload_detail("zload: load_rdata: Read raw_data "
+ "length=%d.\n",
+ raw_data_length);
}
}
/* Each item has refcount already incremented for saving in rdata. */
if (knot_rdata_set_items(rdata, items, rdata_count) != 0) {
- fprintf(stderr, "zoneload: Could not set items "
+ fprintf(stderr, "zload: read_rdata: Could not set items "
"when loading rdata.\n");
+ knot_rdata_deep_free(&rdata, type, 0);
+ return NULL;
}
free(items);
-
- dbg_zload("knot_load_rdata: all %d items read\n",
- desc->length);
-
assert(rdata->count == rdata_count);
-
- rdata->count = rdata_count;
+
+ dbg_zload_detail("zload: read_rdata: All %d items read "
+ "successfully.\n",
+ desc->length);
return rdata;
}
@@ -373,54 +400,77 @@ static knot_rdata_t *knot_load_rdata(uint16_t type, FILE *f,
static knot_rrset_t *knot_load_rrsig(FILE *f, knot_dname_t **id_array,
int use_ids)
{
- knot_rrset_t *rrsig;
+ if (f == NULL || id_array == NULL) {
+ dbg_zload("zload: load_rrsig: Bad arguments.\n");
+ return NULL;
+ }
+
+ knot_rrset_t *rrsig = NULL;
- uint16_t rrset_type;
- uint16_t rrset_class;
- uint32_t rrset_ttl;
+ uint16_t rrset_type = 0;
+ uint16_t rrset_class = 0;
+ uint32_t rrset_ttl = 0;
- uint32_t rdata_count;
+ uint32_t rdata_count = 0;
if (!fread_wrapper(&rrset_type, sizeof(rrset_type), 1, f)) {
+ dbg_zload("zload: load_rrsig: Cannot read type.\n");
return NULL;
}
if (rrset_type != KNOT_RRTYPE_RRSIG) {
- fprintf(stderr, "!! Error: rrsig has wrong type\n");
+ dbg_zload("zload: load_rrsig: RRSIG has wrong type,"
+ " probably data corruption.\n");
return NULL;
}
- dbg_zload("rrset type: %d\n", rrset_type);
+ dbg_zload_detail("zload: load_rrsig: RRSIG type: %d\n", rrset_type);
if (!fread_wrapper(&rrset_class, sizeof(rrset_class), 1, f)) {
+ dbg_zload("zload: load_rrsig: Cannot read class.\n");
return NULL;
}
- dbg_zload("rrset class %d\n", rrset_class);
+ dbg_zload_detail("zload: load_rrsig: Class=%d\n", rrset_class);
if (!fread_wrapper(&rrset_ttl, sizeof(rrset_ttl), 1, f)) {
+ dbg_zload("zload: load_rrsig: Cannot read TTL.\n");
return NULL;
}
- dbg_zload("rrset ttl %d\n", rrset_ttl);
+ dbg_zload_detail("zload: load_rrsig: TTL=%d\n", rrset_ttl);
if (!fread_wrapper(&rdata_count, sizeof(rdata_count), 1, f)) {
+ dbg_zload("zload: load_rrsig: Cannot read rdata count.\n");
return NULL;
}
rrsig = knot_rrset_new(NULL, rrset_type, rrset_class, rrset_ttl);
+ if (rrsig == NULL) {
+ dbg_zload("zload: load_rrsig: Cannot create new RRSIG.\n");
+ return NULL;
+ }
- knot_rdata_t *tmp_rdata;
+ knot_rdata_t *tmp_rdata = NULL;
- dbg_zload("loading %d rdata entries\n", rdata_count);
+ dbg_zload_detail("zload: load_rrsig: Loading %d rdata entries.\n",
+ rdata_count);
for (int i = 0; i < rdata_count; i++) {
tmp_rdata = knot_load_rdata(KNOT_RRTYPE_RRSIG, f,
id_array, use_ids);
if (tmp_rdata) {
- knot_rrset_add_rdata(rrsig, tmp_rdata);
+ int ret = knot_rrset_add_rdata(rrsig, tmp_rdata);
+ if (ret != KNOT_EOK) {
+ dbg_zload("zload: load_rrsig: Cannot "
+ "add RDATA\n.");
+ knot_rrset_deep_free(&rrsig, 0, 1, 1);
+ return NULL;
+ }
} else {
+ dbg_zload("zload: load_rrsig: Cannot load rdata.\n");
knot_rrset_deep_free(&rrsig, 0, 1, 1);
return NULL;
}
}
+ dbg_zload_detail("zload: load_rrsig: RRSIG loaded successfully.\n");
return rrsig;
}
@@ -446,55 +496,63 @@ static knot_rrset_t *knot_load_rrset(FILE *f, knot_dname_t **id_array,
knot_dname_t *owner = NULL;
if (!use_ids) {
- dbg_zload("Loading owner of new RRSet from wire.\n");
+ dbg_zload_detail("zload: load_rrset: "
+ "Loading owner of new RRSet from wire.\n");
owner = read_dname_with_id(f);
+ if (owner == NULL) {
+ dbg_zload("zload: load_rrset: Cannot load owner.\n");
+ return NULL;
+ }
}
if (!fread_wrapper(&rrset_type, sizeof(rrset_type), 1, f)) {
+ dbg_zload("zload: load_rrset: Cannot load RRSet type.\n");
if (!use_ids) {
knot_dname_free(&owner);
}
return NULL;
}
- dbg_zload("Zone load: rrset load: type: %u\n", rrset_type);
+
+ dbg_zload_detail("zload: load_rrset: Type=%u\n", rrset_type);
if (!fread_wrapper(&rrset_class, sizeof(rrset_class), 1, f)) {
+ dbg_zload("zload: load_rrset: Cannot load RRSet class.\n");
if (!use_ids) {
knot_dname_free(&owner);
}
return NULL;
}
- dbg_zload("Zone load: rrset class: type: %u\n", rrset_class);
+ dbg_zload_detail("zload: load_rrset: Class=%u\n", rrset_class);
if (!fread_wrapper(&rrset_ttl, sizeof(rrset_ttl), 1, f)) {
+ dbg_zload("zload: load_rrset: Cannot load RRSet TTL.\n");
if (!use_ids) {
knot_dname_free(&owner);
}
return NULL;
}
- dbg_zload("Zone load: rrset ttl: type: %u\n", rrset_ttl);
+ dbg_zload_detail("zload: load_rrset: TTL=%u\n", rrset_ttl);
if (!fread_wrapper(&rdata_count, sizeof(rdata_count), 1, f)) {
if (!use_ids) {
knot_dname_free(&owner);
}
return NULL;
}
- dbg_zload("Zone load: rrset load: rdata count: %u\n", rdata_count);
+ dbg_zload_detail("zload: load_rrset: rdata count=%u\n", rdata_count);
if (!fread_wrapper(&rrsig_count, sizeof(rrsig_count), 1, f)) {
if (!use_ids) {
knot_dname_free(&owner);
}
return NULL;
}
- dbg_zload("Zone load: rrset load: type: %u\n", rrset_type);
+ dbg_zload_detail("zload: load_rrset: RRSIG count=%u\n", rrsig_count);
dbg_zload_exec_detail(
char *name = knot_dname_to_str(owner);
- dbg_zload("Loading RRSet owned by: %s\n",
+ dbg_zload_detail("zload: load_rrset: Loading RRSet owned by: %s.\n",
name);
free(name);
);
rrset = knot_rrset_new(owner, rrset_type, rrset_class, rrset_ttl);
-
if (rrset == NULL) {
dbg_zload("zload: load_rrset: Could not create rrset.");
knot_dname_free(&owner);
@@ -507,7 +565,7 @@ dbg_zload_exec_detail(
owner = NULL;
}
- dbg_zload("RRSet type: %d\n", rrset->type);
+ dbg_zload_detail("zload: load_rrset: RRSet type=%d\n", rrset->type);
knot_rdata_t *tmp_rdata = NULL;
@@ -515,7 +573,13 @@ dbg_zload_exec_detail(
tmp_rdata = knot_load_rdata(rrset->type, f,
id_array, use_ids);
if (tmp_rdata) {
- knot_rrset_add_rdata(rrset, tmp_rdata);
+ int ret = knot_rrset_add_rdata(rrset, tmp_rdata);
+ if (ret != KNOT_EOK) {
+ dbg_zload("zload: load_rrset: Cannot add "
+ "RDATA.\n");
+ knot_rrset_deep_free(&rrset, 0, 1, 1);
+ return NULL;
+ }
} else {
knot_rrset_deep_free(&rrset, 0, 1, 1);
return NULL;
@@ -524,9 +588,15 @@ dbg_zload_exec_detail(
knot_rrset_t *tmp_rrsig = NULL;
- dbg_zload("Reading: %d RRSIGs\n", rrsig_count);
+ dbg_zload_detail("zload: load_rrset: Reading: %d RRSIGs.\n",
+ rrsig_count);
if (rrsig_count) {
tmp_rrsig = knot_load_rrsig(f, id_array, use_ids);
+ if (tmp_rrsig == NULL) {
+ dbg_zload("zload: load_rrset: Cannot load RRSIG.\n");
+ knot_rrset_deep_free(&rrset, 0, 1, 1);
+ return NULL;
+ }
if (!use_ids) {
knot_rrset_set_owner(tmp_rrsig, rrset->owner);
}
@@ -534,8 +604,8 @@ dbg_zload_exec_detail(
knot_rrset_set_rrsigs(rrset, tmp_rrsig);
- dbg_zload("Finished loading RRSet %p\n", rrset);
-
+ dbg_zload_detail("zload: load_rrset: Finished loading RRSet %p.\n",
+ rrset);
return rrset;
}
@@ -548,6 +618,10 @@ dbg_zload_exec_detail(
*/
static knot_node_t *knot_load_node(FILE *f, knot_dname_t **id_array)
{
+ if (f == NULL || id_array == NULL) {
+ dbg_zload("zload: load_node: Wrong parameters.\n");
+ return NULL;
+ }
uint8_t flags = 0;
knot_node_t *node = NULL;
uint32_t parent_id = 0;
@@ -557,45 +631,51 @@ static knot_node_t *knot_load_node(FILE *f, knot_dname_t **id_array)
/* At the beginning of node - just dname_id !!!.*/
if (!fread_wrapper(&dname_id, sizeof(dname_id), 1, f)) {
+ dbg_zload("zload: load_node: Cannot read owner ID.\n");
return NULL;
}
if (!fread_wrapper(&parent_id, sizeof(parent_id), 1, f)) {
+ dbg_zload("zload: load_node: Cannot read owner ID.\n");
return NULL;
}
if (!fread_wrapper(&flags, sizeof(flags), 1, f)) {
+ dbg_zload("zload: load_node: Cannot read node flags.\n");
return NULL;
}
if (!fread_wrapper(&nsec3_node_id, sizeof(nsec3_node_id), 1, f)) {
+ dbg_zload("zload: load_node: Cannot read NSEC3 node.\n");
return NULL;
}
if (!fread_wrapper(&rrset_count, sizeof(rrset_count), 1, f)) {
+ dbg_zload("zload: load_node: Cannot read rrset count.\n");
return NULL;
}
knot_dname_t *owner = id_array[dname_id];
- dbg_zload("Node owner id: %d\n", dname_id);
- dbg_zload("Node owned by: %s\n", knot_dname_to_str(owner));
- dbg_zload("Number of RRSets in a node: %d\n", rrset_count);
+ dbg_zload_detail("zload: load_node: Node owner id: %d.\n", dname_id);
+dbg_zload_exec_detail(
+ char *name = knot_dname_to_str(owner);
+ dbg_zload_detail("zload: load_node: Node owned by: %s.\n");
+ free(name);
+);
+ dbg_zload_detail("zload: load_node: Number of RRSets in a node: %d.\n",
+ rrset_count);
node = owner->node;
if (node == NULL) {
- fprintf(stderr, "zone: Could not create node.\n");
+ dbg_zload("zload: load_node: NULL node, cannot proceed.\n");
return NULL;
}
/* XXX can it be 0, ever? I think not. */
if (nsec3_node_id != 0) {
knot_node_set_nsec3_node(node, id_array[nsec3_node_id]->node);
- /* CLEANUP */
-// node->nsec3_node = id_array[nsec3_node_id]->node;
} else {
knot_node_set_nsec3_node(node, NULL);
- /* CLEANUP */
-// node->nsec3_node = NULL;
}
/* Retain new owner while releasing replaced owner. */
@@ -611,7 +691,7 @@ static knot_node_t *knot_load_node(FILE *f, knot_dname_t **id_array)
knot_node_set_parent(node, NULL);
}
- knot_rrset_t *tmp_rrset;
+ knot_rrset_t *tmp_rrset = NULL;
for (int i = 0; i < rrset_count; i++) {
if ((tmp_rrset = knot_load_rrset(f, id_array, 1)) == NULL) {
@@ -619,7 +699,7 @@ static knot_node_t *knot_load_node(FILE *f, knot_dname_t **id_array)
/*!< \todo #1686
* Refactor freeing, might not be enough.
*/
- fprintf(stderr, "zone: Could not load rrset.\n");
+ dbg_zload("zload: load_node: Cannot load RRSet.\n");
return NULL;
}
/* Retain new owner while releasing replaced owner. */
@@ -628,12 +708,13 @@ static knot_node_t *knot_load_node(FILE *f, knot_dname_t **id_array)
knot_rrset_set_owner(tmp_rrset->rrsigs, node->owner);
}
if (knot_node_add_rrset(node, tmp_rrset, 0) < 0) {
- fprintf(stderr, "zone: Could not add rrset.\n");
+ dbg_zload("zload: load_node: Cannot add RRSet "
+ "to node.\n");
return NULL;
}
}
assert(node != NULL);
- dbg_zload("Node loaded: %p\n", node);
+ dbg_zload_detail("zload: load_node: Node loaded: %p\n", node);
return node;
}
@@ -647,6 +728,10 @@ static knot_node_t *knot_load_node(FILE *f, knot_dname_t **id_array)
static void find_and_set_wildcard_child(knot_zone_contents_t *zone,
knot_node_t *node, int nsec3)
{
+ if (zone == NULL || node == NULL) {
+ dbg_zload("zload: set_wc: Bad arguments.\n");
+ return;
+ }
knot_dname_t *chopped = knot_dname_left_chop(node->owner);
knot_node_t *wildcard_parent;
if (!nsec3) {
@@ -708,7 +793,10 @@ static unsigned long calculate_crc(FILE *f)
unsigned char *chunk = malloc(sizeof(unsigned char) * chunk_size);
CHECK_ALLOC_LOG(chunk, 0);
while ((file_size - read_bytes) > chunk_size) {
- if (!fread_wrapper(chunk, sizeof(unsigned char), chunk_size, f)) {
+ if (!fread_wrapper(chunk,
+ sizeof(unsigned char), chunk_size, f)) {
+ dbg_zload("zload: calculate_crc: Failed to read "
+ "data chunk.\n");
free(chunk);
return 0;
}
@@ -720,6 +808,8 @@ static unsigned long calculate_crc(FILE *f)
/* Read the rest of the file */
if (!fread_wrapper(chunk, sizeof(unsigned char), file_size - read_bytes,
f)) {
+ dbg_zload("zload: calculate_crc: Failed to read "
+ "data remainder.\n");
free(chunk);
return 0;
}
@@ -737,6 +827,7 @@ int knot_zload_open(zloader_t **dst, const char *filename)
char crc_buf[65];
if (!dst || !filename) {
+ dbg_zload("zload: open: Bad arguments.\n");
return KNOT_EBADARG;
}
@@ -749,7 +840,7 @@ int knot_zload_open(zloader_t **dst, const char *filename)
if (unlikely(!f)) {
int reason = errno;
dbg_zload("knot_zload_open: failed to open '%s'\n",
- filename);
+ filename);
switch (reason) {
case EACCES: return KNOT_EACCES; break;
case ENOENT: return KNOT_ENOENT; break;
@@ -765,9 +856,11 @@ int knot_zload_open(zloader_t **dst, const char *filename)
/* Read CRC from filename.crc file */
char *crc_path =
- malloc(sizeof(char) * (strlen(filename) + 4 /* strlen(".crc") */ + 1));
+ malloc(sizeof(char) *
+ (strlen(filename) + 4 /* strlen(".crc") */ + 1));
if (unlikely(!crc_path)) {
fclose(f);
+ ERR_ALLOC_FAILED;
return KNOT_ENOMEM;
}
memcpy(crc_path, filename, strlen(filename));
@@ -891,43 +984,12 @@ static void cleanup_id_array(knot_dname_t **id_array,
free(id_array);
}
-//static knot_dname_table_t *create_dname_table(FILE *f, uint max_id)
-//{
-// if (f == NULL ) {
-// return NULL;
-// }
-
-// if (!fread_wrapper(&max_id, sizeof(max_id), 1, f)) {
-// return NULL;
-// }
-
-// knot_dname_table_t *dname_table = knot_dname_table_new();
-// if (dname_table == NULL) {
-// return NULL;
-// }
-
-// /* Create nodes containing dnames. */
-// for (uint i = 1; i < max_id; i++) {
-// knot_dname_t *loaded_dname = read_dname_with_id(f);
-// if (loaded_dname == NULL) {
-// knot_dname_table_deep_free(&dname_table);
-// return NULL;
-// }
-// if (knot_dname_table_add_dname(dname_table,
-// loaded_dname) != KNOT_EOK) {
-
-// }
-// }
-
-// return dname_table;
-//}
-
static knot_dname_table_t *create_dname_table_from_array(
knot_dname_t **array, uint max_id)
{
if (array == NULL) {
/* should I set errno or what ... ? */
- dbg_zload("No array passed\n");
+ dbg_zload("zload: create_dname_table: No array passed.\n");
return NULL;
}
@@ -941,19 +1003,28 @@ static knot_dname_table_t *create_dname_table_from_array(
assert(array[i]);
if (knot_dname_table_add_dname(ret,
array[i]) != KNOT_EOK) {
- dbg_zload("Could not add: %s\n",
- knot_dname_to_str(array[i]));
+dbg_zload_exec_detail(
+ char *name = knot_dname_to_str(array[i]);
+ dbg_zload_detail("zload: create_dname_table: "
+ "Could not add dname: %s.\n",
+ name);
+ free(name);
+);
+ dbg_zload("zload: create_dname_table: "
+ "Could not add dname.\n");
knot_dname_table_deep_free(&ret);
return NULL;
}
}
+ dbg_zload("zload: create_dname_table: Table loaded.\n");
return ret;
}
static knot_dname_t **create_dname_array(FILE *f, uint max_id)
{
if (f == NULL) {
+ dbg_zload("zload: create_dname_array: Wrong arguments.\n");
return NULL;
}
@@ -964,23 +1035,24 @@ static knot_dname_t **create_dname_array(FILE *f, uint max_id)
return NULL;
}
- memset(array, 0, sizeof(knot_dname_t *) * (max_id + 1));
+ memset(array, 0, sizeof(knot_dname_t *) * (max_id + 1));
for (uint i = 0; i < max_id - 1; i++) {
knot_dname_t *read_dname = read_dname_with_id(f);
if (read_dname == NULL) {
+ dbg_zload("zload: create_dname_array: "
+ "Cannot read dname.\n" );
cleanup_id_array(array, 0, i);
return NULL;
}
if (read_dname->id < max_id) {
-
/* Create new node from dname. */
read_dname->node = knot_node_new(read_dname, NULL, 0);
-
if (read_dname->node == NULL) {
- ERR_ALLOC_FAILED;
-
+ dbg_zload("zload: create_dname_array: "
+ "Cannot create new node "
+ "from dname.\n");
/* Release read dname. */
knot_dname_release(read_dname);
cleanup_id_array(array, 0, i);
@@ -991,21 +1063,24 @@ static knot_dname_t **create_dname_array(FILE *f, uint max_id)
array[read_dname->id] = read_dname;
} else {
/* Release read dname. */
+ dbg_zload("zload: create_dname_array: "
+ "dname id is out of range.\n");
knot_dname_release(read_dname);
cleanup_id_array(array, 0, i);
return NULL;
}
}
-
+
+ dbg_zload("zload: create_dname_array: Array created.\n");
return array;
}
knot_zone_t *knot_zload_load(zloader_t *loader)
{
- dbg_zload("Loading zone, loader: %p\n", loader);
+ dbg_zload("zload: load: Loading zone, loader: %p.\n", loader);
if (!loader) {
- dbg_zload("NULL loader!\n");
+ dbg_zload("zload: load: NULL loader!\n");
return NULL;
}
@@ -1020,22 +1095,24 @@ knot_zone_t *knot_zload_load(zloader_t *loader)
uint32_t auth_node_count;
if (!fread_wrapper(&node_count, sizeof(node_count), 1, f)) {
- dbg_zload("wrong read!\n");
+ dbg_zload("zload: load: Cannot read node count!\n");
return NULL;
}
if (!fread_wrapper(&nsec3_node_count, sizeof(nsec3_node_count), 1, f)) {
- dbg_zload("wrong read!\n");
+ dbg_zload("zload: load: Cannot read NSEC3 node count!\n");
return NULL;
}
if (!fread_wrapper(&auth_node_count,
sizeof(auth_node_count), 1, f)) {
- dbg_zload("wrong read!\n");
+ dbg_zload("zload: load: Cannot read authoritative "
+ "node count!\n");
return NULL;
}
- dbg_zload("authoritative nodes: %u\n", auth_node_count);
-
- dbg_zload("loading %u nodes\n", node_count);
+
+ dbg_zload_verb("zload: load: Authoritative nodes: %u.\n",
+ auth_node_count);
+ dbg_zload_verb("zload: load: :oading %u nodes.\n", node_count);
uint32_t total_dnames = 0;
/* First, read number of dnames in dname table. */
@@ -1043,18 +1120,19 @@ knot_zone_t *knot_zload_load(zloader_t *loader)
return NULL;
}
- dbg_zload("total dname count: %d\n", total_dnames);
+ dbg_zload_verb("zload: load: Total dname count: %d.\n", total_dnames);
/* Create id array. */
knot_dname_t **id_array = create_dname_array(f, total_dnames);
if (id_array == NULL) {
+ dbg_zload("zload: load: Cannot create ID array.\n");
return NULL;
}
knot_dname_table_t *dname_table =
create_dname_table_from_array(id_array, total_dnames);
if (dname_table == NULL) {
- ERR_ALLOC_FAILED;
+ dbg_zload("zload: load: Cannot create ID array.\n");
cleanup_id_array(id_array, 1, total_dnames);
free(dname_table);
return NULL;
@@ -1071,13 +1149,14 @@ knot_zone_t *knot_zload_load(zloader_t *loader)
return NULL;
}
- dbg_zload("Apex node loaded: %p\n", apex);
+ dbg_zload_verb("zload: load: Apex node loaded: %p.\n", apex);
knot_zone_t *zone = knot_zone_new(apex, auth_node_count, 0);
if (zone == NULL) {
cleanup_id_array(id_array, 1,
node_count + nsec3_node_count + 1);
- dbg_zload("Failed to create new zone from apex!\n");
+ dbg_zload("zload: load: Failed to create new "
+ "zone from apex!\n");
knot_node_free(&apex, 0);
free(dname_table);
return NULL;
@@ -1090,19 +1169,21 @@ knot_zone_t *knot_zload_load(zloader_t *loader)
contents->dname_table = dname_table;
knot_node_set_previous(apex, NULL);
-
knot_node_t *last_node = 0;
-
last_node = apex;
for (uint i = 1; i < node_count; i++) {
tmp_node = knot_load_node(f, id_array);
-
if (tmp_node != NULL) {
if (knot_zone_contents_add_node(contents, tmp_node,
0, 0, 0) != 0) {
- fprintf(stderr, "!! cannot add node\n");
- continue;
+ cleanup_id_array(id_array, 1,
+ node_count +
+ nsec3_node_count + 1);
+ knot_zone_deep_free(&zone, 0);
+ dbg_zload("zload: load: Failed to add node "
+ "to zone.\n");
+ return NULL;
}
if (knot_dname_is_wildcard(tmp_node->owner)) {
find_and_set_wildcard_child(contents,
@@ -1118,8 +1199,12 @@ knot_zone_t *knot_zload_load(zloader_t *loader)
}
} else {
- fprintf(stderr, "zone: Node error (in %s).\n",
+ dbg_zload("zload: load: Node error (in %s).\n",
loader->filename);
+ knot_zone_deep_free(&zone, 0);
+ cleanup_id_array(id_array, node_count + 1,
+ nsec3_node_count + 1);
+ return NULL;
}
}
@@ -1128,7 +1213,8 @@ knot_zone_t *knot_zload_load(zloader_t *loader)
knot_node_set_previous(knot_zone_contents_get_apex(contents),
last_node);
- dbg_zload("loading %u nsec3 nodes\n", nsec3_node_count);
+ dbg_zload_detail("zload: load: Loading %u nsec3 nodes\n",
+ nsec3_node_count);
knot_node_t *nsec3_first = NULL;
@@ -1137,10 +1223,12 @@ knot_zone_t *knot_zload_load(zloader_t *loader)
assert(nsec3_first != NULL);
- if (knot_zone_contents_add_nsec3_node(contents, nsec3_first, 0, 0, 0)
+ if (knot_zone_contents_add_nsec3_node(contents, nsec3_first,
+ 0, 0, 0)
!= 0) {
- fprintf(stderr, "!! cannot add first nsec3 node, "
- "exiting.\n");
+ dbg_zload(stderr, "zload: load: "
+ "cannot add first nsec3 node, "
+ "exiting.\n");
knot_zone_deep_free(&zone, 0);
cleanup_id_array(id_array, node_count + 1,
nsec3_node_count + 1);
@@ -1157,8 +1245,12 @@ knot_zone_t *knot_zload_load(zloader_t *loader)
if (tmp_node != NULL) {
if (knot_zone_contents_add_nsec3_node(contents,
tmp_node, 0, 0, 0) != 0) {
- fprintf(stderr, "!! cannot add nsec3 node\n");
- continue;
+ dbg_zload("zload: load: Cannot add "
+ "NSEC3 node.\n");
+ knot_zone_deep_free(&zone, 0);
+ cleanup_id_array(id_array, node_count + 1,
+ nsec3_node_count + 1);
+ return NULL;
}
knot_node_set_previous(tmp_node, last_node);
@@ -1182,8 +1274,7 @@ knot_zone_t *knot_zload_load(zloader_t *loader)
}
free(id_array);
- dbg_zload("zone loaded, returning: %p\n", zone);
-
+ dbg_zload("zload: load: Zone loaded, returning: %p,\n", zone);
return zone;
}
@@ -1231,6 +1322,7 @@ int knot_zload_rrset_deserialize(knot_rrset_t **rrset,
uint8_t *stream, size_t *size)
{
if (stream == NULL || size == 0) {
+ dbg_zload("zload: rrset_deserialize: Bad arguments.\n");
return KNOT_EBADARG;
}
@@ -1240,8 +1332,8 @@ int knot_zload_rrset_deserialize(knot_rrset_t **rrset,
knot_zload_stream_remaining = knot_zload_stream_size = *size;
knot_rrset_t *ret = knot_load_rrset(NULL, NULL, 0);
-
if (ret == NULL) {
+ dbg_zload("zload: rrset_deserialize: Cannot load RRSet.\n");
knot_zload_stream = NULL;
knot_zload_stream_remaining = 0;
knot_zload_stream_size = 0;
@@ -1254,7 +1346,9 @@ int knot_zload_rrset_deserialize(knot_rrset_t **rrset,
knot_zload_stream = NULL;
knot_zload_stream_remaining = 0;
knot_zload_stream_size = 0;
-
+
+ dbg_zload_detail("zload: rrset_deserialize: RRSet deserialized "
+ "successfully.\n");
return KNOT_EOK;
}
diff --git a/src/libknot/dname.c b/src/libknot/dname.c
index 0ab3d11..7a6ea5a 100644
--- a/src/libknot/dname.c
+++ b/src/libknot/dname.c
@@ -163,8 +163,7 @@ static int knot_dname_str_to_wire(const char *name, uint size,
return -1;
}
- dbg_dname("Allocated space for wire format of dname: %p\n",
- wire);
+ dbg_dname("Allocated space for wire format of dname: %p\n", wire);
if (root) {
*wire = '\0';
@@ -399,13 +398,22 @@ knot_dname_t *knot_dname_new_from_str(const char *name, uint size,
return NULL;
}
- knot_dname_str_to_wire(name, size, dname);
- dbg_dname("Created dname with size: %d\n", dname->size);
- dbg_dname("Label offsets: ");
+ /*! \todo The function should return error codes. */
+ int ret = knot_dname_str_to_wire(name, size, dname);
+ if (ret != 0) {
+ dbg_dname("Failed to create domain name from string.\n");
+ knot_dname_free(&dname);
+ return NULL;
+ }
+
+dbg_dname_exec_verb(
+ dbg_dname_verb("Created dname with size: %d\n", dname->size);
+ dbg_dname_verb("Label offsets: ");
for (int i = 0; i < dname->label_count; ++i) {
- dbg_dname("%d, ", dname->labels[i]);
+ dbg_dname_verb("%d, ", dname->labels[i]);
}
- dbg_dname("\n");
+ dbg_dname_verb("\n");
+);
if (dname->size <= 0) {
dbg_dname("Could not parse domain name "
@@ -467,6 +475,7 @@ knot_dname_t *knot_dname_new_from_wire(const uint8_t *name, uint size,
dname->size = size;
if (knot_dname_find_labels(dname, 1) != 0) {
+ dbg_dname("Could not find labels in dname (new from wire).\n");
knot_dname_free(&dname);
return NULL;
}
@@ -567,6 +576,7 @@ knot_dname_t *knot_dname_parse_from_wire(const uint8_t *wire,
memcpy(dname->name, name, i + 1);
dname->size = i + 1;
+ /*! \todo Why l + 1 ?? */
dname->labels = (uint8_t *)malloc((l + 1) * sizeof(uint8_t));
if (dname->labels == NULL) {
ERR_ALLOC_FAILED;
@@ -603,8 +613,35 @@ int knot_dname_from_wire(const uint8_t *name, uint size,
knot_dname_t *knot_dname_deep_copy(const knot_dname_t *dname)
{
- return knot_dname_new_from_wire(dname->name, dname->size,
- dname->node);
+ //return knot_dname_new_from_wire(dname->name, dname->size, dname->node);
+ /* dname_new_from_wire() does not accept non-FQDN dnames, so we
+ * do the copy by hand. It's faster anyway */
+
+ knot_dname_t *copy = knot_dname_new();
+ CHECK_ALLOC(copy, NULL);
+
+ copy->labels = (uint8_t *)(malloc(dname->label_count));
+
+ if (copy->labels == NULL) {
+ knot_dname_free(&copy);
+ return NULL;
+ }
+
+ copy->name = (uint8_t *)(malloc(dname->size));
+ if (copy->name == NULL) {
+ knot_dname_free(&copy);
+ return NULL;
+ }
+
+ memcpy(copy->labels, dname->labels, dname->label_count);
+ copy->label_count = dname->label_count;
+
+ memcpy(copy->name, dname->name, dname->size);
+ copy->size = dname->size;
+
+ copy->node = dname->node;
+
+ return copy;
}
/*----------------------------------------------------------------------------*/
diff --git a/src/libknot/dname.h b/src/libknot/dname.h
index 5a182ae..473bca7 100644
--- a/src/libknot/dname.h
+++ b/src/libknot/dname.h
@@ -116,6 +116,9 @@ knot_dname_t *knot_dname_new_from_str(const char *name, unsigned int size,
* e.g. to knot_dname_to_str() may result in crash. Decide whether it
* is OK to retain this and check the data in other functions before
* calling this one, or if it should verify the given data.
+ *
+ * \warning Actually, right now this function does not accept non-FQDN dnames.
+ * For some reason there is a check for this.
*/
knot_dname_t *knot_dname_new_from_wire(const uint8_t *name,
unsigned int size,
diff --git a/src/libknot/hash/cuckoo-hash-table.c b/src/libknot/hash/cuckoo-hash-table.c
index 831aef8..50a7a0f 100644
--- a/src/libknot/hash/cuckoo-hash-table.c
+++ b/src/libknot/hash/cuckoo-hash-table.c
@@ -821,17 +821,19 @@ void ck_destroy_table(ck_hash_table_t **table, void (*dtor_value)(void *value),
while (item != NULL) {
// disconnect the item
(*table)->stash = item->next;
- /*! \todo Investigate this. */
- assert(item->item != NULL);
- if (dtor_value) {
- dtor_value(item->item->value);
- }
- if (delete_key) {
- free((void *)item->item->key);
+ /*! \todo Check item semantics. (#1688) */
+ if (item->item != NULL) {
+ if (dtor_value) {
+ dtor_value(item->item->value);
+ }
+ if (delete_key) {
+ free((void *)item->item->key);
+ }
+
+ free((void *)item->item);
}
- free((void *)item->item);
free(item);
item = (*table)->stash;
}
diff --git a/src/libknot/nameserver/name-server.c b/src/libknot/nameserver/name-server.c
index dea16ec..e1ccdd4 100644
--- a/src/libknot/nameserver/name-server.c
+++ b/src/libknot/nameserver/name-server.c
@@ -646,6 +646,8 @@ static int ns_put_authority_soa(const knot_zone_contents_t *zone,
knot_rrset_set_ttl(soa_copy, min);
soa_rrset = soa_copy;
+ /* Need to add it as temporary, so it get's freed. */
+ knot_packet_add_tmp_rrset(resp, soa_copy);
}
assert(soa_rrset != NULL);
diff --git a/src/libknot/nameserver/name-server.h b/src/libknot/nameserver/name-server.h
index 1ae309c..42fa0f2 100644
--- a/src/libknot/nameserver/name-server.h
+++ b/src/libknot/nameserver/name-server.h
@@ -87,6 +87,7 @@ typedef struct knot_ns_xfr {
knot_rcode_t rcode;
xfr_callback_t send;
int session;
+ int session_closed;
/*!
* XFR-out: Output buffer.
diff --git a/src/libknot/updates/xfr-in.c b/src/libknot/updates/xfr-in.c
index 75d7fd7..4874ccd 100644
--- a/src/libknot/updates/xfr-in.c
+++ b/src/libknot/updates/xfr-in.c
@@ -1374,13 +1374,20 @@ static int xfrin_changes_check_rdata(knot_rdata_t ***rdatas, uint **types,
static void xfrin_changes_add_rdata(knot_rdata_t **rdatas, uint *types,
int *count, knot_rdata_t *rdata, uint type)
{
- dbg_xfrin_detail("Adding RDATA to new RDATA list: %p\n", rdata);
+ dbg_xfrin_detail("Adding RDATA to RDATA list: %p\n", rdata);
+
+ if (rdata == NULL) {
+ return;
+ }
dbg_xfrin_exec_detail(
// try to find the first RDATA in the given list
for (int i = 0; i < *count; ++i) {
knot_rdata_t *r = rdatas[i];
- while (r->next != rdatas[i]) {
+ if (r == NULL) {
+ continue;
+ }
+ while (r != NULL && r->next != rdatas[i]) {
if (r == rdata) {
dbg_xfrin_detail("Found same RDATA: %p\n", rdata);
knot_rdata_dump(rdata, type, 0);
@@ -1454,6 +1461,7 @@ static knot_rdata_t *xfrin_remove_rdata(knot_rrset_t *from,
static int xfrin_copy_old_rrset(knot_rrset_t *old, knot_rrset_t **copy,
knot_changes_t *changes)
{
+ dbg_xfrin("Copying old RRSet: %p\n", old);
// create new RRSet by copying the old one
// int ret = knot_rrset_shallow_copy(old, copy);
int ret = knot_rrset_deep_copy(old, copy);
@@ -1486,6 +1494,7 @@ static int xfrin_copy_old_rrset(knot_rrset_t *old, knot_rrset_t **copy,
changes->new_rrsets[changes->new_rrsets_count++] = *copy;
+ dbg_xfrin_verb("Adding RDATA from the RRSet copy to new RDATA list.\n");
xfrin_changes_add_rdata(changes->new_rdata, changes->new_rdata_types,
&changes->new_rdata_count,
knot_rrset_get_rdata(*copy),
@@ -1495,6 +1504,8 @@ static int xfrin_copy_old_rrset(knot_rrset_t *old, knot_rrset_t **copy,
assert(old->rrsigs != NULL);
changes->new_rrsets[changes->new_rrsets_count++] =
(*copy)->rrsigs;
+ dbg_xfrin_verb("Adding RDATA from RRSIG of the RRSet copy to "
+ "new RDATA list.\n");
xfrin_changes_add_rdata(changes->new_rdata,
changes->new_rdata_types,
&changes->new_rdata_count,
@@ -1523,6 +1534,7 @@ static int xfrin_copy_old_rrset(knot_rrset_t *old, knot_rrset_t **copy,
changes->old_rrsets[changes->old_rrsets_count++] = old;
+ dbg_xfrin_verb("Adding RDATA from old RRSet to old RDATA list.\n");
xfrin_changes_add_rdata(changes->old_rdata, changes->old_rdata_types,
&changes->old_rdata_count, old->rdata,
knot_rrset_type(old));
@@ -1531,6 +1543,8 @@ static int xfrin_copy_old_rrset(knot_rrset_t *old, knot_rrset_t **copy,
assert(old->rrsigs != NULL);
changes->old_rrsets[changes->old_rrsets_count++] = old->rrsigs;
+ dbg_xfrin_verb("Adding RDATA from RRSIG of the old RRSet to "
+ "old RDATA list.\n");
xfrin_changes_add_rdata(changes->old_rdata,
changes->old_rdata_types,
&changes->old_rdata_count,
@@ -1546,8 +1560,18 @@ static int xfrin_copy_old_rrset(knot_rrset_t *old, knot_rrset_t **copy,
static int xfrin_copy_rrset(knot_node_t *node, knot_rr_type_t type,
knot_rrset_t **rrset, knot_changes_t *changes)
{
+dbg_xfrin_exec_verb(
+ char *name = knot_dname_to_str(knot_node_owner(node));
+ dbg_xfrin_verb("Removing RRSet of type %s from node %s (%p)\n",
+ knot_rrtype_to_string(type), name, node);
+ free(name);
+);
knot_rrset_t *old = knot_node_remove_rrset(node, type);
+ dbg_xfrin_verb("Removed RRSet: %p\n", old);
+ dbg_xfrin_detail("Other RRSet of the same type in the node: %p\n",
+ knot_node_rrset(node, type));
+
if (old == NULL) {
dbg_xfrin("RRSet not found for RR to be removed.\n");
return 1;
@@ -1558,7 +1582,7 @@ static int xfrin_copy_rrset(knot_node_t *node, knot_rr_type_t type,
return ret;
}
- dbg_xfrin_detail("Copied old rrset %p to new %p.\n", old, *rrset);
+ dbg_xfrin_verb("Copied old rrset %p to new %p.\n", old, *rrset);
// replace the RRSet in the node copy by the new one
ret = knot_node_add_rrset(node, *rrset, 0);
@@ -1601,6 +1625,7 @@ static int xfrin_apply_remove_rrsigs(knot_changes_t *changes,
knot_rrset_rdata(remove));
// copy the rrset
+ dbg_xfrin_verb("Copying RRSet that carries the RRSIGs.\n");
ret = xfrin_copy_rrset(node, type, rrset, changes);
if (ret != KNOT_EOK) {
dbg_xfrin("Failed to copy rrset from changeset.\n");
@@ -1615,10 +1640,12 @@ static int xfrin_apply_remove_rrsigs(knot_changes_t *changes,
// this RRSet should be the already copied RRSet so we may
// update it right away
/*! \todo Does this case even occur? */
+ dbg_xfrin_verb("Using RRSet from previous iteration.\n");
}
// get the old rrsigs
knot_rrset_t *old = knot_rrset_get_rrsigs(*rrset);
+ dbg_xfrin_verb("Old RRSIGs from RRSet: %p\n", old);
if (old == NULL) {
return 1;
}
@@ -1630,8 +1657,10 @@ static int xfrin_apply_remove_rrsigs(knot_changes_t *changes,
if (ret != KNOT_EOK) {
return ret;
}
+ dbg_xfrin_verb("Copied RRSIGs: %p\n", rrsigs);
} else {
rrsigs = old;
+ dbg_xfrin_verb("Using old RRSIGs: %p\n", rrsigs);
}
// set the RRSIGs to the new RRSet copy
@@ -1935,14 +1964,22 @@ static int xfrin_apply_add_normal(knot_changes_t *changes,
dbg_xfrin("applying rrset:\n");
knot_rrset_dump(add, 0);
- if (!*rrset
- || knot_dname_compare(knot_rrset_owner(*rrset),
- knot_node_owner(node)) != 0
- || knot_rrset_type(*rrset)
- != knot_rrset_type(add)) {
- dbg_xfrin("Removing rrset!\n");
- *rrset = knot_node_remove_rrset(node, knot_rrset_type(add));
- }
+ /*! \note Reusing RRSet from previous function caused it not to be
+ * removed from the node.
+ * Maybe modification of the code would allow reusing the RRSet
+ * as in apply_add_rrsigs() - the RRSet should not be copied
+ * in such case.
+ */
+// if (!*rrset
+// || knot_dname_compare(knot_rrset_owner(*rrset),
+// knot_node_owner(node)) != 0
+// || knot_rrset_type(*rrset)
+// != knot_rrset_type(add)) {
+// dbg_xfrin("Removing rrset!\n");
+// *rrset = knot_node_remove_rrset(node, knot_rrset_type(add));
+// }
+
+ *rrset = knot_node_remove_rrset(node, knot_rrset_type(add));
dbg_xfrin("Removed RRSet: \n");
knot_rrset_dump(*rrset, 1);
@@ -1992,6 +2029,8 @@ dbg_xfrin_exec(
return ret;
}
+ dbg_xfrin("Copied RRSet: %p\n", *rrset);
+
// dbg_xfrin("After copy: Found RRSet with owner %s, type %s\n",
// knot_dname_to_str((*rrset)->owner),
// knot_rrtype_to_string(knot_rrset_type(*rrset)));
@@ -2007,11 +2046,13 @@ dbg_xfrin_exec(
*
* TODO: add the 'add' rrset to list of old RRSets?
*/
- dbg_xfrin("Merging RRSets with owners: %s %s types: %d %d\n",
- (*rrset)->owner->name, add->owner->name, (*rrset)->type,
- add->type);
+ dbg_xfrin("Merging RRSets with owners: %s, %s types: %s, %s\n",
+ (*rrset)->owner->name, add->owner->name,
+ knot_rrtype_to_string((*rrset)->type),
+ knot_rrtype_to_string(add->type));
dbg_xfrin_detail("RDATA in RRSet1: %p, RDATA in RRSet2: %p\n",
(*rrset)->rdata, add->rdata);
+
ret = knot_rrset_merge((void **)rrset, (void **)&add);
if (ret != KNOT_EOK) {
dbg_xfrin("Failed to merge changeset RRSet to copy.\n");
@@ -2021,6 +2062,11 @@ dbg_xfrin_exec(
knot_rrset_dump(*rrset, 1);
ret = knot_node_add_rrset(node, *rrset, 0);
+ if (ret < 0) {
+ dbg_xfrin("Failed to add merged RRSet to the node.\n");
+ return ret;
+ }
+
// return 2 so that the add RRSet is removed from
// the changeset (and thus not deleted)
// and put to list of new RRSets (is this ok?)
@@ -2058,6 +2104,9 @@ dbg_xfrin_exec(
int copied = 0;
+ /*! \note Here the check is OK, because if we aready have the RRSet,
+ * it's a copied one, so it is OK to modify it right away.
+ */
if (!*rrset
|| knot_dname_compare(knot_rrset_owner(*rrset),
knot_node_owner(node)) != 0
@@ -2081,7 +2130,6 @@ dbg_xfrin_exec(
if (*rrset == NULL) {
dbg_xfrin("RRSet to be added not found in zone.\n");
- dbg_xfrin("Creating new RRSet for RRSIG.\n");
// create a new RRSet to add the RRSIGs into
*rrset = knot_rrset_new(knot_node_get_owner(node), type,
knot_rrset_class(add),
@@ -2090,6 +2138,7 @@ dbg_xfrin_exec(
dbg_xfrin("Failed to create new RRSet for RRSIGs.\n");
return KNOT_ENOMEM;
}
+ dbg_xfrin("Created new RRSet for RRSIG: %p.\n", *rrset);
// add the RRset to the list of new RRsets
ret = xfrin_changes_check_rrsets(
@@ -2448,6 +2497,17 @@ static int xfrin_apply_remove2(knot_zone_contents_t *contents,
int is_nsec3 = 0;
for (int i = 0; i < chset->remove_count; ++i) {
+dbg_xfrin_exec_verb(
+ char *name = knot_dname_to_str(
+ knot_rrset_owner(chset->remove[i]));
+ dbg_xfrin_verb("Removing RRSet: %s, type %s\n", name,
+ knot_rrtype_to_string(
+ knot_rrset_type(chset->remove[i])));
+ free(name);
+);
+dbg_xfrin_exec_detail(
+ knot_rrset_dump(chset->remove[i], 0);
+);
is_nsec3 = 0;
@@ -2524,8 +2584,17 @@ static int xfrin_apply_add2(knot_zone_contents_t *contents,
int is_nsec3 = 0;
for (int i = 0; i < chset->add_count; ++i) {
- dbg_xfrin_detail("Adding RRSet:\n");
+dbg_xfrin_exec_verb(
+ char *name = knot_dname_to_str(
+ knot_rrset_owner(chset->add[i]));
+ dbg_xfrin_verb("Adding RRSet: %s, type: %s\n", name,
+ knot_rrtype_to_string(
+ knot_rrset_type(chset->add[i])));
+ free(name);
+);
+dbg_xfrin_exec_detail(
knot_rrset_dump(chset->add[i], 0);
+);
is_nsec3 = 0;
@@ -2647,6 +2716,7 @@ static int xfrin_apply_replace_soa2(knot_zone_contents_t *contents,
knot_changes_t *changes,
knot_changeset_t *chset)
{
+ dbg_xfrin("Replacing SOA record.\n");
knot_node_t *node = knot_zone_contents_get_apex(contents);
assert(node != NULL);
@@ -2658,6 +2728,7 @@ static int xfrin_apply_replace_soa2(knot_zone_contents_t *contents,
contents->apex = node;
// remove the SOA RRSet from the apex
+ dbg_xfrin_verb("Removing SOA.\n");
knot_rrset_t *rrset = knot_node_remove_rrset(node, KNOT_RRTYPE_SOA);
assert(rrset != NULL);
@@ -2704,6 +2775,7 @@ static int xfrin_apply_replace_soa2(knot_zone_contents_t *contents,
changes->old_rrsets[changes->old_rrsets_count++] = rrset;
/*! \todo Maybe check if the SOA does not have more RDATA? */
+ dbg_xfrin_verb("Adding RDATA from old SOA to the list of old RDATA.\n");
xfrin_changes_add_rdata(changes->old_rdata, changes->old_rdata_types,
&changes->old_rdata_count, rrset->rdata,
KNOT_RRTYPE_SOA);
@@ -2725,6 +2797,7 @@ static int xfrin_apply_replace_soa2(knot_zone_contents_t *contents,
changes->new_rrsets[changes->new_rrsets_count++] = chset->soa_to;
+ dbg_xfrin_verb("Adding RDATA from new SOA to the list of new RDATA.\n");
xfrin_changes_add_rdata(changes->new_rdata,
changes->new_rdata_types,
&changes->new_rdata_count,
@@ -2750,6 +2823,9 @@ static int xfrin_apply_changeset2(knot_zone_contents_t *contents,
* SOA in the zone apex.
*/
+ dbg_xfrin("APPLYING CHANGESET: from serial %u to serial %u\n",
+ chset->serial_from, chset->serial_to);
+
// check if serial matches
/*! \todo Only if SOA is present? */
const knot_rrset_t *soa = knot_node_rrset(contents->apex,
diff --git a/src/libknot/util/debug.h b/src/libknot/util/debug.h
index e02f988..b6aba6e 100644
--- a/src/libknot/util/debug.h
+++ b/src/libknot/util/debug.h
@@ -33,6 +33,7 @@
#include <stdio.h>
#include "config.h" /* autoconf generated */
+#include "common/log.h"
/*
* Debug macros
@@ -132,8 +133,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Brief messages. */
#ifdef DEBUG_ENABLE_BRIEF
-#define dbg_ns(msg...) fprintf(stderr, msg)
-#define dbg_ns_hex(data, len) hex_print((data), (len))
+#define dbg_ns(msg...) log_msg(LOG_SERVER, LOG_DEBUG, msg)
+#define dbg_ns_hex(data, len) hex_log(LOG_SERVER, (data), (len))
#define dbg_ns_exec(cmds) do { cmds } while (0)
#else
#define dbg_ns(msg...)
@@ -143,8 +144,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Verbose messages. */
#ifdef DEBUG_ENABLE_VERBOSE
-#define dbg_ns_verb(msg...) fprintf(stderr, msg)
-#define dbg_ns_hex_verb(data, len) hex_print((data), (len))
+#define dbg_ns_verb(msg...) log_msg(LOG_SERVER, LOG_DEBUG, msg)
+#define dbg_ns_hex_verb(data, len) hex_log(LOG_SERVER, (data), (len))
#define dbg_ns_exec_verb(cmds) do { cmds } while (0)
#else
#define dbg_ns_verb(msg...)
@@ -154,8 +155,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Detail messages. */
#ifdef DEBUG_ENABLE_DETAILS
-#define dbg_ns_detail(msg...) fprintf(stderr, msg)
-#define dbg_ns_hex_detail(data, len) hex_print((data), (len))
+#define dbg_ns_detail(msg...) log_msg(LOG_SERVER, LOG_DEBUG, msg)
+#define dbg_ns_hex_detail(data, len) hex_log(LOG_SERVER, (data), (len))
#define dbg_ns_exec_detail(cmds) do { cmds } while (0)
#else
#define dbg_ns_detail(msg...)
@@ -182,8 +183,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Brief messages. */
#ifdef DEBUG_ENABLE_BRIEF
-#define dbg_dname(msg...) fprintf(stderr, msg)
-#define dbg_dname_hex(data, len) hex_print((data), (len))
+#define dbg_dname(msg...) log_msg(LOG_ZONE, LOG_DEBUG, msg)
+#define dbg_dname_hex(data, len) hex_log(LOG_ZONE, (data), (len))
#define dbg_dname_exec(cmds) do { cmds } while (0)
#else
#define dbg_dname(msg...)
@@ -193,8 +194,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Verbose messages. */
#ifdef DEBUG_ENABLE_VERBOSE
-#define dbg_dname_verb(msg...) fprintf(stderr, msg)
-#define dbg_dname_hex_verb(data, len) hex_print((data), (len))
+#define dbg_dname_verb(msg...) log_msg(LOG_ZONE, LOG_DEBUG, msg)
+#define dbg_dname_hex_verb(data, len) hex_log(LOG_ZONE, (data), (len))
#define dbg_dname_exec_verb(cmds) do { cmds } while (0)
#else
#define dbg_dname_verb(msg...)
@@ -204,8 +205,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Detail messages. */
#ifdef DEBUG_ENABLE_DETAILS
-#define dbg_dname_detail(msg...) fprintf(stderr, msg)
-#define dbg_dname_hex_detail(data, len) hex_print((data), (len))
+#define dbg_dname_detail(msg...) log_msg(LOG_ZONE, LOG_DEBUG, msg)
+#define dbg_dname_hex_detail(data, len) hex_log(LOG_ZONE, (data), (len))
#define dbg_dname_exec_detail(cmds) do { cmds } while (0)
#else
#define dbg_dname_detail(msg...)
@@ -232,8 +233,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Brief messages. */
#ifdef DEBUG_ENABLE_BRIEF
-#define dbg_node(msg...) fprintf(stderr, msg)
-#define dbg_node_hex(data, len) hex_print((data), (len))
+#define dbg_node(msg...) log_msg(LOG_ZONE, LOG_DEBUG, msg)
+#define dbg_node_hex(data, len) hex_log(LOG_ZONE, (data), (len))
#else
#define dbg_node(msg...)
#define dbg_node_hex(data, len)
@@ -241,8 +242,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Verbose messages. */
#ifdef DEBUG_ENABLE_VERBOSE
-#define dbg_node_verb(msg...) fprintf(stderr, msg)
-#define dbg_node_hex_verb(data, len) hex_print((data), (len))
+#define dbg_node_verb(msg...) log_msg(LOG_ZONE, LOG_DEBUG, msg)
+#define dbg_node_hex_verb(data, len) hex_log(LOG_ZONE, (data), (len))
#else
#define dbg_node_verb(msg...)
#define dbg_node_hex_verb(data, len)
@@ -250,8 +251,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Detail messages. */
#ifdef DEBUG_ENABLE_DETAILS
-#define dbg_node_detail(msg...) fprintf(stderr, msg)
-#define dbg_node_hex_detail(data, len) hex_print((data), (len))
+#define dbg_node_detail(msg...) log_msg(LOG_ZONE, LOG_DEBUG, msg)
+#define dbg_node_hex_detail(data, len) hex_log(LOG_ZONE, (data), (len))
#else
#define dbg_node_detail(msg...)
#define dbg_node_hex_detail(data, len)
@@ -273,8 +274,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Brief messages. */
#ifdef DEBUG_ENABLE_BRIEF
-#define dbg_zone(msg...) fprintf(stderr, msg)
-#define dbg_zone_hex(data, len) hex_print((data), (len))
+#define dbg_zone(msg...) log_msg(LOG_ZONE, LOG_DEBUG, msg)
+#define dbg_zone_hex(data, len) hex_log(LOG_ZONE, (data), (len))
#define dbg_zone_exec(cmds) do { cmds } while (0)
#else
#define dbg_zone(msg...)
@@ -284,8 +285,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Verbose messages. */
#ifdef DEBUG_ENABLE_VERBOSE
-#define dbg_zone_verb(msg...) fprintf(stderr, msg)
-#define dbg_zone_hex_verb(data, len) hex_print((data), (len))
+#define dbg_zone_verb(msg...) log_msg(LOG_ZONE, LOG_DEBUG, msg)
+#define dbg_zone_hex_verb(data, len) hex_log(LOG_ZONE, (data), (len))
#define dbg_zone_exec_verb(cmds) do { cmds } while (0)
#else
#define dbg_zone_verb(msg...)
@@ -295,8 +296,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Detail messages. */
#ifdef DEBUG_ENABLE_DETAILS
-#define dbg_zone_detail(msg...) fprintf(stderr, msg)
-#define dbg_zone_hex_detail(data, len) hex_print((data), (len))
+#define dbg_zone_detail(msg...) log_msg(LOG_ZONE, LOG_DEBUG, msg)
+#define dbg_zone_hex_detail(data, len) hex_log(LOG_ZONE, (data), (len))
#define dbg_zone_exec_detail(cmds) do { cmds } while (0)
#else
#define dbg_zone_detail(msg...)
@@ -323,8 +324,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Brief messages. */
#ifdef DEBUG_ENABLE_BRIEF
-#define dbg_zonedb(msg...) fprintf(stderr, msg)
-#define dbg_zonedb_hex(data, len) hex_print((data), (len))
+#define dbg_zonedb(msg...) log_msg(LOG_ZONE, LOG_DEBUG, msg)
+#define dbg_zonedb_hex(data, len) hex_log(LOG_ZONE, (data), (len))
#define dbg_zonedb_exec(cmds) do { cmds } while (0)
#else
#define dbg_zonedb(msg...)
@@ -334,8 +335,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Verbose messages. */
#ifdef DEBUG_ENABLE_VERBOSE
-#define dbg_zonedb_verb(msg...) fprintf(stderr, msg)
-#define dbg_zonedb_hex_verb(data, len) hex_print((data), (len))
+#define dbg_zonedb_verb(msg...) log_msg(LOG_ZONE, LOG_DEBUG, msg)
+#define dbg_zonedb_hex_verb(data, len) hex_log(LOG_ZONE, (data), (len))
#define dbg_zonedb_exec_verb(cmds) do { cmds } while (0)
#else
#define dbg_zonedb_verb(msg...)
@@ -345,8 +346,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Detail messages. */
#ifdef DEBUG_ENABLE_DETAILS
-#define dbg_zonedb_detail(msg...) fprintf(stderr, msg)
-#define dbg_zonedb_hex_detail(data, len) hex_print((data), (len))
+#define dbg_zonedb_detail(msg...) log_msg(LOG_ZONE, LOG_DEBUG, msg)
+#define dbg_zonedb_hex_detail(data, len) hex_log(LOG_ZONE, (data), (len))
#define dbg_zonedb_exec_detail(cmds) do { cmds } while (0)
#else
#define dbg_zonedb_detail(msg...)
@@ -373,8 +374,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Brief messages. */
#ifdef DEBUG_ENABLE_BRIEF
-#define dbg_response(msg...) fprintf(stderr, msg)
-#define dbg_response_hex(data, len) hex_print((data), (len))
+#define dbg_response(msg...) log_msg(LOG_ANSWER, LOG_DEBUG, msg)
+#define dbg_response_hex(data, len) hex_log(LOG_ANSWER, (data), (len))
#define dbg_response_exec(cmds) do { cmds } while (0)
#else
#define dbg_response(msg...)
@@ -384,8 +385,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Verbose messages. */
#ifdef DEBUG_ENABLE_VERBOSE
-#define dbg_response_verb(msg...) fprintf(stderr, msg)
-#define dbg_response_hex_verb(data, len) hex_print((data), (len))
+#define dbg_response_verb(msg...) log_msg(LOG_ANSWER, LOG_DEBUG, msg)
+#define dbg_response_hex_verb(data, len) hex_log(LOG_ANSWER, (data), (len))
#define dbg_response_exec_verb(cmds) do { cmds } while (0)
#else
#define dbg_response_verb(msg...)
@@ -395,8 +396,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Detail messages. */
#ifdef DEBUG_ENABLE_DETAILS
-#define dbg_response_detail(msg...) fprintf(stderr, msg)
-#define dbg_response_hex_detail(data, len) hex_print((data), (len))
+#define dbg_response_detail(msg...) log_msg(LOG_ANSWER, LOG_DEBUG, msg)
+#define dbg_response_hex_detail(data, len) hex_log(LOG_ANSWER, (data), (len))
#define dbg_response_exec_detail(cmds) do { cmds } while (0)
#else
#define dbg_response_detail(msg...)
@@ -423,8 +424,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Brief messages. */
#ifdef DEBUG_ENABLE_BRIEF
-#define dbg_packet(msg...) fprintf(stderr, msg)
-#define dbg_packet_hex(data, len) hex_print((data), (len))
+#define dbg_packet(msg...) log_msg(LOG_ANSWER, LOG_DEBUG, msg)
+#define dbg_packet_hex(data, len) hex_log(LOG_ANSWER, (data), (len))
#define dbg_packet_exec(cmds) do { cmds } while (0)
#else
#define dbg_packet(msg...)
@@ -434,8 +435,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Verbose messages. */
#ifdef DEBUG_ENABLE_VERBOSE
-#define dbg_packet_verb(msg...) fprintf(stderr, msg)
-#define dbg_packet_hex_verb(data, len) hex_print((data), (len))
+#define dbg_packet_verb(msg...) log_msg(LOG_ANSWER, LOG_DEBUG, msg)
+#define dbg_packet_hex_verb(data, len) hex_log(LOG_ANSWER, (data), (len))
#define dbg_packet_exec_verb(cmds) do { cmds } while (0)
#else
#define dbg_packet_verb(msg...)
@@ -445,8 +446,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Detail messages. */
#ifdef DEBUG_ENABLE_DETAILS
-#define dbg_packet_detail(msg...) fprintf(stderr, msg)
-#define dbg_packet_hex_detail(data, len) hex_print((data), (len))
+#define dbg_packet_detail(msg...) log_msg(LOG_ANSWER, LOG_DEBUG, msg)
+#define dbg_packet_hex_detail(data, len) hex_log(LOG_ANSWER, (data), (len))
#define dbg_packet_exec_detail(cmds) do { cmds } while (0)
#else
#define dbg_packet_detail(msg...)
@@ -473,8 +474,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Brief messages. */
#ifdef DEBUG_ENABLE_BRIEF
-#define dbg_edns(msg...) fprintf(stderr, msg)
-#define dbg_edns_hex(data, len) hex_print((data), (len))
+#define dbg_edns(msg...) log_msg(LOG_ZONE, LOG_DEBUG, msg)
+#define dbg_edns_hex(data, len) hex_log(LOG_ZONE, (data), (len))
#else
#define dbg_edns(msg...)
#define dbg_edns_hex(data, len)
@@ -482,8 +483,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Verbose messages. */
#ifdef DEBUG_ENABLE_VERBOSE
-#define dbg_edns_verb(msg...) fprintf(stderr, msg)
-#define dbg_edns_hex_verb(data, len) hex_print((data), (len))
+#define dbg_edns_verb(msg...) log_msg(LOG_ZONE, LOG_DEBUG, msg)
+#define dbg_edns_hex_verb(data, len) hex_log(LOG_ZONE, (data), (len))
#else
#define dbg_edns_verb(msg...)
#define dbg_edns_hex_verb(data, len)
@@ -491,8 +492,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Detail messages. */
#ifdef DEBUG_ENABLE_DETAILS
-#define dbg_edns_detail(msg...) fprintf(stderr, msg)
-#define dbg_edns_hex_detail(data, len) hex_print((data), (len))
+#define dbg_edns_detail(msg...) log_msg(LOG_ZONE, LOG_DEBUG, msg)
+#define dbg_edns_hex_detail(data, len) hex_log(LOG_ZONE, (data), (len))
#else
#define dbg_edns_detail(msg...)
#define dbg_edns_hex_detail(data, len)
@@ -514,8 +515,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Brief messages. */
#ifdef DEBUG_ENABLE_BRIEF
-#define dbg_nsec3(msg...) fprintf(stderr, msg)
-#define dbg_nsec3_hex(data, len) hex_print((data), (len))
+#define dbg_nsec3(msg...) log_msg(LOG_ZONE, LOG_DEBUG, msg)
+#define dbg_nsec3_hex(data, len) hex_log(LOG_ZONE, (data), (len))
#else
#define dbg_nsec3(msg...)
#define dbg_nsec3_hex(data, len)
@@ -523,8 +524,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Verbose messages. */
#ifdef DEBUG_ENABLE_VERBOSE
-#define dbg_nsec3_verb(msg...) fprintf(stderr, msg)
-#define dbg_nsec3_hex_verb(data, len) hex_print((data), (len))
+#define dbg_nsec3_verb(msg...) log_msg(LOG_ZONE, LOG_DEBUG, msg)
+#define dbg_nsec3_hex_verb(data, len) hex_log(LOG_ZONE, (data), (len))
#else
#define dbg_nsec3_verb(msg...)
#define dbg_nsec3_hex_verb(data, len)
@@ -532,8 +533,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Detail messages. */
#ifdef DEBUG_ENABLE_DETAILS
-#define dbg_nsec3_detail(msg...) fprintf(stderr, msg)
-#define dbg_nsec3_hex_detail(data, len) hex_print((data), (len))
+#define dbg_nsec3_detail(msg...) log_msg(LOG_ZONE, LOG_DEBUG, msg)
+#define dbg_nsec3_hex_detail(data, len) hex_log(LOG_ZONE, (data), (len))
#else
#define dbg_nsec3_detail(msg...)
#define dbg_nsec3_hex_detail(data, len)
@@ -555,8 +556,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Brief messages. */
#ifdef DEBUG_ENABLE_BRIEF
-#define dbg_ck(msg...) fprintf(stderr, msg)
-#define dbg_ck_hex(data, len) hex_print((data), (len))
+#define dbg_ck(msg...) log_msg(LOG_SERVER, LOG_DEBUG, msg)
+#define dbg_ck_hex(data, len) hex_log(LOG_SERVER, (data), (len))
#define dbg_ck_exec(cmds) do { cmds } while (0)
#else
#define dbg_ck(msg...)
@@ -566,8 +567,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Verbose messages. */
#ifdef DEBUG_ENABLE_VERBOSE
-#define dbg_ck_verb(msg...) fprintf(stderr, msg)
-#define dbg_ck_hex_verb(data, len) hex_print((data), (len))
+#define dbg_ck_verb(msg...) log_msg(LOG_SERVER, LOG_DEBUG, msg)
+#define dbg_ck_hex_verb(data, len) hex_log(LOG_SERVER, (data), (len))
#define dbg_ck_exec_verb(cmds) do { cmds } while (0)
#else
#define dbg_ck_verb(msg...)
@@ -577,8 +578,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Detail messages. */
#ifdef DEBUG_ENABLE_DETAILS
-#define dbg_ck_detail(msg...) fprintf(stderr, msg)
-#define dbg_ck_hex_detail(data, len) hex_print((data), (len))
+#define dbg_ck_detail(msg...) log_msg(LOG_SERVER, LOG_DEBUG, msg)
+#define dbg_ck_hex_detail(data, len) hex_log(LOG_SERVER, (data), (len))
#define dbg_ck_exec_detail(cmds) do { cmds } while (0)
#else
#define dbg_ck_detail(msg...)
@@ -605,9 +606,9 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Brief messages. */
#ifdef DEBUG_ENABLE_BRIEF
-#define dbg_ck_hash(msg...) fprintf(stderr, msg)
-#define dbg_ck_rehash(msg...) fprintf(stderr, msg)
-#define dbg_ck_hash_hex(data, len) hex_print((data), (len))
+#define dbg_ck_hash(msg...) log_msg(LOG_SERVER, LOG_DEBUG, msg)
+#define dbg_ck_rehash(msg...) log_msg(LOG_SERVER, LOG_DEBUG, msg)
+#define dbg_ck_hash_hex(data, len) hex_log(LOG_SERVER, (data), (len))
#else
#define dbg_ck_hash(msg...)
#define dbg_ck_rehash(msg...)
@@ -616,8 +617,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Verbose messages. */
#ifdef DEBUG_ENABLE_VERBOSE
-#define dbg_ck_hash_verb(msg...) fprintf(stderr, msg)
-#define dbg_ck_hash_hex_verb(data, len) hex_print((data), (len))
+#define dbg_ck_hash_verb(msg...) log_msg(LOG_SERVER, LOG_DEBUG, msg)
+#define dbg_ck_hash_hex_verb(data, len) hex_log(LOG_SERVER, (data), (len))
#else
#define dbg_ck_hash_verb(msg...)
#define dbg_ck_hash_hex_verb(data, len)
@@ -625,8 +626,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Detail messages. */
#ifdef DEBUG_ENABLE_DETAILS
-#define dbg_ck_hash_detail(msg...) fprintf(stderr, msg)
-#define dbg_ck_hash_hex_detail(data, len) hex_print((data), (len))
+#define dbg_ck_hash_detail(msg...) log_msg(LOG_SERVER, LOG_DEBUG, msg)
+#define dbg_ck_hash_hex_detail(data, len) hex_log(LOG_SERVER, (data), (len))
#else
#define dbg_ck_hash_detail(msg...)
#define dbg_ck_hash_hex_detail(data, len)
@@ -649,8 +650,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Brief messages. */
#ifdef DEBUG_ENABLE_BRIEF
-#define dbg_xfrin(msg...) fprintf(stderr, msg)
-#define dbg_xfrin_hex(data, len) hex_print((data), (len))
+#define dbg_xfrin(msg...) log_msg(LOG_ZONE, LOG_DEBUG, msg)
+#define dbg_xfrin_hex(data, len) hex_log(LOG_ZONE, (data), (len))
#define dbg_xfrin_exec(cmds) do { cmds } while (0)
#else
#define dbg_xfrin(msg...)
@@ -660,8 +661,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Verbose messages. */
#ifdef DEBUG_ENABLE_VERBOSE
-#define dbg_xfrin_verb(msg...) fprintf(stderr, msg)
-#define dbg_xfrin_hex_verb(data, len) hex_print((data), (len))
+#define dbg_xfrin_verb(msg...) log_msg(LOG_ZONE, LOG_DEBUG, msg)
+#define dbg_xfrin_hex_verb(data, len) hex_log(LOG_ZONE, (data), (len))
#define dbg_xfrin_exec_verb(cmds) do { cmds } while (0)
#else
#define dbg_xfrin_verb(msg...)
@@ -671,8 +672,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Detail messages. */
#ifdef DEBUG_ENABLE_DETAILS
-#define dbg_xfrin_detail(msg...) fprintf(stderr, msg)
-#define dbg_xfrin_hex_detail(data, len) hex_print((data), (len))
+#define dbg_xfrin_detail(msg...) log_msg(LOG_ZONE, LOG_DEBUG, msg)
+#define dbg_xfrin_hex_detail(data, len) hex_log(LOG_ZONE, (data), (len))
#define dbg_xfrin_exec_detail(cmds) do { cmds } while (0)
#else
#define dbg_xfrin_detail(msg...)
@@ -699,8 +700,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Brief messages. */
#ifdef DEBUG_ENABLE_BRIEF
-#define dbg_ddns(msg...) fprintf(stderr, msg)
-#define dbg_ddns_hex(data, len) hex_print((data), (len))
+#define dbg_ddns(msg...) log_msg(LOG_ZONE, LOG_DEBUG, msg)
+#define dbg_ddns_hex(data, len) hex_log(LOG_ZONE, (data), (len))
#else
#define dbg_ddns(msg...)
#define dbg_ddns_hex(data, len)
@@ -708,8 +709,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Verbose messages. */
#ifdef DEBUG_ENABLE_VERBOSE
-#define dbg_ddns_verb(msg...) fprintf(stderr, msg)
-#define dbg_ddns_hex_verb(data, len) hex_print((data), (len))
+#define dbg_ddns_verb(msg...) log_msg(LOG_ZONE, LOG_DEBUG, msg)
+#define dbg_ddns_hex_verb(data, len) hex_log(LOG_ZONE, (data), (len))
#else
#define dbg_ddns_verb(msg...)
#define dbg_ddns_hex_verb(data, len)
@@ -717,8 +718,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Detail messages. */
#ifdef DEBUG_ENABLE_DETAILS
-#define dbg_ddns_detail(msg...) fprintf(stderr, msg)
-#define dbg_ddns_hex_detail(data, len) hex_print((data), (len))
+#define dbg_ddns_detail(msg...) log_msg(LOG_ZONE, LOG_DEBUG, msg)
+#define dbg_ddns_hex_detail(data, len) hex_log(LOG_ZONE, (data), (len))
#else
#define dbg_ddns_detail(msg...)
#define dbg_ddns_hex_detail(data, len)
@@ -738,8 +739,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Brief messages. */
#ifdef DEBUG_ENABLE_BRIEF
-#define dbg_tsig(msg...) fprintf(stderr, msg)
-#define dbg_tsig_hex(data, len) hex_print((const char*)(data), (len))
+#define dbg_tsig(msg...) log_msg(LOG_ZONE, LOG_DEBUG, msg)
+#define dbg_tsig_hex(data, len) hex_log(LOG_ZONE, (data), (len))
#else
#define dbg_tsig(msg...)
#define dbg_tsig_hex(data, len)
@@ -747,8 +748,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Verbose messages. */
#ifdef DEBUG_ENABLE_VERBOSE
-#define dbg_tsig_verb(msg...) fprintf(stderr, msg)
-#define dbg_tsig_hex_verb(data, len) hex_print((const char*)(data), (len))
+#define dbg_tsig_verb(msg...) log_msg(LOG_ZONE, LOG_DEBUG, msg)
+#define dbg_tsig_hex_verb(data, len) hex_log(LOG_ZONE, (data), (len))
#else
#define dbg_tsig_verb(msg...)
#define dbg_tsig_hex_verb(data, len)
@@ -756,8 +757,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Detail messages. */
#ifdef DEBUG_ENABLE_DETAILS
-#define dbg_tsig_detail(msg...) fprintf(stderr, msg)
-#define dbg_tsig_hex_detail(data, len) hex_print((const char*)(data), (len))
+#define dbg_tsig_detail(msg...) log_msg(LOG_ZONE, LOG_DEBUG, msg)
+#define dbg_tsig_hex_detail(data, len) hex_log(LOG_ZONE, (data), (len))
#else
#define dbg_tsig_detail(msg...)
#define dbg_tsig_hex_detail(data, len)
@@ -777,8 +778,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Brief messages. */
#ifdef DEBUG_ENABLE_BRIEF
-#define dbg_rrset(msg...) fprintf(stderr, msg)
-#define dbg_rrset_hex(data, len) hex_print((data), (len))
+#define dbg_rrset(msg...) log_msg(LOG_ZONE, LOG_DEBUG, msg)
+#define dbg_rrset_hex(data, len) hex_log(LOG_ZONE, (data), (len))
#else
#define dbg_rrset(msg...)
#define dbg_rrset_hex(data, len)
@@ -786,8 +787,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Verbose messages. */
#ifdef DEBUG_ENABLE_VERBOSE
-#define dbg_rrset_verb(msg...) fprintf(stderr, msg)
-#define dbg_rrset_hex_verb(data, len) hex_print((data), (len))
+#define dbg_rrset_verb(msg...) log_msg(LOG_ZONE, LOG_DEBUG, msg)
+#define dbg_rrset_hex_verb(data, len) hex_log(LOG_ZONE, (data), (len))
#else
#define dbg_rrset_verb(msg...)
#define dbg_rrset_hex_verb(data, len)
@@ -795,8 +796,8 @@ void knot_zone_contents_dump(knot_zone_contents_t *zone, char loaded_zone);
/* Detail messages. */
#ifdef DEBUG_ENABLE_DETAILS
-#define dbg_rrset_detail(msg...) fprintf(stderr, msg)
-#define dbg_rrset_hex_detail(data, len) hex_print((data), (len))
+#define dbg_rrset_detail(msg...) log_msg(LOG_ZONE, LOG_DEBUG, msg)
+#define dbg_rrset_hex_detail(data, len) hex_log(LOG_ZONE, (data), (len))
#else
#define dbg_rrset_detail(msg...)
#define dbg_rrset_hex_detail(data, len)
diff --git a/src/tests/common/acl_tests.c b/src/tests/common/acl_tests.c
index ea7b653..c1884cd 100644
--- a/src/tests/common/acl_tests.c
+++ b/src/tests/common/acl_tests.c
@@ -34,7 +34,7 @@ unit_api acl_tests_api = {
static int acl_tests_count(int argc, char *argv[])
{
- return 18;
+ return 20;
}
static int acl_tests_run(int argc, char *argv[])
@@ -146,6 +146,17 @@ static int acl_tests_run(int argc, char *argv[])
ret = acl_match(acl, &test_pf4, &rval);
ok(rval->val == sval, "acl: search for preferred node");
+ // 19. Scenario after truncating
+ ok(acl_truncate(acl) == ACL_ACCEPT, "acl: truncate");
+ sockaddr_set(&test_pf6, AF_INET6, "2001:a1b0:e11e:50d1::3:300", 0);
+ acl_create(acl, &test_pf6, ACL_ACCEPT, 0, 0);
+ sockaddr_set(&test_pf4, AF_INET, "231.17.67.223", 0);
+ acl_create(acl, &test_pf4, ACL_ACCEPT, 0, 0);
+ sockaddr_set(&test_pf4, AF_INET, "82.87.48.136", 0);
+ acl_create(acl, &test_pf4, ACL_ACCEPT, 0, 0);
+ sockaddr_set(&match_pf4, AF_INET, "82.87.48.136", 12345);
+ ret = acl_match(acl, &match_pf4, 0);
+ ok(ret == ACL_ACCEPT, "acl: scenario after truncating");
acl_delete(&acl);
// Return
diff --git a/src/tests/files/sample_conf b/src/tests/files/sample_conf
index 6cd9e50..b15fce5 100644
--- a/src/tests/files/sample_conf
+++ b/src/tests/files/sample_conf
@@ -8,7 +8,7 @@ system {
identity "I have no mouth and must scream";
version "Infinitesimal";
- storage "/var/run/knot/";
+ storage ".";
}
keys {
diff --git a/src/tests/knot/dthreads_tests.c b/src/tests/knot/dthreads_tests.c
index d95fbed..982329b 100644
--- a/src/tests/knot/dthreads_tests.c
+++ b/src/tests/knot/dthreads_tests.c
@@ -372,7 +372,6 @@ static int dt_tests_run(int argc, char *argv[])
ret += dt_join(0); // -1
ret += dt_repurpose(0, 0, 0); // -1
ret += dt_resize(0, 0); // -1
- ret += dt_setprio(0, 0); // -1
ret += dt_signalize(0, SIGALRM); // -1
ret += dt_start(0); // -1
ret += dt_start_id(0); // -1
diff --git a/src/tests/knot/journal_tests.c b/src/tests/knot/journal_tests.c
index 420300e..7c8125e 100644
--- a/src/tests/knot/journal_tests.c
+++ b/src/tests/knot/journal_tests.c
@@ -34,7 +34,7 @@ unit_api journal_tests_api = {
/*
* Unit implementation.
*/
-static const int JOURNAL_TEST_COUNT = 12;
+static const int JOURNAL_TEST_COUNT = 20;
/*! \brief Generate random string with given length. */
static int randstr(char* dst, size_t len)
@@ -164,13 +164,13 @@ static int journal_tests_run(int argc, char *argv[])
memcpy(chk_buf, tmpbuf, sizeof(chk_buf));
}
}
- ok(ret == 0, "journal: sustained looped writes");
+ ok(j && ret == 0, "journal: sustained looped writes");
/* Test 11: Check data integrity. */
memset(tmpbuf, 0, sizeof(tmpbuf));
journal_read(j, chk_key, 0, tmpbuf);
ret = strncmp(chk_buf, tmpbuf, sizeof(chk_buf));
- ok(ret == 0, "journal: read data integrity check");
+ ok(j && ret == 0, "journal: read data integrity check");
/* Test 12: Reopen log and re-read value. */
memset(tmpbuf, 0, sizeof(tmpbuf));
@@ -178,7 +178,89 @@ static int journal_tests_run(int argc, char *argv[])
j = journal_open(jfilename, fsize, 0, 0);
journal_read(j, chk_key, 0, tmpbuf);
ret = strncmp(chk_buf, tmpbuf, sizeof(chk_buf));
- ok(ret == 0, "journal: read data integrity check after close/open");
+ ok(j && ret == 0, "journal: read data integrity check after close/open");
+
+ /* Test 13: Map journal entry. */
+ char *mptr = NULL;
+ memset(chk_buf, 0xde, sizeof(chk_buf));
+ ret = journal_map(j, 0x12345, &mptr, sizeof(chk_buf));
+ ok(j && mptr && ret == 0, "journal: mapped journal entry");
+ skip(ret != 0, 2);
+
+ /* Test 14: Write to mmaped entry and unmap. */
+ memcpy(mptr, chk_buf, sizeof(chk_buf));
+ ret = journal_unmap(j, 0x12345, mptr, 1);
+ ok(j && mptr && ret == 0, "journal: written to mapped entry and finished");
+
+ /* Test 15: Compare mmaped entry. */
+ memset(tmpbuf, 0, sizeof(tmpbuf));
+ journal_read(j, 0x12345, NULL, tmpbuf);
+ ret = strncmp(chk_buf, tmpbuf, sizeof(chk_buf));
+ ok(j && ret == 0, "journal: mapped entry data integrity check");
+ endskip;
+
+ /* Test 17: Make a transaction. */
+ uint64_t tskey = 0x75750000;
+ ret = journal_trans_begin(j);
+ ok(j && ret == 0, "journal: TRANS begin");
+ for (int i = 0; i < 16; ++i) {
+ memset(tmpbuf, i, sizeof(tmpbuf));
+ journal_write(j, tskey + i, tmpbuf, sizeof(tmpbuf));
+ }
+
+ /* Test 18: Check if uncommited node exists. */
+ ret = journal_read(j, tskey + rand() % 16, NULL, chk_buf);
+ ok(j && ret != 0, "journal: check for uncommited node");
+
+ /* Test 19: Commit transaction. */
+ ret = journal_trans_commit(j);
+ int read_ret = journal_read(j, tskey + rand() % 16, NULL, chk_buf);
+ ok(j && ret == 0 && read_ret == 0, "journal: transaction commit");
+
+ /* Test 20: Rollback transaction. */
+ tskey = 0x6B6B0000;
+ journal_trans_begin(j);
+ for (int i = 0; i < 16; ++i) {
+ memset(tmpbuf, i, sizeof(tmpbuf));
+ journal_write(j, tskey + i, tmpbuf, sizeof(tmpbuf));
+ }
+ ret = journal_trans_rollback(j);
+ read_ret = journal_read(j, tskey + rand() % 16, NULL, chk_buf);
+ ok(j && ret == 0 && read_ret != 0, "journal: transaction rollback");
+
+ /* Test 16: Write random data. */
+ ret = 0;
+ for (int i = 0; i < 512; ++i) {
+ int key = i;
+ randstr(tmpbuf, sizeof(tmpbuf));
+ ret = journal_map(j, key, &mptr, sizeof(tmpbuf));
+ if (ret != KNOTD_EOK) {
+ diag("journal_map failed: %s", knotd_strerror(ret));
+ break;
+ }
+ memcpy(mptr, tmpbuf, sizeof(tmpbuf));
+ if ((ret = journal_unmap(j, key, mptr, 1)) != KNOTD_EOK) {
+ diag("journal_unmap failed: %s", knotd_strerror(ret));
+ break;
+ }
+
+ /* Store some key on the end. */
+ memset(chk_buf, 0, sizeof(chk_buf));
+ ret = journal_read(j, key, 0, chk_buf);
+ if (ret != 0) {
+ diag("journal_map integrity check failed %s",
+ knotd_strerror(ret));
+ break;
+ }
+ ret = strncmp(chk_buf, tmpbuf, sizeof(chk_buf));
+ if (ret != 0) {
+ diag("journal_map integrity check failed");
+ break;
+ }
+ }
+
+ /* Test 16: Check data integrity. */
+ ok(j && ret == 0, "journal: sustained mmap r/w");
/* Close journal. */
journal_close(j);
diff --git a/src/tests/libknot/libknot/dname_tests.c b/src/tests/libknot/libknot/dname_tests.c
index 22f6fbc..35ac230 100644
--- a/src/tests/libknot/libknot/dname_tests.c
+++ b/src/tests/libknot/libknot/dname_tests.c
@@ -39,7 +39,7 @@ unit_api dname_tests_api = {
// C will not accept const int in other const definition
enum { TEST_DOMAINS_OK = 8 };
-enum { TEST_DOMAINS_BAD = 4 };
+enum { TEST_DOMAINS_BAD = 5 };
enum { TEST_DOMAINS_NON_FQDN = 6 };
@@ -92,7 +92,8 @@ static const struct test_domain
{ NULL, "\2ex\3com", 0, "", 0 },
{ "ex.com.", NULL, 0, "", 0 },
{ "ex.com.\5", "\3ex\3com\0\5", 10, "", 0 },
- { "example.com", "\3example\3com", 12, "\x0\x8", 2 }
+ { "example.com", "\3example\3com", 12, "\x0\x8", 2 },
+ { "example..", "\7example\0\0", 12, "\x0\x8", 2 }
};
static int test_dname_create()
@@ -194,7 +195,9 @@ static int test_dname_create_from_str_non_fqdn()
knot_dname_t *dname = NULL;
for (int i = 0; i < TEST_DOMAINS_NON_FQDN; ++i) {
- //note("testing domain: %s", test_domains_non_fqdn[i].str);
+// note("testing domain: %s, size: %zu",
+// test_domains_non_fqdn[i].str,
+// strlen(test_domains_non_fqdn[i].str));
dname = knot_dname_new_from_str(test_domains_non_fqdn[i].str,
strlen(test_domains_non_fqdn[i].str), NULL);
errors += check_domain_name(dname, test_domains_non_fqdn, i, 0);
@@ -490,7 +493,7 @@ static int test_dname_is_subdomain()
for (int i = 0; i < TEST_DOMAINS_NON_FQDN; ++i) {
dnames_non_fqdn[i] = knot_dname_new_from_str(
test_domains_non_fqdn[i].str,
- test_domains_non_fqdn[i].size, NULL);
+ strlen(test_domains_non_fqdn[i].str), NULL);
assert(dnames_non_fqdn[i] != NULL);
}
@@ -606,6 +609,60 @@ static int test_dname_is_subdomain()
return (errors == 0);
}
+static int test_dname_deep_copy() {
+ int errors = 0;
+
+ knot_dname_t *dnames_fqdn[TEST_DOMAINS_OK];
+ knot_dname_t *dnames_non_fqdn[TEST_DOMAINS_NON_FQDN];
+ knot_dname_t *dnames_fqdn_copy[TEST_DOMAINS_OK];
+ knot_dname_t *dnames_non_fqdn_copy[TEST_DOMAINS_NON_FQDN];
+
+ for (int i = 0; i < TEST_DOMAINS_OK; ++i) {
+ dnames_fqdn[i] = knot_dname_new_from_wire(
+ (const uint8_t *)test_domains_ok[i].wire,
+ test_domains_ok[i].size, NODE_ADDRESS);
+ assert(dnames_fqdn[i] != NULL);
+ }
+
+ for (int i = 0; i < TEST_DOMAINS_NON_FQDN; ++i) {
+ dnames_non_fqdn[i] = knot_dname_new_from_str(
+ test_domains_non_fqdn[i].str,
+ strlen(test_domains_non_fqdn[i].str),
+ NODE_ADDRESS);
+// note("Created name: %.*s\n", dnames_non_fqdn[i]->size,
+// dnames_non_fqdn[i]->name);
+ assert(dnames_non_fqdn[i] != NULL);
+ }
+
+ /*
+ * Create copies of the domain names.
+ */
+ for (int i = 0; i < TEST_DOMAINS_OK; ++i) {
+// note("Testing %d. FQDN domain.\n", i);
+ dnames_fqdn_copy[i] = knot_dname_deep_copy(dnames_fqdn[i]);
+ assert(dnames_fqdn_copy[i] != NULL);
+ errors += check_domain_name(dnames_fqdn_copy[i],
+ test_domains_ok, i, 1);
+ knot_dname_free(&dnames_fqdn_copy[i]);
+ knot_dname_free(&dnames_fqdn[i]);
+ }
+
+ for (int i = 0; i < TEST_DOMAINS_NON_FQDN; ++i) {
+// note("Testing %d. non-FQDN domain: ", i);
+// note("%.*s\n", dnames_non_fqdn[i]->size,
+// dnames_non_fqdn[i]->name);
+ dnames_non_fqdn_copy[i] =
+ knot_dname_deep_copy(dnames_non_fqdn[i]);
+ assert(dnames_non_fqdn_copy[i] != NULL);
+ errors += check_domain_name(dnames_non_fqdn_copy[i],
+ test_domains_non_fqdn, i, 1);
+ knot_dname_free(&dnames_non_fqdn_copy[i]);
+ knot_dname_free(&dnames_non_fqdn[i]);
+ }
+
+ return (errors == 0);
+}
+
static int check_wires(const uint8_t *wire1, uint size1,
uint8_t *wire2, uint size2)
{
@@ -652,7 +709,7 @@ static int test_dname_name(knot_dname_t **dnames_fqdn,
for (int i = 0; i < TEST_DOMAINS_NON_FQDN; i++) {
const uint8_t *tmp_name;
tmp_name = knot_dname_name(dnames_non_fqdn[i]);
- if (!check_wires(tmp_name, dnames_non_fqdn[i]->size - 1,
+ if (!check_wires(tmp_name, dnames_non_fqdn[i]->size,
(uint8_t *)test_domains_non_fqdn[i].wire,
test_domains_non_fqdn[i].size)) {
diag("Got bad name value from structure: "
@@ -757,10 +814,13 @@ static int test_dname_getters(uint type)
}
for (int i = 0; i < TEST_DOMAINS_NON_FQDN; i++) {
- printf("Creating dname: %s size: %d\n", test_domains_non_fqdn[i].wire, test_domains_non_fqdn[i].size);
+// note("Creating dname: %s size: %d\n",
+// test_domains_non_fqdn[i].wire,
+// test_domains_non_fqdn[i].size);
dnames_non_fqdn[i] = knot_dname_new_from_str(
test_domains_non_fqdn[i].str,
- test_domains_non_fqdn[i].size, NODE_ADDRESS);
+ strlen(test_domains_non_fqdn[i].str),
+ NODE_ADDRESS);
assert(dnames_non_fqdn[i] != NULL);
}
@@ -792,7 +852,7 @@ static int test_dname_getters(uint type)
return (errors == 0);
}
-static const int KNOT_DNAME_TEST_COUNT = 15;
+static const int KNOT_DNAME_TEST_COUNT = 16;
/*! This helper routine should report number of
* scheduled tests for given parameters.
@@ -834,15 +894,11 @@ static int knot_dname_tests_run(int argc, char *argv[])
res_final *= res_wire;
res_final *= res_str_non_fqdn;
- todo();
res = test_dname_getters(0);
ok(res, "dname: name");
- endtodo;
- todo();
res = test_dname_getters(1);
ok(res, "dname: size");
- endtodo;
res = test_dname_getters(2);
ok(res, "dname: node");
@@ -871,6 +927,9 @@ static int knot_dname_tests_run(int argc, char *argv[])
ok((res = test_dname_is_subdomain()), "dname: is subdomain");
res_final *= res;
+ ok((res = test_dname_deep_copy()), "dname: deep copy");
+ res_final *= res;
+
endskip; /* create failed */
return res_final;
diff --git a/src/tests/libknot/libknot/packet_tests.c b/src/tests/libknot/libknot/packet_tests.c
index 185504f..916328d 100644
--- a/src/tests/libknot/libknot/packet_tests.c
+++ b/src/tests/libknot/libknot/packet_tests.c
@@ -168,10 +168,8 @@ static int test_packet_parse_rest()
knot_packet_new(KNOT_PACKET_PREALLOC_NONE);
assert(packet);
- todo();
lives_ok({res = knot_packet_parse_rest(packet);},
- "packet: parser rest empty packet");
- endtodo;
+ "packet: parser rest empty packet");
knot_packet_free(&packet);
diff --git a/src/tests/unittests_main.c b/src/tests/unittests_main.c
index 2d57ed2..1ec336a 100644
--- a/src/tests/unittests_main.c
+++ b/src/tests/unittests_main.c
@@ -36,6 +36,8 @@ int main(int argc, char *argv[])
// Open log
log_init();
log_levels_set(LOGT_SYSLOG, LOG_ANY, 0);
+ log_levels_set(LOGT_STDERR, LOG_ANY, 0);
+ log_levels_set(LOGT_STDOUT, LOG_ANY, LOG_MASK(LOG_DEBUG));
// Build test set
unit_api *tests[] = {
diff --git a/src/tests/xfr_tests.c b/src/tests/xfr_tests.c
index 9ea19fe..5017109 100644
--- a/src/tests/xfr_tests.c
+++ b/src/tests/xfr_tests.c
@@ -16,11 +16,9 @@
/*
* This test is basically a copy of the whole server, with following exceptions:
- * - conf file path is hardcoded, because it is generated by script
- * invoking this binary.
* - signal handler now handles one more signal
- * SIGCONT is used to signal this
- * binary that an integrity check should be done
+ * SIGUSR1 is used to signal this
+ * binary that an integrity check should be done
*/
#include <time.h>
@@ -69,7 +67,7 @@ void interrupt_handle(int s)
}
// Start zone integrity check
- if (s == SIGCONT) {
+ if (s == SIGUSR1) {
sig_integrity_check = 1;
return;
}
@@ -85,7 +83,8 @@ void help(int argc, char **argv)
" -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");
+ " -h, --help Print help and usage.\n"
+ "Send SIGUSR1 to trigger integrity check.\n");
}
int main(int argc, char **argv)
@@ -272,7 +271,7 @@ int main(int argc, char **argv)
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
sigaction(SIGHUP, &sa, NULL);
- sigaction(SIGCONT, &sa, NULL);
+ sigaction(SIGUSR1, &sa, NULL);
sa.sa_flags = 0;
pthread_sigmask(SIG_BLOCK, &sa.sa_mask, NULL);
diff --git a/src/zcompile/parser-descriptor.c b/src/zcompile/parser-descriptor.c
index 41e7f2d..152781c 100644
--- a/src/zcompile/parser-descriptor.c
+++ b/src/zcompile/parser-descriptor.c
@@ -61,7 +61,7 @@
/* FIXME: Generate .y and .l to zoneparser/ */
#include "zparser.h"
-enum desclen { PARSER_RRTYPE_DESCRIPTORS_LENGTH = 32770 }; // used to be 101
+enum desclen { PARSER_RRTYPE_DESCRIPTORS_LENGTH = 65536 }; // used to be 101
/* Taken from RFC 1035, section 3.2.4. */
static knot_lookup_table_t dns_rrclasses[] = {
@@ -364,12 +364,13 @@ static parser_rrtype_descriptor_t
/* 32769 */
[32769] = { PARSER_RRTYPE_DLV, T_DLV, "DLV", 4,
{ PARSER_RDATA_WF_SHORT, PARSER_RDATA_WF_BYTE,
- PARSER_RDATA_WF_BYTE, PARSER_RDATA_WF_BINARY } },
+ PARSER_RDATA_WF_BYTE, PARSER_RDATA_WF_BINARY }},
+ [32770 ... 65535] = { PARSER_RRTYPE_TYPEXXX, T_UTYPE, NULL, 1, { PARSER_RDATA_WF_BINARY }}
};
parser_rrtype_descriptor_t *parser_rrtype_descriptor_by_type(uint16_t type)
{
- if (type <= PARSER_RRTYPE_DLV) {
+ if (type <= 65535) {
return &knot_rrtype_descriptors[type];
}
return &knot_rrtype_descriptors[0];
diff --git a/src/zcompile/parser-util.c b/src/zcompile/parser-util.c
index dde5411..c225872 100644
--- a/src/zcompile/parser-util.c
+++ b/src/zcompile/parser-util.c
@@ -62,7 +62,7 @@
#include "common/base32hex.h"
#include "zcompile/parser-util.h"
#include "zcompile/zcompile.h"
-#include "libknot/util/descriptor.h"
+#include "parser-descriptor.h"
#include "libknot/util/utils.h"
#include "zcompile/zcompile-error.h"
@@ -812,6 +812,7 @@ uint32_t strtoserial(const char *nptr, const char **endptr)
inline void write_uint32(void *dst, uint32_t data)
{
+/*!< \todo Check what this means and delete if obsolete. */
#ifdef ALLOW_UNALIGNED_ACCESSES
*(uint32_t *) dst = htonl(data);
#else
@@ -925,7 +926,6 @@ time_t mktime_from_utc(const struct tm *tm)
}
/*!< Following functions are conversions from text to wire. */
-
//#define DEBUG_UNKNOWN_RDATA
#ifdef DEBUG_UNKNOWN_RDATA
@@ -994,6 +994,8 @@ static inline int rdata_atom_is_domain(uint16_t type, size_t index)
&& (descriptor->wireformat[index] ==
KNOT_RDATA_WF_COMPRESSED_DNAME ||
descriptor->wireformat[index] ==
+ KNOT_RDATA_WF_LITERAL_DNAME ||
+ descriptor->wireformat[index] ==
KNOT_RDATA_WF_UNCOMPRESSED_DNAME));
}
@@ -1013,6 +1015,8 @@ static inline uint8_t rdata_atom_wireformat_type(uint16_t type, size_t index)
return descriptor->wireformat[index];
}
+typedef int (*printf_t)(const char *fmt, ...);
+
/*!
* \brief Converts rdata wireformat to rdata items.
*
@@ -1028,10 +1032,12 @@ static ssize_t rdata_wireformat_to_rdata_atoms(const uint16_t *wireformat,
const uint16_t data_size,
knot_rdata_item_t **items)
{
- dbg_rdata("read length: %d\n", data_size);
- uint16_t const *end = (uint16_t *)((uint8_t *)wireformat + (data_size));
+ /*!< \todo This is so ugly, it makes me wanna puke. */
+ uint16_t const *end =
+ (uint16_t *)((uint8_t *)wireformat + (data_size));
dbg_rdata("set end pointer: %p which means length: %d\n", end,
(uint8_t *)end - (uint8_t *)wireformat);
+ dbg_rdata("Parsing following wf: ");
size_t i;
knot_rdata_item_t *temp_rdatas =
malloc(sizeof(*temp_rdatas) * MAXRDATALEN);
@@ -1050,69 +1056,78 @@ static ssize_t rdata_wireformat_to_rdata_atoms(const uint16_t *wireformat,
descriptor->length, data_size);
for (i = 0; i < descriptor->length; ++i) {
+ dbg_rdata("this particular item is type %d.\n",
+ rdata_atom_wireformat_type(rrtype, i));
int is_domain = 0;
int is_wirestore = 0;
size_t length = 0;
length = 0;
- int required = descriptor->length;
+ bool required = descriptor->fixed_items;
switch (rdata_atom_wireformat_type(rrtype, i)) {
case KNOT_RDATA_WF_COMPRESSED_DNAME:
case KNOT_RDATA_WF_UNCOMPRESSED_DNAME:
+ dbg_rdata("Parsed item is a dname.\n");
is_domain = 1;
break;
case KNOT_RDATA_WF_LITERAL_DNAME:
+ dbg_rdata("Parsed item is a literal dname.\n");
is_domain = 1;
is_wirestore = 1;
break;
case KNOT_RDATA_WF_BYTE:
+ dbg_rdata("Parsed item is a byte.\n");
length = sizeof(uint8_t);
break;
case KNOT_RDATA_WF_SHORT:
+ dbg_rdata("Parsed item is a short.\n");
length = sizeof(uint16_t);
break;
case KNOT_RDATA_WF_LONG:
+ dbg_rdata("Parsed item is a long.\n");
length = sizeof(uint32_t);
break;
+ case KNOT_RDATA_WF_APL:
+ dbg_rdata("APL data.\n");
+ case KNOT_RDATA_WF_TEXT_SINGLE:
case KNOT_RDATA_WF_TEXT:
+ dbg_rdata("TEXT rdata.\n");
case KNOT_RDATA_WF_BINARYWITHLENGTH:
+ dbg_rdata("BINARYWITHLENGTH rdata.\n");
/* Length is stored in the first byte. */
- length = 1;
- if ((uint8_t *)wireformat + length <= (uint8_t *)end) {
- // length += wireformat[length - 1];
- length += *((uint8_t *)wireformat);
- dbg_rdata("%d: set new length: %d\n", i,
- length);
- }
- /*if (buffer_position(packet) + length <= end) {
- length += buffer_current(packet)[length - 1];
- }*/
+ length = data_size;
break;
case KNOT_RDATA_WF_A:
+ dbg_rdata("Parsed item is an IPv4 address.\n");
length = sizeof(in_addr_t);
break;
case KNOT_RDATA_WF_AAAA:
+ dbg_rdata("Parsed item is an IPv6 address.\n");
length = IP6ADDRLEN;
break;
case KNOT_RDATA_WF_BINARY:
/* Remaining RDATA is binary. */
- dbg_rdata("%d: guessing length from pointers: %p %p\n",
+ dbg_rdata("BINARY: item %d: guessing length from pointers: %p %p. ",
i,
wireformat, end);
length = (uint8_t *)end - (uint8_t *)wireformat;
-// length = end - buffer_position(packet);
- break;
- case KNOT_RDATA_WF_APL:
- length = (sizeof(uint16_t) /* address family */
- + sizeof(uint8_t) /* prefix */
- + sizeof(uint8_t)); /* length */
- if ((uint8_t *)wireformat + length <= (uint8_t *)end) {
- /* Mask out negation bit. */
- length += (wireformat[length - 1]
- & APL_LENGTH_MASK);
- }
+ dbg_rdata("Result: %d.\n",
+ length);
break;
+// case KNOT_RDATA_WF_APL:
+// length = (sizeof(uint16_t) /* address family */
+// + sizeof(uint8_t) /* prefix */
+// + sizeof(uint8_t)); /* length */
+// if ((uint8_t *)wireformat + length <= (uint8_t *)end) {
+// /* Mask out negation bit. */
+// dbg_rdata("APL: length was %d. ", length);
+// length += (wireformat[data_size - 1]
+// & APL_LENGTH_MASK);
+// dbg_rdata("APL: after masking: %d.\n", length);
+// }
+// break;
case KNOT_RDATA_WF_IPSECGATEWAY:
+ dbg_rdata("Parsed item is an IPSECGATEWAY address.\n");
switch (rdata_atom_data(temp_rdatas[1])[0]) {
/* gateway type */
default:
@@ -1130,19 +1145,34 @@ static ssize_t rdata_wireformat_to_rdata_atoms(const uint16_t *wireformat,
is_wirestore = 1;
break;
}
+
break;
}
if (is_domain) {
- knot_dname_t *dname;
+ knot_dname_t *dname = NULL;
+ /*
+ * Since we don't know how many dnames there are
+ * in the whole wireformat we have to search for next
+ * '\0'.
+ */
+ for (length = 0;
+ (length < ((uint8_t *)end - (uint8_t *)wireformat))
+ && (((uint8_t *)wireformat)[length] != '\0');
+ length++) {
+ ;
+ }
+ length++;
+ dbg_rdata("item %d: length derived from position of "
+ "0: %d\n", i, length);
if (!required && (wireformat == end)) {
break;
}
- dname = knot_dname_new_from_str((char *)wireformat,
- length,
- NULL);
+ dname = knot_dname_new_from_wire((uint8_t *)wireformat,
+ length,
+ NULL);
if (dname == NULL) {
dbg_rdata("malformed dname!\n");
@@ -1150,8 +1180,9 @@ static ssize_t rdata_wireformat_to_rdata_atoms(const uint16_t *wireformat,
free(temp_rdatas);
return KNOTDZCOMPILE_EBRDATA;
}
- dbg_rdata("%d: created dname: %s\n", i,
- knot_dname_to_str(dname));
+
+ dbg_rdata("item %d: created dname: %s, length: %d\n", i,
+ knot_dname_to_str(dname), length);
if (is_wirestore) {
/*temp_rdatas[i].raw_data =
@@ -1180,7 +1211,8 @@ static ssize_t rdata_wireformat_to_rdata_atoms(const uint16_t *wireformat,
}
} else {
- dbg_rdata("%d :length: %d %d %p %p\n", i, length,
+ /*!< \todo This calculated length makes no sense! */
+ dbg_rdata("item %d :length: %d calculated: %d (%p %p)\n", i, length,
end - wireformat,
wireformat, end);
if ((uint8_t *)wireformat + length > (uint8_t *)end) {
@@ -1188,7 +1220,8 @@ static ssize_t rdata_wireformat_to_rdata_atoms(const uint16_t *wireformat,
/* Truncated RDATA. */
/*! \todo rdata purge */
free(temp_rdatas);
- dbg_rdata("truncated rdata\n");
+ dbg_rdata("truncated rdata, end pointer is exceeded by %d octets.\n",
+ (wireformat + length) - end);
return KNOTDZCOMPILE_EBRDATA;
} else {
break;
@@ -1224,15 +1257,13 @@ static ssize_t rdata_wireformat_to_rdata_atoms(const uint16_t *wireformat,
dbg_rdata("wire: %p\n", wireformat);
dbg_rdata("remaining now: %d\n",
end - wireformat);
-
}
dbg_rdata("%p %p\n", wireformat, (uint8_t *)wireformat);
if (wireformat < end) {
/* Trailing garbage. */
- dbg_rdata("w: %p e: %p %d\n", wireformat, end, end - wireformat);
-// region_destroy(temp_region);
+ dbg_rdata("Garbage: w: %p e: %p %d\n", wireformat, end, end - wireformat);
free(temp_rdatas);
return KNOTDZCOMPILE_EBRDATA;
}
@@ -1240,6 +1271,8 @@ static ssize_t rdata_wireformat_to_rdata_atoms(const uint16_t *wireformat,
*items = temp_rdatas;
/* *rdatas = (rdata_atom_type *) region_alloc_init(
region, temp_rdatas, i * sizeof(rdata_atom_type)); */
+ dbg_rdata("wf_to_rdata_atoms: Succesfully converted %d items.\n",
+ i);
return (ssize_t)i;
}
@@ -2062,8 +2095,9 @@ uint16_t * zparser_conv_loc(char *str)
zc_error_prev_line("space expected after seconds");
return NULL;
}
-
- if (sscanf(start, "%16lf", &d) != 1) {
+
+ d = strtod(start, &start);
+ if (errno != 0) {
zc_error_prev_line("error parsing seconds");
}
@@ -2160,9 +2194,10 @@ uint16_t * zparser_conv_loc(char *str)
if (!isspace((int)*str) && *str != '\0') {
++str;
}
-
- if (sscanf(start, "%16lf", &d) != 1) {
- zc_error_prev_line("error parsing altitude");
+
+ d = strtod(start, &start);
+ if (errno != 0) {
+ zc_error_prev_line("error parsing altitued");
}
alt = (uint32_t)(10000000.0 + d * 100 + 0.5);
@@ -2342,18 +2377,12 @@ void zadd_rdata_txt_wireformat(uint16_t *data, int first)
return;
}
dbg_zp("Adding text!\n");
-// hex_print(data + 1, data[0]);
knot_rdata_item_t *rd;
/* First STR in str_seq, allocate 65K in first unused rdata
* else find last used rdata */
if (first) {
rd = &parser->temporary_items[parser->rdata_count];
-// if ((rd->data = (uint8_t *) region_alloc(parser->rr_region,
-// sizeof(uint8_t) + 65535 * sizeof(uint8_t))) == NULL) {
-// zc_error_prev_line("Could not allocate memory for TXT RR");
-// return;
-// }
rd->raw_data = alloc_rdata(65535 * sizeof(uint8_t));
if (rd->raw_data == NULL) {
parser->error_occurred = KNOTDZCOMPILE_ENOMEM;
@@ -2361,7 +2390,6 @@ void zadd_rdata_txt_wireformat(uint16_t *data, int first)
parser->rdata_count++;
rd->raw_data[0] = 0;
} else {
-// assert(0);
rd = &parser->temporary_items[parser->rdata_count-1];
}
@@ -2392,8 +2420,8 @@ void zadd_rdata_domain(knot_dname_t *dname)
void parse_unknown_rdata(uint16_t type, uint16_t *wireformat)
{
- dbg_rdata("parsing unknown rdata for type: %d\n", type);
-// buffer_type packet;
+ dbg_rdata("parsing unknown rdata for type: %s (%d)\n",
+ knot_rrtype_to_string(type), type);
uint16_t size;
ssize_t rdata_count;
ssize_t i;
@@ -2405,14 +2433,13 @@ void parse_unknown_rdata(uint16_t type, uint16_t *wireformat)
return;
}
-// buffer_create_from(&packet, wireformat + 1, *wireformat);
rdata_count = rdata_wireformat_to_rdata_atoms(wireformat + 1, type,
size, &items);
-// dbg_rdata("got %d items\n", rdata_count);
- dbg_rdata("wf to items returned error: %s (%d)\n",
- error_to_str(knot_zcompile_error_msgs, rdata_count),
- rdata_count);
+ dbg_rdata("got %d items\n", rdata_count);
if (rdata_count < 0) {
+ dbg_rdata("wf to items returned error: %s (%d)\n",
+ error_to_str(knot_zcompile_error_msgs, rdata_count),
+ rdata_count);
zc_error_prev_line("bad unknown RDATA\n");
/*!< \todo leaks */
return;
@@ -2429,6 +2456,8 @@ void parse_unknown_rdata(uint16_t type, uint16_t *wireformat)
free(items);
/* Free wireformat */
free(wireformat);
+
+ dbg_rdata("parse_unknown_rdata: Successfuly parsed unknown rdata.\n");
}
void set_bitnsec(uint8_t bits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE],
diff --git a/src/zcompile/zcompile.c b/src/zcompile/zcompile.c
index d84feb7..263d0d7 100644
--- a/src/zcompile/zcompile.c
+++ b/src/zcompile/zcompile.c
@@ -36,6 +36,8 @@
#include <sys/stat.h>
#include "common/base32hex.h"
+#include "common/log.h"
+#include "knot/other/debug.h"
#include "zcompile/zcompile.h"
#include "zcompile/parser-util.h"
#include "zcompile/zcompile-error.h"
@@ -54,12 +56,6 @@ static long int totalrrs = 0;
extern FILE *zp_get_in(void *scanner);
-#ifdef KNOT_COMPILER_DEBUG
-#define dbg_zp(msg...) fprintf(stderr, msg)
-#else
-#define dbg_zp(msg...)
-#endif
-
/*!
* \brief Adds RRSet to list.
*
@@ -86,6 +82,8 @@ 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 KNOTDZCOMPILE_EOK;
}
@@ -109,6 +107,8 @@ static void rrset_list_delete(rrset_list_t **head)
}
*head = NULL;
+
+ dbg_zp("zp: list_delete: List deleleted.\n");
}
static int find_rrset_for_rrsig_in_zone(knot_zone_contents_t *zone,
@@ -127,10 +127,11 @@ static int find_rrset_for_rrsig_in_zone(knot_zone_contents_t *zone,
rrsig->owner);
}
- dbg_zp("Found this node for RRSIG: %p\n",
- tmp_node);
+ dbg_zp_verb("zp: find_rr_for_sig: Found this node for RRSIG: %p.\n",
+ tmp_node);
if (tmp_node == NULL) {
+ dbg_zp("zp: find_rr_for_sig: There is no node for this RR.\n");
return KNOTDZCOMPILE_EINVAL;
}
@@ -139,23 +140,37 @@ static int find_rrset_for_rrsig_in_zone(knot_zone_contents_t *zone,
knot_rdata_rrsig_type_covered(
rrsig->rdata));
- dbg_zp("Found this rrset for RRSIG: %p\n",
- tmp_rrset);
+ dbg_zp_verb("zp: find_rr_for_sig: Found this RRSet for RRSIG: %p.\n",
+ tmp_rrset);
if (tmp_rrset == NULL) {
+ dbg_zp("zp: find_rr_for_sig: There is no RRSet "
+ "for this RRSIG.\n");
return KNOTDZCOMPILE_EINVAL;
}
if (tmp_rrset->rrsigs != NULL) {
- knot_zone_contents_add_rrsigs(zone, rrsig, &tmp_rrset, &tmp_node,
+ int ret = knot_zone_contents_add_rrsigs(zone, rrsig,
+ &tmp_rrset, &tmp_node,
KNOT_RRSET_DUPL_MERGE, 1);
+ if (ret != KNOT_EOK) {
+ dbg_zp("zp: find_rr_for_sig: Cannot add RRSIG.\n");
+ return ret;
+ }
knot_rrset_free(&rrsig);
} else {
- knot_zone_contents_add_rrsigs(zone, rrsig, &tmp_rrset, &tmp_node,
+ int ret = knot_zone_contents_add_rrsigs(zone, rrsig,
+ &tmp_rrset, &tmp_node,
KNOT_RRSET_DUPL_SKIP, 1);
+ if (ret != KNOT_EOK) {
+ dbg_zp("zp: find_rr_for_sig: Cannot add RRSIG.\n");
+ return ret;
+ }
}
-
+
+ dbg_zp("zp: find_rr_for_sig: Found node: %p found rrset: %p.\n",
+ tmo_node, tmp_rrset);
return KNOTDZCOMPILE_EOK;
}
@@ -173,18 +188,25 @@ static int find_rrset_for_rrsig_in_node(knot_zone_contents_t *zone,
knot_node_get_rrset(node, rrsig_type_covered(rrsig));
if (tmp_rrset == NULL) {
+ dbg_zp("zp: find_rr_for_sig_in_node: Node does not contain "
+ "RRSet of type %s.\n",
+ knot_rrtype_to_string(rrsig_type_covered(rrsig)));
return KNOTDZCOMPILE_EINVAL;
}
if (tmp_rrset->rrsigs != NULL) {
- if (knot_zone_contents_add_rrsigs(zone, rrsig, &tmp_rrset, &node,
+ if (knot_zone_contents_add_rrsigs(zone, rrsig,
+ &tmp_rrset, &node,
KNOT_RRSET_DUPL_MERGE, 1) < 0) {
+ dbg_zp("zp: find_rr_for_sig: Cannot add RRSIG.\n");
return KNOTDZCOMPILE_EINVAL;
}
knot_rrset_free(&rrsig);
} else {
- if (knot_zone_contents_add_rrsigs(zone, rrsig, &tmp_rrset, &node,
+ if (knot_zone_contents_add_rrsigs(zone, rrsig,
+ &tmp_rrset, &node,
KNOT_RRSET_DUPL_SKIP, 1) < 0) {
+ dbg_zp("zp: find_rr_for_sig: Cannot add RRSIG.\n");
return KNOTDZCOMPILE_EINVAL;
}
}
@@ -201,6 +223,8 @@ static knot_node_t *create_node(knot_zone_contents_t *zone,
knot_node_t *(*node_get_func)(const knot_zone_contents_t *zone,
const knot_dname_t *owner))
{
+ dbg_zp_verb("zp: create_node: Creating node using RRSet: %p.\n",
+ current_rrset);
knot_node_t *node =
knot_node_new(current_rrset->owner, NULL, 0);
if (node_add_func(zone, node, 1, 0, 1) != 0) {
@@ -215,6 +239,8 @@ static knot_node_t *create_node(knot_zone_contents_t *zone,
static void process_rrsigs_in_node(knot_zone_contents_t *zone,
knot_node_t *node)
{
+ dbg_zp_verb("zp: process_rrsigs: Processing RRSIGS in node: %p.\n",
+ node);
rrset_list_t *tmp = parser->node_rrsigs;
while (tmp != NULL) {
if (find_rrset_for_rrsig_in_node(zone, node,
@@ -238,18 +264,22 @@ int process_rr(void)
knot_rrtype_descriptor_t *descriptor =
knot_rrtype_descriptor_by_type(current_rrset->type);
- dbg_zp("%s\n", knot_dname_to_str(parser->current_rrset->owner));
- dbg_zp("type: %s\n", knot_rrtype_to_string(parser->current_rrset->type));
- dbg_zp("rdata count: %d\n", parser->current_rrset->rdata->count);
-// hex_print(parser->current_rrset->rdata->items[0].raw_data,
-// parser->current_rrset->rdata->items[0].raw_data[0]);
+dbg_zp_exec_detail(
+ char *name = knot_dname_to_str(parser->current_rrset->owner);
+ dbg_zp_detail("zp: process_rr: Processing RR owned by: %s .\n",
+ name);
+ free(name);
+);
+ dbg_zp_verb("zp: process_rr: Processing type: %s.\n",
+ knot_rrtype_to_string(parser->current_rrset->type));
+ dbg_zp_verb("zp: process_rr: RDATA count: %d.\n",\
+ parser->current_rrset->rdata->count);
if (descriptor->fixed_items) {
assert(current_rrset->rdata->count == descriptor->length);
}
assert(current_rrset->rdata->count > 0);
-
assert(knot_dname_is_fqdn(current_rrset->owner));
int (*node_add_func)(knot_zone_contents_t *, knot_node_t *, int,
@@ -312,12 +342,15 @@ int process_rr(void)
current_rrset->rclass,
current_rrset->ttl);
if (tmp_rrsig == NULL) {
+ dbg_zp("zp: process_rr: Cannot create tmp RRSIG.\n");
return KNOTDZCOMPILE_ENOMEM;
}
if (knot_rrset_add_rdata(tmp_rrsig,
current_rrset->rdata) != KNOT_EOK) {
knot_rrset_free(&tmp_rrsig);
+ dbg_zp("zp: process_rr: Cannot add data to tmp"
+ " RRSIG.\n");
return KNOTDZCOMPILE_EBRDATA;
}
@@ -353,18 +386,24 @@ int process_rr(void)
current_rrset, node_add_func,
node_get_func)) == NULL) {
knot_rrset_free(&tmp_rrsig);
+ dbg_zp("zp: process_rr: Cannot "
+ "create new node.\n");
return KNOTDZCOMPILE_EBADNODE;
}
}
}
if (rrset_list_add(&parser->node_rrsigs, tmp_rrsig) != 0) {
+ dbg_zp("zp: process_rr: Cannot "
+ "create new node.\n");
return KNOTDZCOMPILE_ENOMEM;
}
-
+
+ dbg_zp_verb("zp: process_rr: RRSIG proccesed successfully.\n");
return KNOTDZCOMPILE_EOK;
}
-
+
+ /*! \todo Move RRSIG and RRSet handling to funtions. */
assert(current_rrset->type != KNOT_RRTYPE_RRSIG);
knot_node_t *node = NULL;
@@ -395,6 +434,8 @@ int process_rr(void)
if ((node = create_node(contents, current_rrset,
node_add_func,
node_get_func)) == NULL) {
+ dbg_zp("zp: process_rr: Cannot "
+ "create new node.\n");
return KNOTDZCOMPILE_EBADNODE;
}
}
@@ -406,11 +447,15 @@ int process_rr(void)
current_rrset->rclass,
current_rrset->ttl);
if (rrset == NULL) {
+ dbg_zp("zp: process_rr: Cannot "
+ "create new RRSet.\n");
return KNOTDZCOMPILE_ENOMEM;
}
if (knot_rrset_add_rdata(rrset, current_rrset->rdata) != 0) {
- free(rrset);
+ knot_rrset_free(&rrset);
+ dbg_zp("zp: process_rr: Cannot "
+ "add RDATA to RRSet.\n");
return KNOTDZCOMPILE_EBRDATA;
}
@@ -418,7 +463,9 @@ int process_rr(void)
* any rrset to skip */
if (knot_zone_contents_add_rrset(contents, rrset, &node,
KNOT_RRSET_DUPL_SKIP, 1) < 0) {
- free(rrset);
+ knot_rrset_free(&rrset);
+ dbg_zp("zp: process_rr: Cannot "
+ "add RDATA to RRSet.\n");
return KNOTDZCOMPILE_EBRDATA;
}
} else {
@@ -426,12 +473,14 @@ int process_rr(void)
KNOT_RRTYPE_RRSIG && rrset->ttl !=
current_rrset->ttl) {
zc_error_prev_line(
- "TTL does not match the TTL of the RRset");
+ "TTL does not match the TTL of the RRSet");
}
if (knot_zone_contents_add_rrset(contents, current_rrset,
&node,
KNOT_RRSET_DUPL_MERGE, 1) < 0) {
+ dbg_zp("zp: process_rr: Cannot "
+ "merge RRSets.\n");
return KNOTDZCOMPILE_EBRDATA;
}
}
@@ -441,9 +490,10 @@ int process_rr(void)
}
parser->last_node = node;
-
++totalrrs;
-
+
+ dbg_zp_verb("zp: process_rr: RRSet %p processed successfully.\n",
+ parser->current_rrset);
return KNOTDZCOMPILE_EOK;
}
@@ -454,12 +504,14 @@ static uint find_rrsets_orphans(knot_zone_contents_t *zone, rrset_list_t
while (head != NULL) {
if (find_rrset_for_rrsig_in_zone(zone, head->data) == 0) {
found_rrsets += 1;
- dbg_zp("RRSET succesfully found: owner %s type %s\n",
+ dbg_zp("zp: find_orphans: "
+ "RRSet succesfully found: owner %s type %s\n",
knot_dname_to_str(head->data->owner),
knot_rrtype_to_string(head->data->type));
}
else { /* we can throw it away now */
- dbg_zp("RRSet not found for RRSIG: %s (%s)\n",
+ dbg_zp("zp: find_orphans: "
+ "RRSet not found for RRSIG: %s (%s)\n",
knot_dname_to_str(head->data->owner),
knot_rrtype_to_string(
knot_rdata_rrsig_type_covered(head->data->rdata)));
@@ -473,6 +525,10 @@ static uint find_rrsets_orphans(knot_zone_contents_t *zone, rrset_list_t
static int zone_open(const char *filename, uint32_t ttl, uint16_t rclass,
knot_node_t *origin, void *scanner, knot_dname_t *origin_from_config)
{
+ /*!< \todo #1676 Implement proper locking. */
+ zparser_init(filename, ttl, rclass, origin, origin_from_config);
+
+
/* Open the zone file... */
if (strcmp(filename, "-") == 0) {
zp_set_in(stdin, scanner);
@@ -487,11 +543,7 @@ static int zone_open(const char *filename, uint32_t ttl, uint16_t rclass,
return 0;
}
}
-
- /*!< \todo #1676 Implement proper locking. */
-
- zparser_init(filename, ttl, rclass, origin, origin_from_config);
-
+
return 1;
}
@@ -503,6 +555,8 @@ int zone_read(const char *name, const char *zonefile, const char *outfile,
zonefile);
return KNOTDZCOMPILE_EINVAL;
}
+
+ dbg_zp("zp: zone_read: Reading zone: %s.\n", zonefile);
/* Check that we can write to outfile. */
FILE *f = fopen(outfile, "wb");
@@ -526,9 +580,8 @@ int zone_read(const char *name, const char *zonefile, const char *outfile,
}
knot_node_t *origin_node = knot_node_new(dname, NULL, 0);
-
+ knot_dname_release(dname); /* Stored in node or should be freed. */
if (origin_node == NULL) {
- knot_dname_release(dname);
return KNOTDZCOMPILE_ENOMEM;
}
@@ -554,10 +607,9 @@ int zone_read(const char *name, const char *zonefile, const char *outfile,
origin_from_config)) {
zc_error_prev_line("Cannot open '%s' (%s).",
zonefile, strerror(errno));
- zparser_free();
zp_lex_destroy(scanner);
knot_dname_release(origin_from_config);
- knot_node_free(&origin_node, 0);
+// knot_node_free(&origin_node, 0);
return KNOTDZCOMPILE_EZONEINVAL;
}
@@ -566,7 +618,8 @@ int zone_read(const char *name, const char *zonefile, const char *outfile,
FILE *in_file = (FILE *)zp_get_in(scanner);
fclose(in_file);
zp_lex_destroy(scanner);
- knot_node_free(&origin_node, 0);
+ knot_dname_release(origin_from_config);
+// knot_node_free(&origin_node, 0);
return KNOTDZCOMPILE_ESYNT;
}
@@ -579,7 +632,8 @@ int zone_read(const char *name, const char *zonefile, const char *outfile,
/*!< \todo #1676 Implement proper locking. */
- dbg_zp("zp complete %p\n", parser->current_zone);
+ dbg_zp("zp: zone_read: Parse complete for %s.\n",
+ zonefile);
if (parser->last_node && parser->node_rrsigs != NULL) {
/* assign rrsigs to last node in the zone*/
@@ -588,15 +642,15 @@ int zone_read(const char *name, const char *zonefile, const char *outfile,
rrset_list_delete(&parser->node_rrsigs);
}
- dbg_zp("zone parsed\n");
+ dbg_zp("zp: zone_read: RRSIGs processed.\n");
if (!(parser->current_zone &&
knot_node_rrset(parser->current_zone->contents->apex,
KNOT_RRTYPE_SOA))) {
zc_error_prev_line("Zone file does not contain SOA record!\n");
- knot_zone_deep_free(&parser->current_zone, 1);
- zparser_free();
- knot_node_free(&origin_node, 0);
+// knot_zone_deep_free(&parser->current_zone, 1);
+ knot_dname_release(origin_from_config);
+// knot_node_free(&origin_node, 0);
return KNOTDZCOMPILE_EZONEINVAL;
}
@@ -604,7 +658,7 @@ int zone_read(const char *name, const char *zonefile, const char *outfile,
found_orphans = find_rrsets_orphans(contents,
parser->rrsig_orphans);
- dbg_zp("%u orphans found\n", found_orphans);
+ dbg_zp("zp: zone_read: %u RRSIG orphans found.\n", found_orphans);
rrset_list_delete(&parser->rrsig_orphans);
@@ -618,17 +672,17 @@ int zone_read(const char *name, const char *zonefile, const char *outfile,
/*! \todo Check return value. */
knot_zone_contents_adjust(contents);
- dbg_zp("rdata adjusted\n");
+ dbg_zp("zp: zone_read: Zone adjusted.\n");
if (parser->errors != 0) {
- fprintf(stderr,
- "Parser finished with error, not dumping the zone!\n");
+ log_zone_error("Parser finished with %d error(s), "
+ "not dumping the zone!\n",
+ parser->errors);
} else {
int fd = open(outfile, O_RDWR | O_CREAT | O_TRUNC, S_IRWXU | S_IRWXG);
if (fd < 0) {
- fprintf(stderr,
- "Could not open destination file for db: %s.\n",
- outfile);
+ log_zone_error("Could not open destination file for db: %s.\n",
+ outfile);
totalerrors++;
} else {
crc_t crc;
@@ -636,22 +690,22 @@ int zone_read(const char *name, const char *zonefile, const char *outfile,
semantic_checks,
zonefile, &crc);
if (ret != KNOT_EOK) {
- fprintf(stderr, "Could not dump zone, reason: "
- "%s.\n", knot_strerror(ret));
+ log_zone_error("Could not dump zone, reason: "
+ "%s.\n", knot_strerror(ret));
remove(outfile);
totalerrors++;
} else {
/* Write CRC file. */
char *crc_path = knot_zdump_crc_file(outfile);
if (crc_path == NULL) {
- fprintf(stderr,
- "Could not get crc file path.\n");
+ log_zone_error(
+ "Could not get crc file path.\n");
remove(outfile);
totalerrors++;
} else {
FILE *f_crc = fopen(crc_path, "w");
if (f_crc == NULL) {
- fprintf(stderr,
+ log_zone_error(
"Could not open crc file \n");
remove(outfile);
totalerrors++;
@@ -667,12 +721,13 @@ int zone_read(const char *name, const char *zonefile, const char *outfile,
}
- dbg_zp("zone dumped.\n");
+ dbg_zp("zp: zone_read: Zone %s dumped successfully.\n",
+ zonefile);
}
fflush(stdout);
totalerrors += parser->errors;
- zparser_free();
+ knot_dname_release(origin_from_config);
return totalerrors;
}
diff --git a/src/zcompile/zcompile_main.c b/src/zcompile/zcompile_main.c
index c873af6..4b631ce 100644
--- a/src/zcompile/zcompile_main.c
+++ b/src/zcompile/zcompile_main.c
@@ -19,6 +19,7 @@
#include <stdlib.h>
#include "zcompile/zcompile.h"
+#include "common/log.h"
#include <config.h>
static void help(int argc, char **argv)
@@ -81,21 +82,21 @@ int main(int argc, char **argv)
origin = argv[optind];
zonefile = argv[optind + 1];
- // Initialize log (no output)
- //log_init(0);
- //log_levels_set(LOGT_STDOUT, LOG_ANY, LOG_MASK(LOG_DEBUG));
-
- printf("Parsing file '%s', origin '%s' ...\n",
- zonefile, origin);
+ // Initialize log (no syslog)
+ log_init();
+ log_levels_set(LOGT_SYSLOG, LOG_ANY, 0);
+ log_zone_info("Parsing file '%s', origin '%s' ...\n",
+ zonefile, origin);
parser = zparser_create();
if (!parser) {
- fprintf(stderr, "Failed to create parser.\n");
+ log_server_error("Failed to create parser.\n");
//log_close();
return 1;
}
int error = zone_read(origin, zonefile, outfile, semantic_checks);
+ zparser_free();
if (error != 0) {
/* FIXME! */
@@ -107,7 +108,7 @@ int main(int argc, char **argv)
// }
return 1;
} else {
- printf("Compilation successful.\n");
+ log_zone_info("Compilation of '%s' successful.\n", origin);
}
//log_close();
diff --git a/src/zcompile/zparser.y b/src/zcompile/zparser.y
index 59f037d..b353fbe 100644
--- a/src/zcompile/zparser.y
+++ b/src/zcompile/zparser.y
@@ -54,6 +54,7 @@
#include <assert.h>
#include "zcompile/parser-util.h"
+#include "common/log.h"
#include "libknot/libknot.h"
#include "zcompile/zcompile.h"
@@ -198,7 +199,7 @@ line: NL
assert(parser->current_rrset->rdata == NULL);
if (knot_rrset_add_rdata(parser->current_rrset, tmp_rdata)
!= 0) {
- fprintf(stderr, "Could not add rdata!\n");
+ log_zone_error("Could not add rdata!\n");
}
// tmp_rdata->next = tmp_rdata;
// parser->current_rrset->rdata = tmp_rdata;
@@ -223,7 +224,7 @@ line: NL
if ((ret = process_rr()) != 0) {
char *name =
knot_dname_to_str(parser->current_rrset->owner);
- fprintf(stderr, "Error: could not process RRSet\n"
+ log_zone_error("Error: could not process RRSet\n"
"owner: %s reason: %s\n",
name,
error_to_str(knot_zcompile_error_msgs, ret));
@@ -258,7 +259,7 @@ line: NL
* of the converting function was not able to convert. */
if (parser->error_occurred == KNOTDZCOMPILE_ENOMEM) {
/* Ran out of memory in converting functions. */
- fprintf(stderr, "Parser ran out "
+ log_zone_error("Parser ran out "
"of memory, aborting!\n");
knot_rrset_deep_free(&(parser->current_rrset),
0, 0, 0);
@@ -691,7 +692,7 @@ str_sp_seq: STR
char *result = malloc($1.len + $3.len + 1);
if (result == NULL) {
ERR_ALLOC_FAILED;
- fprintf(stderr, "Parser ran out of memory, aborting!\n");
+ log_zone_error("Parser ran out of memory, aborting!\n");
knot_rrset_deep_free(&(parser->current_rrset),
0, 0, 0);
knot_zone_deep_free(&(parser->current_zone),
@@ -719,7 +720,7 @@ str_dot_seq: STR
char *result = malloc($1.len + $3.len + 1);
if (result == NULL) {
ERR_ALLOC_FAILED;
- fprintf(stderr, "Parser ran out of memory, aborting!\n");
+ log_zone_error("Parser ran out of memory, aborting!\n");
knot_rrset_deep_free(&(parser->current_rrset),
0, 0, 0);
knot_zone_deep_free(&(parser->current_zone),
@@ -751,7 +752,7 @@ dotted_str: STR
char *result = malloc($1.len + 2);
if (result == NULL) {
ERR_ALLOC_FAILED;
- fprintf(stderr, "Parser ran out of memory, aborting!\n");
+ log_zone_error("Parser ran out of memory, aborting!\n");
knot_rrset_deep_free(&(parser->current_rrset),
0, 0, 0);
knot_zone_deep_free(&(parser->current_zone),
@@ -771,7 +772,7 @@ dotted_str: STR
char *result = malloc($1.len + $3.len + 2);
if (result == NULL) {
ERR_ALLOC_FAILED;
- fprintf(stderr, "Parser ran out of memory, aborting!\n");
+ log_zone_error("Parser ran out of memory, aborting!\n");
knot_rrset_deep_free(&(parser->current_rrset),
0, 0, 0);
knot_zone_deep_free(&(parser->current_zone),
@@ -1563,23 +1564,19 @@ zparser_type *zparser_create()
result->current_rrset = knot_rrset_new(NULL, 0, 0, 0);
if (result->current_rrset == NULL) {
- ERR_ALLOC_FAILED;
free(result->temporary_items);
free(result);
return NULL;
}
result->root_domain = knot_dname_new_from_str(".", 1, NULL);
-// printf("THE NEW ROOT: %p\n", result->root_domain);
if (result->root_domain == NULL) {
- ERR_ALLOC_FAILED;
free(result->temporary_items);
free(result->current_rrset);
free(result);
return NULL;
}
- knot_dname_retain(result->root_domain);
return result;
}
@@ -1610,6 +1607,7 @@ zparser_init(const char *filename, uint32_t ttl, uint16_t rclass,
parser->filename = filename;
parser->rdata_count = 0;
parser->origin_from_config = origin_from_config;
+ knot_dname_retain(origin_from_config);
parser->last_node = origin;
// parser->root_domain = NULL;
@@ -1630,9 +1628,10 @@ zparser_init(const char *filename, uint32_t ttl, uint16_t rclass,
void zparser_free()
{
-// knot_dname_release(parser->root_domain);
+ knot_dname_release(parser->root_domain);
// knot_dname_release(parser->prev_dname);
- knot_dname_free(&parser->origin_from_config);
+ knot_zone_deep_free(&parser->current_zone, 1);
+ knot_dname_release(parser->origin_from_config);
free(parser->temporary_items);
if (parser->current_rrset != NULL) {
free(parser->current_rrset);
@@ -1649,13 +1648,29 @@ yyerror(void *scanner, const char *message)
static void
error_va_list(unsigned line, const char *fmt, va_list args)
{
+ char sbuf[4096] = {0};
+ size_t buflen = sizeof(sbuf) - 1;
+ char *buf = sbuf;
+ int wb = 0;
if (parser->filename) {
- fprintf(stderr, "%s:%u: ", parser->filename, line);
+ wb = snprintf(buf, buflen, "%s:%u: ",
+ parser->filename, line);
+ if (wb > 0) {
+ buf += wb;
+ buflen -= wb;
+ }
}
- fprintf(stderr, "error: ");
- vfprintf(stderr, fmt, args);
- fprintf(stderr, "\n");
-
+
+ wb = vsnprintf(buf, buflen, fmt, args);
+ if (wb > 0) {
+ buf += wb;
+ buflen -= wb;
+ *buf = '\n';
+ *(buf + 1) = '\0';
+ }
+
+ log_zone_error("%s", sbuf);
+
++parser->errors;
parser->error_occurred = 1;
}
@@ -1685,12 +1700,28 @@ zc_error(const char *fmt, ...)
static void
warning_va_list(unsigned line, const char *fmt, va_list args)
{
+ char sbuf[4096] = {0};
+ size_t buflen = sizeof(sbuf) - 1;
+ char *buf = sbuf;
+ int wb = 0;
if (parser->filename) {
- fprintf(stderr, "%s:%u: ", parser->filename, line);
+ wb = snprintf(buf, buflen, "%s:%u: ",
+ parser->filename, line);
+ if (wb > 0) {
+ buf += wb;
+ buflen -= wb;
+ }
}
- fprintf(stderr, "warning: ");
- vfprintf(stderr, fmt, args);
- fprintf(stderr, "\n");
+
+ wb = vsnprintf(buf, buflen, fmt, args);
+ if (wb > 0) {
+ buf += wb;
+ buflen -= wb;
+ *buf = '\n';
+ *(buf + 1) = '\0';
+ }
+
+ log_zone_warning("%s", sbuf);
}
void