]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: optionally, allocate DnsResourceKey objects on the stack
authorLennart Poettering <lennart@poettering.net>
Thu, 3 Dec 2015 16:27:13 +0000 (17:27 +0100)
committerLennart Poettering <lennart@poettering.net>
Thu, 3 Dec 2015 20:17:49 +0000 (21:17 +0100)
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
src/resolve/resolved-dns-rr.c
src/resolve/resolved-dns-rr.h
src/resolve/resolved-dns-zone.c

index 3f34017789ab7c6c050452a6715a467ca7d9b3ce..3abb0374b6917f90d6b0feb3c9365acb8a151247 100644 (file)
@@ -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;
 
index 281e228b12c3bb0c285ac10663b62d64948902fe..b109934d3afc1864a985e6a5bddff5165931dd66 100644 (file)
@@ -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) {
index 2a103aab8da12ac40088eb7c6e346c7d1616ec85..adaca962fcfdc14be8a38008e39e7261685d5b57 100644 (file)
@@ -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);
index 493d11dd14169a9a234bb3c9d1c0da6a5eef2a01..78f44d51a279ef0d7749f1b1cbad54380e7961d7 100644 (file)
@@ -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;