Commit 9661e47b authored by Vladimír Čunát's avatar Vladimír Čunát

Merge pointer-arith changes into cache-NSEC3

parents 1f848a12 fcb227b7
- fix a rare case of zones incorrectly dowgraded to insecure status
- avoid turning off qname minimization in some cases, e.g. (#339)
Knot Resolver 2.3.0 (2018-04-23)
......@@ -23,6 +23,7 @@ RUN apt-get install -y -qqq python3-pip wget augeas-tools
RUN pip3 install --upgrade pip
RUN pip3 install pylint
RUN pip3 install pep8
RUN pip3 install pytest-xdist
# C dependencies for python-augeas
RUN apt-get install -y -qqq libaugeas-dev libffi-dev
......@@ -27,7 +27,8 @@
#include <stdint.h>
#include <string.h>
#if defined(__linux__)
#if defined(__linux__) || defined(__gnu_hurd__) || \
(defined(__FreeBSD_kernel__) && defined(__GLIBC__))
# include <endian.h>
# ifndef be64toh
# include <arpa/inet.h>
......@@ -997,9 +997,9 @@ specified worker count and process rank.
Return current worker ID (starting from `0` up to `worker.count - 1`)
.. envvar:: pid (number)
.. envvar::
Current worker process PID.
Current worker process PID (number).
.. function:: worker.stats()
knot-resolver (2.0.0-1) unstable; urgency=medium
Knot Resolver systemd service units are now templated, so that multiple
processes can run concurrently on multi-core systems. For a full
overview of the status of all the running daemons, use:
systemctl status system-kresd.slice
For more information about this setup, please see kresd.systemd(7).
-- Daniel Kahn Gillmor <> Sat, 03 Feb 2018 22:51:02 -0500
knot-resolver (1.1.0~git2016072900-1) unstable; urgency=medium
Knot Resolver now starts and runs under unprivileged user and uses a
socket activations to bind on the privileged ports. That means that if
you use anything more complicated than that you need to either override
the default service file with `systemd edit kresd.service` and
`systemd edit kresd.socket` to add more IP addresses, or just disable
it with `systemd mask kresd*.socket kresd.service` and provide your
own custom system service file tailored to your needs.
-- Ondřej Surý <> Thu, 04 Aug 2016 09:04:53 +0200
Tracking upstream sources in git
This debian package is tracked in git at, which
This debian package is tracked in the git "debian/master" branch at, which
includes the commits from the upstream git repository at When importing
upstream tarballs, make sure you've fetched from the upstream repo
......@@ -11,7 +11,9 @@ upstream-vcs-tag from debian/gbp.conf to link upstream git history
with new package history.
See Joey Hess's thoughts about why tracking upstream git history is
useful:, as
well as DEP-14 for the branch-naming scheme:
Rebuilding epoch.js and epoch.css
......@@ -65,4 +67,4 @@ sass -t compact sass/epoch.scss > dist/css/epoch.css
sass -t compressed sass/epoch.scss > dist/css/epoch.min.css
-- Daniel Kahn Gillmor <>, Sun, 12 Nov 2017 12:52:39 +0800
-- Daniel Kahn Gillmor <>, Thu, 22 Feb 2018 13:25:27 -0800
......@@ -16,17 +16,13 @@ Build-Depends:
libknot-dev (>= 2.6.4),
libsystemd-dev (>= 227),
libsystemd-dev (>= 227) [linux-any],
Rules-Requires-Root: no
......@@ -3,7 +3,7 @@ Upstream-Name: knot-resolver
Files: *
Copyright: 2015 CZ.NIC
Copyright: 2015-2018 CZ.NIC
License: GPL-3.0+
Files: contrib/ccan/asprintf/*
......@@ -40,7 +40,7 @@ License: BSD-3-clause
Files: contrib/murmurhash3/*
Copyright: Austin Appleby
License: public-domain
License: CC0-1.0
Files: debian/missing-sources/dygraph-combined.js
......@@ -440,3 +440,14 @@ License: OpenLDAP
OpenLDAP is a registered trademark of the OpenLDAP Foundation.
License: CC0-1.0
This work is licensed under the "Creative Commons Zero" license.
On debian systems, a copy of the Creative Commons Zero license may be
found at /usr/share/common-licenses/CC0-1.0.
License: public-domain
This work has been released into the public domain. The map
implementation builds off of prior public domain work from Dan
Bernstein (qhasm) and Adam Langley (critbit).
......@@ -19,4 +19,12 @@ if [ "$1" = "triggered" ]; then
exit 0
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then
if [ -d /run/systemd/system ]; then
systemctl try-restart 'kresd@*.service' || true
invoke-rc.d kresd try-restart || true
......@@ -42,9 +42,8 @@ override_dh_auto_build-indep:
cd doc && sphinx-build -b html -D html_theme=nature . html
dh_auto_install --destdir=debian/tmp -- V=1
rm debian/tmp/etc/knot-resolver/icann-ca.pem
rm debian/tmp/etc/knot-resolver/root.hints
dh_auto_install --destdir=debian/tmp -- V=1 KEYFILE_DEFAULT=/usr/share/dns/root.key
rm -f debian/tmp/etc/knot-resolver/root.hints debian/tmp/etc/knot-resolver/icann-ca.pem
# install just the http/2 module
......@@ -14,18 +14,15 @@ to see how you can build it from sources (or package it), or use official `Docke
Platform considerations
.. csv-table::
:header: "Project", "Platforms", "Compatibility notes"
"``daemon``", "UNIX-like [#]_", "C99, libuv_ provides portable I/O"
"``library``", "UNIX-like", "MSVC_ not supported, needs MinGW_"
"``modules``", "*varies*", ""
"``tests/unit``", "*equivalent to library*", ""
"``tests/integration``", "UNIX-like", "Depends on library injection (see [2]_)"
Knot-resolver is written for UNIX-like systems, mainly in C99.
Portable I/O is provided by libuv_.
Some 64-bit systems with LuaJIT 2.1 may be affected by
`a problem <>`_
-- Linux on x86_64 is unaffected but `Linux on aarch64 is
.. [#] Known to be running (not exclusively) on FreeBSD, Linux and OS X.
.. Windows status??? Modules are not supported yet, as the PE/DLL loading is different. Library injection is working with ELF *(or Mach-O flat namespace)* only.
Windows systems might theoretically work without large changes,
but it's most likely broken and currently not planned to be supported.
......@@ -36,12 +33,13 @@ The following is a list of software required to build Knot DNS Resolver from sou
:header: "Requirement", "Required by", "Notes"
"`GNU Make`_ 3.80+", "*all*", "*(build only)*"
"C compiler", "*all*", "*(build only)* [#]_"
"C and C++ compiler", "*all*", "*(build only)* [#]_"
"`pkg-config`_", "*all*", "*(build only)* [#]_"
"hexdump or xxd", "``daemon``", "*(build only)*"
"libknot_ 2.4.0+", "*all*", "Knot DNS library (requires autotools, GnuTLS and Jansson)."
"libknot_ 2.6.4+", "*all*", "Knot DNS libraries - requires autotools, GnuTLS, ..."
"LuaJIT_ 2.0+", "``daemon``", "Embedded scripting language."
"libuv_ 1.7+", "``daemon``", "Multiplatform I/O and services (libuv_ 1.0 with limitations [#]_)."
"lmdb", "``daemon``", "If missing, a static version is embedded."
There are also *optional* packages that enable specific functionality in Knot DNS Resolver, they are useful mainly for developers to build documentation and tests.
......@@ -51,9 +49,6 @@ There are also *optional* packages that enable specific functionality in Knot DN
"`lua-http`_", "``modules/http``", "HTTP/2 client/server for Lua."
"luasocket_", "``trust anchors, modules/stats``", "Sockets for Lua."
"luasec_", "``trust anchors``", "TLS for Lua."
"libmemcached_", "``modules/memcached``", "To build memcached backend module."
"hiredis_", "``modules/redis``", "To build redis backend module."
"Go_ 1.5+", "``modules``", "Build modules written in Go."
"cmocka_", "``unit tests``", "Unit testing framework."
"Doxygen_", "``documentation``", "Generating API documentation."
"Sphinx_ and sphinx_rtd_theme_", "``documentation``", "Building this HTML/PDF documentation."
......@@ -66,6 +61,10 @@ There are also *optional* packages that enable specific functionality in Knot DN
"`clang-tidy`_", "``lint-c``", "Syntax and static analysis checker for C."
"luacov_", "``check-config``", "Code coverage analysis for Lua modules."
.. "libmemcached_", "``modules/memcached``", "To build memcached backend module."
"hiredis_", "``modules/redis``", "To build redis backend module."
"Go_ 1.5+", "``modules``", "Build modules written in Go."
.. [#] Requires C99, ``__attribute__((cleanup))`` and ``-MMD -MP`` for dependency file generation. GCC, Clang and ICC are supported.
.. [#] You can use variables ``<dependency>_CFLAGS`` and ``<dependency>_LIBS`` to configure dependencies manually (i.e. ``libknot_CFLAGS`` and ``libknot_LIBS``).
.. [#] libuv 1.7 brings SO_REUSEPORT support that is needed for multiple forks. libuv < 1.7 can be still used, but only in single-process mode. Use :ref:`different method <daemon-reuseport>` for load balancing.
......@@ -2,9 +2,9 @@
Knot DNS Resolver
The Knot DNS Resolver is a minimalistic caching resolver implementation.
The project provides both a resolver library and a small daemon.
Modular architecture of the library keeps the core tiny and efficient, and provides a state-machine like API for extensions.
Knot Resolver is a minimalistic implementation of a caching validating DNS resolver.
Modular architecture keeps the core tiny and efficient,
and it provides a state-machine like API for extensions.
.. toctree::
:maxdepth: 2
......@@ -132,7 +132,7 @@ that all enabled daemons are started and running, do:
.RS 4n
.B systemctl start 'kresd@*.service'
.B systemctl start --all 'kresd@*.service'
......@@ -21,7 +21,7 @@
#include "lib/cache/impl.h"
int rdataset_dematerialize(const knot_rdataset_t *rds, void * restrict data)
int rdataset_dematerialize(const knot_rdataset_t *rds, uint8_t * restrict data)
//const void *data0 = data;
......@@ -47,12 +47,12 @@ int rdataset_dematerialize(const knot_rdataset_t *rds, void * restrict data)
/** Materialize a knot_rdataset_t from cache with given TTL.
* Return the number of bytes consumed or an error code.
static int rdataset_materialize(knot_rdataset_t * restrict rds, const void * const data,
const void *data_bound, uint32_t ttl, knot_mm_t *pool)
static int rdataset_materialize(knot_rdataset_t * restrict rds, const uint8_t * const data,
const uint8_t *data_bound, uint32_t ttl, knot_mm_t *pool)
assert(rds && data && data_bound && data_bound > data && !rds->data);
assert(pool); /* not required, but that's our current usage; guard leaks */
const void *d = data; /* iterates over the cache data */
const uint8_t *d = data; /* iterates over the cache data */
uint16_t rr_count;
memcpy(&rr_count, d, sizeof(rr_count));
......@@ -238,7 +238,7 @@ static inline int rdataset_dematerialize_size(const knot_rdataset_t *rds)
/** Dematerialize a rdataset. */
int rdataset_dematerialize(const knot_rdataset_t *rds, void * restrict data);
int rdataset_dematerialize(const knot_rdataset_t *rds, uint8_t * restrict data);
/** NSEC* parameters; almost nothing is meaningful for NSEC. */
struct nsec_p {
......@@ -650,17 +650,28 @@ static int process_answer(knot_pkt_t *pkt, struct kr_request *req)
struct kr_query *query = req->current_query;
/* Response for minimized QNAME.
/* Response for minimized QNAME. Note that current iterator's minimization
* is only able ask one label below a zone cut.
* NODATA => may be empty non-terminal, retry (found zone cut)
* NOERROR => found zone cut, retry
* NOERROR => found zone cut, retry, except the case described below
* NXDOMAIN => parent is zone cut, retry as a workaround for bad authoritatives
bool is_final = (query->parent == NULL);
int pkt_class = kr_response_classify(pkt);
if (!knot_dname_is_equal(knot_pkt_qname(pkt), query->sname) &&
const bool is_final = (query->parent == NULL);
const int pkt_class = kr_response_classify(pkt);
const knot_dname_t * pkt_qname = knot_pkt_qname(pkt);
if (!knot_dname_is_equal(pkt_qname, query->sname) &&
VERBOSE_MSG("<= found cut, retrying with non-minimized name\n");
query->flags.NO_MINIMIZE = true;
/* Check for parent server that is authoritative for child zone,
* several CCTLDs where the SLD and TLD have the same name servers */
const knot_pktsection_t *ans = knot_pkt_section(pkt, KNOT_ANSWER);
if ((pkt_class & (PKT_NOERROR)) && ans->count > 0 &&
knot_dname_is_equal(pkt_qname, query-> {
VERBOSE_MSG("<= continuing with qname minimization\n")
} else {
/* fall back to disabling minimization */
VERBOSE_MSG("<= retrying with non-minimized name\n");
query->flags.NO_MINIMIZE = true;
......@@ -420,13 +420,17 @@ static int update_delegation(struct kr_request *req, struct kr_query *qry, knot_
/* Rank the corresponding nonauth NS as insecure. */
for (int i = 0; i < req->auth_selected.len; ++i) {
ranked_rr_array_entry_t *ns = req->[i];
if (ns->qry_uid != qry->uid || !ns->rr
if (ns->qry_uid != qry->uid
|| !ns->rr
|| ns->rr->type != KNOT_RRTYPE_NS) {
if (!referral && !knot_dname_is_equal(qry->sname, ns->rr->owner)) {
/* Found the record. Note: this is slightly fragile
* in case there were more NS records in the packet.
* As it is now, kr_nsec*_ref_to_unsigned consider
* As it is now for referrals, kr_nsec*_ref_to_unsigned consider
* (only) the first NS record in the packet. */
if (!kr_rank_test(ns->rank, KR_RANK_AUTH)) { /* sanity */
ns->rank = KR_RANK_INSECURE;
......@@ -222,10 +222,12 @@ static int ns_fetch_cut(struct kr_query *qry, const knot_dname_t *requested_name
* even if cut name is covered by TA. */
qry->flags.DNSSEC_WANT = false;
qry->flags.DNSSEC_INSECURE = true;
VERBOSE_MSG(qry, "=> going insecure because parent query is insecure\n");
} else if (kr_ta_covers_qry(req->ctx, qry->, KNOT_RRTYPE_NS)) {
qry->flags.DNSSEC_WANT = true;
} else {
qry->flags.DNSSEC_WANT = false;
VERBOSE_MSG(qry, "=> going insecure because there's no covering TA\n");
struct kr_zonecut cut_found;
......@@ -442,8 +442,8 @@ int kr_zonecut_find_cached(struct kr_context *ctx, struct kr_zonecut *cut,
auto_free char *label_str = kr_dname_text(label);
"found cut: %s (return codes: DS %d, DNSKEY %d)\n",
label_str, ret_ds, ret_dnskey);
"found cut: %s (rank 0%.2o return codes: DS %d, DNSKEY %d)\n",
label_str, rank, ret_ds, ret_dnskey);
return kr_ok();
......@@ -22,7 +22,7 @@ A *filter* selects which queries will be affected by specified *action*. There a
- applies the action if QNAME suffix matches one of suffixes in the table (useful for "is domain in zone" rules),
uses `Aho-Corasick`_ string matching algorithm `from CloudFlare <>`_ (BSD 3-clause)
* :any:`policy.suffix_common`
* ``rpz``
* ``rpz(default_action, path)``
- implements a subset of RPZ_ in zonefile format. See below for details: :any:`policy.rpz`.
* custom filter function
......@@ -182,9 +182,9 @@ Most properties (actions, filters) are described above.
Like suffix match, but you can also provide a common suffix of all matches for faster processing (nil otherwise).
This function is faster for small suffix tables (in the order of "hundreds").
.. function:: policy.rpz(action, path[, format])
.. function:: policy.rpz(action, path)
:param action: the default action for match in the zone (e.g. RH-value `.`)
:param action: the default action for match in the zone; typically you want ``policy.DENY``
:param path: path to zone file | database
Enforce RPZ_ rules. This can be used in conjunction with published blocklist feeds.
......@@ -194,13 +194,16 @@ Most properties (actions, filters) are described above.
.. csv-table::
:header: "Policy Action", "RH Value", "Support"
"NXDOMAIN", "``.``", "**yes**"
"NODATA", "``*.``", "*partial*, implemented as NXDOMAIN"
"Unchanged", "``rpz-passthru.``", "**yes**"
"Nothing", "``rpz-drop.``", "**yes**"
"Truncated", "``rpz-tcp-only.``", "**yes**"
"``action`` is used", "``.``", "**yes**, if ``action`` is ``DENY``"
"``action`` is used ", "``*.``", "*partial* [#]_"
"``policy.PASS``", "``rpz-passthru.``", "**yes**"
"``policy.DROP``", "``rpz-drop.``", "**yes**"
"``policy.TC``", "``rpz-tcp-only.``", "**yes**"
"Modified", "anything", "no"
.. [#] The specification for ``*.`` wants a ``NODATA`` answer.
For now, ``policy.DENY`` action doing ``NXDOMAIN`` is typically used instead.
.. csv-table::
:header: "Policy Trigger", "Support"
......@@ -9,7 +9,7 @@ filters and ACLs, sort of like ISC BIND views.
There are two identification mechanisms:
* ``subnet``
* ``addr``
- identifies the client based on his subnet
* ``tsig``
- identifies the client based on a TSIG key
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment