diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2024-01-10 03:34:44 +0100 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2024-01-10 18:10:32 +0100 |
commit | a72cf22d065630da74cf8aee12d8a2a23fcfefb6 (patch) | |
tree | c9e619f75d8aa1ca4febe1b501d432c6b206b1ac | |
parent | resolvectl: use JSON_ALLOW_EXTENSIONS (diff) | |
download | systemd-a72cf22d065630da74cf8aee12d8a2a23fcfefb6.tar.xz systemd-a72cf22d065630da74cf8aee12d8a2a23fcfefb6.zip |
resolve: introduce DNSSEC_UPSTREAM_FAILURE
and include EDE code and message in the error messages.
This replaces 9ca133e97a0c8795b1f293ccea4965b4ad1accc4, and implements
originally suggested at
https://github.com/systemd/systemd/pull/30513#discussion_r1433823737
-rw-r--r-- | src/resolve/resolved-bus.c | 17 | ||||
-rw-r--r-- | src/resolve/resolved-dns-dnssec.c | 1 | ||||
-rw-r--r-- | src/resolve/resolved-dns-dnssec.h | 3 | ||||
-rw-r--r-- | src/resolve/resolved-dns-transaction.c | 19 | ||||
-rw-r--r-- | src/resolve/resolved-varlink.c | 12 | ||||
-rw-r--r-- | src/shared/varlink-io.systemd.Resolve.c | 8 |
6 files changed, 50 insertions, 10 deletions
diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c index ef3f5237a9..d9d967ec40 100644 --- a/src/resolve/resolved-bus.c +++ b/src/resolve/resolved-bus.c @@ -145,8 +145,13 @@ static int reply_query_state(DnsQuery *q) { return reply_method_errorf(q, BUS_ERROR_ABORTED, "Query aborted"); case DNS_TRANSACTION_DNSSEC_FAILED: - return reply_method_errorf(q, BUS_ERROR_DNSSEC_FAILED, "DNSSEC validation failed: %s", - dnssec_result_to_string(q->answer_dnssec_result)); + return reply_method_errorf(q, BUS_ERROR_DNSSEC_FAILED, "DNSSEC validation failed: %s%s%s%s%s%s", + dnssec_result_to_string(q->answer_dnssec_result), + q->answer_ede_rcode >= 0 ? " (" : "", + q->answer_ede_rcode >= 0 ? FORMAT_DNS_EDE_RCODE(q->answer_ede_rcode) : "", + (q->answer_ede_rcode >= 0 && !isempty(q->answer_ede_msg)) ? ": " : "", + q->answer_ede_rcode >= 0 ? strempty(q->answer_ede_msg) : "", + q->answer_ede_rcode >= 0 ? ")" : ""); case DNS_TRANSACTION_NO_TRUST_ANCHOR: return reply_method_errorf(q, BUS_ERROR_NO_TRUST_ANCHOR, "No suitable trust anchor known"); @@ -183,7 +188,13 @@ static int reply_query_state(DnsQuery *q) { rc = FORMAT_DNS_RCODE(q->answer_rcode); n = strjoina(_BUS_ERROR_DNS, rc); - sd_bus_error_setf(&error, n, "Could not resolve '%s', server or network returned error %s", dns_query_string(q), rc); + sd_bus_error_setf(&error, n, "Could not resolve '%s', server or network returned error: %s%s%s%s%s%s", + dns_query_string(q), rc, + q->answer_ede_rcode >= 0 ? " (" : "", + q->answer_ede_rcode >= 0 ? FORMAT_DNS_EDE_RCODE(q->answer_ede_rcode) : "", + (q->answer_ede_rcode >= 0 && !isempty(q->answer_ede_msg)) ? ": " : "", + q->answer_ede_rcode >= 0 ? strempty(q->answer_ede_msg) : "", + q->answer_ede_rcode >= 0 ? ")" : ""); } return sd_bus_reply_method_error(req, &error); diff --git a/src/resolve/resolved-dns-dnssec.c b/src/resolve/resolved-dns-dnssec.c index 3c9b90c89b..8788bd6b0b 100644 --- a/src/resolve/resolved-dns-dnssec.c +++ b/src/resolve/resolved-dns-dnssec.c @@ -2564,6 +2564,7 @@ static const char* const dnssec_result_table[_DNSSEC_RESULT_MAX] = { [DNSSEC_FAILED_AUXILIARY] = "failed-auxiliary", [DNSSEC_NSEC_MISMATCH] = "nsec-mismatch", [DNSSEC_INCOMPATIBLE_SERVER] = "incompatible-server", + [DNSSEC_UPSTREAM_FAILURE] = "upstream-failure", }; DEFINE_STRING_TABLE_LOOKUP(dnssec_result, DnssecResult); diff --git a/src/resolve/resolved-dns-dnssec.h b/src/resolve/resolved-dns-dnssec.h index 954bb3ef9d..2f93a7f585 100644 --- a/src/resolve/resolved-dns-dnssec.h +++ b/src/resolve/resolved-dns-dnssec.h @@ -20,11 +20,12 @@ enum DnssecResult { DNSSEC_NO_SIGNATURE, DNSSEC_MISSING_KEY, - /* These two are added by the DnsTransaction logic */ + /* These five are added by the DnsTransaction logic */ DNSSEC_UNSIGNED, DNSSEC_FAILED_AUXILIARY, DNSSEC_NSEC_MISMATCH, DNSSEC_INCOMPATIBLE_SERVER, + DNSSEC_UPSTREAM_FAILURE, _DNSSEC_RESULT_MAX, _DNSSEC_RESULT_INVALID = -EINVAL, diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c index aabaa12944..4ec58dc1c8 100644 --- a/src/resolve/resolved-dns-transaction.c +++ b/src/resolve/resolved-dns-transaction.c @@ -888,8 +888,21 @@ static int dns_transaction_dnssec_ready(DnsTransaction *t) { /* We handle DNSSEC failures different from other errors, as we care about the DNSSEC * validation result */ - log_debug("Auxiliary DNSSEC RR query failed validation: %s", dnssec_result_to_string(dt->answer_dnssec_result)); - t->answer_dnssec_result = dt->answer_dnssec_result; /* Copy error code over */ + log_debug("Auxiliary DNSSEC RR query failed validation: %s%s%s%s%s%s", + dnssec_result_to_string(dt->answer_dnssec_result), + dt->answer_ede_rcode >= 0 ? " (" : "", + dt->answer_ede_rcode >= 0 ? FORMAT_DNS_EDE_RCODE(dt->answer_ede_rcode) : "", + (dt->answer_ede_rcode >= 0 && !isempty(dt->answer_ede_msg)) ? ": " : "", + dt->answer_ede_rcode >= 0 ? strempty(dt->answer_ede_msg) : "", + dt->answer_ede_rcode >= 0 ? ")" : ""); + + /* Copy error code over */ + t->answer_dnssec_result = dt->answer_dnssec_result; + t->answer_ede_rcode = dt->answer_ede_rcode; + r = free_and_strdup(&t->answer_ede_msg, dt->answer_ede_msg); + if (r < 0) + log_oom_debug(); + dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED); return 0; @@ -1226,6 +1239,8 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p, bool encrypt FORMAT_DNS_EDE_RCODE(t->answer_ede_rcode), isempty(t->answer_ede_msg) ? "" : ": ", strempty(t->answer_ede_msg)); + + t->answer_dnssec_result = DNSSEC_UPSTREAM_FAILURE; dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED); return; } diff --git a/src/resolve/resolved-varlink.c b/src/resolve/resolved-varlink.c index 3e178a69f3..4e7e91bdfb 100644 --- a/src/resolve/resolved-varlink.c +++ b/src/resolve/resolved-varlink.c @@ -49,7 +49,11 @@ static int reply_query_state(DnsQuery *q) { case DNS_TRANSACTION_DNSSEC_FAILED: return varlink_errorb(q->varlink_request, "io.systemd.Resolve.DNSSECValidationFailed", - JSON_BUILD_OBJECT(JSON_BUILD_PAIR("result", JSON_BUILD_STRING(dnssec_result_to_string(q->answer_dnssec_result))))); + JSON_BUILD_OBJECT(JSON_BUILD_PAIR("result", JSON_BUILD_STRING(dnssec_result_to_string(q->answer_dnssec_result))), + JSON_BUILD_PAIR_CONDITION(q->answer_ede_rcode >= 0, + "extendedDNSErrorCode", JSON_BUILD_INTEGER(q->answer_ede_rcode)), + JSON_BUILD_PAIR_CONDITION(q->answer_ede_rcode >= 0 && !isempty(q->answer_ede_msg), + "extendedDNSErrorMessage", JSON_BUILD_STRING(q->answer_ede_msg)))); case DNS_TRANSACTION_NO_TRUST_ANCHOR: return varlink_error(q->varlink_request, "io.systemd.Resolve.NoTrustAnchor", NULL); @@ -74,7 +78,11 @@ static int reply_query_state(DnsQuery *q) { case DNS_TRANSACTION_RCODE_FAILURE: return varlink_errorb(q->varlink_request, "io.systemd.Resolve.DNSError", - JSON_BUILD_OBJECT(JSON_BUILD_PAIR("rcode", JSON_BUILD_INTEGER(q->answer_rcode)))); + JSON_BUILD_OBJECT(JSON_BUILD_PAIR("rcode", JSON_BUILD_INTEGER(q->answer_rcode)), + JSON_BUILD_PAIR_CONDITION(q->answer_ede_rcode >= 0, + "extendedDNSErrorCode", JSON_BUILD_INTEGER(q->answer_ede_rcode)), + JSON_BUILD_PAIR_CONDITION(q->answer_ede_rcode >= 0 && !isempty(q->answer_ede_msg), + "extendedDNSErrorMessage", JSON_BUILD_STRING(q->answer_ede_msg)))); case DNS_TRANSACTION_NULL: case DNS_TRANSACTION_PENDING: diff --git a/src/shared/varlink-io.systemd.Resolve.c b/src/shared/varlink-io.systemd.Resolve.c index 0d8ad281fa..627b062ab0 100644 --- a/src/shared/varlink-io.systemd.Resolve.c +++ b/src/shared/varlink-io.systemd.Resolve.c @@ -40,7 +40,9 @@ static VARLINK_DEFINE_ERROR(InvalidReply); static VARLINK_DEFINE_ERROR(QueryAborted); static VARLINK_DEFINE_ERROR( DNSSECValidationFailed, - VARLINK_DEFINE_FIELD(result, VARLINK_STRING, 0)); + VARLINK_DEFINE_FIELD(result, VARLINK_STRING, 0), + VARLINK_DEFINE_FIELD(extendedDNSErrorCode, VARLINK_INT, VARLINK_NULLABLE), + VARLINK_DEFINE_FIELD(extendedDNSErrorMessage, VARLINK_STRING, VARLINK_NULLABLE)); static VARLINK_DEFINE_ERROR(NoTrustAnchor); static VARLINK_DEFINE_ERROR(ResourceRecordTypeUnsupported); static VARLINK_DEFINE_ERROR(NetworkDown); @@ -48,7 +50,9 @@ static VARLINK_DEFINE_ERROR(NoSource); static VARLINK_DEFINE_ERROR(StubLoop); static VARLINK_DEFINE_ERROR( DNSError, - VARLINK_DEFINE_FIELD(rcode, VARLINK_INT, 0)); + VARLINK_DEFINE_FIELD(rcode, VARLINK_INT, 0), + VARLINK_DEFINE_FIELD(extendedDNSErrorCode, VARLINK_INT, VARLINK_NULLABLE), + VARLINK_DEFINE_FIELD(extendedDNSErrorMessage, VARLINK_STRING, VARLINK_NULLABLE)); static VARLINK_DEFINE_ERROR(CNAMELoop); static VARLINK_DEFINE_ERROR(BadAddressSize); |