resolved: when looking for a SOA RR in a reply, pick the right one
authorLennart Poettering <lennart@poettering.net>
Mon, 21 Dec 2015 15:27:13 +0000 (16:27 +0100)
committerLennart Poettering <lennart@poettering.net>
Sat, 26 Dec 2015 18:09:09 +0000 (19:09 +0100)
If there are multiple SOA RRs, and we look for a suitable one covering
our request, then make sure to pick the one that is furthest away from
the root name, not just the first one we encounter.

src/resolve/resolved-dns-answer.c

index 7057745..7e64ca5 100644 (file)
@@ -303,8 +303,8 @@ int dns_answer_contains_nsec_or_nsec3(DnsAnswer *a) {
 }
 
 int dns_answer_find_soa(DnsAnswer *a, const DnsResourceKey *key, DnsResourceRecord **ret, DnsAnswerFlags *flags) {
-        DnsResourceRecord *rr;
-        DnsAnswerFlags rr_flags;
+        DnsResourceRecord *rr, *soa = NULL;
+        DnsAnswerFlags rr_flags, soa_flags = 0;
         int r;
 
         assert(key);
@@ -318,15 +318,29 @@ int dns_answer_find_soa(DnsAnswer *a, const DnsResourceKey *key, DnsResourceReco
                 if (r < 0)
                         return r;
                 if (r > 0) {
-                        if (ret)
-                                *ret = rr;
-                        if (flags)
-                                *flags = rr_flags;
-                        return 1;
+
+                        if (soa) {
+                                r = dns_name_endswith(DNS_RESOURCE_KEY_NAME(rr->key), DNS_RESOURCE_KEY_NAME(soa->key));
+                                if (r < 0)
+                                        return r;
+                                if (r > 0)
+                                        continue;
+                        }
+
+                        soa = rr;
+                        soa_flags = rr_flags;
                 }
         }
 
-        return 0;
+        if (!soa)
+                return 0;
+
+        if (ret)
+                *ret = soa;
+        if (flags)
+                *flags = soa_flags;
+
+        return 1;
 }
 
 int dns_answer_find_cname_or_dname(DnsAnswer *a, const DnsResourceKey *key, DnsResourceRecord **ret, DnsAnswerFlags *flags) {