From: George Thessalonikefs Date: Thu, 13 Jul 2023 09:25:59 +0000 (+0200) Subject: Merge branch 'master' into features/ede-caching X-Git-Tag: release-1.18.0rc1~24^2^2~7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=15b8d8b96ad02101a9a960efdcc051b57b77c0c0;p=thirdparty%2Funbound.git Merge branch 'master' into features/ede-caching --- 15b8d8b96ad02101a9a960efdcc051b57b77c0c0 diff --cc daemon/worker.c index 20c50ae2c,c0b34ff4a..505616b39 --- a/daemon/worker.c +++ b/daemon/worker.c @@@ -484,13 -507,13 +507,13 @@@ answer_norec_from_cache(struct worker* msg->rep, LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad, worker->env.now_tv)) return 0; - /* TODO store the reason for the bogus reply in cache - * and implement in here instead of the hardcoded EDE */ + /* Attached the cached EDE (RFC8914) */ if (worker->env.cfg->ede) { - EDNS_OPT_LIST_APPEND_EDE(&edns->opt_list_out, - worker->scratchpad, LDNS_EDE_DNSSEC_BOGUS, ""); + edns_opt_list_append_ede(&edns->opt_list_out, + worker->scratchpad, msg->rep->reason_bogus, + msg->rep->reason_bogus_str); } - error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL, + error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL, &msg->qinfo, id, flags, edns); if(worker->stats.extended) { worker->stats.ans_bogus++; diff --cc iterator/iterator.c index e1c07fa42,e7365c566..8fe8a0c99 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@@ -302,82 -302,65 +302,66 @@@ error_response(struct module_qstate* qs static int error_response_cache(struct module_qstate* qstate, int id, int rcode) { - if(!qstate->no_cache_store) { - /* store in cache */ - struct reply_info err; - if(qstate->prefetch_leeway > NORR_TTL) { - verbose(VERB_ALGO, "error response for prefetch in cache"); - /* attempt to adjust the cache entry prefetch */ - if(dns_cache_prefetch_adjust(qstate->env, &qstate->qinfo, - NORR_TTL, qstate->query_flags)) - return error_response(qstate, id, rcode); - /* if that fails (not in cache), fall through to store err */ - } - if(qstate->env->cfg->serve_expired) { - /* if serving expired contents, and such content is - * already available, don't overwrite this servfail */ - struct msgreply_entry* msg; - if((msg=msg_cache_lookup(qstate->env, - qstate->qinfo.qname, qstate->qinfo.qname_len, - qstate->qinfo.qtype, qstate->qinfo.qclass, - qstate->query_flags, 0, - qstate->env->cfg->serve_expired_ttl_reset)) - != NULL) { - if(qstate->env->cfg->serve_expired_ttl_reset) { - struct reply_info* rep = - (struct reply_info*)msg->entry.data; - if(rep && *qstate->env->now + - qstate->env->cfg->serve_expired_ttl > - rep->serve_expired_ttl) { - rep->serve_expired_ttl = - *qstate->env->now + - qstate->env->cfg->serve_expired_ttl; - } - } - lock_rw_unlock(&msg->entry.lock); - return error_response(qstate, id, rcode); - } - /* serving expired contents, but nothing is cached - * at all, so the servfail cache entry is useful - * (stops waste of time on this servfail NORR_TTL) */ - } else { - /* don't overwrite existing (non-expired) data in - * cache with a servfail */ - struct msgreply_entry* msg; - if((msg=msg_cache_lookup(qstate->env, - qstate->qinfo.qname, qstate->qinfo.qname_len, - qstate->qinfo.qtype, qstate->qinfo.qclass, - qstate->query_flags, *qstate->env->now, 0)) - != NULL) { - struct reply_info* rep = (struct reply_info*) - msg->entry.data; - if(FLAGS_GET_RCODE(rep->flags) == - LDNS_RCODE_NOERROR || - FLAGS_GET_RCODE(rep->flags) == - LDNS_RCODE_NXDOMAIN) { - /* we have a good entry, - * don't overwrite */ - lock_rw_unlock(&msg->entry.lock); - return error_response(qstate, id, rcode); - } - lock_rw_unlock(&msg->entry.lock); - } - - } - memset(&err, 0, sizeof(err)); - err.flags = (uint16_t)(BIT_QR | BIT_RA); - FLAGS_SET_RCODE(err.flags, rcode); - err.qdcount = 1; - err.ttl = NORR_TTL; - err.prefetch_ttl = PREFETCH_TTL_CALC(err.ttl); - err.serve_expired_ttl = NORR_TTL; - /* do not waste time trying to validate this servfail */ - err.security = sec_status_indeterminate; - err.reason_bogus_str = NULL; - verbose(VERB_ALGO, "store error response in message cache"); - iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0, 0, NULL, - qstate->query_flags, qstate->qstarttime); - } + struct reply_info err; + struct msgreply_entry* msg; + if(qstate->no_cache_store) { + return error_response(qstate, id, rcode); + } + if(qstate->prefetch_leeway > NORR_TTL) { + verbose(VERB_ALGO, "error response for prefetch in cache"); + /* attempt to adjust the cache entry prefetch */ + if(dns_cache_prefetch_adjust(qstate->env, &qstate->qinfo, + NORR_TTL, qstate->query_flags)) + return error_response(qstate, id, rcode); + /* if that fails (not in cache), fall through to store err */ + } + if((msg=msg_cache_lookup(qstate->env, + qstate->qinfo.qname, qstate->qinfo.qname_len, + qstate->qinfo.qtype, qstate->qinfo.qclass, + qstate->query_flags, 0, + qstate->env->cfg->serve_expired_ttl_reset)) != NULL) { + struct reply_info* rep = (struct reply_info*)msg->entry.data; + if(qstate->env->cfg->serve_expired && + qstate->env->cfg->serve_expired_ttl_reset && rep && + *qstate->env->now + qstate->env->cfg->serve_expired_ttl + > rep->serve_expired_ttl) { + verbose(VERB_ALGO, "reset serve-expired-ttl for " + "response in cache"); + rep->serve_expired_ttl = *qstate->env->now + + qstate->env->cfg->serve_expired_ttl; + } + if(rep && (FLAGS_GET_RCODE(rep->flags) == + LDNS_RCODE_NOERROR || + FLAGS_GET_RCODE(rep->flags) == + LDNS_RCODE_NXDOMAIN || + FLAGS_GET_RCODE(rep->flags) == + LDNS_RCODE_YXDOMAIN) && + (qstate->env->cfg->serve_expired || + *qstate->env->now <= rep->ttl)) { + /* we have a good entry, don't overwrite */ + lock_rw_unlock(&msg->entry.lock); + return error_response(qstate, id, rcode); + } + lock_rw_unlock(&msg->entry.lock); + /* nothing interesting is cached (already error response or + * expired good record when we don't serve expired), so this + * servfail cache entry is useful (stops waste of time on this + * servfail NORR_TTL) */ + } + /* store in cache */ + memset(&err, 0, sizeof(err)); + err.flags = (uint16_t)(BIT_QR | BIT_RA); + FLAGS_SET_RCODE(err.flags, rcode); + err.qdcount = 1; + err.ttl = NORR_TTL; + err.prefetch_ttl = PREFETCH_TTL_CALC(err.ttl); + err.serve_expired_ttl = NORR_TTL; + /* do not waste time trying to validate this servfail */ + err.security = sec_status_indeterminate; ++ err.reason_bogus_str = NULL; + verbose(VERB_ALGO, "store error response in message cache"); + iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0, 0, NULL, + qstate->query_flags, qstate->qstarttime); return error_response(qstate, id, rcode); }