-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <math.h>
assert(name);
- k = new0(DnsResourceKey, 1);
+ k = new(DnsResourceKey, 1);
if (!k)
return NULL;
- k->n_ref = 1;
- k->class = class;
- k->type = type;
- k->_name = name;
+ *k = (DnsResourceKey) {
+ .n_ref = 1,
+ .class = class,
+ .type = type,
+ ._name = name,
+ };
return k;
}
/* Static/const keys created with DNS_RESOURCE_KEY_CONST will
* set this to -1, they should not be reffed/unreffed */
- assert(k->n_ref != (unsigned) -1);
+ assert(k->n_ref != UINT_MAX);
assert(k->n_ref > 0);
k->n_ref++;
if (!k)
return NULL;
- assert(k->n_ref != (unsigned) -1);
+ assert(k->n_ref != UINT_MAX);
assert(k->n_ref > 0);
if (k->n_ref == 1) {
}
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;
+ int r;
- ret = CMP(x->type, y->type);
- if (ret != 0)
- return ret;
+ r = dns_name_compare_func(dns_resource_key_name(x), dns_resource_key_name(y));
+ if (r != 0)
+ return r;
- ret = CMP(x->class, y->class);
- if (ret != 0)
- return ret;
+ r = CMP(x->type, y->type);
+ if (r != 0)
+ return r;
- return 0;
+ return CMP(x->class, y->class);
}
DEFINE_HASH_OPS(dns_resource_key_hash_ops, DnsResourceKey, dns_resource_key_hash_func, dns_resource_key_compare_func);
return false;
/* We refuse merging const keys */
- if ((*a)->n_ref == (unsigned) -1)
+ if ((*a)->n_ref == UINT_MAX)
return false;
- if ((*b)->n_ref == (unsigned) -1)
+ if ((*b)->n_ref == UINT_MAX)
return false;
/* Already the same? */
DnsResourceRecord* dns_resource_record_new(DnsResourceKey *key) {
DnsResourceRecord *rr;
- rr = new0(DnsResourceRecord, 1);
+ rr = new(DnsResourceRecord, 1);
if (!rr)
return NULL;
- rr->n_ref = 1;
- rr->key = dns_resource_key_ref(key);
- rr->expiry = USEC_INFINITY;
- rr->n_skip_labels_signer = rr->n_skip_labels_source = (unsigned) -1;
+ *rr = (DnsResourceRecord) {
+ .n_ref = 1,
+ .key = dns_resource_key_ref(key),
+ .expiry = USEC_INFINITY,
+ .n_skip_labels_signer = UINT_MAX,
+ .n_skip_labels_source = UINT_MAX,
+ };
return rr;
}
/* Returns the RRset's signer, if it is known. */
- if (rr->n_skip_labels_signer == (unsigned) -1)
+ if (rr->n_skip_labels_signer == UINT_MAX)
return -ENODATA;
n = dns_resource_key_name(rr->key);
/* Returns the RRset's synthesizing source, if it is known. */
- if (rr->n_skip_labels_source == (unsigned) -1)
+ if (rr->n_skip_labels_source == UINT_MAX)
return -ENODATA;
n = dns_resource_key_name(rr->key);
/* Returns > 0 if the RR is generated from a wildcard, and is not the asterisk name itself */
- if (rr->n_skip_labels_source == (unsigned) -1)
+ if (rr->n_skip_labels_source == UINT_MAX)
return -ENODATA;
if (rr->n_skip_labels_source == 0)
DnsTxtItem *j;
LIST_FOREACH(items, j, rr->txt.items) {
- siphash24_compress(j->data, j->length, state);
+ siphash24_compress_safe(j->data, j->length, state);
/* Add an extra NUL byte, so that "a" followed by "b" doesn't result in the same hash as "ab"
* followed by "". */
case DNS_TYPE_SSHFP:
siphash24_compress(&rr->sshfp.algorithm, sizeof(rr->sshfp.algorithm), state);
siphash24_compress(&rr->sshfp.fptype, sizeof(rr->sshfp.fptype), state);
- siphash24_compress(rr->sshfp.fingerprint, rr->sshfp.fingerprint_size, state);
+ siphash24_compress_safe(rr->sshfp.fingerprint, rr->sshfp.fingerprint_size, state);
break;
case DNS_TYPE_DNSKEY:
siphash24_compress(&rr->dnskey.flags, sizeof(rr->dnskey.flags), state);
siphash24_compress(&rr->dnskey.protocol, sizeof(rr->dnskey.protocol), state);
siphash24_compress(&rr->dnskey.algorithm, sizeof(rr->dnskey.algorithm), state);
- siphash24_compress(rr->dnskey.key, rr->dnskey.key_size, state);
+ siphash24_compress_safe(rr->dnskey.key, rr->dnskey.key_size, state);
break;
case DNS_TYPE_RRSIG:
siphash24_compress(&rr->rrsig.inception, sizeof(rr->rrsig.inception), state);
siphash24_compress(&rr->rrsig.key_tag, sizeof(rr->rrsig.key_tag), state);
dns_name_hash_func(rr->rrsig.signer, state);
- siphash24_compress(rr->rrsig.signature, rr->rrsig.signature_size, state);
+ siphash24_compress_safe(rr->rrsig.signature, rr->rrsig.signature_size, state);
break;
case DNS_TYPE_NSEC:
siphash24_compress(&rr->ds.key_tag, sizeof(rr->ds.key_tag), state);
siphash24_compress(&rr->ds.algorithm, sizeof(rr->ds.algorithm), state);
siphash24_compress(&rr->ds.digest_type, sizeof(rr->ds.digest_type), state);
- siphash24_compress(rr->ds.digest, rr->ds.digest_size, state);
+ siphash24_compress_safe(rr->ds.digest, rr->ds.digest_size, state);
break;
case DNS_TYPE_NSEC3:
siphash24_compress(&rr->nsec3.algorithm, sizeof(rr->nsec3.algorithm), state);
siphash24_compress(&rr->nsec3.flags, sizeof(rr->nsec3.flags), state);
siphash24_compress(&rr->nsec3.iterations, sizeof(rr->nsec3.iterations), state);
- siphash24_compress(rr->nsec3.salt, rr->nsec3.salt_size, state);
- siphash24_compress(rr->nsec3.next_hashed_name, rr->nsec3.next_hashed_name_size, state);
+ siphash24_compress_safe(rr->nsec3.salt, rr->nsec3.salt_size, state);
+ siphash24_compress_safe(rr->nsec3.next_hashed_name, rr->nsec3.next_hashed_name_size, state);
/* FIXME: We leave the bitmaps out */
break;
siphash24_compress(&rr->tlsa.cert_usage, sizeof(rr->tlsa.cert_usage), state);
siphash24_compress(&rr->tlsa.selector, sizeof(rr->tlsa.selector), state);
siphash24_compress(&rr->tlsa.matching_type, sizeof(rr->tlsa.matching_type), state);
- siphash24_compress(rr->tlsa.data, rr->tlsa.data_size, state);
+ siphash24_compress_safe(rr->tlsa.data, rr->tlsa.data_size, state);
break;
case DNS_TYPE_CAA:
siphash24_compress(&rr->caa.flags, sizeof(rr->caa.flags), state);
string_hash_func(rr->caa.tag, state);
- siphash24_compress(rr->caa.value, rr->caa.value_size, state);
+ siphash24_compress_safe(rr->caa.value, rr->caa.value_size, state);
break;
case DNS_TYPE_OPENPGPKEY:
default:
- siphash24_compress(rr->generic.data, rr->generic.data_size, state);
+ siphash24_compress_safe(rr->generic.data, rr->generic.data_size, state);
break;
}
}
-static int dns_resource_record_compare_func(const DnsResourceRecord *x, const DnsResourceRecord *y) {
+int dns_resource_record_compare_func(const DnsResourceRecord *x, const DnsResourceRecord *y) {
int r;
r = dns_resource_key_compare_func(x->key, y->key);
if (r != 0)
return r;
- if (dns_resource_record_equal(x, y))
+ if (dns_resource_record_payload_equal(x, y) > 0)
return 0;
/* We still use CMP() here, even though don't implement proper
return NULL;
copy->nsec3.salt_size = rr->nsec3.salt_size;
copy->nsec3.next_hashed_name = memdup(rr->nsec3.next_hashed_name, rr->nsec3.next_hashed_name_size);
- if (!copy->nsec3.next_hashed_name_size)
+ if (!copy->nsec3.next_hashed_name)
return NULL;
copy->nsec3.next_hashed_name_size = rr->nsec3.next_hashed_name_size;
copy->nsec3.types = bitmap_copy(rr->nsec3.types);
return 1;
}
+bool dns_resource_record_is_link_local_address(DnsResourceRecord *rr) {
+ assert(rr);
+
+ if (rr->key->class != DNS_CLASS_IN)
+ return false;
+
+ if (rr->key->type == DNS_TYPE_A)
+ return in4_addr_is_link_local(&rr->a.in_addr);
+
+ if (rr->key->type == DNS_TYPE_AAAA)
+ return in6_addr_is_link_local(&rr->aaaa.in6_addr);
+
+ return false;
+}
+
+int dns_resource_record_get_cname_target(DnsResourceKey *key, DnsResourceRecord *cname, char **ret) {
+ _cleanup_free_ char *d = NULL;
+ int r;
+
+ assert(key);
+ assert(cname);
+
+ if (key->class != cname->key->class && key->class != DNS_CLASS_ANY)
+ return -EUNATCH;
+
+ if (cname->key->type == DNS_TYPE_CNAME) {
+ r = dns_name_equal(dns_resource_key_name(key),
+ dns_resource_key_name(cname->key));
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return -EUNATCH; /* CNAME RR key doesn't actually match the original key */
+
+ d = strdup(cname->cname.name);
+ if (!d)
+ return -ENOMEM;
+
+ } else if (cname->key->type == DNS_TYPE_DNAME) {
+
+ r = dns_name_change_suffix(
+ dns_resource_key_name(key),
+ dns_resource_key_name(cname->key),
+ cname->dname.name,
+ &d);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return -EUNATCH; /* DNAME RR key doesn't actually match the original key */
+
+ } else
+ return -EUNATCH; /* Not a CNAME/DNAME RR, hence doesn't match the proposition either */
+
+ *ret = TAKE_PTR(d);
+ return 0;
+}
+
DnsTxtItem *dns_txt_item_free_all(DnsTxtItem *i) {
DnsTxtItem *n;