From e4501ed4e66e31f5bc6e40046ac8f27ce6e13a5c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 30 Jul 2014 20:39:52 +0200 Subject: [PATCH] resolved: when we got a successful DNS reply, then only wait for other transactions on the same scope, nowhere else --- src/resolve/resolved-dns-query.c | 35 +++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/resolve/resolved-dns-query.c b/src/resolve/resolved-dns-query.c index 14ae68395..227700230 100644 --- a/src/resolve/resolved-dns-query.c +++ b/src/resolve/resolved-dns-query.c @@ -567,10 +567,13 @@ int dns_query_new(Manager *m, DnsQuery **ret, DnsQuestion *question) { q->question = dns_question_ref(question); for (i = 0; i < question->n_keys; i++) { - log_debug("Looking up RR for %s %s %s", - strna(dns_class_to_string(question->keys[i]->class)), - strna(dns_type_to_string(question->keys[i]->type)), - DNS_RESOURCE_KEY_NAME(question->keys[i])); + _cleanup_free_ char *p; + + r = dns_resource_key_to_string(question->keys[i], &p); + if (r < 0) + return r; + + log_debug("Looking up RR for %s", p); } LIST_PREPEND(queries, m->dns_queries, q); @@ -801,6 +804,7 @@ void dns_query_ready(DnsQuery *q) { _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL; int rcode = 0; DnsScope *scope = NULL; + bool pending = false; Iterator i; assert(q); @@ -820,9 +824,11 @@ void dns_query_ready(DnsQuery *q) { if (state == DNS_QUERY_SUCCESS && t->scope != scope) continue; - /* One of the transactions is still going on, let's wait for it */ - if (t->state == DNS_QUERY_PENDING || t->state == DNS_QUERY_NULL) - return; + /* One of the transactions is still going on, let's maybe wait for it */ + if (IN_SET(t->state, DNS_QUERY_PENDING, DNS_QUERY_NULL)) { + pending = true; + continue; + } /* One of the transactions is successful, let's use * it, and copy its data out */ @@ -884,6 +890,21 @@ void dns_query_ready(DnsQuery *q) { state = t->state; } + if (pending) { + + /* If so far we weren't successful, and there's + * something still pending, then wait for it */ + if (state != DNS_QUERY_SUCCESS) + return; + + /* If we already were successful, then only wait for + * other transactions on the same scope to finish. */ + SET_FOREACH(t, q->transactions, i) { + if (t->scope == scope && IN_SET(t->state, DNS_QUERY_PENDING, DNS_QUERY_NULL)) + return; + } + } + if (IN_SET(state, DNS_QUERY_SUCCESS, DNS_QUERY_FAILURE)) { q->answer = dns_answer_ref(answer); q->answer_rcode = rcode; -- 2.30.2