summaryrefslogtreecommitdiff
path: root/src/resolve/resolved-dns-rr.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-11-24 00:18:49 +0100
committerLennart Poettering <lennart@poettering.net>2015-11-24 00:20:39 +0100
commit58db254ade4fb2ef77de68f28c4f13814819f6a1 (patch)
tree597cc7eb7ec7822f62b91e25558e3e9d490b655c /src/resolve/resolved-dns-rr.c
parent5ce1946f4def03e0ab7127dd5729949a32e060ac (diff)
resolved: implement client-side DNAME resolution
Most servers apparently always implicitly convert DNAME to CNAME, but some servers don't, hence implement this properly, as this is required by edns0.
Diffstat (limited to 'src/resolve/resolved-dns-rr.c')
-rw-r--r--src/resolve/resolved-dns-rr.c33
1 files changed, 29 insertions, 4 deletions
diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c
index 636e07dea9..9b264900fc 100644
--- a/src/resolve/resolved-dns-rr.c
+++ b/src/resolve/resolved-dns-rr.c
@@ -57,10 +57,33 @@ DnsResourceKey* dns_resource_key_new_cname(const DnsResourceKey *key) {
}
DnsResourceKey* dns_resource_key_new_redirect(const DnsResourceKey *key, const DnsResourceRecord *cname) {
+ int r;
+
assert(key);
assert(cname);
- return dns_resource_key_new(key->class, key->type, cname->cname.name);
+ assert(IN_SET(cname->key->type, DNS_TYPE_CNAME, DNS_TYPE_DNAME));
+
+ if (cname->key->type == DNS_TYPE_CNAME)
+ return dns_resource_key_new(key->class, key->type, cname->cname.name);
+ else {
+ DnsResourceKey *k;
+ char *destination = NULL;
+
+ r = dns_name_change_suffix(DNS_RESOURCE_KEY_NAME(key), DNS_RESOURCE_KEY_NAME(cname->key), cname->dname.name, &destination);
+ if (r < 0)
+ return NULL;
+ if (r == 0)
+ return dns_resource_key_ref((DnsResourceKey*) key);
+
+ k = dns_resource_key_new_consume(key->class, key->type, destination);
+ if (!k) {
+ free(destination);
+ return NULL;
+ }
+
+ return k;
+ }
}
DnsResourceKey* dns_resource_key_new_consume(uint16_t class, uint16_t type, char *name) {
@@ -142,10 +165,12 @@ int dns_resource_key_match_cname(const DnsResourceKey *key, const DnsResourceRec
if (rr->key->class != key->class && key->class != DNS_CLASS_ANY)
return 0;
- if (rr->key->type != DNS_TYPE_CNAME)
+ if (rr->key->type == DNS_TYPE_CNAME)
+ return dns_name_equal(DNS_RESOURCE_KEY_NAME(key), DNS_RESOURCE_KEY_NAME(rr->key));
+ else if (rr->key->type == DNS_TYPE_DNAME)
+ return dns_name_endswith(DNS_RESOURCE_KEY_NAME(key), DNS_RESOURCE_KEY_NAME(rr->key));
+ else
return 0;
-
- return dns_name_equal(DNS_RESOURCE_KEY_NAME(rr->key), DNS_RESOURCE_KEY_NAME(key));
}
static void dns_resource_key_hash_func(const void *i, struct siphash *state) {