]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: when adding RR to an answer, avoid comparing keys twice
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 27 Feb 2019 09:37:40 +0000 (10:37 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 4 Mar 2019 14:53:37 +0000 (15:53 +0100)
We'd call dns_resource_record_equal(), which calls dns_resource_key_equal()
internally, and then dns_resource_key_equal() a second time. Let's be
a bit smarter, and call dns_resource_key_equal() only once.

(before)
dns_resource_key_hash_func_count=514
dns_resource_key_compare_func_count=275
dns_resource_key_equal_count=62371
4.13s user 0.01s system 99% cpu 4.153 total

(after)
dns_resource_key_hash_func_count=514
dns_resource_key_compare_func_count=276
dns_resource_key_equal_count=31337
2.13s user 0.01s system 99% cpu 2.139 total

src/resolve/resolved-dns-answer.c
src/resolve/resolved-dns-packet.c

index d7252d3dac133ac287d679c5ca133dcfa07cc6dd..44dc6552b4f06cbd49cd270799365105923fd889 100644 (file)
@@ -87,40 +87,33 @@ int dns_answer_add(DnsAnswer *a, DnsResourceRecord *rr, int ifindex, DnsAnswerFl
                 if (a->items[i].ifindex != ifindex)
                         continue;
 
-                r = dns_resource_record_equal(a->items[i].rr, rr);
+                r = dns_resource_key_equal(a->items[i].rr->key, rr->key);
                 if (r < 0)
                         return r;
-                if (r > 0) {
-                        /* Don't mix contradicting TTLs (see below) */
-                        if ((rr->ttl == 0) != (a->items[i].rr->ttl == 0))
-                                return -EINVAL;
-
-                        /* Entry already exists, keep the entry with
-                         * the higher RR. */
-                        if (rr->ttl > a->items[i].rr->ttl) {
-                                dns_resource_record_ref(rr);
-                                dns_resource_record_unref(a->items[i].rr);
-                                a->items[i].rr = rr;
-                        }
+                if (r == 0)
+                        continue;
 
-                        a->items[i].flags |= flags;
-                        return 0;
-                }
+                /* There's already an RR of the same RRset in place! Let's see if the TTLs more or less
+                 * match. We don't really care if they match precisely, but we do care whether one is 0 and
+                 * the other is not. See RFC 2181, Section 5.2. */
+                if ((rr->ttl == 0) != (a->items[i].rr->ttl == 0))
+                        return -EINVAL;
 
-                r = dns_resource_key_equal(a->items[i].rr->key, rr->key);
+                r = dns_resource_record_payload_equal(a->items[i].rr, rr);
                 if (r < 0)
                         return r;
-                if (r > 0) {
-                        /* There's already an RR of the same RRset in
-                         * place! Let's see if the TTLs more or less
-                         * match. We don't really care if they match
-                         * precisely, but we do care whether one is 0
-                         * and the other is not. See RFC 2181, Section
-                         * 5.2. */
-
-                        if ((rr->ttl == 0) != (a->items[i].rr->ttl == 0))
-                                return -EINVAL;
+                if (r == 0)
+                        continue;
+
+                /* Entry already exists, keep the entry with the higher RR. */
+                if (rr->ttl > a->items[i].rr->ttl) {
+                        dns_resource_record_ref(rr);
+                        dns_resource_record_unref(a->items[i].rr);
+                        a->items[i].rr = rr;
                 }
+
+                a->items[i].flags |= flags;
+                return 0;
         }
 
         return dns_answer_add_raw(a, rr, ifindex, flags);
index ff58a9d810143e2f74108ad818d4c4f43cbff458..278546da8489633ecc5bd8525aca5ea30d650a66 100644 (file)
@@ -2258,7 +2258,7 @@ static int dns_packet_extract_answer(DnsPacket *p, DnsAnswer **ret_answer) {
                                          * be contained in questions, never in replies. Crappy
                                          * Belkin routers copy the OPT data for example, hence let's
                                          * detect this so that we downgrade early. */
-                                        log_debug("OPT RR contained RFC6975 data, ignoring.");
+                                        log_debug("OPT RR contains RFC6975 data, ignoring.");
                                         bad_opt = true;
                                         continue;
                                 }