resolved: optionally, allocate DnsResourceKey objects on the stack
Sometimes when looking up entries in hashmaps indexed by a DnsResourceKey it is helpful not having to allocate a full DnsResourceKey dynamically just to use it as search key. Instead, optionally allow allocation of a DnsResourceKey on the stack. Resource keys allocated like that of course are subject to other lifetime cycles than the usual Resource keys, hence initialize the reference counter to to (unsigned) -1. While we are at it, remove the prototype for dns_resource_key_new_dname() which was never implemented.
This commit is contained in:
parent
2a44bec4f6
commit
1b4f6e79ec
|
@ -522,7 +522,6 @@ fail:
|
|||
}
|
||||
|
||||
static DnsCacheItem *dns_cache_get_by_key_follow_cname_dname_nsec(DnsCache *c, DnsResourceKey *k) {
|
||||
_cleanup_(dns_resource_key_unrefp) DnsResourceKey *nsec_key = NULL, *cname_key = NULL;
|
||||
DnsCacheItem *i;
|
||||
const char *n;
|
||||
int r;
|
||||
|
@ -540,35 +539,23 @@ static DnsCacheItem *dns_cache_get_by_key_follow_cname_dname_nsec(DnsCache *c, D
|
|||
n = DNS_RESOURCE_KEY_NAME(k);
|
||||
|
||||
/* Check if we have an NSEC record instead for the name. */
|
||||
nsec_key = dns_resource_key_new(k->class, DNS_TYPE_NSEC, n);
|
||||
if (!nsec_key)
|
||||
return NULL;
|
||||
|
||||
i = hashmap_get(c->by_key, nsec_key);
|
||||
i = hashmap_get(c->by_key, &DNS_RESOURCE_KEY_CONST(k->class, DNS_TYPE_NSEC, n));
|
||||
if (i)
|
||||
return i;
|
||||
|
||||
/* Check if we have a CNAME record instead */
|
||||
cname_key = dns_resource_key_new_cname(k);
|
||||
if (!cname_key)
|
||||
return NULL;
|
||||
i = hashmap_get(c->by_key, cname_key);
|
||||
i = hashmap_get(c->by_key, &DNS_RESOURCE_KEY_CONST(k->class, DNS_TYPE_CNAME, n));
|
||||
if (i)
|
||||
return i;
|
||||
|
||||
/* OK, let's look for cached DNAME records. */
|
||||
for (;;) {
|
||||
_cleanup_(dns_resource_key_unrefp) DnsResourceKey *dname_key = NULL;
|
||||
char label[DNS_LABEL_MAX];
|
||||
|
||||
if (isempty(n))
|
||||
return NULL;
|
||||
|
||||
dname_key = dns_resource_key_new(k->class, DNS_TYPE_DNAME, n);
|
||||
if (!dname_key)
|
||||
return NULL;
|
||||
|
||||
i = hashmap_get(c->by_key, dname_key);
|
||||
i = hashmap_get(c->by_key, &DNS_RESOURCE_KEY_CONST(k->class, DNS_TYPE_DNAME, n));
|
||||
if (i)
|
||||
return i;
|
||||
|
||||
|
|
|
@ -51,12 +51,6 @@ DnsResourceKey* dns_resource_key_new(uint16_t class, uint16_t type, const char *
|
|||
return k;
|
||||
}
|
||||
|
||||
DnsResourceKey* dns_resource_key_new_cname(const DnsResourceKey *key) {
|
||||
assert(key);
|
||||
|
||||
return dns_resource_key_new(key->class, DNS_TYPE_CNAME, DNS_RESOURCE_KEY_NAME(key));
|
||||
}
|
||||
|
||||
DnsResourceKey* dns_resource_key_new_redirect(const DnsResourceKey *key, const DnsResourceRecord *cname) {
|
||||
int r;
|
||||
|
||||
|
@ -137,6 +131,10 @@ DnsResourceKey* dns_resource_key_ref(DnsResourceKey *k) {
|
|||
if (!k)
|
||||
return NULL;
|
||||
|
||||
/* 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 > 0);
|
||||
k->n_ref++;
|
||||
|
||||
|
@ -147,6 +145,7 @@ DnsResourceKey* dns_resource_key_unref(DnsResourceKey *k) {
|
|||
if (!k)
|
||||
return NULL;
|
||||
|
||||
assert(k->n_ref != (unsigned) -1);
|
||||
assert(k->n_ref > 0);
|
||||
|
||||
if (k->n_ref == 1) {
|
||||
|
|
|
@ -78,6 +78,19 @@ struct DnsResourceKey {
|
|||
char *_name; /* don't access directy, use DNS_RESOURCE_KEY_NAME()! */
|
||||
};
|
||||
|
||||
/* Creates a temporary resource key. This is only useful to quickly
|
||||
* look up something, without allocating a full DnsResourceKey object
|
||||
* for it. Note that it is not OK to take references to this kind of
|
||||
* resource key object. */
|
||||
#define DNS_RESOURCE_KEY_CONST(c, t, n) \
|
||||
((DnsResourceKey) { \
|
||||
.n_ref = (unsigned) -1, \
|
||||
.class = c, \
|
||||
.type = t, \
|
||||
._name = (char*) n, \
|
||||
})
|
||||
|
||||
|
||||
struct DnsTxtItem {
|
||||
size_t length;
|
||||
LIST_FIELDS(DnsTxtItem, items);
|
||||
|
@ -221,8 +234,6 @@ static inline const char* DNS_RESOURCE_KEY_NAME(const DnsResourceKey *key) {
|
|||
}
|
||||
|
||||
DnsResourceKey* dns_resource_key_new(uint16_t class, uint16_t type, const char *name);
|
||||
DnsResourceKey* dns_resource_key_new_cname(const DnsResourceKey *key);
|
||||
DnsResourceKey* dns_resource_key_new_dname(const DnsResourceKey *key);
|
||||
DnsResourceKey* dns_resource_key_new_redirect(const DnsResourceKey *key, const DnsResourceRecord *cname);
|
||||
int dns_resource_key_new_append_suffix(DnsResourceKey **ret, DnsResourceKey *key, char *name);
|
||||
DnsResourceKey* dns_resource_key_new_consume(uint16_t class, uint16_t type, char *name);
|
||||
|
|
|
@ -163,7 +163,6 @@ static int dns_zone_link_item(DnsZone *z, DnsZoneItem *i) {
|
|||
}
|
||||
|
||||
static int dns_zone_item_probe_start(DnsZoneItem *i) {
|
||||
_cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
|
||||
DnsTransaction *t;
|
||||
int r;
|
||||
|
||||
|
@ -172,12 +171,14 @@ static int dns_zone_item_probe_start(DnsZoneItem *i) {
|
|||
if (i->probe_transaction)
|
||||
return 0;
|
||||
|
||||
key = dns_resource_key_new(i->rr->key->class, DNS_TYPE_ANY, DNS_RESOURCE_KEY_NAME(i->rr->key));
|
||||
if (!key)
|
||||
return -ENOMEM;
|
||||
|
||||
t = dns_scope_find_transaction(i->scope, key, false);
|
||||
t = dns_scope_find_transaction(i->scope, &DNS_RESOURCE_KEY_CONST(i->rr->key->class, DNS_TYPE_ANY, DNS_RESOURCE_KEY_NAME(i->rr->key)), false);
|
||||
if (!t) {
|
||||
_cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
|
||||
|
||||
key = dns_resource_key_new(i->rr->key->class, DNS_TYPE_ANY, DNS_RESOURCE_KEY_NAME(i->rr->key));
|
||||
if (!key)
|
||||
return -ENOMEM;
|
||||
|
||||
r = dns_transaction_new(&t, i->scope, key);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
|
Loading…
Reference in a new issue