diff options
author | Martin Nagy <mnagy@redhat.com> | 2009-03-16 10:59:11 +0100 |
---|---|---|
committer | Martin Nagy <mnagy@redhat.com> | 2009-03-16 15:45:41 +0100 |
commit | e5f852b66a5fc39216321bff98a7cf3ca398b7a8 (patch) | |
tree | 63a39951e1ec764e44435f5db33b67828c511d45 | |
parent | 23e451caebfb11e1e313ef597a52a67385375088 (diff) | |
download | ldap_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.c | 80 |
1 files changed, 42 insertions, 38 deletions
@@ -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; |