summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Nagy <mnagy@redhat.com>2009-03-16 10:59:11 +0100
committerMartin Nagy <mnagy@redhat.com>2009-03-16 15:45:41 +0100
commite5f852b66a5fc39216321bff98a7cf3ca398b7a8 (patch)
tree63a39951e1ec764e44435f5db33b67828c511d45
parent23e451caebfb11e1e313ef597a52a67385375088 (diff)
downloadldap_driver_testing-e5f852b66a5fc39216321bff98a7cf3ca398b7a8.tar.gz
ldap_driver_testing-e5f852b66a5fc39216321bff98a7cf3ca398b7a8.tar.xz
ldap_driver_testing-e5f852b66a5fc39216321bff98a7cf3ca398b7a8.zip
Add expiration option 'cache_ttl'.
Defaults to 120 seconds.
-rw-r--r--cache.c80
1 files changed, 42 insertions, 38 deletions
diff --git a/cache.c b/cache.c
index 40c25ce..69d8545 100644
--- a/cache.c
+++ b/cache.c
@@ -19,6 +19,7 @@
#include <isc/mem.h>
#include <isc/result.h>
+#include <isc/time.h>
#include <isc/util.h>
#include <dns/rbt.h>
@@ -37,13 +38,13 @@
struct ldap_cache {
isc_mem_t *mctx;
dns_rbt_t *rbt;
- /* TODO: Add a timeout period setting. */
+ isc_interval_t cache_ttl;
};
typedef struct {
isc_mem_t *mctx;
ldapdb_rdatalist_t rdatalist;
- /* TODO: Add time of creation for expiration purposes. */
+ isc_time_t valid_until;
} cache_node_t;
static void
@@ -59,54 +60,58 @@ cache_node_deleter(void *data, void *deleter_arg)
}
static isc_result_t
-cache_node_create(isc_mem_t *mctx, ldapdb_rdatalist_t rdatalist,
+cache_node_create(ldap_cache_t *cache, ldapdb_rdatalist_t rdatalist,
cache_node_t **nodep)
{
isc_result_t result;
cache_node_t *node;
- REQUIRE(mctx != NULL);
+ REQUIRE(cache != NULL);
REQUIRE(nodep != NULL && *nodep == NULL);
- CHECKED_MEM_GET_PTR(mctx, node);
+ CHECKED_MEM_GET_PTR(cache->mctx, node);
ZERO_PTR(node);
- isc_mem_attach(mctx, &node->mctx);
+ isc_mem_attach(cache->mctx, &node->mctx);
node->rdatalist = rdatalist;
+ CHECK(isc_time_nowplusinterval(&node->valid_until, &cache->cache_ttl));
*nodep = node;
return ISC_R_SUCCESS;
cleanup:
- SAFE_MEM_PUT_PTR(mctx, node);
+ SAFE_MEM_PUT_PTR(cache->mctx, node);
return result;
}
-/*
- * TODO: Add setting saying if we want to enable cache, if not, then
- * cache->rbt must be set to NULL.
- */
isc_result_t
new_ldap_cache(isc_mem_t *mctx, ldap_cache_t **cachep,
const char * const *argv)
{
isc_result_t result;
ldap_cache_t *cache = NULL;
-
- UNUSED(argv);
+ unsigned int cache_ttl;
+ setting_t cache_settings[] = {
+ { "cache_ttl", default_uint(120) },
+ end_of_settings
+ };
REQUIRE(cachep != NULL && *cachep == NULL);
+ cache_settings[0].target = &cache_ttl;
+ CHECK(set_settings(cache_settings, argv));
+
CHECKED_MEM_GET_PTR(mctx, cache);
ZERO_PTR(cache);
isc_mem_attach(mctx, &cache->mctx);
- if (1) {
+ isc_interval_set(&cache->cache_ttl, cache_ttl, 0);
+
+ if (cache_ttl) {
CHECK(dns_rbt_create(mctx, cache_node_deleter, NULL,
&cache->rbt));
}
-
*cachep = cache;
return ISC_R_SUCCESS;
@@ -134,7 +139,6 @@ destroy_ldap_cache(ldap_cache_t **cachep)
*cachep = NULL;
}
-/* TODO: Implement expiration. */
isc_result_t
cached_ldap_rdatalist_get(isc_mem_t *mctx, ldap_cache_t *cache,
ldap_db_t *ldap_db, dns_name_t *name,
@@ -143,47 +147,47 @@ cached_ldap_rdatalist_get(isc_mem_t *mctx, ldap_cache_t *cache,
isc_result_t result;
ldapdb_rdatalist_t rdlist;
cache_node_t *node = NULL;
- void *data = NULL;
- int found = 0;
- int expired = 0;
+ int in_cache = 0;
REQUIRE(cache != NULL);
- INIT_LIST(*rdatalist);
- INIT_LIST(rdlist);
-
if (cache->rbt == NULL)
return ldapdb_rdatalist_get(mctx, ldap_db, name, rdatalist);
- result = dns_rbt_findname(cache->rbt, name, 0, NULL, &data);
+ result = dns_rbt_findname(cache->rbt, name, 0, NULL, (void *)&node);
if (result == ISC_R_SUCCESS) {
- found = 1;
- expired = 0; /* find out if we are expired */
- node = (cache_node_t *)data;
- rdlist = node->rdatalist;
+ isc_time_t now;
+
+ CHECK(isc_time_now(&now));
+
+ /* Check if the record is still valid. */
+ if (isc_time_compare(&now, &node->valid_until) > 0) {
+ CHECK(dns_rbt_deletename(cache->rbt, name, ISC_FALSE));
+ node = NULL;
+ in_cache = 0;
+ } else {
+ rdlist = node->rdatalist;
+ in_cache = 1;
+ }
} else if (result != ISC_R_NOTFOUND && result != DNS_R_PARTIALMATCH) {
goto cleanup;
+ } else {
+ node = NULL;
}
- if ((found && expired) || !found) {
- if (found) {
- CHECK(dns_rbt_deletename(cache->rbt, name, ISC_FALSE));
- data = NULL; /* ? */
- }
+ if (!in_cache) {
INIT_LIST(rdlist);
result = ldapdb_rdatalist_get(mctx, ldap_db, name, &rdlist);
if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
goto cleanup;
- CHECK(cache_node_create(mctx, rdlist, &node));
- data = (void *)node;
- CHECK(dns_rbt_addname(cache->rbt, name, data));
+ CHECK(cache_node_create(cache, rdlist, &node));
+ CHECK(dns_rbt_addname(cache->rbt, name, (void *)node));
}
+
CHECK(ldap_rdatalist_copy(mctx, rdlist, rdatalist));
if (EMPTY(*rdatalist))
- return ISC_R_NOTFOUND;
- else
- return ISC_R_SUCCESS;
+ result = ISC_R_NOTFOUND;
cleanup:
return result;