]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: propagate source where an RR from back to client 18617/head
authorLennart Poettering <lennart@poettering.net>
Tue, 10 Nov 2020 22:34:40 +0000 (23:34 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 16 Feb 2021 09:03:43 +0000 (10:03 +0100)
This is extremely useful when debugging stuff: knowing whether a result
was cached, came from network, or was synthesized.

src/resolve/resolvectl.c
src/resolve/resolved-bus.c
src/resolve/resolved-def.h
src/resolve/resolved-dns-query.c
src/resolve/resolved-dns-query.h
src/resolve/resolved-dns-transaction.h
src/resolve/resolved-varlink.c

index c24bc4e27e490f5e8ce0a04ee226c5ccc0b8ff32..2302ca48ba3ad04eaa36ce9ab7ce08db624183b0 100644 (file)
@@ -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) {
index 90e043be62a0905ab1277307a1240ae495be4e8f..71374a19ad68286438c385d15d4d8f25976afa33 100644 (file)
@@ -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;
 
index cdcd06d82051a1bfb0a995c1d0e82ccdfe3b402f..702d3f8b41857b1b8b5e41c3bbd01e355bbceef5 100644 (file)
 /* 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)
index ee1da97e1e30960e5408f56d044dc221e08a537d..1413afe3b9b84f644f5b4b404a08ad0d61b54e87 100644 (file)
@@ -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);
index 607390b8efbcdae7aae3e5251ad0b79ed74c44b3..4874aa0c1773f8b2136edf502cecb5e7198f3461 100644 (file)
@@ -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));
 }
index 2c1894f9c237980da8a4142b9bf48cdb27806a52..b036adec2e4aae608e3e16455ceaab541abdc480 100644 (file)
@@ -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_;
 
index 05bb2ec817756fbb6798382524d657d7505c68b9..77e75b8a8d1770dacf7221cb987422e38101a269 100644 (file)
@@ -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) {