return (false);
}
+/*%
+ * If serving stale answers is allowed, set up 'qctx' to look for one and
+ * return true; otherwise, return false.
+ */
+static bool
+query_usestale(query_ctx_t *qctx) {
+ bool staleanswersok = false;
+ dns_ttl_t stale_ttl = 0;
+ isc_result_t result;
+
+ qctx_clean(qctx);
+ qctx_freedata(qctx);
+
+ /*
+ * Stale answers only make sense if stale_ttl > 0 but we want rndc to
+ * be able to control returning stale answers if they are configured.
+ */
+ dns_db_attach(qctx->client->view->cachedb, &qctx->db);
+ result = dns_db_getservestalettl(qctx->db, &stale_ttl);
+ if (result == ISC_R_SUCCESS && stale_ttl > 0) {
+ switch (qctx->client->view->staleanswersok) {
+ case dns_stale_answer_yes:
+ staleanswersok = true;
+ break;
+ case dns_stale_answer_conf:
+ staleanswersok =
+ qctx->client->view->staleanswersenable;
+ break;
+ case dns_stale_answer_no:
+ staleanswersok = false;
+ break;
+ }
+ } else {
+ staleanswersok = false;
+ }
+
+ if (staleanswersok) {
+ qctx->want_stale = true;
+ qctx->client->query.dboptions |= DNS_DBFIND_STALEOK;
+ inc_stats(qctx->client, ns_statscounter_trystale);
+ if (qctx->client->query.fetch != NULL) {
+ dns_resolver_destroyfetch(&qctx->client->query.fetch);
+ }
+ } else {
+ dns_db_detach(&qctx->db);
+ }
+
+ return (staleanswersok);
+}
+
/*%
* Continue after doing a database lookup or returning from
* recursion, and call out to the next function depending on the
"query_gotanswer: unexpected error: %s",
isc_result_totext(result));
CCTRACE(ISC_LOG_ERROR, errmsg);
- if (qctx->resuming) {
- qctx->want_stale = true;
- } else {
- QUERY_ERROR(qctx, DNS_R_SERVFAIL);
+ if (qctx->resuming && query_usestale(qctx)) {
+ /*
+ * If serve-stale is enabled, query_usestale() already
+ * set up 'qctx' for looking up a stale response.
+ */
+ return (query_lookup(qctx));
}
+ QUERY_ERROR(qctx, DNS_R_SERVFAIL);
return (query_done(qctx));
}
}
return (ns__query_start(qctx));
}
- if (qctx->want_stale) {
- dns_ttl_t stale_ttl = 0;
- isc_result_t result;
- bool staleanswersok = false;
-
- /*
- * Stale answers only make sense if stale_ttl > 0 but
- * we want rndc to be able to control returning stale
- * answers if they are configured.
- */
- dns_db_attach(qctx->client->view->cachedb, &qctx->db);
- result = dns_db_getservestalettl(qctx->db, &stale_ttl);
- if (result == ISC_R_SUCCESS && stale_ttl > 0) {
- switch (qctx->client->view->staleanswersok) {
- case dns_stale_answer_yes:
- staleanswersok = true;
- break;
- case dns_stale_answer_conf:
- staleanswersok =
- qctx->client->view->staleanswersenable;
- break;
- case dns_stale_answer_no:
- staleanswersok = false;
- break;
- }
- } else {
- staleanswersok = false;
- }
-
- if (staleanswersok) {
- qctx->client->query.dboptions |= DNS_DBFIND_STALEOK;
- inc_stats(qctx->client, ns_statscounter_trystale);
- if (qctx->client->query.fetch != NULL)
- dns_resolver_destroyfetch(
- &qctx->client->query.fetch);
- return (query_lookup(qctx));
- }
- dns_db_detach(&qctx->db);
- qctx->want_stale = false;
- QUERY_ERROR(qctx, DNS_R_SERVFAIL);
- return (query_done(qctx));
- }
-
if (qctx->result != ISC_R_SUCCESS &&
(!PARTIALANSWER(qctx->client) || WANTRECURSION(qctx->client) ||
qctx->result == DNS_R_DROP))