summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2024-01-10 03:34:44 +0100
committerYu Watanabe <watanabe.yu+github@gmail.com>2024-01-10 18:10:32 +0100
commita72cf22d065630da74cf8aee12d8a2a23fcfefb6 (patch)
treec9e619f75d8aa1ca4febe1b501d432c6b206b1ac
parentresolvectl: use JSON_ALLOW_EXTENSIONS (diff)
downloadsystemd-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.c17
-rw-r--r--src/resolve/resolved-dns-dnssec.c1
-rw-r--r--src/resolve/resolved-dns-dnssec.h3
-rw-r--r--src/resolve/resolved-dns-transaction.c19
-rw-r--r--src/resolve/resolved-varlink.c12
-rw-r--r--src/shared/varlink-io.systemd.Resolve.c8
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);