Hello community,
here is the log from the commit of package knot for openSUSE:Factory checked in at 2015-12-09 19:49:34
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/knot (Old)
and /work/SRC/openSUSE:Factory/.knot.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "knot"
Changes:
--------
--- /work/SRC/openSUSE:Factory/knot/knot.changes 2015-09-11 09:04:56.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.knot.new/knot.changes 2015-12-09 22:21:07.000000000 +0100
@@ -1,0 +2,13 @@
+Tue Nov 24 22:24:55 UTC 2015 - mrueckert@suse.de
+
+- update to 1.6.6
+ - Fix daemon startup systemd notification
+ - Out-of-bound read in packet parser for malformed NAPTR records
+ (LibFuzzer)
+ - Add rosedb module
+- enable rosedb
+- refresh patches to apply cleanly again
+ 0001-loosen-openssl-dependency.patch
+ 0002-make-configure.ac-compatible-with-old-tools.patch
+
+-------------------------------------------------------------------
Old:
----
knot-1.6.5.tar.xz
New:
----
knot-1.6.6.tar.xz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ knot.spec ++++++
--- /var/tmp/diff_new_pack.VE6CQN/_old 2015-12-09 22:21:09.000000000 +0100
+++ /var/tmp/diff_new_pack.VE6CQN/_new 2015-12-09 22:21:09.000000000 +0100
@@ -22,6 +22,11 @@
%bcond_with dnstap
%bcond_with lto
%endif
+%if 0%{?suse_version} > 1310
+%bcond_without rosedb
+%else
+%bcond_with rosedb
+%endif
%if 0%{?suse_version} > 1230
%bcond_without systemd
%else
@@ -29,7 +34,7 @@
%endif
Name: knot
-Version: 1.6.5
+Version: 1.6.6
Release: 0
%define pkg_name knot
Summary: An authoritative DNS daemon
@@ -53,7 +58,7 @@
BuildRequires: xz
Requires(pre): pwdutils
BuildRoot: %{_tmppath}/%{pkg_name}-%{version}-build
-%if 0%{?suse_version} > 1310
+%if %{with rosedb}
BuildRequires: lmdb-devel
%endif
%if 0%{?suse_version} > 1140
@@ -95,6 +100,9 @@
%if %{with dnstap}
--enable-dnstap=yes \
%endif
+%if %{with rosedb}
+ --enable-rosedb \
+%endif
%if %{with systemd}
--enable-systemd=yes \
%endif
++++++ 0001-loosen-openssl-dependency.patch ++++++
--- /var/tmp/diff_new_pack.VE6CQN/_old 2015-12-09 22:21:09.000000000 +0100
+++ /var/tmp/diff_new_pack.VE6CQN/_new 2015-12-09 22:21:09.000000000 +0100
@@ -1,8 +1,8 @@
-Index: knot-1.6.5/configure.ac
+Index: knot-1.6.6/configure.ac
===================================================================
---- knot-1.6.5.orig/configure.ac
-+++ knot-1.6.5/configure.ac
-@@ -293,14 +293,6 @@ AS_IF([test "$with_openssl" = "no"],[
+--- knot-1.6.6.orig/configure.ac
++++ knot-1.6.6/configure.ac
+@@ -298,14 +298,6 @@ AS_IF([test "$with_openssl" = "no"],[
AC_MSG_ERROR([OpenSSL library is required.])
])
++++++ 0002-make-configure.ac-compatible-with-old-tools.patch ++++++
--- /var/tmp/diff_new_pack.VE6CQN/_old 2015-12-09 22:21:09.000000000 +0100
+++ /var/tmp/diff_new_pack.VE6CQN/_new 2015-12-09 22:21:09.000000000 +0100
@@ -5,7 +5,7 @@
@@ -2,8 +2,8 @@
AC_PREREQ([2.60])
- AC_INIT([knot], [1.6.5], [knot-dns@labs.nic.cz])
+ AC_INIT([knot], [1.6.6], [knot-dns@labs.nic.cz])
-AM_INIT_AUTOMAKE([gnits subdir-objects dist-xz -Wall -Werror])
-AM_SILENT_RULES([yes])
+AM_INIT_AUTOMAKE([gnits subdir-objects -Wall -Werror])
++++++ knot-1.6.5.tar.xz -> knot-1.6.6.tar.xz ++++++
++++ 3706 lines of diff (skipped)
++++ retrying with extended exclude list
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/knot-1.6.5/Makefile.am new/knot-1.6.6/Makefile.am
--- old/knot-1.6.5/Makefile.am 2015-09-01 16:43:42.000000000 +0200
+++ new/knot-1.6.6/Makefile.am 2015-11-24 17:36:40.000000000 +0100
@@ -2,7 +2,8 @@
SUBDIRS = libtap src tests samples doc man patches
AM_DISTCHECK_CONFIGURE_FLAGS = \
- --disable-code-coverage
+ --disable-code-coverage \
+ --enable-rosedb
CODE_COVERAGE_INFO = coverage.info
CODE_COVERAGE_HTML = coverage.html
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/knot-1.6.5/NEWS new/knot-1.6.6/NEWS
--- old/knot-1.6.5/NEWS 2015-09-01 16:43:42.000000000 +0200
+++ new/knot-1.6.6/NEWS 2015-11-24 17:36:40.000000000 +0100
@@ -1,3 +1,15 @@
+Knot DNS 1.6.6 (2015-11-24)
+===========================
+
+Bugfixes:
+---------
+ - Fix daemon startup systemd notification
+ - Out-of-bound read in packet parser for malformed NAPTR records (LibFuzzer)
+
+Features:
+---------
+ - Add rosedb module
+
Knot DNS 1.6.5 (2015-09-01)
===========================
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/knot-1.6.5/ar-lib new/knot-1.6.6/ar-lib
--- old/knot-1.6.5/ar-lib 2015-09-01 16:43:53.000000000 +0200
+++ new/knot-1.6.6/ar-lib 2015-11-24 17:36:51.000000000 +0100
@@ -4,7 +4,7 @@
me=ar-lib
scriptversion=2012-03-01.08; # UTC
-# Copyright (C) 2010-2013 Free Software Foundation, Inc.
+# Copyright (C) 2010-2014 Free Software Foundation, Inc.
# Written by Peter Rosin .
#
# This program is free software; you can redistribute it and/or modify
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/knot-1.6.5/compile new/knot-1.6.6/compile
--- old/knot-1.6.5/compile 2015-09-01 16:43:53.000000000 +0200
+++ new/knot-1.6.6/compile 2015-11-24 17:36:51.000000000 +0100
@@ -3,7 +3,7 @@
scriptversion=2012-10-14.11; # UTC
-# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
# Written by Tom Tromey .
#
# This program is free software; you can redistribute it and/or modify
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/knot-1.6.5/configure.ac new/knot-1.6.6/configure.ac
--- old/knot-1.6.5/configure.ac 2015-09-01 16:43:42.000000000 +0200
+++ new/knot-1.6.6/configure.ac 2015-11-24 17:36:40.000000000 +0100
@@ -1,7 +1,7 @@
# -*- Autoconf -*-
AC_PREREQ([2.60])
-AC_INIT([knot], [1.6.5], [knot-dns@labs.nic.cz])
+AC_INIT([knot], [1.6.6], [knot-dns@labs.nic.cz])
AM_INIT_AUTOMAKE([gnits subdir-objects dist-xz -Wall -Werror])
AM_SILENT_RULES([yes])
AC_CONFIG_SRCDIR([src/knot/main.c])
@@ -94,20 +94,25 @@
AS_HELP_STRING([--enable-systemd=auto|yes|no], [enable systemd integration [default=auto]]),
[enable_systemd="$enableval"], [enable_systemd=auto])
-AS_IF([test "$enable_daemon" = "yes"],[
-
AS_IF([test "$enable_systemd" != "no"],[
AS_CASE([$enable_systemd],
[auto],[PKG_CHECK_MODULES([systemd], [libsystemd], [enable_systemd=yes], [
PKG_CHECK_MODULES([systemd], [libsystemd-daemon libsystemd-journal], [enable_systemd=yes], [enable_systemd=no])])],
[yes],[PKG_CHECK_MODULES([systemd], [libsystemd], [], [
- → PKG_CHECK_MODULES([systemd], [libsystemd-daemon libsystemd-journal])])],
+ PKG_CHECK_MODULES([systemd], [libsystemd-daemon libsystemd-journal])])],
[*],[AC_MSG_ERROR([Invalid value of --enable-systemd.])])
])
AS_IF([test "$enable_systemd" = "yes"],[
AC_DEFINE([ENABLE_SYSTEMD], [1], [Use systemd integration.])])
-])
+
+dnl Check for rosedb module
+AC_ARG_ENABLE([rosedb],
+ AS_HELP_STRING([--enable-rosedb], [Enable static RR query module.]),
+ [], [enable_rosedb=no])
+
+AS_IF([test "$enable_rosedb" = yes], [AC_DEFINE([HAVE_ROSEDB], [1], [Define to 1 to enable static RR query module.])])
+AM_CONDITIONAL([HAVE_ROSEDB], [test "$enable_rosedb" = yes])
# Debug modules
AC_ARG_ENABLE([debug],
@@ -423,6 +428,7 @@
Fast zone parser: ${enable_fastparser}
Utilities with IDN: ${with_libidn}
Systemd integration: ${enable_systemd}
+ Rosedb module: ${enable_rosedb}
Dnstap support: ${opt_dnstap}
Code coverage: ${enable_code_coverage}
LMDB support: ${enable_lmdb}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/knot-1.6.5/doc/configuration.rst new/knot-1.6.6/doc/configuration.rst
--- old/knot-1.6.5/doc/configuration.rst 2015-09-01 16:43:42.000000000 +0200
+++ new/knot-1.6.6/doc/configuration.rst 2015-11-24 17:36:40.000000000 +0100
@@ -469,3 +469,86 @@
NSEC or NSEC3 is supported) nor DNSSEC signed records. However,
since the module is hooked in the query processing plan, it will be
possible to do online signing in the future.
+
+``rosedb`` - Static resource records
+------------------------------------
+
+The module provides a mean to override responses for certain queries before the record is searched in
+the available zones. The modules comes with a tool ``rosedb_tool`` to manipulate with the database
+of static records. Neither the tool nor the module are enabled by default, recompile with the configure flag ``--enable-rosedb``
+to enable them.
+
+For example, suppose we have a database of following records::
+
+ myrecord.com. 3600 IN A 127.0.0.1
+ www.myrecord.com. 3600 IN A 127.0.0.2
+ ipv6.myrecord.com. 3600 IN AAAA ::1
+
+And we query the nameserver with following::
+
+ $ kdig IN A myrecord.com
+ ... returns NOERROR, 127.0.0.1
+ $ kdig IN A www.myrecord.com
+ ... returns NOERROR, 127.0.0.2
+ $ kdig IN A stuff.myrecord.com
+ ... returns NOERROR, 127.0.0.1
+ $ kdig IN AAAA myrecord.com
+ ... returns NOERROR, NODATA
+ $ kdig IN AAAA ipv6.myrecord.com
+ ... returns NOERROR, ::1
+
+*Note: An entry in the database matches anything at or below it, i.e. 'myrecord.com' matches 'a.a.myrecord.com' as well.
+This can be exploited to create a catch-all entries.*
+
+You can also add an authority information for the entries, provided you create a SOA + NS records for a name, like so::
+
+ myrecord.com. 3600 IN SOA master host 1 3600 60 3600 3600
+ myrecord.com. 3600 IN NS ns1.myrecord.com.
+ myrecord.com. 3600 IN NS ns2.myrecord.com.
+ ns1.myrecord.com. 3600 IN A 127.0.0.1
+ ns2.myrecord.com. 3600 IN A 127.0.0.2
+
+In this case, the responses will:
+
+1. Be authoritative (AA flag set)
+2. Provide an authority section (SOA + NS)
+3. NXDOMAIN if the name is found *(i.e. the 'IN AAAA myrecord.com' from the example)*, but not the RR type *(this is to allow synthesis of negative responses)*
+
+*Note: The SOA record applies only to the 'myrecord.com.', not to any other record (even below it). From this point of view,
+all records in the database are unrelated and not hierarchical. The reasoning is to provide a subtree isolation for each entry.*
+
+In addition the module is able to log matching queries via remote syslog if you specify a syslog address endpoint and an
+optional string code.
+
+Here is an example on how to use the module:
+
+* Create the entries in the database::
+
+ $ mkdir /tmp/static_rrdb
+ $ rosedb_tool /tmp/static_rrdb add myrecord.com. A 3600 "127.0.0.1" "-" "-" # No logging
+ $ rosedb_tool /tmp/static_rrdb add www.myrecord.com. A 3600 "127.0.0.1" "www_query" "10.0.0.1" # Syslog @ 10.0.0.1
+ $ rosedb_tool /tmp/static_rrdb add ipv6.myrecord.com. AAAA 3600 "::1" "ipv6_query" "10.0.0.1" # Syslog @ 10.0.0.1
+ $ rosedb_tool /tmp/static_rrdb list # Verify
+ www.myrecord.com. A RDATA=10B www_query 10.0.0.1
+ ipv6.myrecord.com. AAAA RDATA=22B ipv6_query 10.0.0.1
+ myrecord.com. A RDATA=10B - -
+
+ *Note: the database may be modified while the server is running later on.*
+
+* Configure the query module and start the server::
+
+ $ vim knot.conf
+ knot.conf:
+ zones {
+ query_module {
+ rosedb "/tmp/static_rrdb";
+ }
+ }
+
+ $ knotd -c knot.conf
+
+ *Note: The module accepts just one parameter - path to the directory where the database will be stored.*
+
+* Verify the running instance::
+
+ $ kdig @127.0.0.1#6667 A myrecord.com
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/knot-1.6.5/man/kdig.1 new/knot-1.6.6/man/kdig.1
--- old/knot-1.6.5/man/kdig.1 2015-09-01 16:44:02.000000000 +0200
+++ new/knot-1.6.6/man/kdig.1 2015-11-24 17:37:01.000000000 +0100
@@ -1,4 +1,4 @@
-.TH "kdig" "1" "2015-09-01" "CZ.NIC Labs" "Knot DNS, version 1.6.5"
+.TH "kdig" "1" "2015-11-24" "CZ.NIC Labs" "Knot DNS, version 1.6.6"
.SH NAME
.TP 5
.B kdig
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/knot-1.6.5/man/khost.1 new/knot-1.6.6/man/khost.1
--- old/knot-1.6.5/man/khost.1 2015-09-01 16:44:02.000000000 +0200
+++ new/knot-1.6.6/man/khost.1 2015-11-24 17:37:01.000000000 +0100
@@ -1,4 +1,4 @@
-.TH "khost" "1" "2015-09-01" "CZ.NIC Labs" "Knot DNS, version 1.6.5"
+.TH "khost" "1" "2015-11-24" "CZ.NIC Labs" "Knot DNS, version 1.6.6"
.SH NAME
.TP 6
.B khost
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/knot-1.6.5/man/knot.conf.5 new/knot-1.6.6/man/knot.conf.5
--- old/knot-1.6.5/man/knot.conf.5 2015-09-01 16:44:02.000000000 +0200
+++ new/knot-1.6.6/man/knot.conf.5 2015-11-24 17:37:01.000000000 +0100
@@ -1,4 +1,4 @@
-.TH "knot.conf" "5" "2015-09-01" "CZ.NIC Labs" "Knot DNS, version 1.6.5"
+.TH "knot.conf" "5" "2015-11-24" "CZ.NIC Labs" "Knot DNS, version 1.6.6"
.SH NAME
.B knot.conf
\- Configuration file manual for Knot DNS server.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/knot-1.6.5/man/knotc.8 new/knot-1.6.6/man/knotc.8
--- old/knot-1.6.5/man/knotc.8 2015-09-01 16:44:02.000000000 +0200
+++ new/knot-1.6.6/man/knotc.8 2015-11-24 17:37:01.000000000 +0100
@@ -1,4 +1,4 @@
-.TH knotc "8" "2015-09-01" "CZ.NIC Labs" "Knot DNS, version 1.6.5"
+.TH knotc "8" "2015-11-24" "CZ.NIC Labs" "Knot DNS, version 1.6.6"
.SH NAME
.B knotc
\- Knot DNS control utility
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/knot-1.6.5/man/knotd.8 new/knot-1.6.6/man/knotd.8
--- old/knot-1.6.5/man/knotd.8 2015-09-01 16:44:02.000000000 +0200
+++ new/knot-1.6.6/man/knotd.8 2015-11-24 17:37:01.000000000 +0100
@@ -1,4 +1,4 @@
-.TH "knotd" "8" "2015-09-01" "CZ.NIC Labs" "Knot DNS, version 1.6.5"
+.TH "knotd" "8" "2015-11-24" "CZ.NIC Labs" "Knot DNS, version 1.6.6"
.SH NAME
.B knotd
\- Knot DNS server daemon
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/knot-1.6.5/man/knsec3hash.1 new/knot-1.6.6/man/knsec3hash.1
--- old/knot-1.6.5/man/knsec3hash.1 2015-09-01 16:44:02.000000000 +0200
+++ new/knot-1.6.6/man/knsec3hash.1 2015-11-24 17:37:01.000000000 +0100
@@ -1,4 +1,4 @@
-.TH "knsec3hash" "1" "2015-09-01" "CZ.NIC Labs" "Knot DNS, version 1.6.5"
+.TH "knsec3hash" "1" "2015-11-24" "CZ.NIC Labs" "Knot DNS, version 1.6.6"
.SH NAME
.B knsec3hash
\- Simple utility to compute NSEC3 hash (libknot equivalent of ISC nsec3hash)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/knot-1.6.5/man/knsupdate.1 new/knot-1.6.6/man/knsupdate.1
--- old/knot-1.6.5/man/knsupdate.1 2015-09-01 16:44:02.000000000 +0200
+++ new/knot-1.6.6/man/knsupdate.1 2015-11-24 17:37:01.000000000 +0100
@@ -1,4 +1,4 @@
-.TH "knsupdate" "1" "2015-09-01" "CZ.NIC Labs" "Knot DNS, version 1.6.5"
+.TH "knsupdate" "1" "2015-11-24" "CZ.NIC Labs" "Knot DNS, version 1.6.6"
.SH NAME
.TP 10
.B knsupdate
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/knot-1.6.5/missing new/knot-1.6.6/missing
--- old/knot-1.6.5/missing 2015-09-01 16:43:53.000000000 +0200
+++ new/knot-1.6.6/missing 2015-11-24 17:36:51.000000000 +0100
@@ -3,7 +3,7 @@
scriptversion=2013-10-28.13; # UTC
-# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
# Originally written by Fran,cois Pinard , 1996.
# This program is free software; you can redistribute it and/or modify
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/knot-1.6.5/src/Makefile.am new/knot-1.6.6/src/Makefile.am
--- old/knot-1.6.5/src/Makefile.am 2015-09-01 16:43:42.000000000 +0200
+++ new/knot-1.6.6/src/Makefile.am 2015-11-24 17:36:40.000000000 +0100
@@ -178,6 +178,7 @@
libknot/processing/process.c \
libknot/processing/process.h \
libknot/rrtype/dnskey.h \
+ libknot/rrtype/naptr.c \
libknot/rrtype/naptr.h \
libknot/rrtype/nsec.h \
libknot/rrtype/nsec.h \
@@ -359,6 +360,15 @@
libknotd_la_LIBADD += dnstap/libdnstap.la
endif
+if HAVE_ROSEDB
+libknotd_la_SOURCES += \
+ knot/modules/rosedb.c \
+ knot/modules/rosedb.h
+bin_PROGRAMS += rosedb_tool
+rosedb_tool_SOURCES = knot/modules/rosedb_tool.c
+rosedb_tool_LDADD = libknot.la libknotd.la
+endif # HAVE_ROSEDB
+
# Create storage and run-time directories
install-data-hook:
$(INSTALL) -d $(DESTDIR)/@config_dir@
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/knot-1.6.5/src/config.h.in new/knot-1.6.6/src/config.h.in
--- old/knot-1.6.5/src/config.h.in 2015-09-01 16:43:52.000000000 +0200
+++ new/knot-1.6.6/src/config.h.in 2015-11-24 17:36:50.000000000 +0100
@@ -96,6 +96,9 @@
/* Define to 1 if you have the header file. */
#undef HAVE_RESOLV_H
+/* Define to 1 to enable static RR query module. */
+#undef HAVE_ROSEDB
+
/* Define to 1 if you have the `select' function. */
#undef HAVE_SELECT
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/knot-1.6.5/src/knot/modules/rosedb.c new/knot-1.6.6/src/knot/modules/rosedb.c
--- old/knot-1.6.5/src/knot/modules/rosedb.c 1970-01-01 01:00:00.000000000 +0100
+++ new/knot-1.6.6/src/knot/modules/rosedb.c 2015-11-24 17:36:40.000000000 +0100
@@ -0,0 +1,615 @@
+/* Copyright (C) 2014 CZ.NIC, z.s.p.o.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+#include
+
+#include "knot/modules/rosedb.h"
+#include "knot/nameserver/process_query.h"
+#include "libknot/rrtype/rdname.h"
+#include "libknot/dnssec/random.h"
+#include "libknot/rrset-dump.h"
+#include "libknot/util/utils.h"
+
+/*! \note Below is an implementation of basic RR cache in LMDB,
+ * it shall be replaced with the namedb API later, when
+ * it supports multiple dbs + the basic "node" representation,
+ * as the cache implementation requires DUPSORT.
+ */
+
+#define LMDB_MAPSIZE (100 * 1024 * 1024)
+
+struct cache
+{
+ MDB_dbi dbi;
+ MDB_env *env;
+ mm_ctx_t *pool;
+};
+
+struct rdentry {
+ uint16_t type;
+ knot_rdataset_t rrs;
+};
+
+struct entry {
+ struct rdentry data;
+ const char *threat_code;
+ const char *syslog_ip;
+ MDB_cursor *cursor;
+};
+
+struct iter {
+ MDB_cursor *cur;
+ MDB_val key;
+ MDB_val val;
+};
+
+/* MDB access */
+
+static int dbase_open(struct cache *cache, const char *handle)
+{
+ long page_size = sysconf(_SC_PAGESIZE);
+ if (page_size <= 0) {
+ return KNOT_EINVAL;
+ }
+
+ int ret = mdb_env_create(&cache->env);
+ if (ret != 0) {
+ return ret;
+ }
+
+ size_t map_size = (LMDB_MAPSIZE / page_size) * page_size;
+ ret = mdb_env_set_mapsize(cache->env, map_size);
+ if (ret != 0) {
+ mdb_env_close(cache->env);
+ return ret;
+ }
+
+ ret = mdb_env_open(cache->env, handle, 0, 0644);
+ if (ret != 0) {
+ mdb_env_close(cache->env);
+ return ret;
+ }
+
+ MDB_txn *txn = NULL;
+ ret = mdb_txn_begin(cache->env, NULL, 0, &txn);
+ if (ret != 0) {
+ mdb_env_close(cache->env);
+ return ret;
+ }
+
+ ret = mdb_open(txn, NULL, MDB_DUPSORT, &cache->dbi);
+ if (ret != 0) {
+ mdb_txn_abort(txn);
+ mdb_env_close(cache->env);
+ return ret;
+ }
+
+ ret = mdb_txn_commit(txn);
+ if (ret != 0) {
+ mdb_env_close(cache->env);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void dbase_close(struct cache *cache)
+{
+ mdb_close(cache->env, cache->dbi);
+ mdb_env_close(cache->env);
+}
+
+/* data access */
+
+static MDB_cursor *cursor_acquire(MDB_txn *txn, MDB_dbi dbi)
+{
+ MDB_cursor *cursor = NULL;
+
+ int ret = mdb_cursor_open(txn, dbi, &cursor);
+ if (ret != 0) {
+ return NULL;
+ }
+
+ return cursor;
+}
+
+static void cursor_release(MDB_cursor *cursor)
+{
+ mdb_cursor_close(cursor);
+}
+
+/* data serialization */
+
+#define ENTRY_MAXLEN 65535
+#define PACKED_LEN(str) (strlen(str) + 1) /* length of packed string including terminal byte */
+static inline void pack_str(char **stream, const char *str) {
+ int len = PACKED_LEN(str);
+ memcpy(*stream, str, len);
+ *stream += len;
+}
+
+static inline char *unpack_str(char **stream) {
+ char *ret = *stream;
+ *stream += PACKED_LEN(ret);
+ return ret;
+}
+
+static inline void pack_bin(char **stream, const void *data, uint32_t len) {
+ knot_wire_write_u32((uint8_t *)*stream, len);
+ *stream += sizeof(uint32_t);
+ memcpy(*stream, data, len);
+ *stream += len;
+}
+
+static inline void *unpack_bin(char **stream, uint32_t *len) {
+ *len = knot_wire_read_u32((uint8_t *)*stream);
+ *stream += sizeof(uint32_t);
+ void *ret = *stream;
+ *stream += *len;
+ return ret;
+}
+
+static MDB_val pack_key(const knot_dname_t *name)
+{
+ MDB_val key = { knot_dname_size(name), (void *)name };
+ return key;
+}
+
+static int pack_entry(MDB_val *data, struct entry *entry)
+{
+ char *stream = data->mv_data;
+ char *bptr = stream;
+ pack_bin(&stream, &entry->data.type, sizeof(entry->data.type));
+ knot_rdataset_t *rrs = &entry->data.rrs;
+ pack_bin(&stream, &rrs->rr_count, sizeof(rrs->rr_count));
+ pack_bin(&stream, rrs->data, knot_rdataset_size(rrs));
+
+ pack_str(&stream, entry->threat_code);
+ pack_str(&stream, entry->syslog_ip);
+
+ data->mv_size = (stream - bptr);
+ return KNOT_EOK;
+}
+
+static int unpack_entry(MDB_val *data, struct entry *entry)
+{
+ uint32_t len = 0;
+ void *val = NULL;
+ char *stream = data->mv_data;
+
+ val = unpack_bin(&stream, &len);
+ memcpy(&entry->data.type, val, sizeof(uint16_t));
+
+ knot_rdataset_t *rrs = &entry->data.rrs;
+ val = unpack_bin(&stream, &len);
+ memcpy(&rrs->rr_count, val, sizeof(uint16_t));
+ rrs->data = unpack_bin(&stream, &len);
+
+ entry->threat_code = unpack_str(&stream);
+ entry->syslog_ip = unpack_str(&stream);
+
+ return KNOT_EOK;
+}
+
+static int remove_entry(MDB_cursor *cur)
+{
+ int ret = mdb_cursor_del(cur, MDB_NODUPDATA);
+ if (ret != 0) {
+ return KNOT_ERROR;
+ }
+
+ return KNOT_EOK;
+}
+
+/* database api */
+
+struct cache *cache_open(const char *handle, unsigned flags, mm_ctx_t *mm)
+{
+ struct cache *cache = mm_alloc(mm, sizeof(struct cache));
+ if (cache == NULL) {
+ return NULL;
+ }
+ memset(cache, 0, sizeof(struct cache));
+
+ int ret = dbase_open(cache, handle);
+ if (ret != 0) {
+ mm_free(mm, cache);
+ return NULL;
+ }
+
+ cache->pool = mm;
+ return cache;
+}
+
+void cache_close(struct cache *cache)
+{
+ if (cache == NULL) {
+ return;
+ }
+
+ dbase_close(cache);
+ mm_free(cache->pool, cache);
+}
+
+static int cache_iter_begin(struct iter *it, const knot_dname_t *name)
+{
+ it->key = pack_key(name);
+ it->val.mv_data = NULL;
+ it->val.mv_size = 0;
+
+ return mdb_cursor_get(it->cur, &it->key, &it->val, MDB_SET_KEY);
+}
+
+static int cache_iter_next(struct iter *it)
+{
+ return mdb_cursor_get(it->cur, &it->key, &it->val, MDB_NEXT_DUP);
+}
+
+static int cache_iter_val(struct iter *it, struct entry *entry)
+{
+ return unpack_entry(&it->val, entry);
+}
+
+static void cache_iter_free(struct iter *it)
+{
+ mdb_cursor_close(it->cur);
+ it->cur = NULL;
+}
+
+int cache_query_fetch(MDB_txn *txn, MDB_dbi dbi, struct iter *it, const knot_dname_t *name)
+{
+ it->cur = cursor_acquire(txn, dbi);
+ if (it->cur == NULL) {
+ return KNOT_ERROR;
+ }
+
+ int ret = cache_iter_begin(it, name);
+ if (ret != 0) {
+ cache_iter_free(it);
+ return KNOT_ENOENT;
+ }
+
+ return KNOT_EOK;
+}
+
+int cache_insert(MDB_txn *txn, MDB_dbi dbi, const knot_dname_t *name, struct entry *entry)
+{
+ MDB_cursor *cursor = cursor_acquire(txn, dbi);
+ if (cursor == NULL) {
+ return KNOT_ERROR;
+ }
+
+ MDB_val key = pack_key(name);
+ MDB_val data = { 0, malloc(ENTRY_MAXLEN) };
+
+ int ret = pack_entry(&data, entry);
+ if (ret != KNOT_EOK) {
+ free(data.mv_data);
+ return ret;
+ }
+
+ ret = mdb_cursor_put(cursor, &key, &data, 0);
+ free(data.mv_data);
+ cursor_release(cursor);
+
+ return ret;
+}
+
+int cache_remove(MDB_txn *txn, MDB_dbi dbi, const knot_dname_t *name)
+{
+ struct iter it;
+ it.cur = cursor_acquire(txn, dbi);
+ if (it.cur == NULL) {
+ return KNOT_ERROR;
+ }
+
+ int ret = cache_iter_begin(&it, name);
+ if (ret == 0) {
+ ret = remove_entry(it.cur);
+ }
+
+ cursor_release(it.cur);
+ return ret;
+}
+
+/* module callbacks */
+
+#define DEFAULT_PORT 514
+#define SYSLOG_BUFLEN 1024 /* RFC3164, 4.1 message size. */
+#define SYSLOG_FACILITY 3 /* System daemon. */
+#define MODULE_ERR(msg...) log_error("module 'rose', " msg)
+
+/*! \brief Safe stream skipping. */
+static int stream_skip(char **stream, size_t *maxlen, int nbytes)
+{
+ /* Error or space limit exceeded. */
+ if (nbytes < 0 || nbytes >= *maxlen) {
+ return KNOT_ESPACE;
+ }
+
+ *stream += nbytes;
+ *maxlen -= nbytes;
+ return 0;
+}
+
+/*! \brief Stream write with constraints checks. */
+#define STREAM_WRITE(stream, maxlen, fn, args...) \
+ if (stream_skip(&(stream), (maxlen), fn(stream, *(maxlen), args)) != KNOT_EOK) { \
+ return KNOT_ESPACE; \
+ }
+
+#define sockaddr_tostr_wrap(buf, maxlen, ss) sockaddr_tostr((ss), (buf), (maxlen))
+
+static int rosedb_log_message(char *stream, size_t *maxlen, knot_pkt_t *pkt,
+ const char *threat_code, struct query_data *qdata)
+{
+ char dname_buf[KNOT_DNAME_MAXLEN] = {'\0'};
+ struct sockaddr_storage addr;
+ socklen_t addr_len = sizeof(addr);
+ time_t now = time(NULL);
+ struct tm tm;
+ gmtime_r(&now, &tm);
+
+ /* Field 1 Timestamp (UTC). */
+ STREAM_WRITE(stream, maxlen, strftime, "%Y-%m-%d %H:%M:%S\t", &tm);
+
+ /* Field 2/3 Remote, local address. */
+ addr = *qdata->param->remote;
+ int client_port = sockaddr_port(&addr);
+ sockaddr_port_set(&addr, 0);
+ STREAM_WRITE(stream, maxlen, sockaddr_tostr_wrap, &addr);
+ STREAM_WRITE(stream, maxlen, snprintf, "\t");
+ getsockname(qdata->param->socket, (struct sockaddr *)&addr, &addr_len);
+ int server_port = sockaddr_port(&addr);
+ sockaddr_port_set(&addr, 0);
+ STREAM_WRITE(stream, maxlen, sockaddr_tostr_wrap, &addr);
+ STREAM_WRITE(stream, maxlen, snprintf, "\t");
+
+ /* Field 4/5 Local, remote port. */
+ STREAM_WRITE(stream, maxlen, snprintf, "%d\t%d\t", client_port, server_port);
+
+ /* Field 6 Threat ID. */
+ STREAM_WRITE(stream, maxlen, snprintf, "%s\t", threat_code);
+
+ /* Field 7 - 13 NULL */
+ STREAM_WRITE(stream, maxlen, snprintf, "\t\t\t\t\t\t\t");
+
+ /* Field 14 QNAME */
+ knot_dname_to_str(dname_buf, knot_pkt_qname(qdata->query), sizeof(dname_buf));
+ STREAM_WRITE(stream, maxlen, snprintf, "%s\t", dname_buf);
+
+ /* Field 15 Resolution (0 = local, 1 = lookup)*/
+ STREAM_WRITE(stream, maxlen, snprintf, "0\t");
+
+ /* Field 16 RDATA.
+ * - Return randomly RDATA in the answer section (probabilistic rotation).
+ * - Empty if no answer.
+ */
+ const knot_pktsection_t *ans = knot_pkt_section(pkt, KNOT_ANSWER);
+ if (ans->count > 0) {
+ const knot_rrset_t *rr = &ans->rr[knot_random_uint16_t() % ans->count];
+ int ret = knot_rrset_txt_dump_data(rr, 0, stream, *maxlen, &KNOT_DUMP_STYLE_DEFAULT);
+ if (ret < 0) {
+ return ret;
+ }
+ stream_skip(&stream, maxlen, ret);
+ }
+ STREAM_WRITE(stream, maxlen, snprintf, "\t");
+
+ /* Field 17 Connection type. */
+ STREAM_WRITE(stream, maxlen, snprintf, "%s\t",
+ net_is_connected(qdata->param->socket) ? "TCP" : "UDP");
+
+ /* Field 18 Query type. */
+ char type_str[16] = { '\0' };
+ knot_rrtype_to_string(knot_pkt_qtype(qdata->query), type_str, sizeof(type_str));
+ STREAM_WRITE(stream, maxlen, snprintf, "%s\t", type_str);
+
+ /* Field 19 First authority. */
+ const knot_pktsection_t *ns = knot_pkt_section(pkt, KNOT_AUTHORITY);
+ if (ns->count > 0 && ns->rr[0].type == KNOT_RRTYPE_NS) {
+ const knot_dname_t *label = knot_ns_name(&ns->rr[0].rrs, 0);
+ memset(dname_buf, 0, sizeof(dname_buf));
+ memcpy(dname_buf, label + 1, *label);
+ STREAM_WRITE(stream, maxlen, snprintf, "%s", dname_buf);
+ }
+
+ return KNOT_EOK;
+}
+
+static int rosedb_send_log(int sock, struct sockaddr_storage *dst_addr, knot_pkt_t *pkt,
+ const char *threat_code, struct query_data *qdata)
+{
+ char buf[SYSLOG_BUFLEN];
+ char *stream = buf;
+ size_t maxlen = sizeof(buf);
+
+ time_t now = time(NULL);
+ struct tm tm;
+ localtime_r(&now, &tm);
+
+ /* Add facility. */
+ STREAM_WRITE(stream, &maxlen, snprintf, "<%u>", SYSLOG_FACILITY);
+
+ /* Current local time (4.3.2)*/
+ STREAM_WRITE(stream, &maxlen, strftime, "%b %d %H:%M:%S ", &tm);
+
+ /* Host name / Component. */
+ STREAM_WRITE(stream, &maxlen, snprintf, "%s ", conf()->identity);
+ STREAM_WRITE(stream, &maxlen, snprintf, "%s[%lu]: ", PACKAGE_NAME, (unsigned long) getpid());
+
+ /* Prepare log message line. */
+ int ret = rosedb_log_message(stream, &maxlen, pkt, threat_code, qdata);
+ if (ret != KNOT_EOK) {
+ return ret;
+ }
+
+ /* Send log message line. */
+ sendto(sock, buf, sizeof(buf) - maxlen, 0, (struct sockaddr *)dst_addr, sockaddr_len(dst_addr));
+
+ return ret;
+}
+
+static int rosedb_synth_rr(knot_pkt_t *pkt, struct entry *entry, uint16_t qtype)
+{
+ if (qtype != entry->data.type) {
+ return KNOT_EOK; /* Ignore */
+ }
+
+ knot_rrset_t *rr = knot_rrset_new(knot_pkt_qname(pkt), entry->data.type, KNOT_CLASS_IN, &pkt->mm);
+ int ret = knot_rdataset_copy(&rr->rrs, &entry->data.rrs, &pkt->mm);
+ if (ret != KNOT_EOK) {
+ return ret;
+ }
+
+ ret = knot_pkt_put(pkt, COMPR_HINT_QNAME, rr, KNOT_PF_FREE);
+
+ return ret;
+}
+
+static int rosedb_synth(knot_pkt_t *pkt, const knot_dname_t *key, struct iter *it,
+ struct query_data *qdata)
+{
+ struct entry entry;
+ int ret = KNOT_EOK;
+ uint16_t qtype = knot_pkt_qtype(qdata->query);
+
+ /* Answer section. */
+ while (ret == KNOT_EOK) {
+ if (cache_iter_val(it, &entry) == 0) {
+ ret = rosedb_synth_rr(pkt, &entry, qtype);
+ }
+ if (cache_iter_next(it) != 0) {
+ break;
+ }
+ }
+
+ /* Authority section. */
+ knot_pkt_begin(pkt, KNOT_AUTHORITY);
+
+ /* Not found (zone cut if records exist). */
+ ret = cache_iter_begin(it, key);
+ while (ret == KNOT_EOK) {
+ if (cache_iter_val(it, &entry) == 0) {
+ ret = rosedb_synth_rr(pkt, &entry, KNOT_RRTYPE_NS);
+ ret = rosedb_synth_rr(pkt, &entry, KNOT_RRTYPE_SOA);
+ }
+ if (cache_iter_next(it) != 0) {
+ break;
+ }
+ }
+
+ /* Our response is authoritative. */
+ if (knot_wire_get_nscount(pkt->wire) > 0) {
+ knot_wire_set_aa(pkt->wire);
+ if (knot_wire_get_ancount(pkt->wire) == 0) {
+ qdata->rcode = KNOT_RCODE_NXDOMAIN;
+ }
+ }
+
+ /* Send message to syslog. */
+ struct sockaddr_storage syslog_addr;
+ if (sockaddr_set(&syslog_addr, AF_INET, entry.syslog_ip, DEFAULT_PORT) == KNOT_EOK) {
+ int sock = net_unbound_socket(AF_INET, &syslog_addr);
+ if (sock > 0) {
+ rosedb_send_log(sock, &syslog_addr, pkt,
+ entry.threat_code, qdata);
+ close(sock);
+ }
+ }
+
+ return ret;
+}
+
+static int rosedb_query_txn(MDB_txn *txn, MDB_dbi dbi, knot_pkt_t *pkt, struct query_data *qdata)
+{
+ struct iter it;
+ int ret = KNOT_EOK;
+
+ /* Find suffix for QNAME. */
+ const knot_dname_t *qname = knot_pkt_qname(qdata->query);
+ const knot_dname_t *key = qname;
+ while (key) {
+ ret = cache_query_fetch(txn, dbi, &it, key);
+ if (ret == 0) { /* Found */
+ break;
+ }
+
+ if (*key == '\0') { /* Last label, not found. */
+ return KNOT_ENOENT;
+ }
+
+ key = knot_wire_next_label(key, qdata->query->wire);
+ }
+
+ /* Synthetize record to response. */
+ ret = rosedb_synth(pkt, key, &it, qdata);
+
+ cache_iter_free(&it);
+ return ret;
+}
+
+static int rosedb_query(int state, knot_pkt_t *pkt, struct query_data *qdata, void *ctx)
+{
+ if (pkt == NULL || qdata == NULL || ctx == NULL) {
+ return NS_PROC_FAIL;
+ }
+
+ struct cache *cache = ctx;
+
+ MDB_txn *txn = NULL;
+ int ret = mdb_txn_begin(cache->env, NULL, MDB_RDONLY, &txn);
+ if (ret != 0) { /* Can't start transaction, ignore. */
+ return state;
+ }
+
+ ret = rosedb_query_txn(txn, cache->dbi, pkt, qdata);
+ if (ret != 0) { /* Can't find matching zone, ignore. */
+ mdb_txn_abort(txn);
+ return state;
+ }
+
+ mdb_txn_abort(txn);
+
+ return NS_PROC_DONE;
+}
+
+int rosedb_load(struct query_plan *plan, struct query_module *self)
+{
+ if (self == NULL || plan == NULL) {
+ return KNOT_EINVAL;
+ }
+
+ struct cache *cache = cache_open(self->param, 0, self->mm);
+ if (cache == NULL) {
+ MODULE_ERR("couldn't open db '%s'", self->param);
+ return KNOT_ENOMEM;
+ }
+
+ self->ctx = cache;
+
+ return query_plan_step(plan, QPLAN_BEGIN, rosedb_query, cache);
+}
+
+int rosedb_unload(struct query_module *self)
+{
+ if (self == NULL) {
+ return KNOT_EINVAL;
+ }
+
+ cache_close(self->ctx);
+ return KNOT_EOK;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/knot-1.6.5/src/knot/modules/rosedb.h new/knot-1.6.6/src/knot/modules/rosedb.h
--- old/knot-1.6.5/src/knot/modules/rosedb.h 1970-01-01 01:00:00.000000000 +0100
+++ new/knot-1.6.6/src/knot/modules/rosedb.h 2015-11-24 17:36:40.000000000 +0100
@@ -0,0 +1,41 @@
+/*!
+ * \file rosedb.h
+ *
+ * \author Marek Vavrusa
+ *
+ * \brief Static resource records
+ *
+ * Accepted configurations:
+ * * ""
+ *
+ * The module provides a mean to override responses for certain queries before
+ * the record is searched in the available zones.
+ *
+ * \addtogroup query_processing
+ * @{
+ */
+/* Copyright (C) 2014 CZ.NIC, z.s.p.o.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+#pragma once
+
+#include "knot/nameserver/query_module.h"
+
+/*! \brief Module interface. */
+int rosedb_load(struct query_plan *plan, struct query_module *self);
+int rosedb_unload(struct query_module *self);
+
+/*! @} */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/knot-1.6.5/src/knot/modules/rosedb_tool.c new/knot-1.6.6/src/knot/modules/rosedb_tool.c
--- old/knot-1.6.5/src/knot/modules/rosedb_tool.c 1970-01-01 01:00:00.000000000 +0100
+++ new/knot-1.6.6/src/knot/modules/rosedb_tool.c 2015-11-24 17:36:40.000000000 +0100
@@ -0,0 +1,367 @@
+/* Copyright (C) 2015 CZ.NIC, z.s.p.o.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see http://www.gnu.org/licenses/.
+*/
+
+#include
+#include
+#include
+
+#include "knot/modules/rosedb.c"
+#include "zscanner/scanner.h"
+#include "libknot/libknot.h"
+#include "common/mem.h"
+#include "common/getline.h"
+
+static int rosedb_add(struct cache *cache, MDB_txn *txn, int argc, char *argv[]);
+static int rosedb_del(struct cache *cache, MDB_txn *txn, int argc, char *argv[]);
+static int rosedb_get(struct cache *cache, MDB_txn *txn, int argc, char *argv[]);
+static int rosedb_list(struct cache *cache, MDB_txn *txn, int argc, char *argv[]);
+static int rosedb_import(struct cache *cache, MDB_txn *txn, int argc, char *argv[]);
+
+struct tool_action {
+ const char *name;
+ int (*func)(struct cache *, MDB_txn *, int, char *[]);
+ int min_args;
+ const char *info;
+};
+
+#define TOOL_ACTION_MAXARG 7
+#define TOOL_ACTION_COUNT 5
+static struct tool_action TOOL_ACTION[TOOL_ACTION_COUNT] = {
+{ "add", rosedb_add, 6, "<zone> <rrtype> <ttl> <rdata> " },
+{ "del", rosedb_del, 1, "<zone> [rrtype]" },
+{ "get", rosedb_get, 1, "<zone> [rrtype]" },
+{ "import", rosedb_import, 1, "<file>" },
+{ "list", rosedb_list, 0, "" }
+};
+
+static void help(FILE *stream)
+{
+ fprintf(stream, "Usage: rosedb_tool <dbdir> <action> [params]\n");
+ fprintf(stream, "Actions:\n");
+ for (unsigned i = 0; i < TOOL_ACTION_COUNT; ++i) {
+ struct tool_action *ta = &TOOL_ACTION[i];
+ fprintf(stream, "\t%s %s\n", ta->name, ta->info);
+ }
+}
+
+/* Global instance of RR scanner. */
+static void parse_err(zs_scanner_t *s) {
+ fprintf(stderr, "failed to parse RDATA: %s\n", zs_strerror(s->error_code));
+}
+static zs_scanner_t *g_scanner = NULL;
+
+int main(int argc, char *argv[])
+{
+ static const struct option options[] = {
+ { "version", no_argument, 0, 'V' },
+ { "help", no_argument, 0, 'h' },
+ { NULL }
+ };
+
+ int opt = 0;
+ int index = 0;
+ while ((opt = getopt_long(argc, argv, "Vh", options, &index)) != -1) {
+ switch (opt) {
+ case 'V':
+ printf("rosedb_tool (Knot DNS), version %s\n", PACKAGE_VERSION);
+ return EXIT_SUCCESS;
+ case 'h':
+ help(stdout);
+ return EXIT_SUCCESS;
+ default:
+ help(stderr);
+ return EXIT_FAILURE;
+ }
+ }
+
+ if (argc < 3) {
+ help(stderr);
+ return EXIT_FAILURE;
+ }
+
+ /* Get mandatory parameters. */
+ int ret = EXIT_SUCCESS;
+ char *dbdir = argv[1];
+ char *action = argv[2];
+ argv += 3;
+ argc -= 3;
+
+ g_scanner = zs_scanner_create(".", KNOT_CLASS_IN, 0, NULL, parse_err, NULL);
+ if (g_scanner == NULL) {
+ return EXIT_FAILURE;
+ }
+
+ /* Open cache for operations. */
+ struct cache *cache = cache_open(dbdir, 0, NULL);
+ if (cache == NULL) {
+ fprintf(stderr, "failed to open db '%s'\n", dbdir);
+ zs_scanner_free(g_scanner);
+ return EXIT_FAILURE;
+ }
+
+ /* Execute action. */
+ bool found = false;
+ for (unsigned i = 0; i < TOOL_ACTION_COUNT; ++i) {
+ struct tool_action *ta = &TOOL_ACTION[i];
+ if (strcmp(ta->name, action) == 0) {
+
+ /* Check param count. */
+ if (argc < ta->min_args) {
+ break;
+ }
+
+ /* Now set as found. */
+ found = true;
+
+ MDB_txn *txn = NULL;
+ int ret = mdb_txn_begin(cache->env, NULL, 0, &txn);
+ if (ret != MDB_SUCCESS) {
+ fprintf(stderr, "failed to open transaction, aborting\n");
+ break;
+ }
+
+ /* Execute operation handler. */
+ ret = ta->func(cache, txn, argc, argv);
+ if (ret != 0) {
+ fprintf(stderr, "'%s' failed, aborting transaction\n", action);
+ mdb_txn_abort(txn);
+ } else {
+ mdb_txn_commit(txn);
+ }
+
+ break;
+ }
+ }
+
+ cache_close(cache);
+ zs_scanner_free(g_scanner);
+
+ if (!found) {
+ help(stderr);
+ return EXIT_FAILURE;
+ }
+
+ return ret;
+}
+
+static int parse_rdata(struct entry *entry, const char *owner, const char *rrtype, const char *rdata,
+ int ttl, mm_ctx_t *mm)
+{
+ knot_rdataset_init(&entry->data.rrs);
+ int ret = knot_rrtype_from_string(rrtype, &entry->data.type);
+ if (ret != KNOT_EOK) {
+ return ret;
+ }
+
+ /* Synthetize RR line */
+ char *rr_line = sprintf_alloc("%s %u IN %s %s\n", owner, ttl, rrtype, rdata);
+ ret = zs_scanner_parse(g_scanner, rr_line, rr_line + strlen(rr_line), true);
+ free(rr_line);
+
+ /* Write parsed RDATA. */
+ if (ret == KNOT_EOK) {
+ knot_rdata_t rr[knot_rdata_array_size(g_scanner->r_data_length)];
+ knot_rdata_init(rr, g_scanner->r_data_length, g_scanner->r_data, ttl);
+ ret = knot_rdataset_add(&entry->data.rrs, rr, mm);
+ }
+
+ return ret;
+}
+
+static int rosedb_add(struct cache *cache, MDB_txn *txn, int argc, char *argv[])
+{
+ printf("ADD %s\t%s\t%s\t%s\t%s\t%s\n", argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
+
+ knot_dname_t key[KNOT_DNAME_MAXLEN] = { '\0' };
+ knot_dname_from_str(key, argv[0], sizeof(key));
+ knot_dname_to_lower(key);
+
+ struct entry entry;
+ int ret = parse_rdata(&entry, argv[0], argv[1], argv[3], atoi(argv[2]), cache->pool);
+ entry.threat_code = argv[4];
+ entry.syslog_ip = argv[5];
+ if (ret != 0) {
+ fprintf(stderr, "PARSE: %s\n", knot_strerror(ret));
+ return ret;
+ }
+
+ ret = cache_insert(txn, cache->dbi, key, &entry);
+ if (ret != 0) {
+ fprintf(stderr, "%s\n", mdb_strerror(ret));
+ }
+
+ return ret;
+}
+
+static int rosedb_del(struct cache *cache, MDB_txn *txn, int argc, char *argv[])
+{
+ printf("DEL %s\n", argv[0]);
+
+ knot_dname_t key[KNOT_DNAME_MAXLEN] = { '\0' };
+ knot_dname_from_str(key, argv[0], sizeof(key));
+ knot_dname_to_lower(key);
+
+ int ret = cache_remove(txn, cache->dbi, key);
+ if (ret != 0) {
+ fprintf(stderr, "%s\n", mdb_strerror(ret));
+ }
+
+ return ret;
+}
+
+static int rosedb_get(struct cache *cache, MDB_txn *txn, int argc, char *argv[])
+{
+ knot_dname_t key[KNOT_DNAME_MAXLEN] = { '\0' };
+ knot_dname_from_str(key, argv[0], sizeof(key));
+ knot_dname_to_lower(key);
+
+ char type_str[16] = { '\0' };
+
+ struct iter it;
+ int ret = cache_query_fetch(txn, cache->dbi, &it, key);
+ while (ret == 0) {
+ struct entry entry;
+ cache_iter_val(&it, &entry);
+ knot_rdata_t *rd = knot_rdataset_at(&entry.data.rrs, 0);
+ knot_rrtype_to_string(entry.data.type, type_str, sizeof(type_str));
+ printf("%s\t%s\tTTL=%u\tRDLEN=%u\t%s\t%s\n", argv[0], type_str,
+ knot_rdata_ttl(rd), knot_rdata_rdlen(rd), entry.threat_code, entry.syslog_ip);
+ if (cache_iter_next(&it) != 0) {
+ break;
+ }
+ }
+
+ cache_iter_free(&it);
+
+ return ret;
+}
+
+static int rosedb_list(struct cache *cache, MDB_txn *txn, int argc, char *argv[])
+{
+ MDB_cursor *cursor = cursor_acquire(txn, cache->dbi);
+ MDB_val key, data;
+ char dname_str[KNOT_DNAME_MAXLEN] = {'\0'};
+ char type_str[16] = { '\0' };
+
+ int ret = mdb_cursor_get(cursor, &key, &data, MDB_FIRST);
+ while (ret == 0) {
+ struct entry entry;
+ unpack_entry(&data, &entry);
+ knot_dname_to_str(dname_str, key.mv_data, sizeof(dname_str));
+ knot_rrtype_to_string(entry.data.type, type_str, sizeof(type_str));
+ printf("%s\t%s RDATA=%zuB\t%s\t%s\n", dname_str, type_str,
+ knot_rdataset_size(&entry.data.rrs), entry.threat_code, entry.syslog_ip);
+
+ ret = mdb_cursor_get(cursor, &key, &data, MDB_NEXT);
+ }
+
+ cursor_release(cursor);
+
+ return KNOT_EOK;
+}
+
+static char *trim(char *line)
+{
+ int last = strlen(line) - 1;
+ if (line[last] == '\n') {
+ line[last] = '\0';
+ last -= 1;
+ }
+ if (*line == '"') {
+ line[last] = '\0';
+ line += 1;
+ }
+
+ return line;
+}
+
+static int rosedb_import_line(struct cache *cache, MDB_txn *txn, char *line, const char *file, int lineno)
+{
+ int ret = 0;
+ int argc = 0;
+ char *argv[TOOL_ACTION_MAXARG];
+
+ /* Tokenize */
+ char *saveptr = line;
+ char *token = NULL;
+ while ((token = strtok_r(saveptr, ";\t", &saveptr)) != NULL) {
+ token = trim(token);
+ if (*token == '\0') {
+ continue;
+ }
+ if (argc <= TOOL_ACTION_MAXARG) {
+ argv[argc] = token;
+ argc += 1;
+ } else {
+ fprintf(stderr, "%s#%d command '%s' - too much parameters (%d)\n",
+ file, lineno, line, argc);
+ return KNOT_EPARSEFAIL;
+ }
+ }
+
+ if (argc < 1) {
+ fprintf(stderr, "%s#%d command '%s' - command not recognized\n", file, lineno, line);
+ return KNOT_EOK; /* Ignore NOOP */
+ }
+
+ /* Execute action. */
+ bool found = false;
+ for (unsigned i = 0; i < TOOL_ACTION_COUNT; ++i) {
+ struct tool_action *ta = &TOOL_ACTION[i];
+ if (strcmp(ta->name, argv[0]) == 0) {
+ if (argc < ta->min_args) {
+ help(stderr);
+ return EXIT_FAILURE;
+ }
+ found = true;
+ ret = ta->func(cache, txn, argc - 1, argv + 1);
+ break;
+ }
+ }
+ if (!found) {
+ fprintf(stderr, "%s#%d command '%s' - command not recognized\n", file, lineno, line);
+ return KNOT_EPARSEFAIL;
+ }
+
+ return ret;
+}
+
+static int rosedb_import(struct cache *cache, MDB_txn *txn, int argc, char *argv[])
+{
+ printf("IMPORT %s\n", argv[0]);
+
+ int ret = 0;
+ char *line = NULL;
+ int lineno = 0;
+ size_t line_len = 0;
+ FILE *fp = fopen(argv[0], "r");
+ if (fp == NULL) {
+ return KNOT_ENOENT;
+ }
+
+ while (knot_getline(&line, &line_len, fp) != -1) {
+ lineno += 1;
+ ret = rosedb_import_line(cache, txn, line, argv[0], lineno);
+ if (ret != 0) {
+ break;
+ }
+ }
+
+ free(line);
+ fclose(fp);
+
+ return ret;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/knot-1.6.5/src/knot/nameserver/process_query.c new/knot-1.6.6/src/knot/nameserver/process_query.c
--- old/knot-1.6.5/src/knot/nameserver/process_query.c 2015-09-01 16:43:42.000000000 +0200
+++ new/knot-1.6.6/src/knot/nameserver/process_query.c 2015-11-24 17:36:40.000000000 +0100
@@ -418,7 +418,7 @@
/* Check parse state. */
knot_pkt_t *query = qdata->query;
- int next_state = NS_PROC_DONE;
+ int next_state = NS_PROC_FULL;
if (query->parsed < query->size) {
dbg_ns("%s: incompletely parsed query, FORMERR\n", __func__);
knot_pkt_clear(pkt);
@@ -445,18 +445,20 @@
}
/* Answer based on qclass. */
- switch (knot_pkt_qclass(pkt)) {
- case KNOT_CLASS_CH:
- next_state = query_chaos(pkt, ctx);
- break;
- case KNOT_CLASS_ANY:
- case KNOT_CLASS_IN:
- next_state = query_internet(pkt, ctx);
- break;
- default:
- qdata->rcode = KNOT_RCODE_REFUSED;
- next_state = NS_PROC_FAIL;
- break;
+ if (next_state != NS_PROC_DONE) {
+ switch (knot_pkt_qclass(pkt)) {
+ case KNOT_CLASS_CH:
+ next_state = query_chaos(pkt, ctx);
+ break;
+ case KNOT_CLASS_ANY:
+ case KNOT_CLASS_IN:
+ next_state = query_internet(pkt, ctx);
+ break;
+ default:
+ qdata->rcode = KNOT_RCODE_REFUSED;
+ next_state = NS_PROC_FAIL;
+ break;
+ }
}
/*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/knot-1.6.5/src/knot/nameserver/query_module.c new/knot-1.6.6/src/knot/nameserver/query_module.c
--- old/knot-1.6.5/src/knot/nameserver/query_module.c 2015-09-01 16:43:42.000000000 +0200
+++ new/knot-1.6.6/src/knot/nameserver/query_module.c 2015-11-24 17:36:40.000000000 +0100
@@ -5,6 +5,9 @@
/* Compiled-in module headers. */
#include "knot/modules/synth_record.h"
+#if HAVE_ROSEDB
+#include "knot/modules/rosedb.h"
+#endif
#if USE_DNSTAP
#include "knot/modules/dnstap.h"
#endif
@@ -19,6 +22,9 @@
/*! \note All modules should be dynamically loaded later on. */
struct compiled_module MODULES[] = {
{ "synth_record", &synth_record_load, &synth_record_unload },
+#if HAVE_ROSEDB
+ { "rosedb", &rosedb_load, &rosedb_unload },
+#endif
#if USE_DNSTAP
{ "dnstap", &dnstap_load, &dnstap_unload }
#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/knot-1.6.5/src/libknot/rrset.c new/knot-1.6.6/src/libknot/rrset.c
--- old/knot-1.6.5/src/libknot/rrset.c 2015-09-01 16:43:42.000000000 +0200
+++ new/knot-1.6.6/src/libknot/rrset.c 2015-11-24 17:36:40.000000000 +0100
@@ -25,6 +25,7 @@
#include "libknot/mempattern.h"
#include "libknot/descriptor.h"
#include "libknot/dname.h"
+#include "libknot/errcode.h"
#include "libknot/rrtype/naptr.h"
knot_rrset_t *knot_rrset_new(const knot_dname_t *owner, uint16_t type,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/knot-1.6.5/src/libknot/rrtype/naptr.c new/knot-1.6.6/src/libknot/rrtype/naptr.c
--- old/knot-1.6.5/src/libknot/rrtype/naptr.c 1970-01-01 01:00:00.000000000 +0100
+++ new/knot-1.6.6/src/libknot/rrtype/naptr.c 2015-11-24 17:36:40.000000000 +0100
@@ -0,0 +1,48 @@
+/* Copyright (C) 2015 CZ.NIC, z.s.p.o.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see http://www.gnu.org/licenses/.
+*/
+
+#include
+#include
+
+#include "libknot/errcode.h"
+#include "libknot/rrtype/naptr.h"
+
+int knot_naptr_header_size(const uint8_t *naptr, const uint8_t *maxp)
+{
+ if (!naptr || !maxp || naptr >= maxp) {
+ return KNOT_EINVAL;
+ }
+
+ size_t size = 0;
+
+ /* Fixed fields size (order, preference) */
+ size += 2 * sizeof(uint16_t);
+
+ /* Variable fields size (flags, services, regexp) */
+ for (int i = 0; i < 3; i++) {
+ const uint8_t *len_ptr = naptr + size;
+ if (len_ptr >= maxp) {
+ return KNOT_EMALF;
+ }
+ size += 1 + *len_ptr;
+ }
+
+ if (naptr + size >= maxp) {
+ return KNOT_EMALF;
+ }
+
+ return size;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/knot-1.6.5/src/libknot/rrtype/naptr.h new/knot-1.6.6/src/libknot/rrtype/naptr.h
--- old/knot-1.6.5/src/libknot/rrtype/naptr.h 2015-09-01 16:43:42.000000000 +0200
+++ new/knot-1.6.6/src/libknot/rrtype/naptr.h 2015-11-24 17:36:40.000000000 +0100
@@ -13,24 +13,10 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see http://www.gnu.org/licenses/.
*/
-/*!
- * \file naptr.h
- *
- * \author Lubos Slovak
- *
- * \brief Functions for manipulation of NAPTR RDATA.
- *
- * \addtogroup libknot
- * @{
- */
#pragma once
-#include
#include
-#include
-
-#include "libknot/errcode.h"
/*!
* \brief Counts the size of the NAPTR RDATA before the Replacement domain name.
@@ -43,23 +29,4 @@
* \retval KNOT_EMALF if the record is malformed.
* \retval Size of the RDATA before the Replacement domain name.
*/
-static inline int knot_naptr_header_size(const uint8_t *naptr, const uint8_t *maxp)
-{
- size_t size = 0;
-
- /* Fixed fields size (order, preference) */
- size += 2 * sizeof(uint16_t);
-
- /* Variable fields size (flags, services, regexp) */
- for (int i = 0; i < 3; i++) {
- const uint8_t *len_ptr = naptr + size;
- if (len_ptr >= maxp) {
- return KNOT_EMALF;
- }
- size += 1 + *len_ptr;
- }
-
- return size;
-}
-
-/*! @} */
+int knot_naptr_header_size(const uint8_t *naptr, const uint8_t *maxp);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/knot-1.6.5/ylwrap new/knot-1.6.6/ylwrap
--- old/knot-1.6.5/ylwrap 2015-09-01 16:43:53.000000000 +0200
+++ new/knot-1.6.6/ylwrap 2015-11-24 17:36:51.000000000 +0100
@@ -3,7 +3,7 @@
scriptversion=2013-01-12.17; # UTC
-# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
#
# Written by Tom Tromey .
#