- allow multiple "hook" statements at global or view level
- add "optional bracketed text" type for optional parameter list
- load hook module from specified path rather than hardcoded path
- add a hooktable pointer (and a callback for freeing it) to the
view structure
- change the hooktable functions so they no longer update ns__hook_table
by default, and modify PROCESS_HOOK so it uses the view hooktable, if
set, rather than ns__hook_table. (ns__hook_table is retained for
use by unit tests.)
- update the filter-aaaa system test to load filter-aaaa.so
- add a prereq script to check for dlopen support before running
the filter-aaaa system test
not yet done:
- configuration parameters are not being passed to the filter-aaaa
module; the filter-aaaa ACL and filter-aaaa-on-{v4,v6} settings are
still stored in dns_view
- temporary kluge! in this version, for testing purposes,
named always searches for a filter-aaaa module at /tmp/filter-aaaa.so.
this enables the filter-aaaa system test to run even though the
code to configure hooks in named.conf hasn't been written yet.
- filter-aaaa-on-v4, filter-aaaa-on-v6 and the filter-aaaa ACL are
still configured in the view as they were before, not in the hook.
- these formerly static helper functions have been moved into client.c
and made external so that they can be used in hook modules as well as
internally in libns: query_newrdataset, query_putrdataset,
query_newnamebuf, query_newname, query_getnamebuf, query_keepname,
query_releasename, query_newdbversion, query_findversion
- made query_recurse() and query_done() into public functions
ns_query_recurse() and ns_query_done() so they can be called from
modules.
- the goal of this change is for AAAA filtering to be fully contained
in the query logic, and implemented at discrete points that can be
replaced with hook callouts later on.
- the new code may be slightly less efficient than the old filter-aaaa
implementation, but maximum efficiency was never a priority for AAAA
filtering anyway.
- we now use the rdataset RENDERED attribute to indicate that an AAAA
rdataset should not be included when rendering the message. (this
flag was originally meant to indicate that an rdataset has already
been rendered and should not be repeated, but it can also be used to
prevent rendering in the first place.)
- the DNS_MESSAGERENDER_FILTER_AAAA, NS_CLIENTATTR_FILTER_AAAA,
and DNS_RDATASETGLUE_FILTERAAAA flags are all now unnecessary and
have been removed.
- the purpose of this change is allow for more well-defined hook points
to be available in the query processing logic. some functions that
formerly didn't have access to 'qctx' do now; this is needed because
'qctx' is what gets passed when calling a hook function.
- query_addrdataset() has been broken up into three separate functions
since it used to do three unrelated things, and what was formerly
query_addadditional() has been renamed query_additional_cb() for
clarity.
- client->filter_aaaa is now qctx->filter_aaaa. (later, it will be moved
into opaque storage in the qctx, for use by the filter-aaaa module.)
- cleaned up style and braces
- move hooks.h to public include directory
- ns_hooktable_init() initializes a hook table. if NULL is passed in, it
initializes the global hook table
- ns_hooktable_save() saves a pointer to the current global hook table.
- ns_hooktable_reset() replaces the global hook table with different
one
- ns_hook_add() adds hooks at specified hook points in a hook table (or
the global hook table if the specified table is NULL)
- load and unload functions support dlopen() of hook modules (this is
adapted from dyndb and not yet functional)
- began adding new hook points to query.c
If we know that we'll have a task pool doing specific thing it's better
to use this knowledge and bind tasks to task queues, this behaves better
than randomly choosing the task queue.
- use bound resolver tasks - we have a pool of tasks doing resolutions,
we can spread the load evenly using isc_task_create_bound
- quantum set universally to 25
While implementing the new unit testing framework cmocka, it was found that the
BIND 9 code doesn't compile when assertions are disabled or replaced with any
function (such as mock_assert() from cmocka unit testing framework) that's not
directly recognized as assertion by the compiler.
This made the compiler to complain about blocks of code that was recognized as
unreachable before, but now it isn't.
The changes in this commit include:
* assigns default values to couple of local variables,
* moves some return statements around INSIST assertions,
* adds __builtin_unreachable(); annotations after some INSIST assertions,
* fixes one broken assertion (= instead of ==)
Rationale: the nonce here is only used to make sure there is a low
probability of duplication, according to section B.2 of RFC7873.
It is only 32-bit, and even if an attacker knows the algorithm used
to generate nonces it won't, in any way, give him any platform to
attack the server as long as server secret used to sign the
(nonce, time) pair with HMAC-SHA1 is secure.
On the other hand, currently, each packet sent requires (unnecessarily)
a CS pseudo-random number which is ineffective.
Use a zone's 'type' field instead of the value of its DNS_ZONEOPT_MIRROR
option for checking whether it is a mirror zone. This makes said zone
option and its associated helper function, dns_zone_mirror(), redundant,
so remove them. Remove a check specific to mirror zones from
named_zone_reusable() since another check in that function ensures that
changing a zone's type prevents it from being reused during
reconfiguration.
Rather than overloading dns_zone_slave and discerning between a slave
zone and a mirror zone using a zone option, define a separate enum
value, dns_zone_mirror, to be used exclusively by mirror zones. Update
code handling slave zones to ensure it also handles mirror zones where
applicable.
Commit ba91243542 causes the resolver to
respond to a client query with FORMERR when all upstream queries sent to
the servers authoritative for QNAME elicit FORMERR responses. This
happens because resolver code returns DNS_R_FORMERR in such a case and
dns_result_torcode() acts as a pass-through for all arguments which are
already a valid RCODE.
The correct RCODE to set in the response returned to the client in the
case described above is SERVFAIL. Make sure this happens by overriding
the RCODE in query_gotanswer(), on the grounds that any format errors in
the client query itself should be caught long before execution reaches
that point. This change should not reduce query error logging accuracy
as the resolver code itself reports the exact reason for returning a
DNS_R_FORMERR result using log_formerr().
In some cases, setting qctx->result to DNS_R_SERVFAIL causes the value
of a 'result' variable containing a more specific failure reason to be
effectively discarded. This may cause certain query error log messages
to lack specificity despite a more accurate problem cause being
determined during query processing.
In other cases, qctx->result is set to DNS_R_SERVFAIL even though a more
specific error (e.g. ISC_R_NOMEMORY) could be explicitly indicated.
Since the response message's RCODE is derived from qctx->result using
dns_result_torcode(), which handles a number of possible isc_result_t
values and returns SERVFAIL for anything not explicitly listed, it is
fine to set qctx->result to something more specific than DNS_R_SERVFAIL
(in fact, this is already being done in a few cases). Modify most
QUERY_ERROR() calls so that qctx->result is set to a more specific error
code when possible. Adjust query_error() so that statistics are still
calculated properly. Remove the RECURSE_ERROR() macro which was
introduced exactly because qctx->result could be set to DNS_R_SERVFAIL
instead of DNS_R_DUPLICATE or DNS_R_DROP, which need special handling.
Modify dns_sdlz_putrr() so that it returns DNS_R_SERVFAIL when a DLZ
driver returns invalid RDATA, in order to prevent setting RCODE to
FORMERR (which is what dns_result_torcode() translates e.g. DNS_R_SYNTAX
to) while responding authoritatively.
When something goes wrong while recursing for an answer to a query,
query_gotanswer() sets a flag (qctx->want_stale) in the query context.
query_done() is subsequently called and it can either set up a stale
response lookup (if serve-stale is enabled) or conclude that a SERVFAIL
response should be sent. This may cause confusion when looking at query
error logs since the QUERY_ERROR() line responsible for setting the
response's RCODE to SERVFAIL is not in a catch-all branch of a switch
statement inside query_gotanswer() (like it is for authoritative
responses) but rather in a code branch which appears to have something
to do with serve-stale, even when the latter is not enabled.
Extract the part of query_done() responsible for checking serve-stale
configuration and optionally setting up a stale response lookup into a
separate function, query_usestale(), shifting the responsibility for
setting the response's RCODE to SERVFAIL to the same QUERY_ERROR() line
in query_gotanswer() which is evaluated for authoritative responses.
- update_log() is called to log update errors, but if those errors
occur before the zone is set (for example, when returning NOTAUTH)
it returns without logging anything.