]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/resolve/resolved-dns-query.c
tree-wide: use ASSERT_PTR more
[thirdparty/systemd.git] / src / resolve / resolved-dns-query.c
index 3b5e456db2e06fb8a6e2e7da25b92f983d96f820..8daaacfc197f58a8a5842768fd5eb9e9e8dfe433 100644 (file)
@@ -3,6 +3,8 @@
 #include "alloc-util.h"
 #include "dns-domain.h"
 #include "dns-type.h"
+#include "event-util.h"
+#include "glyph-util.h"
 #include "hostname-util.h"
 #include "local-addresses.h"
 #include "resolved-dns-query.h"
@@ -344,11 +346,9 @@ fail:
 }
 
 static void dns_query_stop(DnsQuery *q) {
-        DnsQueryCandidate *c;
-
         assert(q);
 
-        q->timeout_event_source = sd_event_source_disable_unref(q->timeout_event_source);
+        event_source_disable(q->timeout_event_source);
 
         LIST_FOREACH(candidates_by_query, c, q->candidates)
                 dns_query_candidate_stop(c);
@@ -381,6 +381,8 @@ DnsQuery *dns_query_free(DnsQuery *q) {
         if (!q)
                 return NULL;
 
+        q->timeout_event_source = sd_event_source_disable_unref(q->timeout_event_source);
+
         while (q->auxiliary_queries)
                 dns_query_free(q->auxiliary_queries);
 
@@ -425,6 +427,7 @@ DnsQuery *dns_query_free(DnsQuery *q) {
         }
 
         free(q->request_address_string);
+        free(q->request_name);
 
         if (q->manager) {
                 LIST_REMOVE(queries, q->manager->dns_queries, q);
@@ -583,16 +586,22 @@ void dns_query_complete(DnsQuery *q, DnsTransactionState state) {
 
         q->state = state;
 
+        if (state == DNS_TRANSACTION_SUCCESS && set_size(q->manager->varlink_subscription) > 0) {
+                DnsQuestion *question = q->request_packet ? q->request_packet->question : NULL;
+                const char *query_name = question ? dns_question_first_name(question) : q->request_name;
+                if (query_name)
+                        (void) send_dns_notification(q->manager, q->answer, query_name);
+        }
+
         dns_query_stop(q);
         if (q->complete)
                 q->complete(q);
 }
 
 static int on_query_timeout(sd_event_source *s, usec_t usec, void *userdata) {
-        DnsQuery *q = userdata;
+        DnsQuery *q = ASSERT_PTR(userdata);
 
         assert(s);
-        assert(q);
 
         dns_query_complete(q, DNS_TRANSACTION_TIMEOUT);
         return 0;
@@ -715,8 +724,7 @@ static int dns_query_try_etc_hosts(DnsQuery *q) {
 
 int dns_query_go(DnsQuery *q) {
         DnsScopeMatch found = DNS_SCOPE_NO;
-        DnsScope *s, *first = NULL;
-        DnsQueryCandidate *c;
+        DnsScope *first = NULL;
         int r;
 
         assert(q);
@@ -734,18 +742,9 @@ int dns_query_go(DnsQuery *q) {
 
         LIST_FOREACH(scopes, s, q->manager->dns_scopes) {
                 DnsScopeMatch match;
-                const char *name;
-
-                name = dns_question_first_name(dns_query_question_for_protocol(q, s->protocol));
-                if (!name)
-                        continue;
-
-                match = dns_scope_good_domain(s, q->ifindex, q->flags, name);
-                if (match < 0) {
-                        log_debug("Couldn't check if '%s' matches against scope, ignoring.", name);
-                        continue;
-                }
 
+                match = dns_scope_good_domain(s, q);
+                assert(match >= 0);
                 if (match > found) { /* Does this match better? If so, remember how well it matched, and the first one
                                       * that matches this well */
                         found = match;
@@ -770,18 +769,9 @@ int dns_query_go(DnsQuery *q) {
 
         LIST_FOREACH(scopes, s, first->scopes_next) {
                 DnsScopeMatch match;
-                const char *name;
-
-                name = dns_question_first_name(dns_query_question_for_protocol(q, s->protocol));
-                if (!name)
-                        continue;
-
-                match = dns_scope_good_domain(s, q->ifindex, q->flags, name);
-                if (match < 0) {
-                        log_debug("Couldn't check if '%s' matches against scope, ignoring.", name);
-                        continue;
-                }
 
+                match = dns_scope_good_domain(s, q);
+                assert(match >= 0);
                 if (match < found)
                         continue;
 
@@ -792,17 +782,16 @@ int dns_query_go(DnsQuery *q) {
 
         dns_query_reset_answer(q);
 
-        r = sd_event_add_time_relative(
+        r = event_reset_time_relative(
                         q->manager->event,
                         &q->timeout_event_source,
-                        clock_boottime_or_monotonic(),
+                        CLOCK_BOOTTIME,
                         SD_RESOLVED_QUERY_TIMEOUT_USEC,
-                        0, on_query_timeout, q);
+                        0, on_query_timeout, q,
+                        0, "query-timeout", true);
         if (r < 0)
                 goto fail;
 
-        (void) sd_event_source_set_description(q->timeout_event_source, "query-timeout");
-
         q->state = DNS_TRANSACTION_PENDING;
         q->block_ready++;
 
@@ -869,17 +858,14 @@ static void dns_query_accept(DnsQuery *q, DnsQueryCandidate *c) {
                                 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);
-
+                                DNS_ANSWER_REPLACE(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;
                         q->answer_errno = 0;
 
-                        dns_packet_unref(q->answer_full_packet);
-                        q->answer_full_packet = dns_packet_ref(t->received);
+                        DNS_PACKET_REPLACE(q->answer_full_packet, dns_packet_ref(t->received));
 
                         if (FLAGS_SET(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED)) {
                                 has_authenticated = true;
@@ -915,14 +901,12 @@ static void dns_query_accept(DnsQuery *q, DnsQueryCandidate *c) {
                             !FLAGS_SET(t->answer_query_flags, SD_RESOLVED_AUTHENTICATED))
                                 continue;
 
-                        dns_answer_unref(q->answer);
-                        q->answer = dns_answer_ref(t->answer);
+                        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_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);
+                        DNS_PACKET_REPLACE(q->answer_full_packet, dns_packet_ref(t->received));
 
                         state = t->state;
                         break;
@@ -954,8 +938,7 @@ fail:
 }
 
 void dns_query_ready(DnsQuery *q) {
-
-        DnsQueryCandidate *bad = NULL, *c;
+        DnsQueryCandidate *bad = NULL;
         bool pending = false;
 
         assert(q);
@@ -1016,7 +999,10 @@ static int dns_query_cname_redirect(DnsQuery *q, const DnsResourceRecord *cname)
         if (r < 0)
                 return r;
         if (r > 0)
-                log_debug("Following CNAME/DNAME %s → %s.", dns_question_first_name(q->question_idna), dns_question_first_name(nq_idna));
+                log_debug("Following CNAME/DNAME %s %s %s.",
+                          dns_question_first_name(q->question_idna),
+                          special_glyph(SPECIAL_GLYPH_ARROW_RIGHT),
+                          dns_question_first_name(nq_idna));
 
         k = dns_question_is_equal(q->question_idna, q->question_utf8);
         if (k < 0)
@@ -1030,7 +1016,10 @@ static int dns_query_cname_redirect(DnsQuery *q, const DnsResourceRecord *cname)
                 if (k < 0)
                         return k;
                 if (k > 0)
-                        log_debug("Following UTF8 CNAME/DNAME %s → %s.", dns_question_first_name(q->question_utf8), dns_question_first_name(nq_utf8));
+                        log_debug("Following UTF8 CNAME/DNAME %s %s %s.",
+                                  dns_question_first_name(q->question_utf8),
+                                  special_glyph(SPECIAL_GLYPH_ARROW_RIGHT),
+                                  dns_question_first_name(nq_utf8));
         }
 
         if (r == 0 && k == 0) /* No actual cname happened? */