Changes introduced by the previous two commits make the parts of
query_delegation() and query_zone_delegation() which prepare a
delegation response functionally equivalent. Extract this code into a
separate function, query_prepare_delegation_response(), and then call
the latter from both query_delegation() and query_zone_delegation() in
order to reduce code duplication. Add a comment describing the purpose
of the extracted code. Fix coding style issues.
When query processing hits a delegation from a locally configured zone,
an attempt may be made to look for a better answer in the cache. In
such a case, the zone-sourced delegation data is set aside and the
lookup is retried using the cache database. When that lookup is
completed, a decision is made whether the answer found in the cache is
better than the answer found in the zone.
Currently, if the zone-sourced answer turns out to be better than the
one found in the cache:
- qctx->zdb is not restored into qctx->db,
- qctx->node, holding the zone database node found, is not even saved.
Thus, in such a case both qctx->db and qctx->node will point at cache
data. This is not an issue for BIND versions which do not support
mirror zones because in these versions non-recursive queries always
cause the zone-sourced delegation to be returned and thus the
non-recursive part of query_delegation() is never reached if the
delegation is coming from a zone. With mirror zones, however,
non-recursive queries may cause cache lookups even after a zone
delegation is found. Leaving qctx->db assigned to the cache database
when query_delegation() determines that the zone-sourced delegation is
the best answer to the client's query prevents DS records from being
added to delegations coming from mirror zones. Fix this issue by
keeping the zone database and zone node in qctx while the cache is
searched for an answer and then restoring them into qctx->db and
qctx->node, respectively, if the zone-sourced delegation turns out to be
the best answer. Since this change means that qctx->zdb cannot be used
as the glue database any more as it will be reset to NULL by RESTORE(),
ensure that qctx->db is not a cache database before attaching it to
qctx->client->query.gluedb.
Furthermore, current code contains a conditional statement which
prevents a mirror zone from being used as a source of glue records.
Said statement was added to prevent assertion failures caused by
attempting to use a zone database's glue cache for finding glue for an
NS RRset coming from a cache database. However, that check is overly
strict since it completely prevents glue from being added to delegations
coming from mirror zones. With the changes described above in place,
the scenario this check was preventing can no longer happen, so remove
the aforementioned check.
If qctx->zdb is not NULL, qctx->zfname will also not be NULL;
qctx->zsigrdataset may be NULL in such a case, but query_putrdataset()
handles pointers to NULL pointers gracefully. Remove redundant
conditional expressions to make the cleanup code in query_freedata()
match the corresponding sequences of SAVE() / RESTORE() macros more
closely.
Since idn_output_filter() no longer uses its 'absolute' argument and no
other callback is used with dns_name_settotextfilter(), remove the
'absolute' argument from the dns_name_totextfilter_t prototype.
Since BIND libraries are no longer considered public and
dns_rdataslab_tordataset() is not used anywhere in the tree, remove the
latter and its associated dns_rdatasetmethods_t callbacks from
lib/dns/rdataslab.c.
As mirror zone data should be treated the way validated, cached DNS
responses are, it should not be used when responding to clients who are
not allowed cache access. Reuse code responsible for determining cache
database access for evaluating mirror zone access.
Modify query_checkcacheaccess() so that it only contains a single return
statement rather than three and so that the "check_acl" variable is no
longer needed. Tweak and expand comments. Fix coding style issues.
Modify query_getcachedb() so that it uses a common return path for both
success and failure. Remove a redundant NULL check since 'db' will
never be NULL after being passed as a target pointer to dns_db_attach().
Fix coding style issues.
Extract the parts of query_getcachedb() responsible for checking whether
the client is allowed to access the cache to a separate function, so
that it can be reused for determining mirror zone access.
If transferring or loading a mirror zone fails, resolution should still
succeed by means of falling back to regular recursive queries.
Currently, though, if a slave zone is present in the zone table and not
loaded, a SERVFAIL response is generated. Thus, mirror zones need
special handling in this regard.
Add a new dns_zt_find() flag, DNS_ZTFIND_MIRROR, and set it every time a
domain name is looked up rather than a zone itself. Handle that flag in
dns_zt_find() in such a way that a mirror zone which is expired or not
yet loaded is ignored when looking up domain names, but still possible
to find when the caller wants to know whether the zone is configured.
This causes a fallback to recursion when mirror zone data is unavailable
without making unloaded mirror zones invisible to code checking a zone's
existence.