summaryrefslogtreecommitdiffstats
path: root/ldap_driver.c
diff options
context:
space:
mode:
authorMartin Nagy <mnagy@redhat.com>2009-02-18 20:18:39 +0100
committerMartin Nagy <mnagy@redhat.com>2009-02-18 20:18:39 +0100
commit12c68efa09b48f00f538d84e56622a26034e5e33 (patch)
tree0c30be5d997e367615ef1476da3e5fac0402a39c /ldap_driver.c
parentdf0b8a0a05de3118a4c165c7942469f576de6110 (diff)
downloadldap_driver_testing-12c68efa09b48f00f538d84e56622a26034e5e33.tar.gz
ldap_driver_testing-12c68efa09b48f00f538d84e56622a26034e5e33.tar.xz
ldap_driver_testing-12c68efa09b48f00f538d84e56622a26034e5e33.zip
Fix memory leaks resulted from creating rdatasets.
We use kind of a hack really. We overwrite each created rdataset's methods by our own that will free the resources.
Diffstat (limited to 'ldap_driver.c')
-rw-r--r--ldap_driver.c59
1 files changed, 50 insertions, 9 deletions
diff --git a/ldap_driver.c b/ldap_driver.c
index afc6d65..a7cac48 100644
--- a/ldap_driver.c
+++ b/ldap_driver.c
@@ -25,6 +25,7 @@
#include <dns/db.h>
#include <dns/rdata.h>
#include <dns/rdatalist.h>
+#include <dns/rdataset.h>
#include <dns/result.h>
#include <dns/types.h>
@@ -43,6 +44,8 @@
#define VALID_LDAPDBNODE(ldapdbnode) ISC_MAGIC_VALID(ldapdbnode, \
LDAPDBNODE_MAGIC)
+static dns_rdatasetmethods_t rdataset_methods;
+
typedef struct {
dns_db_t common;
isc_refcount_t refs;
@@ -63,7 +66,6 @@ static void *ldapdb_version = &dummy;
static void free_ldapdb(ldapdb_t *ldapdb);
static void detachnode(dns_db_t *db, dns_dbnode_t **targetp);
-
/* ldapdbnode_t functions */
static isc_result_t
ldapdbnode_create(isc_mem_t *mctx, dns_name_t *owner, ldapdbnode_t **nodep)
@@ -138,25 +140,47 @@ clone_rdatalist_to_rdataset(isc_mem_t *mctx, dns_rdatalist_t *rdlist,
APPEND(new_rdlist->rdata, new_rdata, link);
}
- result = dns_rdatalist_tordataset(new_rdlist, rdataset);
+ CHECK(dns_rdatalist_tordataset(new_rdlist, rdataset));
+ rdataset->methods = &rdataset_methods;
+ isc_mem_attach(mctx, (isc_mem_t **)&rdataset->private5);
return result;
cleanup:
if (new_rdlist != NULL) {
- for (rdata = HEAD(new_rdlist->rdata);
- rdata != NULL;
- rdata = NEXT(rdata, link)) {
- SAFE_MEM_PUT(mctx, rdata->data, rdata->length);
- SAFE_MEM_PUT_PTR(mctx, rdata);
- }
+ free_rdatalist(mctx, rdlist);
+ isc_mem_put(mctx, new_rdlist, sizeof(*new_rdlist));
}
- SAFE_MEM_PUT_PTR(mctx, new_rdlist);
return result;
}
/*
+ * Our own function for disassociating rdatasets. We will also free the
+ * rdatalist that we put inside from clone_rdatalist_to_rdataset.
+ */
+void
+ldapdb_rdataset_disassociate(dns_rdataset_t *rdataset)
+{
+ dns_rdatalist_t *rdlist;
+ isc_mem_t *mctx;
+
+ REQUIRE(rdataset != NULL);
+
+ rdlist = rdataset->private1;
+ mctx = rdataset->private5;
+ if (rdlist == NULL)
+ return;
+ rdataset->private1 = NULL;
+ rdataset->private5 = NULL;
+
+ free_rdatalist(mctx, rdlist);
+ isc_mem_put(mctx, rdlist, sizeof(*rdlist));
+
+ isc_mem_detach(&mctx);
+}
+
+/*
* Functions.
*
* Most of them don't need db parameter but we are checking if it is valid.
@@ -845,6 +869,23 @@ dynamic_driver_init(isc_mem_t *mctx, const char *name, const char * const *argv,
i++;
}
+ /*
+ * We need to discover what rdataset methods does
+ * dns_rdatalist_tordataset use. We then make a copy for ourselves
+ * with the exception that we modify the disassociate method to free
+ * the rdlist we allocate for it in clone_rdatalist_to_rdataset().
+ */
+ if (rdataset_methods.disassociate == NULL) {
+ dns_rdataset_t rdset;
+ dns_rdatalist_t rdatalist;
+
+ dns_rdataset_init(&rdset);
+ dns_rdatalist_tordataset(&rdatalist, &rdset);
+ memcpy(&rdataset_methods, rdset.methods,
+ sizeof(dns_rdatasetmethods_t));
+ rdataset_methods.disassociate = ldapdb_rdataset_disassociate;
+ }
+
/* Register new DNS DB implementation. */
result = dns_db_register(ldapdb_impname, &ldapdb_create, NULL, mctx,
&ldapdb_imp);