#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"
}
static void dns_query_stop(DnsQuery *q) {
- DnsQueryCandidate *c;
-
assert(q);
event_source_disable(q->timeout_event_source);
}
free(q->request_address_string);
+ free(q->request_name);
if (q->manager) {
LIST_REMOVE(queries, q->manager->dns_queries, q);
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;
int dns_query_go(DnsQuery *q) {
DnsScopeMatch found = DNS_SCOPE_NO;
- DnsScope *s, *first = NULL;
- DnsQueryCandidate *c;
+ DnsScope *first = NULL;
int r;
assert(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;
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;
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, "query-timeout", true);
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;
!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;
}
void dns_query_ready(DnsQuery *q) {
-
- DnsQueryCandidate *bad = NULL, *c;
+ DnsQueryCandidate *bad = NULL;
bool pending = false;
assert(q);
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)
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? */