From: Lennart Poettering Date: Tue, 10 Nov 2020 22:34:40 +0000 (+0100) Subject: resolved: propagate source where an RR from back to client X-Git-Tag: v248-rc1~110^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5c1790d1cec785951f16addb257bbf13d594e02b;p=thirdparty%2Fsystemd.git resolved: propagate source where an RR from back to client This is extremely useful when debugging stuff: knowing whether a result was cached, came from network, or was synthesized. --- diff --git a/src/resolve/resolvectl.c b/src/resolve/resolvectl.c index c24bc4e27e4..2302ca48ba3 100644 --- a/src/resolve/resolvectl.c +++ b/src/resolve/resolvectl.c @@ -161,6 +161,16 @@ static void print_source(uint64_t flags, usec_t rtt) { yes_no(flags & SD_RESOLVED_AUTHENTICATED), yes_no(flags & SD_RESOLVED_CONFIDENTIAL), ansi_normal()); + + if ((flags & (SD_RESOLVED_FROM_MASK|SD_RESOLVED_SYNTHETIC)) != 0) + printf("%s-- Data from:%s%s%s%s%s%s\n", + ansi_grey(), + FLAGS_SET(flags, SD_RESOLVED_SYNTHETIC) ? " synthetic" : "", + FLAGS_SET(flags, SD_RESOLVED_FROM_CACHE) ? " cache" : "", + FLAGS_SET(flags, SD_RESOLVED_FROM_ZONE) ? " zone" : "", + FLAGS_SET(flags, SD_RESOLVED_FROM_TRUST_ANCHOR) ? " trust-anchor" : "", + FLAGS_SET(flags, SD_RESOLVED_FROM_NETWORK) ? " network" : "", + ansi_normal()); } static void print_ifindex_comment(int printed_so_far, int ifindex) { diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c index 90e043be62a..71374a19ad6 100644 --- a/src/resolve/resolved-bus.c +++ b/src/resolve/resolved-bus.c @@ -367,7 +367,8 @@ static int parse_as_address(sd_bus_message *m, int ifindex, const char *hostname return r; r = sd_bus_message_append(reply, "st", canonical, - SD_RESOLVED_FLAGS_MAKE(dns_synthesize_protocol(flags), ff, true, true)); + SD_RESOLVED_FLAGS_MAKE(dns_synthesize_protocol(flags), ff, true, true) | + SD_RESOLVED_SYNTHETIC); if (r < 0) return r; diff --git a/src/resolve/resolved-def.h b/src/resolve/resolved-def.h index cdcd06d8205..702d3f8b418 100644 --- a/src/resolve/resolved-def.h +++ b/src/resolve/resolved-def.h @@ -55,8 +55,25 @@ /* Output: Result was only sent via encrypted channels, or never left this system */ #define SD_RESOLVED_CONFIDENTIAL (UINT64_C(1) << 18) +/* Output: Result was (at least partially) synthesized locally */ +#define SD_RESOLVED_SYNTHETIC (UINT64_C(1) << 19) + +/* Output: Result was (at least partially) answered from cache */ +#define SD_RESOLVED_FROM_CACHE (UINT64_C(1) << 20) + +/* Output: Result was (at least partially) answered from local zone */ +#define SD_RESOLVED_FROM_ZONE (UINT64_C(1) << 21) + +/* Output: Result was (at least partially) answered from trust anchor */ +#define SD_RESOLVED_FROM_TRUST_ANCHOR (UINT64_C(1) << 22) + +/* Output: Result was (at least partially) answered from network */ +#define SD_RESOLVED_FROM_NETWORK (UINT64_C(1) << 23) + #define SD_RESOLVED_LLMNR (SD_RESOLVED_LLMNR_IPV4|SD_RESOLVED_LLMNR_IPV6) #define SD_RESOLVED_MDNS (SD_RESOLVED_MDNS_IPV4|SD_RESOLVED_MDNS_IPV6) #define SD_RESOLVED_PROTOCOLS_ALL (SD_RESOLVED_MDNS|SD_RESOLVED_LLMNR|SD_RESOLVED_DNS) +#define SD_RESOLVED_FROM_MASK (SD_RESOLVED_FROM_CACHE|SD_RESOLVED_FROM_ZONE|SD_RESOLVED_FROM_TRUST_ANCHOR|SD_RESOLVED_FROM_NETWORK) + #define SD_RESOLVED_QUERY_TIMEOUT_USEC (120 * USEC_PER_SEC) diff --git a/src/resolve/resolved-dns-query.c b/src/resolve/resolved-dns-query.c index ee1da97e1e3..1413afe3b9b 100644 --- a/src/resolve/resolved-dns-query.c +++ b/src/resolve/resolved-dns-query.c @@ -630,7 +630,7 @@ static int dns_query_synthesize_reply(DnsQuery *q, DnsTransactionState *state) { q->answer_rcode = DNS_RCODE_NXDOMAIN; q->answer_protocol = dns_synthesize_protocol(q->flags); q->answer_family = dns_synthesize_family(q->flags); - q->answer_query_flags = SD_RESOLVED_AUTHENTICATED|SD_RESOLVED_CONFIDENTIAL; + q->answer_query_flags = SD_RESOLVED_AUTHENTICATED|SD_RESOLVED_CONFIDENTIAL|SD_RESOLVED_SYNTHETIC; *state = DNS_TRANSACTION_RCODE_FAILURE; return 0; @@ -644,7 +644,7 @@ static int dns_query_synthesize_reply(DnsQuery *q, DnsTransactionState *state) { q->answer_rcode = DNS_RCODE_SUCCESS; q->answer_protocol = dns_synthesize_protocol(q->flags); q->answer_family = dns_synthesize_family(q->flags); - q->answer_query_flags = SD_RESOLVED_AUTHENTICATED|SD_RESOLVED_CONFIDENTIAL; + q->answer_query_flags = SD_RESOLVED_AUTHENTICATED|SD_RESOLVED_CONFIDENTIAL|SD_RESOLVED_SYNTHETIC; *state = DNS_TRANSACTION_SUCCESS; @@ -676,7 +676,7 @@ static int dns_query_try_etc_hosts(DnsQuery *q) { q->answer_rcode = DNS_RCODE_SUCCESS; q->answer_protocol = dns_synthesize_protocol(q->flags); q->answer_family = dns_synthesize_family(q->flags); - q->answer_query_flags = SD_RESOLVED_AUTHENTICATED|SD_RESOLVED_CONFIDENTIAL; + q->answer_query_flags = SD_RESOLVED_AUTHENTICATED|SD_RESOLVED_CONFIDENTIAL|SD_RESOLVED_SYNTHETIC; return 1; } @@ -833,10 +833,14 @@ static void dns_query_accept(DnsQuery *q, DnsQueryCandidate *c) { r = dns_answer_extend(&q->answer, t->answer); if (r < 0) goto fail; + + q->answer_query_flags |= dns_transaction_source_to_query_flags(t->answer_source); } else { /* Override non-successful previous answers */ dns_answer_unref(q->answer); q->answer = dns_answer_ref(t->answer); + + q->answer_query_flags = dns_transaction_source_to_query_flags(t->answer_source); } q->answer_rcode = t->answer_rcode; @@ -883,7 +887,7 @@ static void dns_query_accept(DnsQuery *q, DnsQueryCandidate *c) { q->answer = dns_answer_ref(t->answer); q->answer_rcode = t->answer_rcode; q->answer_dnssec_result = t->answer_dnssec_result; - q->answer_query_flags = t->answer_query_flags; + 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_unref(q->answer_full_packet); q->answer_full_packet = dns_packet_ref(t->received); diff --git a/src/resolve/resolved-dns-query.h b/src/resolve/resolved-dns-query.h index 607390b8efb..4874aa0c177 100644 --- a/src/resolve/resolved-dns-query.h +++ b/src/resolve/resolved-dns-query.h @@ -141,5 +141,6 @@ static inline uint64_t dns_query_reply_flags_make(DnsQuery *q) { return SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, dns_query_fully_authenticated(q), - dns_query_fully_confidential(q)); + dns_query_fully_confidential(q)) | + (q->answer_query_flags & (SD_RESOLVED_FROM_MASK|SD_RESOLVED_SYNTHETIC)); } diff --git a/src/resolve/resolved-dns-transaction.h b/src/resolve/resolved-dns-transaction.h index 2c1894f9c23..b036adec2e4 100644 --- a/src/resolve/resolved-dns-transaction.h +++ b/src/resolve/resolved-dns-transaction.h @@ -169,6 +169,27 @@ static inline DnsResourceKey *dns_transaction_key(DnsTransaction *t) { return t->bypass->question->keys[0]; } +static inline uint64_t dns_transaction_source_to_query_flags(DnsTransactionSource s) { + + switch (s) { + + case DNS_TRANSACTION_NETWORK: + return SD_RESOLVED_FROM_NETWORK; + + case DNS_TRANSACTION_CACHE: + return SD_RESOLVED_FROM_CACHE; + + case DNS_TRANSACTION_ZONE: + return SD_RESOLVED_FROM_ZONE; + + case DNS_TRANSACTION_TRUST_ANCHOR: + return SD_RESOLVED_FROM_TRUST_ANCHOR; + + default: + return 0; + } +} + const char* dns_transaction_state_to_string(DnsTransactionState p) _const_; DnsTransactionState dns_transaction_state_from_string(const char *s) _pure_; diff --git a/src/resolve/resolved-varlink.c b/src/resolve/resolved-varlink.c index 05bb2ec8177..77e75b8a8d1 100644 --- a/src/resolve/resolved-varlink.c +++ b/src/resolve/resolved-varlink.c @@ -267,7 +267,8 @@ static int parse_as_address(Varlink *link, LookupParameters *p) { JSON_BUILD_PAIR("family", JSON_BUILD_INTEGER(ff)), JSON_BUILD_PAIR("address", JSON_BUILD_BYTE_ARRAY(&parsed, FAMILY_ADDRESS_SIZE(ff)))))), JSON_BUILD_PAIR("name", JSON_BUILD_STRING(canonical)), - JSON_BUILD_PAIR("flags", JSON_BUILD_INTEGER(SD_RESOLVED_FLAGS_MAKE(dns_synthesize_protocol(p->flags), ff, true, true))))); + JSON_BUILD_PAIR("flags", JSON_BUILD_INTEGER(SD_RESOLVED_FLAGS_MAKE(dns_synthesize_protocol(p->flags), ff, true, true)| + SD_RESOLVED_SYNTHETIC)))); } static int vl_method_resolve_hostname(Varlink *link, JsonVariant *parameters, VarlinkMethodFlags flags, void *userdata) {