]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/resolve/resolved-dns-answer.c
resolved: add missing error code check when initializing DNS-over-TLS
[thirdparty/systemd.git] / src / resolve / resolved-dns-answer.c
index ab85754bf7a939ccc1b6656c65837eda0e97722d..0ee7340ffc6b36437de9d66ec0fb717c4a612fe6 100644 (file)
@@ -1,21 +1,6 @@
-/***
-  This file is part of systemd.
+/* SPDX-License-Identifier: LGPL-2.1+ */
 
-  Copyright 2014 Lennart Poettering
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
+#include <stdio.h>
 
 #include "alloc-util.h"
 #include "dns-domain.h"
@@ -23,7 +8,7 @@
 #include "resolved-dns-dnssec.h"
 #include "string-util.h"
 
-DnsAnswer *dns_answer_new(unsigned n) {
+DnsAnswer *dns_answer_new(size_t n) {
         DnsAnswer *a;
 
         a = malloc0(offsetof(DnsAnswer, items) + sizeof(DnsAnswerItem) * n);
@@ -36,15 +21,6 @@ DnsAnswer *dns_answer_new(unsigned n) {
         return a;
 }
 
-DnsAnswer *dns_answer_ref(DnsAnswer *a) {
-        if (!a)
-                return NULL;
-
-        assert(a->n_ref > 0);
-        a->n_ref++;
-        return a;
-}
-
 static void dns_answer_flush(DnsAnswer *a) {
         DnsResourceRecord *rr;
 
@@ -57,21 +33,15 @@ static void dns_answer_flush(DnsAnswer *a) {
         a->n_rrs = 0;
 }
 
-DnsAnswer *dns_answer_unref(DnsAnswer *a) {
-        if (!a)
-                return NULL;
-
-        assert(a->n_ref > 0);
-
-        if (a->n_ref == 1) {
-                dns_answer_flush(a);
-                free(a);
-        } else
-                a->n_ref--;
+static DnsAnswer *dns_answer_free(DnsAnswer *a) {
+        assert(a);
 
-        return NULL;
+        dns_answer_flush(a);
+        return mfree(a);
 }
 
+DEFINE_TRIVIAL_REF_UNREF_FUNC(DnsAnswer, dns_answer, dns_answer_free);
+
 static int dns_answer_add_raw(DnsAnswer *a, DnsResourceRecord *rr, int ifindex, DnsAnswerFlags flags) {
         assert(rr);
 
@@ -105,7 +75,7 @@ static int dns_answer_add_raw_all(DnsAnswer *a, DnsAnswer *source) {
 }
 
 int dns_answer_add(DnsAnswer *a, DnsResourceRecord *rr, int ifindex, DnsAnswerFlags flags) {
-        unsigned i;
+        size_t i;
         int r;
 
         assert(rr);
@@ -119,40 +89,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);
@@ -243,70 +206,6 @@ int dns_answer_match_key(DnsAnswer *a, const DnsResourceKey *key, DnsAnswerFlags
         return found;
 }
 
-int dns_answer_contains_rr(DnsAnswer *a, DnsResourceRecord *rr, DnsAnswerFlags *ret_flags) {
-        DnsAnswerFlags flags = 0, i_flags;
-        DnsResourceRecord *i;
-        bool found = false;
-        int r;
-
-        assert(rr);
-
-        DNS_ANSWER_FOREACH_FLAGS(i, i_flags, a) {
-                r = dns_resource_record_equal(i, rr);
-                if (r < 0)
-                        return r;
-                if (r == 0)
-                        continue;
-
-                if (!ret_flags)
-                        return 1;
-
-                if (found)
-                        flags &= i_flags;
-                else {
-                        flags = i_flags;
-                        found = true;
-                }
-        }
-
-        if (ret_flags)
-                *ret_flags = flags;
-
-        return found;
-}
-
-int dns_answer_contains_key(DnsAnswer *a, const DnsResourceKey *key, DnsAnswerFlags *ret_flags) {
-        DnsAnswerFlags flags = 0, i_flags;
-        DnsResourceRecord *i;
-        bool found = false;
-        int r;
-
-        assert(key);
-
-        DNS_ANSWER_FOREACH_FLAGS(i, i_flags, a) {
-                r = dns_resource_key_equal(i->key, key);
-                if (r < 0)
-                        return r;
-                if (r == 0)
-                        continue;
-
-                if (!ret_flags)
-                        return true;
-
-                if (found)
-                        flags &= i_flags;
-                else {
-                        flags = i_flags;
-                        found = true;
-                }
-        }
-
-        if (ret_flags)
-                *ret_flags = flags;
-
-        return found;
-}
-
 int dns_answer_contains_nsec_or_nsec3(DnsAnswer *a) {
         DnsResourceRecord *i;
 
@@ -441,8 +340,7 @@ int dns_answer_merge(DnsAnswer *a, DnsAnswer *b, DnsAnswer **ret) {
         if (r < 0)
                 return r;
 
-        *ret = k;
-        k = NULL;
+        *ret = TAKE_PTR(k);
 
         return 0;
 }
@@ -466,7 +364,7 @@ int dns_answer_extend(DnsAnswer **a, DnsAnswer *b) {
 int dns_answer_remove_by_key(DnsAnswer **a, const DnsResourceKey *key) {
         bool found = false, other = false;
         DnsResourceRecord *rr;
-        unsigned i;
+        size_t i;
         int r;
 
         assert(a);
@@ -517,8 +415,7 @@ int dns_answer_remove_by_key(DnsAnswer **a, const DnsResourceKey *key) {
                 }
 
                 dns_answer_unref(*a);
-                *a = copy;
-                copy = NULL;
+                *a = TAKE_PTR(copy);
 
                 return 1;
         }
@@ -552,7 +449,7 @@ int dns_answer_remove_by_key(DnsAnswer **a, const DnsResourceKey *key) {
 int dns_answer_remove_by_rr(DnsAnswer **a, DnsResourceRecord *rm) {
         bool found = false, other = false;
         DnsResourceRecord *rr;
-        unsigned i;
+        size_t i;
         int r;
 
         assert(a);
@@ -603,8 +500,7 @@ int dns_answer_remove_by_rr(DnsAnswer **a, DnsResourceRecord *rm) {
                 }
 
                 dns_answer_unref(*a);
-                *a = copy;
-                copy = NULL;
+                *a = TAKE_PTR(copy);
 
                 return 1;
         }
@@ -682,7 +578,7 @@ int dns_answer_move_by_key(DnsAnswer **to, DnsAnswer **from, const DnsResourceKe
 
 void dns_answer_order_by_scope(DnsAnswer *a, bool prefer_link_local) {
         DnsAnswerItem *items;
-        unsigned i, start, end;
+        size_t i, start, end;
 
         if (!a)
                 return;
@@ -713,7 +609,7 @@ void dns_answer_order_by_scope(DnsAnswer *a, bool prefer_link_local) {
         memcpy(a->items, items, sizeof(DnsAnswerItem) * a->n_rrs);
 }
 
-int dns_answer_reserve(DnsAnswer **a, unsigned n_free) {
+int dns_answer_reserve(DnsAnswer **a, size_t n_free) {
         DnsAnswer *n;
 
         assert(a);
@@ -722,7 +618,7 @@ int dns_answer_reserve(DnsAnswer **a, unsigned n_free) {
                 return 0;
 
         if (*a) {
-                unsigned ns;
+                size_t ns;
 
                 if ((*a)->n_ref > 1)
                         return -EBUSY;
@@ -750,7 +646,7 @@ int dns_answer_reserve(DnsAnswer **a, unsigned n_free) {
         return 0;
 }
 
-int dns_answer_reserve_or_clone(DnsAnswer **a, unsigned n_free) {
+int dns_answer_reserve_or_clone(DnsAnswer **a, size_t n_free) {
         _cleanup_(dns_answer_unrefp) DnsAnswer *n = NULL;
         int r;
 
@@ -777,8 +673,7 @@ int dns_answer_reserve_or_clone(DnsAnswer **a, unsigned n_free) {
                 return r;
 
         dns_answer_unref(*a);
-        *a = n;
-        n = NULL;
+        *a = TAKE_PTR(n);
 
         return 0;
 }
@@ -820,7 +715,7 @@ void dns_answer_dump(DnsAnswer *answer, FILE *f) {
         }
 }
 
-bool dns_answer_has_dname_for_cname(DnsAnswer *a, DnsResourceRecord *cname) {
+int dns_answer_has_dname_for_cname(DnsAnswer *a, DnsResourceRecord *cname) {
         DnsResourceRecord *rr;
         int r;
 
@@ -851,7 +746,6 @@ bool dns_answer_has_dname_for_cname(DnsAnswer *a, DnsResourceRecord *cname) {
                         return r;
                 if (r > 0)
                         return 1;
-
         }
 
         return 0;