summaryrefslogtreecommitdiff
path: root/src/resolve/resolved-dns-query.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2014-07-23 00:57:25 +0200
committerLennart Poettering <lennart@poettering.net>2014-07-23 02:00:40 +0200
commit7e8e0422aeb16f2a09a40546c61df753d10029b6 (patch)
treec5fd640ba84c1b3c92367aa4540e90c69c557a0b /src/resolve/resolved-dns-query.c
parentfaa133f3aa7a18f26563dc5d6b95898cb315c37a (diff)
resolved: implement negative caching
Diffstat (limited to 'src/resolve/resolved-dns-query.c')
-rw-r--r--src/resolve/resolved-dns-query.c34
1 files changed, 24 insertions, 10 deletions
diff --git a/src/resolve/resolved-dns-query.c b/src/resolve/resolved-dns-query.c
index 80526bbc28..a56e295f4f 100644
--- a/src/resolve/resolved-dns-query.c
+++ b/src/resolve/resolved-dns-query.c
@@ -335,8 +335,8 @@ void dns_query_transaction_process_reply(DnsQueryTransaction *t, DnsPacket *p) {
if (r < 0) {
dns_query_transaction_complete(t, DNS_QUERY_INVALID_REPLY);
return;
- } else if (r > 0)
- dns_cache_put_answer(&t->scope->cache, p->answer, 0);
+ } else
+ dns_cache_put(&t->scope->cache, p->question, DNS_PACKET_RCODE(p), p->answer, 0);
if (DNS_PACKET_RCODE(p) == DNS_RCODE_SUCCESS)
dns_query_transaction_complete(t, DNS_QUERY_SUCCESS);
@@ -416,14 +416,18 @@ static int dns_query_transaction_go(DnsQueryTransaction *t) {
t->n_attempts++;
t->received = dns_packet_unref(t->received);
t->cached = dns_answer_unref(t->cached);
+ t->cached_rcode = 0;
/* First, let's try the cache */
dns_cache_prune(&t->scope->cache);
- r = dns_cache_lookup(&t->scope->cache, t->question, &t->cached);
+ r = dns_cache_lookup(&t->scope->cache, t->question, &t->cached_rcode, &t->cached);
if (r < 0)
return r;
if (r > 0) {
- dns_query_transaction_complete(t, DNS_QUERY_SUCCESS);
+ if (t->cached_rcode == DNS_RCODE_SUCCESS)
+ dns_query_transaction_complete(t, DNS_QUERY_SUCCESS);
+ else
+ dns_query_transaction_complete(t, DNS_QUERY_FAILURE);
return 0;
}
@@ -707,7 +711,8 @@ fail:
void dns_query_ready(DnsQuery *q) {
DnsQueryTransaction *t;
DnsQueryState state = DNS_QUERY_NO_SERVERS;
- DnsPacket *received = NULL;
+ DnsAnswer *failure_answer = NULL;
+ int failure_rcode = 0, failure_ifindex = 0;
Iterator i;
assert(q);
@@ -737,7 +742,7 @@ void dns_query_ready(DnsQuery *q) {
} else {
q->answer = dns_answer_ref(t->cached);
q->answer_ifindex = t->scope->link ? t->scope->link->ifindex : 0;
- q->answer_rcode = 0;
+ q->answer_rcode = t->cached_rcode;
}
dns_query_complete(q, DNS_QUERY_SUCCESS);
@@ -748,7 +753,16 @@ void dns_query_ready(DnsQuery *q) {
* whether we find anything better, but if not, return
* its response packet */
if (t->state == DNS_QUERY_FAILURE) {
- received = t->received;
+ if (t->received) {
+ failure_answer = t->received->answer;
+ failure_ifindex = t->received->ifindex;
+ failure_rcode = DNS_PACKET_RCODE(t->received);
+ } else {
+ failure_answer = t->cached;
+ failure_ifindex = t->scope->link ? t->scope->link->ifindex : 0;
+ failure_rcode = t->cached_rcode;
+ }
+
state = DNS_QUERY_FAILURE;
continue;
}
@@ -758,9 +772,9 @@ void dns_query_ready(DnsQuery *q) {
}
if (state == DNS_QUERY_FAILURE) {
- q->answer = dns_answer_ref(received->answer);
- q->answer_ifindex = received->ifindex;
- q->answer_rcode = DNS_PACKET_RCODE(received);
+ q->answer = dns_answer_ref(failure_answer);
+ q->answer_ifindex = failure_ifindex;
+ q->answer_rcode = failure_rcode;
}
dns_query_complete(q, state);