Štěpán Balážik [Wed, 19 Aug 2020 08:52:17 +0000 (10:52 +0200)]
daemon/worker: start retransmit timer after UDP packet is sent
Previously this was done *before* calling uv_udp_send which lead to many
early retransmits (significant amount of time might pass between calling
uv_udp_send and the moment the packet is actually send to the wire).
Vladimír Čunát [Sat, 22 Aug 2020 09:47:51 +0000 (11:47 +0200)]
lib/cache kr_cdb_api::space_usage(): also use kr_cdb_pt
- The malloc-free pair could be avoided without difficulty,
but it seemed like premature optimization.
- The libknot functions make error handling a bit difficult
(zero is theoretically valid and doesn't show error type),
but writing this properly without libknot would need 10-20
additional lines of code and the risk of encountering errors
in this function seems very low anyway.
Petr Špaček [Mon, 7 Sep 2020 14:08:05 +0000 (16:08 +0200)]
cache: fix race in assert_right_version
This change fixes race condition in assert_right_version(). Racy
situation:
- Two instances have the (empty) cache open: New binary and old binary.
- New binary executes count() inside assert_right_version(), which
internally starts RO transaction. Returned count is 0.
- Old binary does some writes (RW transaction parallel to RO in the first
process).
- New binary skips cache clear because cache was empty at the time of check.
- Result: The old binary wrote data with an old format into cache which
was not cleared and silenty changed version number to a new one.
This is not complete fix because we lack mechanism to detect cache format
change at run-time, but at least it removes one nasty corner case and
cost of this change seems to be minimal.
Vladimír Čunát [Fri, 4 Sep 2020 18:54:52 +0000 (20:54 +0200)]
lib/cache: switch .cachelock to fcntl()
This gives us correctness, especially on "staleness" detection.
For simplicity we now don't remove "stale" .cachelock on opening cache,
but it doesn't obstruct us in any way (and overflow will remove it).
Vladimír Čunát [Fri, 4 Sep 2020 17:31:51 +0000 (19:31 +0200)]
lib/cache: tweaks round transactions
- The switched order is documented not to make difference,
but it seems much clearer this way.
- MDB_TXN_FULL wasn't handled correctly (a reversed condition)
and current LMDB code indicates that such transaction is
not recoverable anyway... so we give up on trying.
Vladimír Čunát [Thu, 27 Aug 2020 13:08:48 +0000 (15:08 +0200)]
cache, GC: improve handling of LMDB maxsize
This version seems to work OK. Unfortunately we had to resort to
an extra write and cache reopening when attempting to set cache size.
And even so, decreasing the size can't really be done, so we only warn
about failing to do that.
Vladimír Čunát [Mon, 24 Aug 2020 15:47:29 +0000 (17:47 +0200)]
tests: fine tune integration test for GC
TL;DR: tune the test - now it works quite reliably for me,
though it's perhaps not nice.
With 1 MiB cache it's not easy to avoid overflows, as the defaults are
meant for much larger sizes. Normal GC target is to decrease usage
by 10% when above 80% in 100 records per transaction. That just won't
work reliable due to 10% being only 25 pages.
This commit makes the test run GC with more suitable tuning and
frequently pauses kresd to give GC better chance to catch up.
Vladimír Čunát [Tue, 18 Aug 2020 16:45:28 +0000 (18:45 +0200)]
lib/cache: abort() if emergency cache-clear fails
As the code has been so far, there's no usable cache in that case
and some code just can't handle that. Up to now we were getting
SIGSEGV from inside LMDB on the next attempted operation.
We might consider loosening preallocation in that case or even
retrying after a short sleep. Systemd's restart after hold-off
timeout has an effect similar to the short sleep.
Vladimír Čunát [Tue, 18 Aug 2020 09:34:43 +0000 (11:34 +0200)]
utils/cache_gc: tolerate ESPACE unless twice in a row
In the unlikely case that GC happens "too late", it could fail when
deleting, in which case it seems best to reopen the cache and try again,
as it will probably be deleted by a kresd instance by the next interval.
Vladimír Čunát [Mon, 17 Aug 2020 17:15:04 +0000 (19:15 +0200)]
utils/cache_gc: avoid too long RO transactions
Until now the analyzing pass over full DB was taking place
in a single RO transaction. For an unknown reason this caused kresd
processes to get MDB_MAP_FULL from mdb_put(), even though clearly there
were plenty free pages at that point.
Basic experiments show that 1k steps are OK and 10k steps are not.
Vladimír Čunát [Mon, 17 Aug 2020 08:38:20 +0000 (10:38 +0200)]
lib/cache: abort transactions on errors
This apparently gets rid of MDB_BAD_TXN failures that we were getting
when cache overflows. Unfortunately LMDB docs don't mention that
after operation failures one should abort the corresponding transaction.
Vladimír Čunát [Mon, 31 Aug 2020 07:29:44 +0000 (09:29 +0200)]
scripts, docs: specify lua version in `luarocks install`
On some systems luarocks defaults to other lua version (e.g. Fedora),
so the result would not be usable from kresd. I didn't touch scripts
for older distro versions (Debian < 10, Ubuntu < 20.04, CentOS 7).
Vladimír Čunát [Mon, 10 Aug 2020 12:26:59 +0000 (14:26 +0200)]
lib/generic/queue: fix a bug
Emptying the queue and using it again... didn't work :-(
Fortunately, no use case in kresd so far could trigger this, I believe:
- struct session::waiting is a list of tasks waiting
while connection is being established
- the temporary queue in session_tasklist_finalize_expired() is also
only once filled and emptied
Petr Špaček [Tue, 18 Aug 2020 07:42:56 +0000 (09:42 +0200)]
lua: clarify event.recurrent() API
It was rather confusing:
- event.after(0, ...) executed function immediatelly
- event.recurrent(0, ...) executed function immediatelly (seemingly worked)
but stoped after the first execution, i.e. no recurrence took place.
Štěpán Balážik [Tue, 11 Aug 2020 14:18:27 +0000 (16:18 +0200)]
ci: fix divergent commit in Deckard submodule
Branch on Deckard tree tracked in this repository was left unmerged in
Deckard. The two trees therefore diverged and broke CI in knot-resolver
repo on a few commits retroactively.
Petr Špaček [Fri, 24 Jul 2020 13:37:50 +0000 (15:37 +0200)]
validator: up->bottom chase DS if RRSIG(s) are missing
The original approach was using SOA owner in negative answers
to optimize number of DS queries. This approarch is less realiable with
weird "servers", including pre-DNSSEC servers which reply to DS query
with an SOA owner pointing to the child zone instead of parent zone.
We now walk the tree from root down to find the missing DS or proof of
its non-existance.
Vladimír Čunát [Thu, 2 Jul 2020 15:04:08 +0000 (17:04 +0200)]
validator: bottom->up chase DS if RRSIG(s) are missing
This is about situations when validator *thinks* it's in a signed zone
but an unsigned answer comes in. The assumption was that RRSIGs didn't
make it through some middle-boxes and it retried with explicit QTYPE=RRSIG.
There were two issues with that.
1. It seems that in most cases the cause of the situation is that
we skipped over a zone cut that transitioned to insecure state,
so the signatures correctly don't exist.
2. An explicit RRSIG query appears to be more trouble than worth;
it seems reasonable for servers not to answer it (fully);
see RFC 8482 sect. 7.
The new approach simply tries to find a proof that the name is insecure,
by spawning a QTYPE=DS sub-query on that name. That fixes some
real-life cases; usually this happens in iteration mode where one IP
address serves zones on both sides of a cut that transitions to insecure.
For details see new comments in that rrsig_not_found() function.
The change resulted in the iterator fallback not making sense anymore
so it was removed.
Vladimír Čunát [Mon, 3 Aug 2020 17:32:23 +0000 (19:32 +0200)]
daemon/lua: get rid of __engine symbol in lua
In particular this gets rid of last light user data inside kresd.
It was still causing problems on some systems, for example Debian Sid.
The error was the same: "bad light userdata pointer" from luajit,
but note that the problem can still be triggered by lua libraries,
e.g. cqueues.