Andrew Nelless [Fri, 19 Feb 2016 15:25:03 +0000 (15:25 +0000)]
Massage System V context switching out of MTasker
Let's yank all the System-V ucontext switching out of MTasker, massaging it
in to a an implementation neutral, hopefully trivial, pdns_* API.
Stack management and context chaining (similar to ucontexts 'uc_link') are
left exposed, but the implementation is type-erased (void*'d), to force a
clean break. This currently introduces an extra allocation, which hopefully
won't matter once an alternative backend is in place, but means all the
threadWrapper guff can be hidden away.
At the same time, all manual memory management has been removed, with
MThread stacks now being allocated via std::vector with a "lazy_allocator"
which eliminates needless zero-initialization. (Which, compared to a context
switch, is actually quite expensive: diddling 8192 bytes takes ~500ns over
~15 GB/s of memory bandwidth).
pdns_makecontext now takes a std::function object by reference, which must
live until the MThread is started with pdns_swapcontext, at which point it is
std::move'd on to the MThreads stack and can go away. This means a task can
never be started twice (because std::function be empty and throw). I think using
std::function could simplify recursor code, but atm the MTasker makeThread() API
has been left as-is. In MTasker, the MThread start routine is stashed in
ThreadInfo, which also owns the context jointly (via std::shared_ptr) with
any waiters. std::function shouldn't introduce any allocations when used with
trivial function pointers.
In addition, exceptions can hopefully now propagate safely from MThreads
back up to, and through, schedule(), thanks to C++11s exception_ptr.
splitPointer/joinPtr, required to deal with SysVss hairy API, has also been
reimplemented, because master currently still passes one pointer, which only
works on 64-bit thanks to a GNU extension. The new implementation, despite
using memcpy and looking verbose, still compiles down to 2-4 CPU instructions
on each side under GCC -O2, and doesn't depend on any undefined behaviour.
Remi Gacogne [Thu, 18 Feb 2016 16:36:25 +0000 (17:36 +0100)]
dnsdist: Add health check logging, `maxCheckFailures` to backend
`maxCheckFailures` allows waiting for several health check failures
before marking a downstream server down.
Health check errors are logged only in verbose mode and if
`setVerboseHealthChecks()` is set to true.
QPSPoolAction() and DNSSECRule() are mentioned in the README but
the Lua bindings were missing.
Add missing tests for some actions and rules.
Clean existing tests a bit in the process.
Remi Gacogne [Wed, 17 Feb 2016 11:34:39 +0000 (12:34 +0100)]
dnsdist: Better handling of outstanding counter
The outstanding value is now displayed in `showServers()` and we
set the IDS age to 0 as soon as we get a response to prevent
the maintainer thread from cleaning it up during our processing.
Remi Gacogne [Tue, 16 Feb 2016 08:44:51 +0000 (09:44 +0100)]
dnsdist: Lock the Lua context before executing a LuaAction
Otherwise the stack of the Lua context might get corrupted
whenever another Lua function (blockfilter, policy, maintenance or
another LuaAction) is simultaneously called from another thread.
We might be able to use a separate execution stack via
createThread()/lua_newthread(), but if I understand correctly how
it works, we would need to be sure that the Lua function called
does not access the global state at all, which is probably too
restrictive.
This should fix #3374, #3375, #3376, #3377, #3378, #3379, #3383,
and hopefully the random travis failures in our regression tests.
Remi Gacogne [Mon, 15 Feb 2016 08:49:36 +0000 (09:49 +0100)]
dnsdist: Add a simple Packet Cache
Per-pool Packet Cache, using the whole query packet minus the id
has hashing key, to prevent issue related to:
* EDNS Payload size
* ECS
* DNSSEC
The packet cache is not enabled by default, and can be skipped
for specific queries using SkipCacheAction.
It's a per-pool cache, in case you have different responses, but
you can use the same cache for several pools if you want to.
We cache the whole response and age the TTLs when fetching the
response from the cache.
This commit also refactors a bit the way server pools are handled
to be able to have a per-pool cache, and to avoid scanning all
servers when looking for the ones in a given pool.
It is using a fixed-size unordered_map to prevent rehashing. It
is not very efficient with regard to cache cleaning, but I really
would like to use only a ReadLock on the fastpath, and using a
multi index container and moving cache entries to the back / front
on hit / miss would prevent that.
Health checks are moved to a different thread, to prevent them from
being impacted by the cache cleaning operation being slow.
bert hubert [Sun, 14 Feb 2016 10:16:56 +0000 (11:16 +0100)]
add a RE2Rule based on Google RE2 regex library. Note that if we detect it, we compile it in unconditionally which sucks as it is a dynamic link. We should make this something you turn on.
Andrew Nelless [Fri, 12 Feb 2016 22:42:30 +0000 (22:42 +0000)]
Shrink PacketID by 10% by eliminating padding.
PacketID is bloated. Some minor reordering, which shouldn't effect
locality, reduces sizeof(PacketID) from 232 to 208 bytes compiled
against GNU libstdc++ (shipped with GCC 5.3, C++11 ABI) and from 184 to
160 bytes against libc++ 3.7.0. In both cases only 3 bytes of padding
remain for aligning 'bool inIncompleteOkay'.
Remi Gacogne [Thu, 11 Feb 2016 14:43:43 +0000 (15:43 +0100)]
dnsdist: Add an option to log as text. Display filename in showRules
LogAction() could log to the console in text mode or to a file in
binary mode. This commit adds an option to log to a file in text
mode.
When logging to a file, we now display the file name in
showRules().