From 1b4f6e79ec51a57003896a0b605fba427b4a98d2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 3 Dec 2015 17:27:13 +0100 Subject: 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. --- src/resolve/resolved-dns-cache.c | 19 +++---------------- src/resolve/resolved-dns-rr.c | 11 +++++------ src/resolve/resolved-dns-rr.h | 15 +++++++++++++-- src/resolve/resolved-dns-zone.c | 13 +++++++------ 4 files changed, 28 insertions(+), 30 deletions(-) diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c index 3f34017789..3abb0374b6 100644 --- a/src/resolve/resolved-dns-cache.c +++ b/src/resolve/resolved-dns-cache.c @@ -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; diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c index 281e228b12..b109934d3a 100644 --- a/src/resolve/resolved-dns-rr.c +++ b/src/resolve/resolved-dns-rr.c @@ -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) { diff --git a/src/resolve/resolved-dns-rr.h b/src/resolve/resolved-dns-rr.h index 2a103aab8d..adaca962fc 100644 --- a/src/resolve/resolved-dns-rr.h +++ b/src/resolve/resolved-dns-rr.h @@ -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); diff --git a/src/resolve/resolved-dns-zone.c b/src/resolve/resolved-dns-zone.c index 493d11dd14..78f44d51a2 100644 --- a/src/resolve/resolved-dns-zone.c +++ b/src/resolve/resolved-dns-zone.c @@ -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; -- cgit v1.2.3-54-g00ecf