LIBKRES_NAME: libkres
MESON_TEST: meson test -C build_ci* -t 4 --print-errorlogs
PREFIX: $CI_PROJECT_DIR/.local
- GIT_COMMITER_NAME: 'ci'
+ GIT_COMMITTER_NAME: 'ci'
EMAIL: 'ci@nic'
image: $CI_REGISTRY/knot/knot-resolver/ci/debian-11:knot-$KNOT_VERSION
- branches@knot/security/knot-resolver
stage: build
when: delayed
- start_in: 3 minutes # allow some time for mirrorring, job creation
+ start_in: 3 minutes # allow some time for mirroring, job creation
script:
- ci/gh_actions.py ${CI_COMMIT_REF_NAME} ${CI_COMMIT_SHA}
Improvements
------------
-- improve handling of timeouted outgoing TCP connections (!734)
+- improve handling of timed out outgoing TCP connections (!734)
- trust_anchors: check syntax of public keys in DNSKEY RRs (!748)
- validator: clarify message about bogus non-authoritative data (!735)
- dnssec validation failures contain more verbose reasoning (!735)
- DNS cookie module (RFC 7873) is not available in this release,
it will be later reworked to reflect development in IEFT dnsop working group
- version module was permanently removed because it was not really used by users;
- if you want to receive notifications abou new releases please subscribe to
+ if you want to receive notifications about new releases please subscribe to
https://lists.nic.cz/cgi-bin/mailman/listinfo/knot-resolver-announce
Bugfixes
Improvements
------------
- reorder_RR() implementation is brought back
-- bring in performace improvements provided by libknot 2.7
+- bring in performance improvements provided by libknot 2.7
- cache.clear() has a new, more powerful API
- cache documentation was improved
- old name "Knot DNS Resolver" is replaced by unambiguous "Knot Resolver"
Security
--------
-- fix a rare case of zones incorrectly dowgraded to insecure status (!576)
+- fix a rare case of zones incorrectly downgraded to insecure status (!576)
New features
------------
--------
- validation: fix SERVFAIL in case of CNAME to NXDOMAIN in a single zone (!538)
- validation: fix SERVFAIL for DS . query (!544)
-- lib/resolve: don't send unecessary queries to parent zone (!513)
+- lib/resolve: don't send unnecessary queries to parent zone (!513)
- iterate: fix validation for zones where parent and child share NS (!543)
- TLS: improve error handling and documentation (!536, !555, !559)
- trust anchors: support non-root TAs, one domain per file
- policy.DENY: set AA flag and clear AD flag
- lib/resolve: avoid unnecessary DS queries
-- lib/nsrep: don't treat servers with NOIP4 + NOIP6 flags as timeouted
+- lib/nsrep: don't treat servers with NOIP4 + NOIP6 flags as timed out
- layer/iterate: During packet classification (answer vs. referral)
don't analyze AUTHORITY section in authoritative answer if ANSWER
section contains records that have been requested
- lua: do *not* truncate cache size to unsigned
- forwarding mode: correctly forward +cd flag
- fix a potential memory leak
-- don't treat answers that contain DS non-existance proof as insecure
+- don't treat answers that contain DS non-existence proof as insecure
- don't store NSEC3 and their signatures in the cache
- layer/iterate: when processing delegations, check if qname is at or
below new authority
- hints module: previously /etc/hosts was loaded by default, but not anymore.
Users can now actually avoid loading any file.
- DNS over TLS now creates ephemeral certs.
-- Configurable cache.{min,max}_tll option, with max_ttl defaulting to 6 days.
+- Configurable cache.{min,max}_ttl option, with max_ttl defaulting to 6 days.
- Option to reorder RRs in the response.
- New policy.QTRACE policy to print packet contents
return result;
}
-// compatibility layer for the oler lru_* names; it's more compler with lru_create
+// compatibility layer for the older lru_* names
#ifndef lru_create
#define lru_get_new lru_set
#define lru_get_try lru_get
# generic cleanup
RUN apt-get update -qq
-# Knot and Knot Resolver dependecies
+# Knot and Knot Resolver dependencies
RUN apt-get install -y -qqq git make cmake pkg-config meson \
build-essential bsdmainutils libtool autoconf libcmocka-dev \
liburcu-dev libgnutls28-dev libedit-dev liblmdb-dev libcap-ng-dev libsystemd-dev \
golang-any
RUN bash -c "go get github.com/{FiloSottile/gvt,cloudflare/dns,dnstap/golang-dnstap,golang/protobuf/proto}"
-# documentation dependecies
+# documentation dependencies
RUN apt-get install -y -qqq doxygen python3-sphinx python3-breathe python3-sphinx-rtd-theme
-# Python packags required for Deckard CI
+# Python packages required for Deckard CI
# Python: grab latest versions from PyPi
# (Augeas binding in Debian packages are slow and buggy)
RUN apt-get install -y -qqq python3-pip wget augeas-tools
# TODO: run upgrade once buster reaches a stable release
# RUN apt-get upgrade -y -qqq
-# Knot and Knot Resolver dependecies
+# Knot and Knot Resolver dependencies
RUN apt-get install -y -qqq git make cmake pkg-config meson \
build-essential bsdmainutils libtool autoconf libcmocka-dev \
liburcu-dev libgnutls28-dev libedit-dev liblmdb-dev libcap-ng-dev libsystemd-dev \
# package crypto/ed25519: unrecognized import path "crypto/ed25519"
#RUN bash -c "go get github.com/{FiloSottile/gvt,cloudflare/dns,dnstap/golang-dnstap}"
-# documentation dependecies
+# documentation dependencies
RUN apt-get install -y -qqq doxygen python3-sphinx python3-breathe python3-sphinx-rtd-theme
-# Python packags required for Deckard CI
+# Python packages required for Deckard CI
# Python: grab latest versions from PyPi
# (Augeas binding in Debian packages are slow and buggy)
RUN apt-get install -y -qqq python3-pip wget augeas-tools
*
* prefix - identifier prefix, e.g. ptr -> struct ptr_dynarray, ptr_dynarray_add(), ...
* ntype - data type to be stored. Let it be a number, pointer or small struct
- * initial_capacity - how many data items will be allocated on stac and copied with assignment
+ * initial_capacity - how many data items will be allocated on stack and copied with assignment
*
* prefix_dynarray_add() - add a data item
* prefix_dynarray_fix() - call EVERYTIME the array is copied from some already invalid stack
/**
* [[std]]
* This allocator uses <<basics:xmalloc()>>, <<basics:xrealloc()>> and <<basics:xfree()>>. The memory
- * it allocates is left unitialized.
+ * it allocates is left uninitialized.
**/
extern struct ucw_allocator ucw_allocator_std;
* you can grow it incrementally to needed size. You can grow only
* one buffer at a time on a given mempool.
*
- * Similar functionality is provided by <<growbuf:,growing buffes>> module.
+ * Similar functionality is provided by <<growbuf:,growing buffers>> module.
***/
/* For internal use only, do not call directly */
[round] => 1
[subtree] => com.
> worker.sleep(0.1)
- [cache] asynchonous cache.clear('com', false) finished
+ [cache] asynchronous cache.clear('com', false) finished
-- Clear only 'www.example.com.'
> cache.clear('www.example.com.', true)
:return: event id
- Execute function immediatelly and then periodically after each ``interval``.
+ Execute function immediately and then periodically after each ``interval``.
Example:
local interval = 1 * minute
event.after(1 * minute, function (ev)
print('Good morning!')
- -- Halven the interval for each iteration
+ -- Halve the interval for each iteration
interval = interval / 2
event.reschedule(ev, interval)
end)
function async_print(testname, sleep)
log(testname .. ': system time before sleep' .. tostring(os.time())
- worker.sleep(sleep) -- other corroutines continue execution now
+ worker.sleep(sleep) -- other coroutines continue execution now
log(testname .. ': system time AFTER sleep' .. tostring(os.time())
end
if (ret != 0) {
kr_log_error(SYSTEM, "error: %s\n", lua_tostring(L, -1));
}
- /* Clear the stack, there may be event a/o enything returned */
+ /* Clear the stack, there may be event a/o anything returned */
lua_settop(L, 0);
return ret;
}
int n = lua_gettop(L);
if (n < 1 || n > 3) {
lua_error_p(L, "expected one to three arguments; usage:\n"
- "net.listen(addressses, [port = " STR(KR_DNS_PORT)
+ "net.listen(addresses, [port = " STR(KR_DNS_PORT)
", flags = {tls = (port == " STR(KR_DNS_TLS_PORT) ")}])\n");
}
if (*pp != NULL || !strcasecmp(kind, "dns") || !strcasecmp(kind, "tls"))
lua_error_p(L, "attempt to register known kind '%s'\n", kind);
*pp = (char *)NULL + fun_id;
- /* We don't attempt to engage correspoinding endpoints now.
+ /* We don't attempt to engage corresponding endpoints now.
* That's the job for network_engage_endpoints() later. */
return 0;
}
Get/set maximum EDNS payload size advertised in DNS packets. Different values can be configured for communication downstream (towards clients) and upstream (towards other DNS servers). Set and also get operations use values in this order.
- Default is 1232 bytes which was chosed to minimize risk of `issues caused by IP fragmentation <https://blog.apnic.net/2019/07/12/its-time-to-consider-avoiding-ip-fragmentation-in-the-dns/>`_. Further details can be found at `DNS Flag Day 2020 <https://dnsflagday.net/2020/>`_ web site.
+ Default is 1232 bytes which was chosen to minimize risk of `issues caused by IP fragmentation <https://blog.apnic.net/2019/07/12/its-time-to-consider-avoiding-ip-fragmentation-in-the-dns/>`_. Further details can be found at `DNS Flag Day 2020 <https://dnsflagday.net/2020/>`_ web site.
Minimal value allowed by standard :rfc:`6891` is 512 bytes, which is equal to DNS packet size without Extension Mechanisms for DNS. Value 1220 bytes is minimum size required by DNSSEC standard :rfc:`4035`.
If you provide the same secret to multiple instances, they will be able to resume
each other's sessions *without* any further communication between them.
- This synchronization works only among instances having the same endianess
+ This synchronization works only among instances having the same endianness
and time_t structure and size (`sizeof(time_t)`).
**For good security** the secret must have enough entropy to be hard to guess,
local prev_count = cache.count()
ok(prev_count > 0, 'previous subtree clearing did not remove everything')
res = cache.clear('.', false, nil, 10000)
- is(res.count, prev_count, 'clear on root removed everyting including proofs')
+ is(res.count, prev_count, 'clear on root removed everything including proofs')
check_answer('exact match on qname must flush negative proofs for owner from cache',
'a.b.subtree1.', kres.type.NULL, kres.rcode.SERVFAIL)
end
/* Network deinit is split up. We first need to stop listening,
* then we can unload modules during which we still want
* e.g. the endpoint kind registry to work (inside ->net),
- * and this registry deinitization uses the lua state. */
+ * and this registry deinitialization uses the lua state. */
network_close_force(&engine->net);
for (size_t i = 0; i < engine->modules.len; ++i) {
engine_unload(engine, engine->modules.at[i]);
{
static const char key[] = "dns=";
static const char *delim = "&";
- static const char *endpoins[] = {"dns-query", "doh"};
+ static const char *endpoints[] = {"dns-query", "doh"};
char *beg;
char *end_prev;
ssize_t endpoint_len;
/* check endpoint */
ret = -1;
- for(int i = 0; i < sizeof(endpoins)/sizeof(*endpoins); i++)
+ for(int i = 0; i < sizeof(endpoints)/sizeof(*endpoints); i++)
{
- if (strlen(endpoins[i]) != endpoint_len)
+ if (strlen(endpoints[i]) != endpoint_len)
continue;
- ret = strncmp(path + 1, endpoins[i], strlen(endpoins[i]));
+ ret = strncmp(path + 1, endpoints[i], strlen(endpoints[i]));
if (!ret)
break;
}
/* Transfer ownership to stream (waiting in wirebuffer) */
/* FIXME: technically, transferring memory ownership should happen
* along with queue_push(ctx->streams) to avoid confusion of who owns
- * what and when. Pushing to queue should be done AFTER we sucessfully
+ * what and when. Pushing to queue should be done AFTER we successfully
* finish this function. On error, we'd clean up and not push anything.
* However, queue's content is now also used to detect first DATA frame
* in stream, so it needs to be refactored first.
}
/*
- * Send dns response provided by the HTTTP/2 data provider.
+ * Send dns response provided by the HTTP/2 data provider.
*
* Data isn't guaranteed to be sent immediately due to underlying HTTP/2 flow control.
*/
* Send HTTP/2 stream data created from packet's wire buffer.
*
* If this function returns an error, the on_write() callback isn't (and
- * musn't be!) called, since such errors are handled in an upper layer - in
+ * mustn't be!) called, since such errors are handled in an upper layer - in
* qr_task_step() in daemon/worker.
*/
static int http_write_pkt(struct http_ctx *ctx, knot_pkt_t *pkt, int32_t stream_id,
the_worker->stats.timeout += finalized;
/* session_tasklist_finalize_expired() may call worker_task_finalize().
* If session is a source session and there were IO errors,
- * worker_task_finalize() can filnalize all tasks and close session. */
+ * worker_task_finalize() can finalize all tasks and close session. */
if (session_flags(s)->closing) {
return;
}
if (data->mode == io_mode_binary) {
/* Leader expects length field in all cases */
if (!message || len_s > UINT32_MAX) {
- kr_log_error(IO, "unrepresentable respose on control socket, "
+ kr_log_error(IO, "unrepresentable response on control socket, "
"sending back empty block (command '%s')\n", cmd);
len_s = 0;
}
local function switch_to_binary_mode(sock)
data = sock:xread(2, nil, timeout)
sock:xwrite('__binary\n', nil, timeout)
- same(data, '> ', 'propably successsful switch to binary mode')
+ same(data, '> ', 'probably successful switch to binary mode')
end
local function socket_connect(path)
})
-- helper for trace_chain_callbacks
--- ignores return values from successfull calls but logs tracebacks for throws
+-- ignores return values from successful calls but logs tracebacks for throws
local function void_xpcall_log_tb(func, req, msg)
local ok, err = xpcall(func, debug.traceback, req, msg)
if not ok then
key_val_sep = ' ',
__inst_mt = {}
}
--- inhertance form base class (for :new())
+-- inheritance form base class (for :new())
setmetatable(serializer_class, { __index = base_class })
-- class instances with following metatable inherit all class members
serializer_class.__inst_mt.__index = serializer_class
function tests_start()
-- just in case, duplicates should not happen
if started then
- log_info(ffi.C.LOG_GRP_TESTS, 'huh? duplicate test invocation ignored, a retrasmit?')
+ log_info(ffi.C.LOG_GRP_TESTS, 'huh? duplicate test invocation ignored, a retransmit?')
return
end
started = true
cache.clear(cbname, cbexact_name, cbrr_type, cbchunk_size, cbself, cbrettable)
end)
elseif cbrettable.round > 1 then
- log_info(ffi.C.LOG_GRP_CACHE, 'asynchonous cache.clear(\'' .. cbname .. '\', '
+ log_info(ffi.C.LOG_GRP_CACHE, 'asynchronous cache.clear(\'' .. cbname .. '\', '
.. tostring(cbexact_name) .. ') finished')
end
return cbrettable
recv = _sock_check(s, s.read, {s, 4}, path,
'response length read')
_sock_assert(recv and #recv == 4, path,
- 'length of response length preambule does not match')
+ 'length of response length preamble does not match')
local len = tonumber(recv:byte(1))
for i=2,4 do
len = bit.bor(bit.lshift(len, 8), tonumber(recv:byte(i)))
ret = _sock_check(s, s.read, {s, len}, path,
'read response')
_sock_assert(ret and #ret == len, path,
- 'actual response length does not match length in preambule')
+ 'actual response length does not match length in preamble')
s:close()
return ret
end
-- @returns table with results, one item per instance + key n=number of instances
-- (order of return values is undefined)
-- @throws Lua error if:
--- - communication failed in the middle of trasaction
+-- - communication failed in the middle of transaction
-- - a result is not serializable
-- - individual call throws an error
-- - number of return values != 1 per instance per call
assert(os.rename(fname_tmp, keyset.filename))
end
--- Search the values of a table and return the corrseponding key (or nil).
+-- Search the values of a table and return the corresponding key (or nil).
local function table_search(t, val)
for k, v in pairs(t) do
if v == val then
.. function:: trust_anchors.remove(zonename)
- Remove specified trust anchor from trusted key set. Removing trust anchor for the root zone effectivelly disables DNSSEC validation (unless you configured another trust anchor).
+ Remove specified trust anchor from trusted key set. Removing trust anchor for the root zone effectively disables DNSSEC validation (unless you configured another trust anchor).
.. code-block:: lua
boom(trust_anchors.add_file, {'nonwriteable/root.keys', false},
"Managed trust anchor in non-writeable directory")
- boom(trust_anchors.add_file, {'nonexist.keys', true},
- "Nonexist unmanaged trust anchor file")
+ boom(trust_anchors.add_file, {'nonexistent.keys', true},
+ "Nonexistent unmanaged trust anchor file")
is(warn_msg[overriding_msg], 0, "No override warning messages at start of test")
trust_anchors.add_file('root.keys', true)
void network_init(struct network *net, uv_loop_t *loop, int tcp_backlog);
void network_deinit(struct network *net);
-/** Start listenting on addr#port with flags.
+/** Start listening on addr#port with flags.
* \note if we did listen on that combination already,
* nothing is done and kr_error(EADDRINUSE) is returned.
* \note there's no short-hand to listen both on UDP and TCP.
int network_listen(struct network *net, const char *addr, uint16_t port,
int16_t nic_queue, endpoint_flags_t flags);
-/** Start listenting on an open file-descriptor.
+/** Start listening on an open file-descriptor.
* \note flags.sock_type isn't meaningful here.
* \note ownership of flags.* is taken on success. TODO: non-success?
*/
Knot Resolver offers several ways to modify its configuration at run-time:
- Using control socket driven by an external system
- - Using Lua program embeded in Resolver's configuration file
+ - Using Lua program embedded in Resolver's configuration file
Both ways can also be combined: For example the configuration file can contain
a little Lua function which gathers statistics and returns them in JSON string.
> map('require("kluautil").kr_table_pack(pcall(net.tls, "cert.pem", "key.pem"))')
{
{
- true, -- function suceeded
+ true, -- function succeeded
true, -- function return value(s)
['n'] = 2,
},
Note that each scheduled event is identified by a number valid for the duration
of the event, you may use it to cancel the event at any time.
-To persist state between two invocations of a fuction Lua uses concept called
+To persist state between two invocations of a function Lua uses concept called
closures_. In the following example function ``speed_monitor()`` is a closure
function, which provides persistent variable called ``previous``.
struct http_ctx *http_ctx; /**< server side http-related data. */
#endif
- trie_t *tasks; /**< list of tasks assotiated with given session. */
+ trie_t *tasks; /**< list of tasks associated with given session. */
queue_t(struct qr_task *) waiting; /**< list of tasks waiting for sending to upstream. */
uint8_t *wire_buf; /**< Buffer for DNS message, except for XDP. */
if (kr_fails_assert(!session_wirebuf_error(session)))
return -1;
int res = worker_submit(session, peer, NULL, NULL, NULL, pkt);
- /* Errors from worker_submit() are intetionally *not* handled in order to
+ /* Errors from worker_submit() are intentionally *not* handled in order to
* ensure the entire wire buffer is processed. */
if (res == kr_ok())
ret += 1;
{
if (kr_fails_assert(ctx && ctx->hash_len >= sizeof(epoch)))
return kr_error(EINVAL);
- /* documented limitation: time_t and endianess must match
+ /* documented limitation: time_t and endianness must match
* on instances sharing a secret */
if (!force_update && memcmp(ctx->hash_data, &epoch, sizeof(epoch)) == 0) {
return kr_ok(); /* we are up to date */
* It can be
* 1) either successful rehandshake; in this case peer
* must be already in the connected list.
- * 2) or successful handshake with session, which was timeouted
+ * 2) or successful handshake with session, which was timed out
* by on_tcp_connect_timeout(); after successful tcp connection;
* in this case peer isn't in the connected list.
**/
const bool log_debug = kr_log_is_debug(WORKER, NULL);
/* Check if the connection is in the waiting list.
- * If no, most likely this is timeouted connection
+ * If no, most likely this is timed out connection
* which was removed from waiting list by
* on_tcp_connect_timeout() callback. */
struct session *s = worker_find_tcp_waiting(worker, peer);
if (!s || s != session) {
/* session isn't on the waiting list.
- * it's timeouted session. */
+ * it's timed out session. */
if (log_debug) {
const char *peer_str = kr_straddr(peer);
kr_log_debug(WORKER, "=> connected to '%s', but session "
- "is already timeouted, close\n",
+ "is already timed out, close\n",
peer_str ? peer_str : "");
}
kr_assert(session_tasklist_is_empty(session));
* for this request.
* So connection callback (on_connect()) must check
* if connection is in the list of waiting connection.
- * If no, most likely this is timeouted connection even if
+ * If no, most likely this is timed out connection even if
* it was successful. */
}
/* No unsent queries at that point. */
if (session_tasklist_get_len(session) >= worker->tcp_pipeline_max) {
- /* Too many outstanding queries, answer with SERFVAIL, */
+ /* Too many outstanding queries, answer with SERVFAIL, */
return kr_error(EINVAL);
}
if (kr_fails_assert(!session_flags(session)->closing))
return kr_error(EINVAL);
addr = peer;
- /* Note recieve time for RTT calculation */
+ /* Note receive time for RTT calculation */
task->recv_time = kr_now();
}
if (kr_fails_assert(!uv_is_closing(session_get_handle(session))))
knot_pkt_begin(answer, KNOT_AUTHORITY);
}
- /* Put target rrset to ANSWER\AUTHORIRY as well as corresponding RRSIG */
+ /* Put target rrset to ANSWER\AUTHORITY as well as corresponding RRSIG */
int err = zi_rrset_put(z_import, answer, rr);
if (err != 0) {
goto cleanup;
%description module-dnstap
dnstap module for Knot Resolver supports logging DNS responses to a unix socket
in dnstap format using fstrm framing library. This logging is useful if you
-need effectivelly log all DNS traffic.
+need effectively log all DNS traffic.
%endif
%if "x%{?suse_version}" == "x"
a domain name. It also tests that DNSSEC validation is turned on.
By default, the *knot-resolver-devel* repo (for knot-resolver) along
-with *knot-resoler-latest* (for knot) is used. To test only the
+with *knot-resolver-latest* (for knot) is used. To test only the
*knot-resolver-latest* repo, set it in `repos.yaml` (or use the
test-distro.sh script which overwrites this file). If you're running
tests in parallel, they all HAVE TO use the same repo(s).
include_vars: "{{ obs_distro }}.yaml"
when: obs_distro != "Debian"
-- name: Configure upstream reporitories
+- name: Configure upstream repositories
include: "{{ obs_distro }}.yaml"
Released tarballs are available from `<https://knot-resolver.cz/download/>`_
-To make a release tarball from git, use the follwing command. The
+To make a release tarball from git, use the following command. The
.. code-block:: bash
Recommended build options for packagers:
-* ``--buildtype=release`` for default flags (optimalization, asserts, ...). For complete control over flags, use ``plain`` and see :ref:`build-custom-flags`.
+* ``--buildtype=release`` for default flags (optimization, asserts, ...). For complete control over flags, use ``plain`` and see :ref:`build-custom-flags`.
* ``--prefix=/usr`` to customize
prefix, other directories can be set in a similar fashion, see ``meson setup
--help``
html_theme_options = {
'logo_only': True, # if we have a html_logo below, this shows only the logo with no title text
- # Toc options
+ # ToC options
'collapse_navigation': False,
'sticky_navigation': True,
}
Answer reordering
=================
Certain clients are "dumb" and always connect to first IP address or name found
-in a DNS answer received from resolver intead of picking randomly.
+in a DNS answer received from resolver instead of picking randomly.
As a workaround for such broken clients it is possible to randomize
order of records in DNS answers sent by resolver:
:return: int (default: 5 minutes in meson's release mode, 0 otherwise)
- If a proccess should be aborted, it can be done in two ways. When this is
+ If a process should be aborted, it can be done in two ways. When this is
set to nonzero (default), a child is forked and aborted to obtain a coredump,
while the parent process recovers and keeps running. This can be useful to
debug a rare issue that occurs in production, since it doesn't affect the
:return: boolean ``true`` when ``debug`` level is enabled.
Toggle between ``debug`` and ``notice`` log level. Use only for debugging purposes.
- On busy systems vebose logging can produce several MB of logs per
+ On busy systems verbose logging can produce several MB of logs per
second and will slow down operation.
.. py:function:: log_target(target)
^^^^^^^^^^^^^^^
.. warning:: Executing processes as root is generally insecure, as these
- proccesses have unconstrained access to the complete system at runtime.
+ processes have unconstrained access to the complete system at runtime.
While not recommended, it is also possible to run kresd directly as root.
> -- this is a comment entered into interactive prompt
> -- comments have no effect here
- > -- the next line shows a command entered interactivelly and its output
+ > -- the next line shows a command entered interactively and its output
> log_level()
'notice'
> -- the previous line without > character is output from log_level() command
-Following example demontrates how to interactivelly list all currently loaded modules, and includes multi-line output:
+Following example demonstrates how to interactively list all currently loaded modules, and includes multi-line output:
.. code-block:: lua
Increase logging to debug level.
.TP
.B \-h
-Show short commandline option help.
+Show short command-line option help.
.TP
.B \-V
Show the version.
Beware that this method has not been scientifically tested and there might be
types of attacks which will allow remote resolvers to infer more information about the client.
- Again: If possible encypt **all** your traffic and not just DNS queries!
+ Again: If possible encrypt **all** your traffic and not just DNS queries!
.. code-block:: lua
"``trust_anchors.keyfile_default = nil``", "``trust_anchors.remove('.')``"
-* Network for HTTP endpoints is now configured using same mechanism as for normal DNS enpoints,
+* Network for HTTP endpoints is now configured using same mechanism as for normal DNS endpoints,
please refer to chapter :ref:`network-configuration`. Migration table:
.. csv-table::
finish = function(pkt)
-- delay exit after packet is finished
-- to prevent us from losing policy.DEBUG finish callback
- event.after(1, -- milisecond
+ event.after(1, -- millisecond
function()
local endtime = cqueues.monotime()
log_info(ffi.C.LOG_GRP_RESOLVER, 'request finished in %f ms', (endtime - starttime) * 1000)
multiple systemd units, and a shared tmpfs space could be used up by other
applications, leading to ``SIGBUS`` errors during runtime.
-Mounting the cache directory as tmpfs_ is recommended apparoach.
+Mounting the cache directory as tmpfs_ is recommended approach.
Make sure to use appropriate ``size=`` option and don't forget to adjust the
size in the config file as well.
* even though it might have taken part in a successful DNSSEC proof:
* 1. any opt-out NSEC3, as they typically aren't much use aggressively anyway
* 2. some kinds of minimal NSEC* ranges, as they'd seem more trouble than worth:
- * - extremely short range of covered names limits the benefits severly
+ * - extremely short range of covered names limits the benefits severely
* - the type-set is often a lie, either a working lie, e.g. CloudFlare's
* black lies, or even a non-working lie, e.g. DVE-2018-0003
* 3. some kinds of "weird" RRsets, to get at least some caching on them
knot_db_val_t *val, int maxcount);
/** Remove maxcount keys.
- * \returns the number of succesfully removed keys or the first error code
+ * \returns the number of successfully removed keys or the first error code
* It returns on first error, but ENOENT is not considered an error. */
int (*remove)(kr_cdb_pt db, struct kr_cdb_stats *stat,
knot_db_val_t keys[], int maxcount);
* cleaned by another instance. */
ret = cdb_check_health(db, stats);
if (ret != 0) {
- if (ret == 1) // file changed and reopened successfuly
+ if (ret == 1) // file changed and reopened successfully
ret = kr_ok();
// else pass some other error
} else {
const knot_dname_t *owner/*log only*/,
const struct kr_query *qry, struct kr_cache *cache, uint32_t timestamp)
{
- //TODO: another review, perhaps incuding the API
+ //TODO: another review, perhaps including the API
if (kr_fails_assert(val_new_entry && val_new_entry->len > 0))
return kr_error(EINVAL);
/* Now we're in trouble. In some cases, parts of data to be written
* is an lmdb entry that may be invalidated by our write request.
* (lmdb does even in-place updates!) Therefore we copy all into a buffer.
- * LATER(optim.): do this only when neccessary, or perhaps another approach.
+ * LATER(optim.): do this only when necessary, or perhaps another approach.
* This is also complicated by the fact that the val_new_entry part
* is to be written *afterwards* by the caller.
*/
/* ^ TODO: performance? TODO: stype - call sites */
if (ta_covers) {
return KR_RANK_INSECURE | KR_RANK_AUTH;
- } /* else falltrhough */
+ } /* else fallthrough */
}
return KR_RANK_INITIAL | KR_RANK_AUTH;
}
if (kr_fails_assert(eh))
return kr_error(ENOENT);
// LATER: recovery in case of error, perhaps via removing the entry?
- // LATER(optim): pehaps optimize the zone cut search
+ // LATER(optim): perhaps optimize the zone cut search
int32_t new_ttl = get_new_ttl(eh, qry, qry->sname, qry->stype,
qry->timestamp.tv_sec);
/**
* According to set flags determine whether NSEC proving
- * RRset or RRType non-existense has been found.
+ * RRset or RRType non-existence has been found.
* @param f Flags to inspect.
* @return True if required NSEC exists.
*/
#define kr_nsec_rrset_noexist(f) \
((f) & (FLG_NOEXIST_RRTYPE | FLG_NOEXIST_RRSET))
/**
- * According to set flags determine whether wildcard non-existense
+ * According to set flags determine whether wildcard non-existence
* has been proven.
* @param f Flags to inspect.
* @return True if wildcard not exists.
* @param sec Packet section.
* @param Number of labels or (negative) error code.
*/
-static int coverign_rrsig_labels(const knot_rrset_t *nsec, const knot_pktsection_t *sec)
+static int covering_rrsig_labels(const knot_rrset_t *nsec, const knot_pktsection_t *sec)
{
if (kr_fails_assert(nsec && sec))
return kr_error(EINVAL);
if (kr_fails_assert(flags && nsec && sec))
return kr_error(EINVAL);
- int rrsig_labels = coverign_rrsig_labels(nsec, sec);
+ int rrsig_labels = covering_rrsig_labels(nsec, sec);
if (rrsig_labels < 0)
return rrsig_labels;
int nsec_labels = knot_dname_labels(nsec->owner, NULL);
if (!knot_dname_is_equal(rrset->owner, sname)) {
int wcard_labels = knot_dname_labels(rrset->owner, NULL);
int common_labels = knot_dname_matched_labels(rrset->owner, sname);
- int rrsig_labels = coverign_rrsig_labels(rrset, sec);
+ int rrsig_labels = covering_rrsig_labels(rrset, sec);
if (wcard_labels < 1 ||
common_labels != wcard_labels - 1 ||
common_labels != rrsig_labels) {
no_data_wildcard_existence_check(&flags, rrset, sec);
}
if (kr_nsec_existence_denied(flags)) {
- /* denial of existence proved accordignly to 4035 5.4 -
- * NSEC proving either rrset non-existance or
- * qtype non-existance has been found,
+ /* denial of existence proved accordingly to 4035 5.4 -
+ * NSEC proving either rrset non-existence or
+ * qtype non-existence has been found,
* and no wildcard expansion occurred.
*/
return kr_ok();
} else if (kr_nsec_rrset_noexist(flags)) {
- /* NSEC proving either rrset non-existance or
- * qtype non-existance has been found,
+ /* NSEC proving either rrset non-existence or
+ * qtype non-existence has been found,
* but wildcard expansion occurs.
* Try to find matching wildcard and check
* corresponding types.
if ((next_size > 0) && (owner_hash.size == next_size) && (name_hash.size == next_size)) {
/* All hash lengths must be same. */
- const uint8_t *ownrd = owner_hash.data;
+ const uint8_t *ownerd = owner_hash.data;
const uint8_t *nextd = next_hash;
int covered = 0;
- int greater_then_owner = (memcmp(ownrd, name_hash.data, next_size) < 0);
+ int greater_then_owner = (memcmp(ownerd, name_hash.data, next_size) < 0);
int less_then_next = (memcmp(name_hash.data, nextd, next_size) < 0);
- if (memcmp(ownrd, nextd, next_size) < 0) {
+ if (memcmp(ownerd, nextd, next_size) < 0) {
/*
* 0 (...) owner ... next (...) MAX
* ^
* Satisfies RFC5155 8.6 (QTYPE == DS), 2nd paragraph.
* Also satisfies ERRATA 3441 8.5 (QTYPE != DS), 3rd paragraph.
* - (wildcard) empty nonterminal
- * derived from unsecure delegation.
+ * derived from insecure delegation.
* Denial of existence can not be proven.
- * Set error code to proceed unsecure.
+ * Set error code to proceed insecure.
*/
ret = kr_error(KNOT_ERANGE);
}
return kr_error(EINVAL);
}
- /* DS/DNSEY types are accepted, for DNSKEY we
+ /* DS/DNSKEY types are accepted, for DNSKEY we
* need to compute a DS digest. */
if (type == KNOT_RRTYPE_DS) {
return insert_ta(trust_anchors, name, ttl, rdata, rdlen);
/** Inserts str into map. Returns 0 if new, 1 if replaced, or ENOMEM. */
int map_set(map_t *map, const char *str, void *val);
-/** Deletes str from the map, returns 0 on suceess */
+/** Deletes str from the map, returns 0 on success */
int map_del(map_t *map, const char *str);
/** Clears the given map */
* @brief A length-prefixed list of objects, also an array list.
*
* Each object is prefixed by item length, unlike array this structure
- * permits variable-length data. It is also equivallent to forward-only list
+ * permits variable-length data. It is also equivalent to forward-only list
* backed by an array.
*
* @note Maximum object size is 2^16 bytes, see ::pack_objlen_t
#define set_add(set, str) \
map_set((set), (str), (void *)1)
-/*! Deletes str from the set, returns 0 on suceess */
+/*! Deletes str from the set, returns 0 on success */
#define set_del(set, str) \
map_del((set), (str))
((query->stype == KNOT_RRTYPE_DS) ||
(query->stype == KNOT_RRTYPE_NS))) {
/* CNAME'ed answer for DS or NS subquery.
- * Treat it as proof of zonecut nonexistance. */
+ * Treat it as proof of zonecut nonexistence. */
return KR_STATE_DONE;
}
VERBOSE_MSG("<= cname chain, following\n");
next->forward_flags.CNAME = true;
}
next->cname_parent = query;
- /* Want DNSSEC if and only if it's posible to secure
+ /* Want DNSSEC if and only if it's possible to secure
* this name (i.e. iff it is covered by a TA) */
if (kr_ta_closest(req->ctx, cname, query->stype)) {
next->flags.DNSSEC_WANT = true;
} else {
/* otherwise it's some nonsense, so we skip it */
kr_log_q(qry, VALIDATOR, "protocol violation: "
- "out-of-bailwick RRSIG signer, skipping\n");
+ "out-of-bailiwick RRSIG signer, skipping\n");
}
}
return NULL;
VERBOSE_MSG(qry, "<= cached insecure response, going insecure\n");
ctx->state = KR_STATE_DONE;
} else if (ctx->state == KR_STATE_YIELD) {
- /* Transition to unsecure state
+ /* Transition to insecure state
occurred during revalidation.
if state remains YIELD, answer will not be cached.
Let cache layers to work. */
return KR_STATE_DONE;
} else if (ret != 0) {
/* something exceptional - no DNS key, empty pointers etc
- * normally it shoudn't happen */
+ * normally it shouldn't happen */
VERBOSE_MSG(qry, "<= couldn't validate RRSIGs\n");
qry->flags.DNSSEC_BOGUS = true;
return KR_STATE_FAIL;
/* Could not return from here,
* we must continue, validate NSEC\NSEC3 and
* call update_parent_keys() to mark
- * parent queries as insecured */
+ * parent queries as insecure */
} else {
VERBOSE_MSG(qry, "<= bad NODATA proof\n");
qry->flags.DNSSEC_BOGUS = true;
referral &&
((!qry->flags.DNSSEC_WANT && qry->flags.DNSSEC_INSECURE) ||
(qry->flags.DNSSEC_NODS))) {
- /* referral with proven DS non-existance */
+ /* referral with proven DS non-existence */
qtype = KNOT_RRTYPE_DS;
}
/* Update parent query zone cut */
#define LOG_GRP_TAUPDATE_TAG "taupd" /**< ``taupd``: TA update */
#define LOG_GRP_TLS_TAG "tls" /**< ``tls``: TLS encryption layer */
#define LOG_GRP_GNUTLS_TAG "gnutls" /**< ``gnutls``: low-level logs from GnuTLS */
-#define LOG_GRP_TLSCLIENT_TAG "tls_cl" /**< ``tls_cl``: TLS client messagess (used for TLS forwarding) */
+#define LOG_GRP_TLSCLIENT_TAG "tls_cl" /**< ``tls_cl``: TLS client messages (used for TLS forwarding) */
#define LOG_GRP_XDP_TAG "xdp" /**< ``xdp``: operations related to XDP */
#define LOG_GRP_ZIMPORT_TAG "zimprt" /**< ``zimprt``: operations related to zimport */
#define LOG_GRP_ZSCANNER_TAG "zscann" /**< ``zscann``: operations related to zscanner */
* Typically you use this as condition to compute some data to be logged,
* in case that's considered too expensive to do unless it really gets logged.
*
- * The request can be NULL, and there's a _qry() shortand to specify query instead.
+ * The request can be NULL, and there's a _qry() shorthand to specify query instead.
*/
#define kr_log_is_debug(grp, req) \
__builtin_expect(kr_log_is_debug_fun(LOG_GRP_ ## grp, (req)), false)
struct kr_request *req, knot_pkt_t *pkt)
{
/* It can occur that here parent query already have
- * provably insecured zonecut which not in the cache yet. */
+ * provably insecure zonecut which not in the cache yet. */
struct kr_qflags pflags;
if (qry->parent) {
pflags = qry->parent->flags;
}
- const bool is_insecured = qry->parent != NULL
+ const bool is_insecure = qry->parent != NULL
&& !(pflags.AWAIT_IPV4 || pflags.AWAIT_IPV6)
&& (pflags.DNSSEC_INSECURE || pflags.DNSSEC_NODS);
/* Want DNSSEC if it's possible to secure this name
* (e.g. is covered by any TA) */
- if (is_insecured) {
- /* If parent is unsecured we don't want DNSSEC
+ if (is_insecure) {
+ /* If parent is insecure we don't want DNSSEC
* even if cut name is covered by TA. */
qry->flags.DNSSEC_WANT = false;
qry->flags.DNSSEC_INSECURE = true;
struct kr_zonecut cut_found;
kr_zonecut_init(&cut_found, requested_name, req->rplan.pool);
/* Cut that has been found can differs from cut that has been requested.
- * So if not already insecured,
+ * So if not already insecure,
* try to fetch ta & keys even if initial cut name not covered by TA */
- bool secured = !is_insecured;
+ bool secure = !is_insecure;
int ret = kr_zonecut_find_cached(req->ctx, &cut_found, requested_name,
- qry, &secured);
+ qry, &secure);
if (ret == kr_error(ENOENT)) {
/* No cached cut found, start from SBELT
* and issue priming query. */
/* Find out security status.
* Go insecure if the zone cut is provably insecure */
- if ((qry->flags.DNSSEC_WANT) && !secured) {
+ if ((qry->flags.DNSSEC_WANT) && !secure) {
VERBOSE_MSG(qry, "=> NS is provably without DS, going insecure\n");
qry->flags.DNSSEC_WANT = false;
qry->flags.DNSSEC_INSECURE = true;
if (qname != NULL) {
/* Deferred zone cut lookup for this query. */
qry->flags.AWAIT_CUT = true;
- /* Want DNSSEC if it's posible to secure this name (e.g. is covered by any TA) */
+ /* Want DNSSEC if it's possible to secure this name (e.g. is covered by any TA) */
if ((knot_wire_get_ad(packet->wire) || knot_pkt_has_dnssec(packet)) &&
kr_ta_closest(request->ctx, qry->sname, qtype)) {
qry->flags.DNSSEC_WANT = true;
}
/* Enable DNSSEC if enters a new island of trust. */
- bool want_secured = (qry->flags.DNSSEC_WANT) &&
+ bool want_secure = (qry->flags.DNSSEC_WANT) &&
!knot_wire_get_cd(request->qsource.packet->wire);
if (!(qry->flags.DNSSEC_WANT) &&
!knot_wire_get_cd(request->qsource.packet->wire) &&
kr_ta_get(trust_anchors, wanted_name)) {
qry->flags.DNSSEC_WANT = true;
- want_secured = true;
+ want_secure = true;
if (kr_log_is_debug_qry(RESOLVER, qry)) {
KR_DNAME_GET_STR(qname_str, wanted_name);
VERBOSE_MSG(qry, ">< TA: '%s'\n", qname_str);
}
}
- if (want_secured && !qry->zone_cut.trust_anchor) {
+ if (want_secure && !qry->zone_cut.trust_anchor) {
knot_rrset_t *ta_rr = kr_ta_get(trust_anchors, wanted_name);
if (!ta_rr) {
char name[] = "\0";
has_ta = (qry->zone_cut.trust_anchor != NULL);
ta_name = (has_ta ? qry->zone_cut.trust_anchor->owner : NULL);
refetch_ta = (!has_ta || !knot_dname_is_equal(wanted_name, ta_name));
- if (!nods && want_secured && refetch_ta) {
+ if (!nods && want_secure && refetch_ta) {
struct kr_query *next = zone_cut_subreq(rplan, qry, wanted_name,
KNOT_RRTYPE_DS);
if (!next) {
* Do not fetch if this is a DNSKEY subrequest to avoid circular dependency. */
is_dnskey_subreq = kr_rplan_satisfies(qry, ta_name, KNOT_CLASS_IN, KNOT_RRTYPE_DNSKEY);
refetch_key = has_ta && (!qry->zone_cut.key || !knot_dname_is_equal(ta_name, qry->zone_cut.key->owner));
- if (want_secured && refetch_key && !is_dnskey_subreq) {
+ if (want_secure && refetch_key && !is_dnskey_subreq) {
struct kr_query *next = zone_cut_subreq(rplan, qry, ta_name, KNOT_RRTYPE_DNSKEY);
if (!next) {
return KR_STATE_FAIL;
}
if (qry->flags.DNSSEC_NODS) {
/* This is the next query iteration with minimized qname.
- * At previous iteration DS non-existance has been proven */
+ * At previous iteration DS non-existence has been proven */
VERBOSE_MSG(qry, "<= DS doesn't exist, going insecure\n");
qry->flags.DNSSEC_NODS = false;
qry->flags.DNSSEC_WANT = false;
const bool has_ta = (qry->zone_cut.trust_anchor != NULL);
const knot_dname_t *ta_name = (has_ta ? qry->zone_cut.trust_anchor->owner : NULL);
const bool refetch_ta = !has_ta || !knot_dname_is_equal(qry->zone_cut.name, ta_name);
- const bool want_secured = qry->flags.DNSSEC_WANT && !has_cd;
- if (want_secured && refetch_ta) {
+ const bool want_secure = qry->flags.DNSSEC_WANT && !has_cd;
+ if (want_secure && refetch_ta) {
/* @todo we could fetch the information from the parent cut, but we don't remember that now */
struct kr_query *next = kr_rplan_push(rplan, qry, qry->zone_cut.name, qry->sclass, KNOT_RRTYPE_DS);
if (!next) {
* Do not fetch if this is a DNSKEY subrequest to avoid circular dependency. */
const bool is_dnskey_subreq = kr_rplan_satisfies(qry, ta_name, KNOT_CLASS_IN, KNOT_RRTYPE_DNSKEY);
const bool refetch_key = has_ta && (!qry->zone_cut.key || !knot_dname_is_equal(ta_name, qry->zone_cut.key->owner));
- if (want_secured && refetch_key && !is_dnskey_subreq) {
+ if (want_secure && refetch_key && !is_dnskey_subreq) {
struct kr_query *next = zone_cut_subreq(rplan, qry, ta_name, KNOT_RRTYPE_DNSKEY);
if (!next) {
return KR_STATE_FAIL;
}
} else {
/* Caller is interested in always tracking a zone cut, even if the answer is cached
- * this is normally not required, and incurrs another cache lookups for cached answer. */
+ * this is normally not required, and incurs another cache lookups for cached answer. */
if (qry->flags.ALWAYS_CUT) {
if (!(qry->flags.STUB)) {
switch(zone_cut_check(request, qry, packet)) {
bool REORDER_RR : 1; /**< Reorder cached RRs. */
bool TRACE : 1; /**< Also log answers on debug level. */
bool NO_0X20 : 1; /**< Disable query case randomization . */
- bool DNSSEC_NODS : 1; /**< DS non-existance is proven */
+ bool DNSSEC_NODS : 1; /**< DS non-existence is proven */
bool DNSSEC_OPTOUT : 1; /**< Closest encloser proof has optout */
bool NONAUTH : 1; /**< Non-authoritative in-bailiwick records are enough.
* TODO: utilize this also outside cache. */
int kr_rplan_init(struct kr_rplan *rplan, struct kr_request *request, knot_mm_t *pool);
/**
- * Deinitialize resolution plan, aborting any uncommited transactions.
+ * Deinitialize resolution plan, aborting any uncommitted transactions.
* @param rplan plan instance
*/
KR_EXPORT
return no6_est.len_used == NO6_PREFIX_COUNT;
}
-static void no6_timeouted(const struct kr_query *qry, const uint8_t *addr)
+static void no6_timed_out(const struct kr_query *qry, const uint8_t *addr)
{
if (no6_is_bad()) { // we can't get worse
- VERBOSE_MSG(qry, "NO6: timeouted, but bad already\n");
+ VERBOSE_MSG(qry, "NO6: timed out, but bad already\n");
return;
}
// If we have the address already, do nothing.
for (int i = 0; i < no6_est.len_used; ++i) {
if (memcmp(addr, no6_est.addr_prefixes[i], NO6_PREFIX_BYTES) == 0) {
- VERBOSE_MSG(qry, "NO6: timeouted, repeated prefix, timeouts %d/%d\n",
+ VERBOSE_MSG(qry, "NO6: timed out, repeated prefix, timeouts %d/%d\n",
no6_est.len_used, (int)NO6_PREFIX_COUNT);
return;
}
}
// Append!
memcpy(no6_est.addr_prefixes[no6_est.len_used++], addr, NO6_PREFIX_BYTES);
- VERBOSE_MSG(qry, "NO6: timeouted, appended, timeouts %d/%d\n",
+ VERBOSE_MSG(qry, "NO6: timed out, appended, timeouts %d/%d\n",
no6_est.len_used, (int)NO6_PREFIX_COUNT);
}
/**
* @internal Check if IP address is TLS capable.
*
- * @p req has to have the selection_context properly initiazed.
+ * @p req has to have the selection_context properly initialized.
*/
static void check_tls_capable(struct address_state *address_state,
struct kr_request *req, struct sockaddr *address)
/**
* Check if there is a existing TCP connection to this address.
*
- * @p req has to have the selection_context properly initiazed.
+ * @p req has to have the selection_context properly initialized.
*/
void check_tcp_connections(struct address_state *address_state, struct kr_request *req, struct sockaddr *address) {
address_state->tcp_connected = req->selection_context.is_tcp_connected ? req->selection_context.is_tcp_connected(address) : false;
uint8_t *address = ip_to_bytes(&transport->address, transport->address_len);
if (transport->address_len == sizeof(struct in6_addr))
- no6_timeouted(qry, address);
+ no6_timed_out(qry, address);
struct rtt_state old_state = addr_state->rtt_state;
struct rtt_state cur_state =
case KR_SELECTION_LAME_DELEGATION:
if (qry->flags.NO_MINIMIZE) {
/* Lame delegations are weird, they breed more lame delegations on broken
- * zones since trying another server from the same set usualy doesn't help.
+ * zones since trying another server from the same set usually doesn't help.
* We force resolution of another NS name in hope of getting somewhere. */
qry->server_selection.local_state->force_resolve = true;
addr_state->broken = true;
};
struct local_state {
- int timeouts; /**< Number of timeouts that occured resolving this query.*/
+ int timeouts; /**< Number of timeouts that occurred resolving this query.*/
bool truncated; /**< Query was truncated, switch to TCP. */
/** Force resolution of a new NS name (if possible)
* Done by selection.c:error in some cases. */
/** Report back the RTT of network operation for transport in ms. */
void (*update_rtt)(struct kr_query *qry,
const struct kr_transport *transport, unsigned rtt);
- /** Report back error encourtered with the chosen transport. See `enum kr_selection` */
+ /** Report back error encountered with the chosen transport. See `enum kr_selection` */
void (*error)(struct kr_query *qry,
const struct kr_transport *transport,
enum kr_selection_error error);
*
* @param choices Options to choose from, see struct above
* @param unresolved Array of names that can be resolved (i.e. no A/AAAA record)
- * @param timeouts Number of timeouts that occured in this query (used for exponential backoff)
+ * @param timeouts Number of timeouts that occurred in this query (used for exponential backoff)
* @param mempool Memory context of current request
* @param tcp Force TCP as transport protocol
* @param[out] choice_index Optionally index of the chosen transport in the @p choices array.
kr_zonecut_deinit(NULL);
kr_zonecut_set(NULL, NULL);
kr_zonecut_set(&cut, NULL);
- /* TODO triggerring inner assertion:
+ /* TODO triggering inner assertion:
assert_int_not_equal(kr_zonecut_add(NULL, NULL, NULL, 0), 0);
*/
assert_null((void *)kr_zonecut_find(NULL, NULL));
static char *print_section_opt(struct mempool *mp, char *endp, const knot_rrset_t *rr, const uint8_t rcode)
{
- uint8_t ercode = knot_edns_get_ext_rcode(rr);
- uint16_t ext_rcode_id = knot_edns_whole_rcode(ercode, rcode);
+ uint8_t errcode = knot_edns_get_ext_rcode(rr);
+ uint16_t ext_rcode_id = knot_edns_whole_rcode(errcode, rcode);
const char *ext_rcode_str = "Unused";
const knot_lookup_t *ext_rcode;
- if (ercode > 0) {
+ if (errcode > 0) {
ext_rcode = knot_lookup_by_id(knot_rcode_names, ext_rcode_id);
if (ext_rcode != NULL) {
ext_rcode_str = ext_rcode->name;
/** Whether kr_assert() and kr_fails_assert() checks should abort. */
KR_EXPORT extern bool kr_dbg_assertion_abort;
-/** How often kr_asert() should fork the process before issuing abort (if configured).
+/** How often kr_assert() should fork the process before issuing abort (if configured).
*
* This can be useful for debugging rare edge-cases in production.
* if (kr_debug_assertion_abort && kr_debug_assertion_fork), it is
knot_rrtype_to_string((rrtype), rrtype_str, sizeof(rrtype_str)); \
rrtype_str[sizeof(rrtype_str) - 1] = 0;
-// Use this for alocations with mm.
-// Use mm_alloc for alocations into mempool
+// Use this for allocations with mm.
+// Use mm_alloc for allocations into mempool
/** A strcmp() variant directly usable for qsort() on an array of strings. */
static inline int strcmp_p(const void *p1, const void *p2)
static inline char *kr_straddr(const struct sockaddr *addr)
{
if (kr_fails_assert(addr)) return NULL;
- /* We are the sinle-threaded application */
+ /* We are the single-threaded application */
static char str[INET6_ADDRSTRLEN + 1 + 5 + 1];
size_t len = sizeof(str);
int ret = kr_inaddr_str(addr, str, &len);
/**
* @brief Check whether node holds proper 'enabled' value.
- * @patam node JSON node holding the value
+ * @param node JSON node holding the value
* @return true if value OK
*/
static bool enabled_ok(const JsonNode *node)
/**
* @brief Check whether node holds proper 'secret' value.
- * @patam node JSON node holding the value
+ * @param node JSON node holding the value
* @return true if value OK
*/
static bool secret_ok(const JsonNode *node)
/**
* @brief Creates new secret.
- * @patam node JSON node holding the secret value
+ * @param node JSON node holding the secret value
* @return pointer to newly allocated secret, NULL on error
*/
static struct kr_cookie_secret *create_secret(const JsonNode *node)
inception = ffi.C.kr_rrsig_sig_inception(rdata)
expiration = ffi.C.kr_rrsig_sig_expiration(rdata)
if now > expiration then
- -- possitive value = in the future
+ -- positive value = in the future
time_diff = now - expiration
elseif now < inception then
-- negative value = in the past
end
end
--- Do uncached priming query and check time validty of RRSIGs.
+-- Do uncached priming query and check time validity of RRSIGs.
local function check_time()
resolve(".", kres.type.NS, kres.class.IN, {"DNSSEC_WANT", "DNSSEC_CD", "NO_CACHE"},
check_time_callback)
The ``dnstap`` module supports logging DNS requests and responses to a unix
socket in `dnstap format <https://dnstap.info>`_ using fstrm framing library.
-This logging is useful if you need effectivelly log all DNS traffic.
+This logging is useful if you need effectively log all DNS traffic.
The unix socket and the socket reader must be present before starting resolver instances.
.. code-block:: bash
- $ etcdctl set /knot-resolvevr/net/127.0.0.1 53
+ $ etcdctl set /knot-resolver/net/127.0.0.1 53
$ etcdctl set /knot-resolver/cache/size 10000000
Configures all listening nodes to following configuration:
If you use package ``luaossl < 20181207``, intermediate certificate is not sent to clients,
which may cause problems with validating the connection in some cases.
-You can disable unecrypted HTTP and enforce HTTPS by passing
+You can disable unencrypted HTTP and enforce HTTPS by passing
``tls = true`` option for all HTTP endpoints:
.. code-block:: lua
local ok, err, reason = http_util.yieldable_pcall(serve, endpoints, h, stream)
if not ok or err then
err = err or '500'
- log_info(ffi.C.LOG_GRP_HTTP, '%s %s HTTTP/%s %s %s',
+ log_info(ffi.C.LOG_GRP_HTTP, '%s %s HTTP/%s %s %s',
m, path, tostring(connection.version), err, reason or '')
-- Method is not supported
local hsend = http_headers.new()
-- modification cannot be implemented as
-- remove_socket + add_socket because remove closes the socket
if instance.kind == kind or kind == '_all' then
- panic('unable to modify configration for '
+ panic('unable to modify configuration for '
.. 'endpoint kind "%s" because it is in '
.. 'use, use net.close() first', kind)
end
local req = assert(req_templ:clone())
req.headers:upsert(':method', 'GET')
req.headers:upsert(':path', '/doh?notdns=' .. basexx.to_url64(string.rep('\0', 1024)))
- check_err(req, '400', 'GET without dns paramter finishes with 400')
+ check_err(req, '400', 'GET without dns parameter finishes with 400')
end
local function test_get_unparseable()
-- Each server needs to have its ctx updated.
for _, s in pairs(ephem_state.servers) do
s.server.ctx = ephem_state.ctx
- s.config.ctx = ephem_state.ctx -- not required, but let's keep it synchonized
+ s.config.ctx = ephem_state.ctx -- not required, but let's keep it synchronized
end
log_info(ffi.C.LOG_GRP_HTTP, 'created new ephemeral TLS certificate')
local _, expiry_stamp = certs[1]:getLifetime()
-- SPDX-License-Identifier: GPL-3.0-or-later
--- disable networking so we can get SERVFAIL immediatelly
+-- disable networking so we can get SERVFAIL immediately
net.ipv4 = false
net.ipv6 = false
This module is enabled by default because it implements mandatory :rfc:`6761` logic.
When no rule applies to a query, built-in rules for `special-use <https://www.iana.org/assignments/special-use-domain-names/special-use-domain-names.xhtml>`_ and `locally-served <http://www.iana.org/assignments/locally-served-dns-zones>`_ domain names are applied.
-These rules can be overriden by action :any:`policy.PASS`. For debugging purposes you can also add ``modules.unload('policy')`` to your config to unload the module.
+These rules can be overridden by action :any:`policy.PASS`. For debugging purposes you can also add ``modules.unload('policy')`` to your config to unload the module.
Filters
Let the query pass through; it's useful to make exceptions before wider rules. For example:
- More specific whitelist rule must preceede generic blacklist rule:
+ More specific whitelist rule must precede generic blacklist rule:
.. code-block:: lua
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
With the use of :func:`policy.slice` function, it is possible to split the
-entire DNS namespace into distinct slices. When used in conjuction with
+entire DNS namespace into distinct slices. When used in conjunction with
:func:`policy.TLS_FORWARD`, it's possible to forward different queries to
different targets.
It utilizes the `Public Suffix List`_ to ensure domains under the same
registrable domain end up in a single slice. (see example below)
- ``seed`` can be used to re-shuffle the slicing algorhitm when the slicing
- function is initialized. By default, the assigment is re-shuffled after one
+ ``seed`` can be used to re-shuffle the slicing algorithm when the slicing
+ function is initialized. By default, the assignment is re-shuffled after one
week (when resolver restart / reloads config). To force a stable
distribution, pass a fixed value. To re-shuffle on every resolver restart,
use ``os.time()``.
caused by grafting. For example, if you grafted your own top-level domain
``example.`` onto the public DNS namespace, at some point the root server might
send proof-of-nonexistence proving e.g. that there are no other top-level
-domain in between names ``events.`` and ``exchange.``, effectivelly proving
+domain in between names ``events.`` and ``exchange.``, effectively proving
non-existence of ``example.``.
These proofs-of-nonexistence protect public DNS from spoofing but break
*grafted* domains because proofs will be latter used by resolver
(when the positive records for the grafted domain timeout from cache),
-effectivelly making grafted domain unavailable.
+effectively making grafted domain unavailable.
The easiest work-around is to disable reading from cache for grafted domains.
.. code-block:: lua
.. code-block:: lua
- -- mirror all queriesm, keep handle so we can retrieve information later
+ -- mirror all queries, keep handle so we can retrieve information later
local rule = policy.add(policy.all(policy.MIRROR('127.0.0.2')))
-- we can print statistics about this rule any time later
print(string.format('id: %d, matched queries: %d', rule.id, rule.count)
else
answer:begin(kres.section.ANSWER)
if type(data.rdata) == 'table' then
- for _, rdato in ipairs(data.rdata) do
- answer:put(qry.sname, ttl, qry.sclass, qry.stype, rdato)
+ for _, entry in ipairs(data.rdata) do
+ answer:put(qry.sname, ttl, qry.sclass, qry.stype, entry)
end
else
answer:put(qry.sname, ttl, qry.sclass, qry.stype, data.rdata)
local act = new_actions[name][parser.r_type]
if act == nil then
new_actions[name][parser.r_type] = { ttl=parser.r_ttl, rdata=rdata }
- else -- mutiple RRs: no reordering or deduplication
+ else -- multiple RRs: no reordering or deduplication
if type(act.rdata) ~= 'table' then
act.rdata = { act.rdata }
end
end
-- load psl
local has_latest, psl = pcall(psl_lib.latest)
- if not has_latest then -- compatiblity with lua-psl < 0.15
+ if not has_latest then -- compatibility with lua-psl < 0.15
psl = psl_lib.builtin()
end
rand_seed = rand_seed + reg_domain:byte(i)
end
- -- use lineral congruential generator with values from ANSI C
+ -- use linear congruential generator with values from ANSI C
rand_seed = rand_seed % 0x80000000 -- ensure seed is positive 32b int
local rand = (1103515245 * rand_seed + 12345) % 0x10000
return 1 + rand % length
local rz_https_fail_interval = 600
local rz_import_error_interval = 600
local rz_cur_interval = rz_default_interval
-local rz_interval_randomizator_limit = 10
+local rz_interval_randomizer_limit = 10
local rz_interval_threshold = 5
local rz_interval_min = 3600
local prefill = {}
--- hack for circular depedency between timer() and fill_cache()
+-- hack for circular dependency between timer() and fill_cache()
local forward_references = {}
local function stop_timer()
local ok, errmsg = pcall(download, rz_url, rz_local_fname)
if not ok then
rz_cur_interval = rz_https_fail_interval
- - math.random(rz_interval_randomizator_limit)
+ - math.random(rz_interval_randomizer_limit)
log_info(ffi.C.LOG_GRP_PREFILL, "cannot download new zone (%s), "
.. "will retry root zone download in %s",
errmsg, display_delay(rz_cur_interval))
rz_cur_interval = 1
else
rz_cur_interval = rz_import_error_interval
- - math.random(rz_interval_randomizator_limit)
+ - math.random(rz_interval_randomizer_limit)
end
log_info(ffi.C.LOG_GRP_PREFILL, "root zone import failed (%s), retry in %s",
errmsg, display_delay(rz_cur_interval))
else
-- re-download before TTL expires
rz_cur_interval = (file_ttl - rz_interval_threshold
- - math.random(rz_interval_randomizator_limit))
+ - math.random(rz_interval_randomizer_limit))
log_info(ffi.C.LOG_GRP_PREFILL, "root zone refresh in %s",
display_delay(rz_cur_interval))
end
====================
This module provides protection from `DNS Rebinding attack`_ by blocking
-answers which cointain IPv4_ or IPv6_ addresses for private use
+answers which contain IPv4_ or IPv6_ addresses for private use
(or some other special-use addresses).
To enable this module insert following line into your configuration file:
Outputs a list of recent upstreams and their RTT. It is sorted by time and stored in a ring buffer of
a fixed size. This means it's not aggregated and readable by multiple consumers, but also that
-you may lose entries if you don't read quickly enough. The default ring size is 512 entries, and may be overriden on compile time by ``-DUPSTREAMS_COUNT=X``.
+you may lose entries if you don't read quickly enough. The default ring size is 512 entries, and may be overridden on compile time by ``-DUPSTREAMS_COUNT=X``.
.. function:: stats.frequent()
local keyset = trust_anchors.keysets[domain]
local qname = prepare_query_name(keyset, domain)
if qname ~= nil then
- log_info(ffi.C.LOG_GRP_TASIGNALING, "signalling query trigered: %s", qname)
+ log_info(ffi.C.LOG_GRP_TASIGNALING, "signalling query triggered: %s", qname)
-- asynchronous query
-- we do not care about result or from where it was obtained
event.after(0, function ()
local function update(keyset, new_keys)
if not new_keys then return false end
if not keyset.managed then
- -- this may happen due to race condition during testing in CI (refesh time < query time)
+ -- this may happen due to race condition during testing in CI (refresh time < query time)
return false
end
}
-- start tracking (already loaded) TA with given zone name in wire format
--- do first refresh immediatelly
+-- do first refresh immediately
function ta_update.start(zname, managed)
local keyset = trust_anchors.keysets[zname]
if not keyset then
#!/usr/bin/python3
"""
-Generate RFC 5011 test simulating succesfull KSK roll-over in 2017.
+Generate RFC 5011 test simulating successful KSK roll-over in 2017.
-Depedencies: Knot DNS server + Deckard library.
+Dependencies: Knot DNS server + Deckard library.
Environment: Set PYTHONPATH variable so "import pydnstest" will use module from Deckard.
Input: Root zone files, presumably created by genkeyszones.sh.
Output: RPL file for Deckard on standard output.
query-minimization: off
CONFIG_END
-SCENARIO_BEGIN Simulation of successfull RFC 5011 KSK roll-over during 2017
+SCENARIO_BEGIN Simulation of successful RFC 5011 KSK roll-over during 2017
""".format(ta=ta))
for rng in ranges:
print(rng)
else
log_info(ffi.C.LOG_GRP_WATCHDOG, 'answer was dropped')
end
- -- failure! quit immediatelly to allow process supervisor to restart us
+ -- failure! quit immediately to allow process supervisor to restart us
private.fail_callback()
end
end
# determine GCOV_PREFIX_STRIP value for current source directory
TOPSRCDIR_SLASHES="${TOPSRCDIR//[^\/]/}" # remove everything except /
-GCOV_PREFIX_STRIP="${#TOPSRCDIR_SLASHES}" # numer of / == number of components
+GCOV_PREFIX_STRIP="${#TOPSRCDIR_SLASHES}" # number of / == number of components
KRESD_COVERAGE_STATS="${OUTPATH}/luacov.stats.out"
GCOV_PREFIX="${OUTPATH}"
#!/bin/bash
# SPDX-License-Identifier: GPL-3.0-or-later
-# Create a develpoment tarball
+# Create a development tarball
set -o errexit -o nounset -o xtrace
cd "$(dirname ${0})/.."
# make sure we don't accidentally add / overwrite forgotten changes in git
(git diff-index --quiet HEAD && git diff-index --cached --quiet HEAD) || \
- (echo 'git index has uncommited changes!'; exit 1)
+ (echo 'git index has uncommitted changes!'; exit 1)
if ! git describe --tags --exact-match; then
# devel version
# modify and commit meson.build
sed -i "s/^\(\s*version\s*:\s*'\)\([^']\+\)\('.*\)/\1\2.$TIMESTAMP.$GIT_HASH\3/" meson.build
- : changed version in meson.build, changes must be commited to git
+ : changed version in meson.build, changes must be committed to git
git add meson.build
git commit -m 'DROP: devel version archive'
set -o errexit -o nounset
# following checkers are disabled on purpose:
-# Clann does not suppor attribute cleanup and this is causing false positives in following checkers:
+# Clang does not support attribute cleanup and this is causing false positives in following checkers:
# unix.Malloc
# alpha.unix.SimpleStream
# alpha.unix.Stream
Knot Resolver can utilize multiple CPUs running in multiple independent instances (processes), where each process utilizes at most single CPU core on your machine. If your machine handles a lot of DNS traffic run multiple instances.
-All instances typically share the same configuration and cache, and incomming queries are automatically distributed by operating system among all instances.
+All instances typically share the same configuration and cache, and incoming queries are automatically distributed by operating system among all instances.
Advantage of using multiple instances is that a problem in a single instance will not affect others, so a single instance crash will not bring whole DNS resolver service down.
Zero-downtime restarts
----------------------
-Resolver restart normally takes just miliseconds and cache content is persistent to avoid performance drop
+Resolver restart normally takes just milliseconds and cache content is persistent to avoid performance drop
after restart. If you want real zero-downtime restarts use `multiple instances`_ and do rolling
restart, i.e. restart only one resolver process at a time.
same(kres.section.ANSWER, 0, 'section constants work')
same(kres.rcode.SERVFAIL, 2, 'rcode constants work')
same(kres.opcode.UPDATE, 5, 'opcode constants work')
- -- Test inverset tables to convert constants to text
+ -- Test inverse tables to convert constants to text
same(kres.tostring.class[1], 'IN', 'text class constants work')
same(kres.tostring.type[2], 'NS', 'text record type constants work')
same(kres.tostring.type[65535], 'TYPE65535', 'text record type undefined constants work')
-- local req = assert(req_templ:clone())
-- req.headers:upsert(':method', 'GET')
-- req.headers:upsert(':path', '/doh?notdns=' .. basexx.to_url64(string.rep('\0', 1024)))
--- check_err(req, '400', 'GET without dns paramter finishes with 400')
+-- check_err(req, '400', 'GET without dns parameter finishes with 400')
-- end
--
-- local function test_get_unparseable()
# python3 dependencies
py3_deps += [
['augeas', 'augeas (for deckard)'],
- ['dns', 'dnspuyhon (for deckard)'],
+ ['dns', 'dnspython (for deckard)'],
['jinja2', 'jinja2 (for deckard)'],
['pytest', 'pytest (for deckard)'],
['xdist', 'pytest-xdist (for deckard)'],
* <distro>
* <version>
- * builddeps - list of build depedencies
- * rundeps - list of runtime depedencies
+ * builddeps - list of build dependencies
+ * rundeps - list of runtime dependencies
* pre-build.sh - script called before build phase
* post-build.sh - script called after build phase
* pre-run.sh - script called before run phase
* post-run.sh - script called after run phase
- * install.sh and build.sh - scripts to rewrite standard commands for building and instaling knot-resolvers
+ * install.sh and build.sh - scripts to rewrite standard commands for building and installing knot-resolvers
* pre-test.sh - script called immediately before testing
* test.config or test.sh - kresd config test or shell script (one of them must exists)
For *build docker image*:
#. run pre-build.sh
-#. install packages specifed in the file *builddeps*
+#. install packages specified in the file *builddeps*
#. run build.sh
#. run install.sh
#. run post-build.sh
For *run docker image*:
#. run pre-run.sh
-#. install packages specifed in the file *rundeps*
+#. install packages specified in the file *rundeps*
#. run pre-test.sh
#. run test (:code:`kresd -c test.config` or :code:`test.sh`)
#. run post-build.sh
each other.
Some tests are omitted from automatic test collection by default, due to their
-resource contraints. These typicially have to be executed separately by providing
+resource constraints. These typically have to be executed separately by providing
the path to test file directly.
.. code-block:: bash
MAX_SOCKETS = 10000 # upper bound of how many connections to open
MAX_ITERATIONS = 10 # number of iterations to run the test
-# we can't use softlimit ifself since kresd already has open sockets,
+# we can't use softlimit itself since kresd already has open sockets,
# so use lesser value
RESERVED_NOFILE = 40 # 40 is empirical value
while time.time() < end_time:
i += 1
- # use exponential backoff algorhitm to choose next delay
+ # use exponential backoff algorithm to choose next delay
rand_delay = random.randrange(0, i)
time.sleep(rand_delay * delay_step)
return self._tls_socket_with_retry(socket.AF_INET6)
def partial_log(self):
- partial_log = '\n (... ommiting log start)\n'
+ partial_log = '\n (... omitting log start)\n'
with open(self.logfile_path, encoding='UTF-8') as log: # display partial log for debugging
past_startup_msgid = False
past_startup = False
check(socket.AF_INET6, socket.SOCK_STREAM, (ip6, port, 0, 0))
check(socket.AF_INET6, socket.SOCK_DGRAM, (ip6, port, 0, 0))
except OSError as exc:
- if exc.errno == 98: # address alrady in use
+ if exc.errno == 98: # address already in use
return False
else:
raise
{
assert(saddr_storage != NULL);
const struct sockaddr *addr = (const struct sockaddr *)saddr_storage;
- /* We are the sinle-threaded application */
+ /* We are the single-threaded application */
static char str[INET6_ADDRSTRLEN + 6];
size_t len = sizeof(str);
int ret = ip_addr_str(addr, str, &len);
# at the first kresd instance
# NOTE TLS 1.3 is intentionally disabled for session resumption tests,
- # becuase python's SSLSocket.session isn't compatible with TLS 1.3
+ # because python's SSLSocket.session isn't compatible with TLS 1.3
# https://docs.python.org/3/library/ssl.html?highlight=ssl%20ticket#tls-1-3
def connect(kresd, ctx, sf, session=None):
outfile = io.open(out, 'w')
if outfile == nil then
- -- this is technicaly an error, but upgrade script shouldn't fail in scriptlets
+ -- this is technically an error, but upgrade script shouldn't fail in scriptlets
os.exit(0) -- make no changes and exit
end