1
0
Fork 0
bind9/lib/dns/ede.c
Daniel Baumann f66ff7eae6
Adding upstream version 1:9.20.9.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
2025-06-21 13:32:37 +02:00

179 lines
4.3 KiB
C

/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
/*! \file */
#include <isc/mem.h>
#include <isc/util.h>
#include <dns/ede.h>
#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);
uint16_t becode = htobe16(code);
dns_ednsopt_t *edns = NULL;
size_t textlen = 0;
if (dns__ede_checkandupdateedeused(edectx, code)) {
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(1),
"ignoring duplicate ede %u %s", code,
text == NULL ? "(null)" : text);
return;
}
if (edectx->nextede >= DNS_EDE_MAX_ERRORS) {
isc_log_write(dns_lctx, 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_lctx, DNS_LOGCATEGORY_RESOLVER,
DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(1),
"set ede: info-code %u extra-text %s", code,
text == NULL ? "(null)" : text);
if (text != NULL) {
textlen = strlen(text);
if (textlen > DNS_EDE_EXTRATEXT_LEN) {
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(1),
"truncate EDE code %hu text: %s", code,
text);
textlen = DNS_EDE_EXTRATEXT_LEN;
}
}
edns = isc_mem_get(edectx->mctx,
sizeof(*edns) + sizeof(becode) + textlen);
*edns = (dns_ednsopt_t){
.code = DNS_OPT_EDE,
.length = sizeof(becode) + textlen,
.value = (uint8_t *)edns + sizeof(*edns),
};
memmove(edns->value, &becode, sizeof(becode));
if (textlen > 0) {
memmove(edns->value + sizeof(becode), text, textlen);
}
edectx->ede[edectx->nextede] = edns;
edectx->nextede++;
}
void
dns_ede_init(isc_mem_t *mctx, dns_edectx_t *edectx) {
REQUIRE(mctx != NULL);
/*
* Memory context is assigned, not attached here,
* thus there's no detach in dns_ede_reset().
*/
*edectx = (dns_edectx_t){
.magic = DNS_EDE_MAGIC,
.mctx = mctx,
};
}
void
dns_ede_reset(dns_edectx_t *edectx) {
REQUIRE(DNS_EDE_VALID(edectx));
for (size_t i = 0; i < DNS_EDE_MAX_ERRORS; i++) {
dns_ednsopt_t *edns = edectx->ede[i];
if (edns == NULL) {
break;
}
isc_mem_put(edectx->mctx, edns, sizeof(*edns) + edns->length);
edectx->ede[i] = NULL;
}
dns_ede_init(edectx->mctx, edectx);
}
void
dns_ede_invalidate(dns_edectx_t *edectx) {
REQUIRE(DNS_EDE_VALID(edectx));
dns_ede_reset(edectx);
edectx->magic = 0;
edectx->mctx = NULL;
}
void
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));
if (edectx_to == edectx_from) {
return;
}
for (size_t pos = 0; pos < DNS_EDE_MAX_ERRORS; pos++) {
uint16_t fromcode;
if (edectx_from->ede[pos] == NULL) {
break;
}
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_lctx, DNS_LOGCATEGORY_RESOLVER,
DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(1),
"too many ede from subfetch");
break;
}
INSIST(edectx_to->ede[edectx_to->nextede] == NULL);
dns_ednsopt_t *edns = isc_mem_get(
edectx_to->mctx,
sizeof(*edns) + edectx_from->ede[pos]->length);
*edns = (dns_ednsopt_t){
.code = DNS_OPT_EDE,
.length = edectx_from->ede[pos]->length,
.value = (uint8_t *)edns + sizeof(*edns),
};
memmove(edns->value, edectx_from->ede[pos]->value,
edectx_from->ede[pos]->length);
edectx_to->ede[edectx_to->nextede] = edns;
edectx_to->nextede++;
}
}