dns_answer_unref(q->reply_authoritative);
dns_answer_unref(q->reply_additional);
+ free(q->answer_ede_msg);
+
if (q->request_stream) {
/* Detach the stream from our query, in case something else keeps a reference to it. */
(void) set_remove(q->request_stream->queries, q);
!FLAGS_SET(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED))
continue;
+ char *answer_ede_msg = NULL;
+ if (t->answer_ede_msg) {
+ answer_ede_msg = strdup(t->answer_ede_msg);
+ if (!answer_ede_msg) {
+ log_oom();
+ goto fail;
+ }
+ }
+
DNS_ANSWER_REPLACE(q->answer, dns_answer_ref(t->answer));
q->answer_rcode = t->answer_rcode;
q->answer_dnssec_result = t->answer_dnssec_result;
+ q->answer_ede_rcode = t->answer_ede_rcode;
+ q->answer_ede_msg = answer_ede_msg;
q->answer_query_flags = t->answer_query_flags | dns_transaction_source_to_query_flags(t->answer_source);
q->answer_errno = t->answer_errno;
DNS_PACKET_REPLACE(q->answer_full_packet, dns_packet_ref(t->received));
dns_resource_key_unref(t->key);
dns_packet_unref(t->bypass);
+ free(t->answer_ede_msg);
+
return mfree(t);
}
.dns_udp_fd = -EBADF,
.answer_source = _DNS_TRANSACTION_SOURCE_INVALID,
.answer_dnssec_result = _DNSSEC_RESULT_INVALID,
+ .answer_ede_rcode = _DNS_EDE_RCODE_INVALID,
.answer_nsec_ttl = UINT32_MAX,
.key = dns_resource_key_ref(key),
.query_flags = query_flags,
"DNS_SERVER_FEATURE_LEVEL=%s", dns_server_feature_level_to_string(t->server->possible_feature_level));
}
+ if (state == DNS_TRANSACTION_UPSTREAM_DNSSEC_FAILURE) {
+ dns_resource_key_to_string(dns_transaction_key(t), key_str, sizeof key_str);
+
+ log_struct(LOG_NOTICE,
+ "MESSAGE_ID=" SD_MESSAGE_DNSSEC_FAILURE_STR,
+ LOG_MESSAGE("Upstream resolver reported failure for question %s: %s%s%s",
+ key_str, dns_ede_rcode_to_string(t->answer_ede_rcode),
+ isempty(t->answer_ede_msg) ? "" : ": ", t->answer_ede_msg),
+ "DNS_TRANSACTION=%" PRIu16, t->id,
+ "DNS_QUESTION=%s", key_str,
+ "DNS_EDE_RCODE=%s", dns_ede_rcode_to_string(t->answer_ede_rcode),
+ "DNS_SERVER=%s", strna(dns_server_string_full(t->server)),
+ "DNS_SERVER_FEATURE_LEVEL=%s", dns_server_feature_level_to_string(t->server->possible_feature_level));
+ }
+
/* Note that this call might invalidate the query. Callers
* should hence not attempt to access the query or transaction
* after calling this function. */
ede_rcode = dns_packet_ede_rcode(p, &ede_msg);
if (ede_rcode < 0 && ede_rcode != -EINVAL)
log_debug_errno(ede_rcode, "Unable to extract EDE error code from packet, ignoring: %m");
+ else {
+ t->answer_ede_rcode = ede_rcode;
+ t->answer_ede_msg = TAKE_PTR(ede_msg);
+ }
if (!t->bypass &&
IN_SET(DNS_PACKET_RCODE(p), DNS_RCODE_FORMERR, DNS_RCODE_SERVFAIL, DNS_RCODE_NOTIMP)) {
log_debug("Server returned error: %s (%s%s%s). Lookup failed.",
FORMAT_DNS_RCODE(DNS_PACKET_RCODE(p)),
FORMAT_DNS_EDE_RCODE(ede_rcode),
- isempty(ede_msg) ? "" : ": ", ede_msg);
- dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
+ isempty(t->answer_ede_msg) ? "" : ": ",
+ t->answer_ede_msg);
+ dns_transaction_complete(t, DNS_TRANSACTION_UPSTREAM_DNSSEC_FAILURE);
return;
}
log_debug("Server returned error: %s (%s%s%s), retrying transaction.",
FORMAT_DNS_RCODE(DNS_PACKET_RCODE(p)),
FORMAT_DNS_EDE_RCODE(ede_rcode),
- isempty(ede_msg) ? "" : ": ", ede_msg);
+ isempty(t->answer_ede_msg) ? "" : ": ",
+ t->answer_ede_msg);
dns_transaction_retry(t, false);
return;
}
log_debug("Server returned error: %s (%s%s%s)",
FORMAT_DNS_RCODE(DNS_PACKET_RCODE(p)),
FORMAT_DNS_EDE_RCODE(ede_rcode),
- isempty(ede_msg) ? "" : ": ", ede_msg);
+ isempty(t->answer_ede_msg) ? "" : ": ", t->answer_ede_msg);
break;
} /* No EDE rcode, or EDE rcode we don't understand */