]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: compare dns question arrays properly 758/head
authorLennart Poettering <lennart@poettering.net>
Tue, 28 Jul 2015 16:38:54 +0000 (18:38 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 28 Jul 2015 16:38:54 +0000 (18:38 +0200)
Let's optimize things a bit and properly compare DNS question arrays,
instead of checking if they are mutual supersets. This also makes ANY
query handling more accurate.

src/resolve/resolved-dns-question.c
src/resolve/resolved-dns-question.h
src/resolve/resolved-dns-transaction.c

index 4d71f5e3d400385a932ffe3e57db1fff13bec8ed..0efe740d1a97c25e39c492a59997926a616c2df5 100644 (file)
@@ -188,6 +188,46 @@ int dns_question_is_superset(DnsQuestion *q, DnsQuestion *other) {
         return 1;
 }
 
+int dns_question_contains(DnsQuestion *a, DnsResourceKey *k) {
+        unsigned j;
+        int r;
+
+        assert(a);
+        assert(k);
+
+        for (j = 0; j < a->n_keys; j++) {
+                r = dns_resource_key_equal(a->keys[j], k);
+                if (r != 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+int dns_question_is_equal(DnsQuestion *a, DnsQuestion *b) {
+        unsigned j;
+        int r;
+
+        assert(a);
+        assert(b);
+
+        /* Checks if all keys in a are also contained b, and vice versa */
+
+        for (j = 0; j < a->n_keys; j++) {
+                r = dns_question_contains(b, a->keys[j]);
+                if (r <= 0)
+                        return r;
+        }
+
+        for (j = 0; j < b->n_keys; j++) {
+                r = dns_question_contains(a, b->keys[j]);
+                if (r <= 0)
+                        return r;
+        }
+
+        return 1;
+}
+
 int dns_question_cname_redirect(DnsQuestion *q, const char *name, DnsQuestion **ret) {
         _cleanup_(dns_question_unrefp) DnsQuestion *n = NULL;
         bool same = true;
index 4ba2fe9f0ed215fe07c39918d58d043b3999271a..fc98677798cb3c98dbe315551d2faff966c816c5 100644 (file)
@@ -43,6 +43,8 @@ int dns_question_matches_rr(DnsQuestion *q, DnsResourceRecord *rr);
 int dns_question_matches_cname(DnsQuestion *q, DnsResourceRecord *rr);
 int dns_question_is_valid(DnsQuestion *q);
 int dns_question_is_superset(DnsQuestion *q, DnsQuestion *other);
+int dns_question_contains(DnsQuestion *a, DnsResourceKey *k);
+int dns_question_is_equal(DnsQuestion *a, DnsQuestion *b);
 
 int dns_question_cname_redirect(DnsQuestion *q, const char *name, DnsQuestion **ret);
 
index b235fda3d2b9086085daa5abdc719df8e0034d31..8a93b265c6b04fe01c13c4343b0fad3a7134f0fd 100644 (file)
@@ -406,8 +406,8 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
         }
 
         /* Only consider responses with equivalent query section to the request */
-        if (!dns_question_is_superset(p->question, t->question) ||
-            !dns_question_is_superset(t->question, p->question)) {
+        r = dns_question_is_equal(p->question, t->question);
+        if (r <= 0) {
                 dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
                 return;
         }