#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",
memmove(edns->value + sizeof(becode), text, textlen);
}
- edectx->ede[pos] = edns;
+ edectx->ede[edectx->nextede] = edns;
+ edectx->nextede++;
}
void
isc_mem_put(edectx->mctx, edns, sizeof(*edns) + edns->length);
edectx->ede[i] = NULL;
}
+
+ dns_ede_init(edectx->mctx, edectx);
}
void
}
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 (size_t pos = 0; pos < DNS_EDE_MAX_ERRORS; pos++) {
+ uint16_t fromcode;
- for (nextede = 0; nextede < DNS_EDE_MAX_ERRORS; nextede++) {
- if (edectx_to->ede[nextede] == NULL) {
+ if (edectx_from->ede[pos] == NULL) {
break;
}
- }
- for (size_t pos = 0; pos < DNS_EDE_MAX_ERRORS; pos++) {
- 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 (nextede >= DNS_EDE_MAX_ERRORS) {
+ 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,
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++;
}
}