]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/resolve/resolved-dns-rr.c
travis: turn on nonnull-attribute on Fuzzit
[thirdparty/systemd.git] / src / resolve / resolved-dns-rr.c
index 26d2cbcc200af37c26af07bea3cf27c8e78a86a4..6ba26a24b2c3f2cc02d6f66851831e0a7844f831 100644 (file)
@@ -1,22 +1,4 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
-/***
-  This file is part of systemd.
-
-  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 <math.h>
 
@@ -25,6 +7,7 @@
 #include "dns-type.h"
 #include "escape.h"
 #include "hexdecoct.h"
+#include "memory-util.h"
 #include "resolved-dns-dnssec.h"
 #include "resolved-dns-packet.h"
 #include "resolved-dns-rr.h"
@@ -95,7 +78,7 @@ int dns_resource_key_new_append_suffix(DnsResourceKey **ret, DnsResourceKey *key
                 return 0;
         }
 
-        r = dns_name_concat(dns_resource_key_name(key), name, &joined);
+        r = dns_name_concat(dns_resource_key_name(key), name, 0, &joined);
         if (r < 0)
                 return r;
 
@@ -240,7 +223,7 @@ int dns_resource_key_match_rr(const DnsResourceKey *key, DnsResourceRecord *rr,
         if (search_domain) {
                 _cleanup_free_ char *joined = NULL;
 
-                r = dns_name_concat(dns_resource_key_name(key), search_domain, &joined);
+                r = dns_name_concat(dns_resource_key_name(key), search_domain, 0, &joined);
                 if (r < 0)
                         return r;
 
@@ -272,7 +255,7 @@ int dns_resource_key_match_cname_or_dname(const DnsResourceKey *key, const DnsRe
         if (search_domain) {
                 _cleanup_free_ char *joined = NULL;
 
-                r = dns_name_concat(dns_resource_key_name(key), search_domain, &joined);
+                r = dns_name_concat(dns_resource_key_name(key), search_domain, 0, &joined);
                 if (r < 0)
                         return r;
 
@@ -300,9 +283,7 @@ int dns_resource_key_match_soa(const DnsResourceKey *key, const DnsResourceKey *
         return dns_name_endswith(dns_resource_key_name(key), dns_resource_key_name(soa));
 }
 
-static void dns_resource_key_hash_func(const void *i, struct siphash *state) {
-        const DnsResourceKey *k = i;
-
+static void dns_resource_key_hash_func(const DnsResourceKey *k, struct siphash *state) {
         assert(k);
 
         dns_name_hash_func(dns_resource_key_name(k), state);
@@ -310,31 +291,25 @@ static void dns_resource_key_hash_func(const void *i, struct siphash *state) {
         siphash24_compress(&k->type, sizeof(k->type), state);
 }
 
-static int dns_resource_key_compare_func(const void *a, const void *b) {
-        const DnsResourceKey *x = a, *y = b;
+static int dns_resource_key_compare_func(const DnsResourceKey *x, const DnsResourceKey *y) {
         int ret;
 
         ret = dns_name_compare_func(dns_resource_key_name(x), dns_resource_key_name(y));
         if (ret != 0)
                 return ret;
 
-        if (x->type < y->type)
-                return -1;
-        if (x->type > y->type)
-                return 1;
+        ret = CMP(x->type, y->type);
+        if (ret != 0)
+                return ret;
 
-        if (x->class < y->class)
-                return -1;
-        if (x->class > y->class)
-                return 1;
+        ret = CMP(x->class, y->class);
+        if (ret != 0)
+                return ret;
 
         return 0;
 }
 
-const struct hash_ops dns_resource_key_hash_ops = {
-        .hash = dns_resource_key_hash_func,
-        .compare = dns_resource_key_compare_func
-};
+DEFINE_HASH_OPS(dns_resource_key_hash_ops, DnsResourceKey, dns_resource_key_hash_func, dns_resource_key_compare_func);
 
 char* dns_resource_key_to_string(const DnsResourceKey *key, char *buf, size_t buf_size) {
         const char *c, *t;
@@ -349,7 +324,7 @@ char* dns_resource_key_to_string(const DnsResourceKey *key, char *buf, size_t bu
         snprintf(buf, buf_size, "%s %s%s%.0u %s%s%.0u",
                  dns_resource_key_name(key),
                  strempty(c), c ? "" : "CLASS", c ? 0 : key->class,
-                 strempty(t), t ? "" : "TYPE", t ? 0 : key->class);
+                 strempty(t), t ? "" : "TYPE", t ? 0 : key->type);
 
         return ans;
 }
@@ -419,26 +394,8 @@ DnsResourceRecord* dns_resource_record_new_full(uint16_t class, uint16_t type, c
         return dns_resource_record_new(key);
 }
 
-DnsResourceRecord* dns_resource_record_ref(DnsResourceRecord *rr) {
-        if (!rr)
-                return NULL;
-
-        assert(rr->n_ref > 0);
-        rr->n_ref++;
-
-        return rr;
-}
-
-DnsResourceRecord* dns_resource_record_unref(DnsResourceRecord *rr) {
-        if (!rr)
-                return NULL;
-
-        assert(rr->n_ref > 0);
-
-        if (rr->n_ref > 1) {
-                rr->n_ref--;
-                return NULL;
-        }
+static DnsResourceRecord* dns_resource_record_free(DnsResourceRecord *rr) {
+        assert(rr);
 
         if (rr->key) {
                 switch(rr->key->type) {
@@ -517,9 +474,13 @@ DnsResourceRecord* dns_resource_record_unref(DnsResourceRecord *rr) {
 
                 case DNS_TYPE_OPENPGPKEY:
                 default:
-                        free(rr->generic.data);
+                        if (!rr->unparseable)
+                                free(rr->generic.data);
                 }
 
+                if (rr->unparseable)
+                        free(rr->generic.data);
+
                 free(rr->wire_format);
                 dns_resource_key_unref(rr->key);
         }
@@ -528,6 +489,8 @@ DnsResourceRecord* dns_resource_record_unref(DnsResourceRecord *rr) {
         return mfree(rr);
 }
 
+DEFINE_TRIVIAL_REF_UNREF_FUNC(DnsResourceRecord, dns_resource_record, dns_resource_record_free);
+
 int dns_resource_record_new_reverse(DnsResourceRecord **ret, int family, const union in_addr_union *address, const char *hostname) {
         _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
         _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
@@ -556,8 +519,7 @@ int dns_resource_record_new_reverse(DnsResourceRecord **ret, int family, const u
         if (!rr->ptr.name)
                 return -ENOMEM;
 
-        *ret = rr;
-        rr = NULL;
+        *ret = TAKE_PTR(rr);
 
         return 0;
 }
@@ -594,20 +556,12 @@ int dns_resource_record_new_address(DnsResourceRecord **ret, int family, const u
 
 #define FIELD_EQUAL(a, b, field) \
         ((a).field ## _size == (b).field ## _size &&  \
-         memcmp((a).field, (b).field, (a).field ## _size) == 0)
+         memcmp_safe((a).field, (b).field, (a).field ## _size) == 0)
 
-int dns_resource_record_equal(const DnsResourceRecord *a, const DnsResourceRecord *b) {
+int dns_resource_record_payload_equal(const DnsResourceRecord *a, const DnsResourceRecord *b) {
         int r;
 
-        assert(a);
-        assert(b);
-
-        if (a == b)
-                return 1;
-
-        r = dns_resource_key_equal(a->key, b->key);
-        if (r <= 0)
-                return r;
+        /* Check if a and b are the same, but don't look at their keys */
 
         if (a->unparseable != b->unparseable)
                 return 0;
@@ -731,6 +685,22 @@ int dns_resource_record_equal(const DnsResourceRecord *a, const DnsResourceRecor
         }
 }
 
+int dns_resource_record_equal(const DnsResourceRecord *a, const DnsResourceRecord *b) {
+        int r;
+
+        assert(a);
+        assert(b);
+
+        if (a == b)
+                return 1;
+
+        r = dns_resource_key_equal(a->key, b->key);
+        if (r <= 0)
+                return r;
+
+        return dns_resource_record_payload_equal(a, b);
+}
+
 static char* format_location(uint32_t latitude, uint32_t longitude, uint32_t altitude,
                              uint8_t size, uint8_t horiz_pre, uint8_t vert_pre) {
         char *s;
@@ -766,7 +736,7 @@ static int format_timestamp_dns(char *buf, size_t l, time_t sec) {
         struct tm tm;
 
         assert(buf);
-        assert(l > strlen("YYYYMMDDHHmmSS"));
+        assert(l > STRLEN("YYYYMMDDHHmmSS"));
 
         if (!gmtime_r(&sec, &tm))
                 return -EINVAL;
@@ -993,7 +963,6 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
         case DNS_TYPE_DNSKEY: {
                 _cleanup_free_ char *alg = NULL;
                 char *ss;
-                int n;
                 uint16_t key_tag;
 
                 key_tag = dnssec_keytag(rr, true);
@@ -1002,16 +971,15 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
                 if (r < 0)
                         return NULL;
 
-                r = asprintf(&s, "%s %u %u %s %n",
+                r = asprintf(&s, "%s %u %u %s",
                              k,
                              rr->dnskey.flags,
                              rr->dnskey.protocol,
-                             alg,
-                             &n);
+                             alg);
                 if (r < 0)
                         return NULL;
 
-                r = base64_append(&s, n,
+                r = base64_append(&s, r,
                                   rr->dnskey.key, rr->dnskey.key_size,
                                   8, columns());
                 if (r < 0)
@@ -1035,9 +1003,8 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
 
         case DNS_TYPE_RRSIG: {
                 _cleanup_free_ char *alg = NULL;
-                char expiration[strlen("YYYYMMDDHHmmSS") + 1], inception[strlen("YYYYMMDDHHmmSS") + 1];
+                char expiration[STRLEN("YYYYMMDDHHmmSS") + 1], inception[STRLEN("YYYYMMDDHHmmSS") + 1];
                 const char *type;
-                int n;
 
                 type = dns_type_to_string(rr->rrsig.type_covered);
 
@@ -1056,7 +1023,7 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
                 /* TYPE?? follows
                  * http://tools.ietf.org/html/rfc3597#section-5 */
 
-                r = asprintf(&s, "%s %s%.*u %s %u %u %s %s %u %s %n",
+                r = asprintf(&s, "%s %s%.*u %s %u %u %s %s %u %s",
                              k,
                              type ?: "TYPE",
                              type ? 0 : 1, type ? 0u : (unsigned) rr->rrsig.type_covered,
@@ -1066,12 +1033,11 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
                              expiration,
                              inception,
                              rr->rrsig.key_tag,
-                             rr->rrsig.signer,
-                             &n);
+                             rr->rrsig.signer);
                 if (r < 0)
                         return NULL;
 
-                r = base64_append(&s, n,
+                r = base64_append(&s, r,
                                   rr->rrsig.signature, rr->rrsig.signature_size,
                                   8, columns());
                 if (r < 0)
@@ -1177,15 +1143,11 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
         }
 
         case DNS_TYPE_OPENPGPKEY: {
-                int n;
-
-                r = asprintf(&s, "%s %n",
-                             k,
-                             &n);
+                r = asprintf(&s, "%s", k);
                 if (r < 0)
                         return NULL;
 
-                r = base64_append(&s, n,
+                r = base64_append(&s, r,
                                   rr->generic.data, rr->generic.data_size,
                                   8, columns());
                 if (r < 0)
@@ -1242,7 +1204,6 @@ ssize_t dns_resource_record_payload(DnsResourceRecord *rr, void **out) {
                 *out = rr->tlsa.data;
                 return rr->tlsa.data_size;
 
-
         case DNS_TYPE_OPENPGPKEY:
         default:
                 *out = rr->generic.data;
@@ -1377,9 +1338,7 @@ int dns_resource_record_is_synthetic(DnsResourceRecord *rr) {
         return !r;
 }
 
-void dns_resource_record_hash_func(const void *i, struct siphash *state) {
-        const DnsResourceRecord *rr = i;
-
+void dns_resource_record_hash_func(const DnsResourceRecord *rr, struct siphash *state) {
         assert(rr);
 
         dns_resource_key_hash_func(rr->key, state);
@@ -1520,27 +1479,22 @@ void dns_resource_record_hash_func(const void *i, struct siphash *state) {
         }
 }
 
-static int dns_resource_record_compare_func(const void *a, const void *b) {
-        const DnsResourceRecord *x = a, *y = b;
-        int ret;
+static int dns_resource_record_compare_func(const DnsResourceRecord *x, const DnsResourceRecord *y) {
+        int r;
 
-        ret = dns_resource_key_compare_func(x->key, y->key);
-        if (ret != 0)
-                return ret;
+        r = dns_resource_key_compare_func(x->key, y->key);
+        if (r != 0)
+                return r;
 
         if (dns_resource_record_equal(x, y))
                 return 0;
 
-        /* This is a bit dirty, we don't implement proper ordering, but
-         * the hashtable doesn't need ordering anyway, hence we don't
-         * care. */
-        return x < y ? -1 : 1;
+        /* We still use CMP() here, even though don't implement proper
+         * ordering, since the hashtable doesn't need ordering anyway. */
+        return CMP(x, y);
 }
 
-const struct hash_ops dns_resource_record_hash_ops = {
-        .hash = dns_resource_record_hash_func,
-        .compare = dns_resource_record_compare_func,
-};
+DEFINE_HASH_OPS(dns_resource_record_hash_ops, DnsResourceRecord, dns_resource_record_hash_func, dns_resource_record_compare_func);
 
 DnsResourceRecord *dns_resource_record_copy(DnsResourceRecord *rr) {
         _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *copy = NULL;
@@ -1730,8 +1684,7 @@ DnsResourceRecord *dns_resource_record_copy(DnsResourceRecord *rr) {
                 break;
         }
 
-        t = copy;
-        copy = NULL;
+        t = TAKE_PTR(copy);
 
         return t;
 }