From 36d9205d669bcdcb04fa730d1f3549a9fc9a9001 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Fri, 4 Sep 2015 01:56:23 +0200 Subject: resolved: rr - introduce dns_resource_key_new_redirect() Takes a key and CNAME RR and returns the canonical RR of the right type. Make use of this in dns_question_redirect(). --- src/resolve/resolved-bus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/resolve/resolved-bus.c') diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c index 12c17003e9..19db781ac4 100644 --- a/src/resolve/resolved-bus.c +++ b/src/resolve/resolved-bus.c @@ -191,7 +191,7 @@ static void bus_method_resolve_hostname_complete(DnsQuery *q) { /* This has a cname? Then update the query with the * new cname. */ - r = dns_query_cname_redirect(q, cname->cname.name); + r = dns_query_cname_redirect(q, cname); if (r < 0) { if (r == -ELOOP) r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_CNAME_LOOP, "CNAME loop on '%s'", q->request_hostname); -- cgit v1.2.3-54-g00ecf From 5643c00afe29eae4b2e3575277038e60e6967d09 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Mon, 17 Aug 2015 07:56:57 +0200 Subject: resolved: cache - handle CNAME redirection CNAME records are special in the way they are treated by DNS servers, and our cache should mimic that behavior: In case a domain name has an alias, its CNAME record is returned in place of any other. Our cache was not doing this despite caching the CNAME records, this entailed needless lookups to re-resolve the CNAME. --- src/resolve/resolved-bus.c | 2 -- src/resolve/resolved-dns-cache.c | 25 ++++++++++++++++++++++++- 2 files changed, 24 insertions(+), 3 deletions(-) (limited to 'src/resolve/resolved-bus.c') diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c index 19db781ac4..bf1b7c8ab4 100644 --- a/src/resolve/resolved-bus.c +++ b/src/resolve/resolved-bus.c @@ -220,8 +220,6 @@ static void bus_method_resolve_hostname_complete(DnsQuery *q) { added++; } - // what about the cache? - /* If we didn't find anything, then let's restart the * query, this time with the cname */ if (added <= 0) { diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c index 478ad29bbf..93b98f3727 100644 --- a/src/resolve/resolved-dns-cache.c +++ b/src/resolve/resolved-dns-cache.c @@ -493,6 +493,29 @@ fail: return r; } +static DnsCacheItem *dns_cache_get_by_key_follow_cname(DnsCache *c, DnsResourceKey *k) { + _cleanup_(dns_resource_key_unrefp) DnsResourceKey *cname_key = NULL; + DnsCacheItem *i, *j; + + assert(c); + assert(k); + + i = hashmap_get(c->by_key, k); + if (i || k->type == DNS_TYPE_CNAME) + return i; + + /* check if we have a CNAME record instead */ + cname_key = dns_resource_key_new_cname(k); + if (!cname_key) + return NULL; + + j = hashmap_get(c->by_key, cname_key); + if (j) + return j; + + return i; +} + int dns_cache_lookup(DnsCache *c, DnsResourceKey *key, int *rcode, DnsAnswer **ret) { _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL; unsigned n = 0; @@ -522,7 +545,7 @@ int dns_cache_lookup(DnsCache *c, DnsResourceKey *key, int *rcode, DnsAnswer **r return 0; } - first = hashmap_get(c->by_key, key); + first = dns_cache_get_by_key_follow_cname(c, key); if (!first) { /* If one question cannot be answered we need to refresh */ -- cgit v1.2.3-54-g00ecf