From dcfcde2ec8a485e143a347fb067b2197d4580a36 Mon Sep 17 00:00:00 2001 From: TCY16 Date: Wed, 21 Sep 2022 11:21:33 +0200 Subject: [PATCH] add cached EDE strings --- daemon/worker.c | 30 ++++++++++++++++++++++-------- iterator/iterator.c | 4 ++++ util/data/msgreply.c | 20 +++++++++++++++++++- util/data/msgreply.h | 11 +++++++++++ validator/validator.c | 14 +++++++++++--- 5 files changed, 67 insertions(+), 12 deletions(-) diff --git a/daemon/worker.c b/daemon/worker.c index bbe9d07af..3f94b22d3 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -484,11 +484,18 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo, 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, msg->rep->reason_bogus, ""); + size_t reason_bogus_str_len = 0; + char* reason_bogus_str = msg->rep->reason_bogus_str; + + if (reason_bogus_str) { + reason_bogus_str_len = strlen(reason_bogus_str); + } + + edns_opt_list_append(&edns->opt_list_out, + msg->rep->reason_bogus, reason_bogus_str_len, + reason_bogus_str, worker->scratchpad); } error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL, &msg->qinfo, id, flags, edns); @@ -660,11 +667,18 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo, LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad, worker->env.now_tv)) goto bail_out; - /* 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, rep->reason_bogus, ""); + size_t reason_bogus_str_len = 0; + char* reason_bogus_str = rep->reason_bogus_str; + + if (reason_bogus_str) { + reason_bogus_str_len = strlen(reason_bogus_str); + } + + edns_opt_list_append(&edns->opt_list_out, + rep->reason_bogus, reason_bogus_str_len, + reason_bogus_str, worker->scratchpad); } error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL, qinfo, id, flags, edns); diff --git a/iterator/iterator.c b/iterator/iterator.c index 25e5cfee4..07f1cc26b 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -373,6 +373,7 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode) 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); @@ -3737,6 +3738,9 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq, /* make sure QR flag is on */ iq->response->rep->flags |= BIT_QR; + /* explicitly set the EDE string size to 0 */ + iq->response->rep->reason_bogus_str_size = 0; + /* we have finished processing this query */ qstate->ext_state[id] = module_finished; diff --git a/util/data/msgreply.c b/util/data/msgreply.c index 59d7b957d..9c0d8565f 100644 --- a/util/data/msgreply.c +++ b/util/data/msgreply.c @@ -117,12 +117,16 @@ construct_reply_info_base(struct regional* region, uint16_t flags, size_t qd, rep->ar_numrrsets = ar; rep->rrset_count = total; rep->security = sec; - /* veryify that we set the EDE to none by setting it explicitly */ + /* verify that we set the EDE to none by setting it explicitly */ if (reason_bogus != LDNS_EDE_NONE) { rep->reason_bogus = reason_bogus; } else { rep->reason_bogus = LDNS_EDE_NONE; } + /* only allocated and used on copy @TODO verify this */ + rep->reason_bogus_str = NULL; + rep->reason_bogus_str_size = 0; + rep->authoritative = 0; /* array starts after the refs */ if(region) @@ -585,6 +589,7 @@ reply_info_parsedelete(struct reply_info* rep, struct alloc_cache* alloc) for(i=0; irrset_count; i++) { ub_packed_rrset_parsedelete(rep->rrsets[i], alloc); } + // @TODO free reason_bogus_str free(rep); } @@ -753,6 +758,19 @@ reply_info_copy(struct reply_info* rep, struct alloc_cache* alloc, rep->rrset_count, rep->security, rep->reason_bogus); if(!cp) return NULL; + + if (rep->reason_bogus_str_size > 0 && rep->reason_bogus_str) { + cp->reason_bogus_str = malloc(sizeof(char) * (rep->reason_bogus_str_size + 1)); + + if (!(cp->reason_bogus_str)) { + // @TODO add this? + // if(!region) + // reply_info_parsedelete(cp, alloc); + return NULL; + } + memcpy(cp->reason_bogus_str, rep->reason_bogus_str, rep->reason_bogus_str_size+1); + } + /* allocate ub_key structures special or not */ if(!reply_info_alloc_rrset_keys(cp, alloc, region)) { if(!region) diff --git a/util/data/msgreply.h b/util/data/msgreply.h index cca0d6c49..c3ca39f09 100644 --- a/util/data/msgreply.h +++ b/util/data/msgreply.h @@ -173,6 +173,17 @@ struct reply_info { */ sldns_ede_code reason_bogus; + /** + * EDE (rfc8914) text string with human-readable reason for DNSSEC + * bogus status. Used for caching the EDE. + */ + char* reason_bogus_str; + + /** + * EDE (rfc8914) text string size. + */ + size_t reason_bogus_str_size; + /** * Number of RRsets in each section. * The answer section. Add up the RRs in every RRset to calculate diff --git a/validator/validator.c b/validator/validator.c index 1723afefe..44e493292 100644 --- a/validator/validator.c +++ b/validator/validator.c @@ -2151,9 +2151,16 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq, log_query_info(NO_VERBOSE, "validation failure", &qstate->qinfo); else { - char* err = errinf_to_str_bogus(qstate); - if(err) log_info("%s", err); - free(err); + char* err_str = errinf_to_str_bogus(qstate); + if(err_str) { + size_t err_str_len = strlen(err_str); + + /* allocate space and store the error string and it's size*/ + vq->orig_msg->rep->reason_bogus_str = malloc(sizeof(char) * (err_str_len + 1)); + memcpy(vq->orig_msg->rep->reason_bogus_str, err_str, err_str_len + 1); + vq->orig_msg->rep->reason_bogus_str_size = err_str_len; + } + free(err_str); } } /* @@ -2195,6 +2202,7 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq, } } } + /* store results in cache */ if(qstate->query_flags&BIT_RD) { /* if secure, this will override cache anyway, no need -- 2.47.3