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.
Revert parts of commit c3b8130fe8 which
inadvertently broke creating and validating EdDSA signatures:
1. EVP_DigestSignInit() returns 1 on success.
2. EdDSA does not support streaming (EVP_Digest*Update() followed by
EVP_Digest*Final()), only one shot operations.
- 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.
The race condition is the timer elapses before isc__timer_create()
returns the pointer to the caller. Assigning the return pointer before
enabling the timer will fix it.
Zone loading happens in a different task (zone->loadtask) than other
zone actions (zone->task). Thus, when zone_postload() is called in the
context of zone->loadtask, it may cause zone maintenance to be queued in
zone->task and another thread can then execute zone_maintenance() before
zone_postload() gets a chance to finish its work in the first thread.
This would not be a problem if zone_maintenance() accounted for this
possibility by locking the zone before checking the state of its
DNS_ZONEFLG_LOADPENDING flag. However, the zone is currently not locked
before the state of that flag is checked, which may prevent zone
maintenance from happening despite zone_postload() scheduling it. Fix
by locking the zone in zone_maintenance() before checking the state of
the zone's DNS_ZONEFLG_LOADPENDING flag.