From e5fc9f5fcbd7f3d0dae8468bec1b801d5a692dba Mon Sep 17 00:00:00 2001 From: Colin Vidal Date: Wed, 29 Jan 2025 23:27:34 +0100 Subject: [PATCH] detect dup EDE with bitmap and store next pos In order to avoid to loop to find the next position to store an EDE in a dns_edectx_t, add a "nextede" state which holds the next available position. Also, in order ot avoid to loop to find if an EDE is already existing in a dns_edectx_t, and avoid a duplicate, use a bitmap to immediately know if the EDE is there or not. Those both changes applies for adding or copying EDE. Also make the direction of dns_ede_copy more explicit/avoid errors by making "edectx_from" a const pointer. (cherry picked from commit 9021f9d802296241dc69431407551d824beeb814) --- lib/dns/ede.c | 63 ++++++++++++++++++++------------------- lib/dns/include/dns/ede.h | 4 ++- 2 files changed, 36 insertions(+), 31 deletions(-) diff --git a/lib/dns/ede.c b/lib/dns/ede.c index 7dcb05f281..7fbbd83905 100644 --- a/lib/dns/ede.c +++ b/lib/dns/ede.c @@ -21,38 +21,39 @@ #define DNS_EDE_MAGIC ISC_MAGIC('E', 'D', 'E', '!') #define DNS_EDE_VALID(v) ISC_MAGIC_VALID(v, DNS_EDE_MAGIC) +static bool +dns__ede_checkandupdateedeused(dns_edectx_t *edectx, uint16_t code) { + if (edectx->edeused & (1 << code)) { + return true; + } + + edectx->edeused |= 1 << code; + return false; +} + void dns_ede_add(dns_edectx_t *edectx, uint16_t code, const char *text) { REQUIRE(DNS_EDE_VALID(edectx)); REQUIRE(code <= DNS_EDE_MAX_CODE); - size_t pos = 0; uint16_t becode = htobe16(code); dns_ednsopt_t *edns = NULL; size_t textlen = 0; - for (pos = 0; pos < DNS_EDE_MAX_ERRORS; pos++) { - edns = edectx->ede[pos]; - - if (edns == NULL) { - break; - } - - if (memcmp(&becode, edns->value, sizeof(becode)) == 0) { - isc_log_write(DNS_LOGCATEGORY_RESOLVER, - DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(1), - "ignoring duplicate ede %u %s", code, - text == NULL ? "(null)" : text); - return; - } + if (dns__ede_checkandupdateedeused(edectx, code)) { + isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, + ISC_LOG_DEBUG(1), "ignoring duplicate ede %u %s", + code, text == NULL ? "(null)" : text); + return; } - if (pos >= DNS_EDE_MAX_ERRORS) { + if (edectx->nextede >= DNS_EDE_MAX_ERRORS) { isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(1), "too many ede, ignoring %u %s", code, text == NULL ? "(null)" : text); return; } + INSIST(edectx->ede[edectx->nextede] == NULL); isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(1), "set ede: info-code %u extra-text %s", @@ -83,7 +84,8 @@ dns_ede_add(dns_edectx_t *edectx, uint16_t code, const char *text) { memmove(edns->value + sizeof(becode), text, textlen); } - edectx->ede[pos] = edns; + edectx->ede[edectx->nextede] = edns; + edectx->nextede++; } void @@ -113,6 +115,8 @@ dns_ede_reset(dns_edectx_t *edectx) { isc_mem_put(edectx->mctx, edns, sizeof(*edns) + edns->length); edectx->ede[i] = NULL; } + + dns_ede_init(edectx->mctx, edectx); } void @@ -126,31 +130,30 @@ dns_ede_invalidate(dns_edectx_t *edectx) { } void -dns_ede_copy(dns_edectx_t *edectx_to, dns_edectx_t *edectx_from) { +dns_ede_copy(dns_edectx_t *edectx_to, const dns_edectx_t *edectx_from) { REQUIRE(DNS_EDE_VALID(edectx_to)); REQUIRE(DNS_EDE_VALID(edectx_from)); - size_t nextede = 0; - - for (nextede = 0; nextede < DNS_EDE_MAX_ERRORS; nextede++) { - if (edectx_to->ede[nextede] == NULL) { - break; - } - } - for (size_t pos = 0; pos < DNS_EDE_MAX_ERRORS; pos++) { + uint16_t fromcode; + if (edectx_from->ede[pos] == NULL) { break; } - if (nextede >= DNS_EDE_MAX_ERRORS) { + fromcode = ISC_U8TO16_BE(edectx_from->ede[pos]->value); + if (dns__ede_checkandupdateedeused(edectx_to, fromcode)) { + continue; + } + + if (edectx_to->nextede >= DNS_EDE_MAX_ERRORS) { isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(1), "too many ede from subfetch"); break; } - INSIST(edectx_to->ede[nextede] == NULL); + INSIST(edectx_to->ede[edectx_to->nextede] == NULL); dns_ednsopt_t *edns = isc_mem_get( edectx_to->mctx, @@ -163,7 +166,7 @@ dns_ede_copy(dns_edectx_t *edectx_to, dns_edectx_t *edectx_from) { memmove(edns->value, edectx_from->ede[pos]->value, edectx_from->ede[pos]->length); - edectx_to->ede[nextede] = edns; - nextede++; + edectx_to->ede[edectx_to->nextede] = edns; + edectx_to->nextede++; } } diff --git a/lib/dns/include/dns/ede.h b/lib/dns/include/dns/ede.h index 8f6cf3bf9a..37194dd5ef 100644 --- a/lib/dns/include/dns/ede.h +++ b/lib/dns/include/dns/ede.h @@ -63,6 +63,8 @@ struct dns_edectx { int magic; isc_mem_t *mctx; dns_ednsopt_t *ede[DNS_EDE_MAX_ERRORS]; + uint32_t edeused; + size_t nextede; }; /*%< * Multiple extended DNS errors (EDE) (defined in RFC 8914) can be raised during @@ -132,7 +134,7 @@ dns_ede_add(dns_edectx_t *edectx, uint16_t code, const char *text); */ void -dns_ede_copy(dns_edectx_t *edectx_to, dns_edectx_t *edectx_from); +dns_ede_copy(dns_edectx_t *edectx_to, const dns_edectx_t *edectx_from); /*%< * Copy all EDE from "edectx_from" into "edectx_to". If "edectx_to" reaches the * maximum number of EDE (see DNS_EDE_MAX_ERRORS), the copy stops and