mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-29 05:28:00 +00:00
Fix a serve-stale issue with a delegated zone
When 'stale-answer-client-timeout' is 0, named is allowed to return a stale answer immediately, while also initiating a new query to get the real answer. This mode is activated in ns__query_start() by setting the 'qctx->options.stalefirst' optoin to 'true' before calling the query_lookup() function, but not when the zone is known to be authoritative to the server. When the zone is authoritative, and query_looup() finds out that the requested name is a delegation, then before proceeding with the query, named tries to look it up in the cache first. Here comes the issue that it doesn't consider enabling 'qctx->options.stalefirst' in this case, and so the 'stale-answer-client-timeout 0' setting doesn't work for those delegated zones - instead of immediately returning the stale answer (if it exists), named tries to resolve it. Fix this issue by enabling 'qctx->options.stalefirst' in the query_zone_delegation() function just before named looks up the name in the cache using a new query_lookup() call. Also, if nothing was found in the cache, don't initiate another query_lookup() from inside query_notfound(), and let query_notfound() do its work, i.e. it will call query_delegation() for further processing. (cherry picked from commit 412aa881f2ce0e9d07b9ab46d2d4863ba388b898)
This commit is contained in:
parent
8f7f97666a
commit
7d652d9994
@ -6206,11 +6206,18 @@ query_lookup(query_ctx_t *qctx) {
|
||||
}
|
||||
} else if (stale_timeout) {
|
||||
if (qctx->options.stalefirst) {
|
||||
if (!stale_found && !answer_found) {
|
||||
/*
|
||||
* We have nothing useful in cache to return
|
||||
* immediately.
|
||||
*/
|
||||
/*
|
||||
* If 'qctx->zdb' is set, this was a cache lookup after
|
||||
* an authoritative lookup returned a delegation (in
|
||||
* order to find a better answer). But we still can
|
||||
* return without getting any usable answer here, as
|
||||
* query_notfound() should handle it from here.
|
||||
* Otherwise, if nothing useful was found in cache then
|
||||
* recursively call query_lookup() again without the
|
||||
* 'stalefirst' option set.
|
||||
*/
|
||||
if (!stale_found && !answer_found && qctx->zdb == NULL)
|
||||
{
|
||||
qctx_clean(qctx);
|
||||
qctx_freedata(qctx);
|
||||
dns_db_attach(qctx->client->view->cachedb,
|
||||
@ -8936,7 +8943,25 @@ query_zone_delegation(query_ctx_t *qctx) {
|
||||
dns_db_attach(qctx->view->cachedb, &qctx->db);
|
||||
qctx->is_zone = false;
|
||||
|
||||
return query_lookup(qctx);
|
||||
/*
|
||||
* Since 'qctx->is_zone' is now false, we should reconsider
|
||||
* setting the 'stalefirst' option, which is usually set in
|
||||
* the beginning in ns__query_start().
|
||||
*/
|
||||
if (qctx->view->staleanswerclienttimeout == 0 &&
|
||||
dns_view_staleanswerenabled(qctx->view))
|
||||
{
|
||||
qctx->options.stalefirst = true;
|
||||
}
|
||||
|
||||
result = query_lookup(qctx);
|
||||
|
||||
/*
|
||||
* After fetch completes, this option is not expected to be set.
|
||||
*/
|
||||
qctx->options.stalefirst = false;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return query_prepare_delegation_response(qctx);
|
||||
|
Loading…
x
Reference in New Issue
Block a user