From 50339f96638eed35dac2b673b64cc6f1eb96406c Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Thu, 15 Jan 2009 23:19:57 +0100 Subject: src: rework of the hash-cache infrastructure Currently, the caching system is implemented in a two layer architecture: hashtable (inner layer) and cache (upper layer). This patch reworks the hash-cache infrastructure to solve some initial design problems to make it more flexible, the main strong points of this patch are: * Memory handling is done in the cache layer, not in the inner hashtable layer. This removes one of the main dependencies between the hashtable and the cache classes. * Remove excessive encapsulation: the former cache used to hide a lot of details of the inner hashtable implementation. * Fix over-hashing of some operations: lookup-delete-add required three hash calculations. Similarly, the update-or-add operation required two hash calculations. Now, we calculate the hash once and re-use the value how many times as we need. This patch simplifies the caching system. As a result, we save ~130 lines of code. Small code means and less complexity means less chance to have bugs. Signed-off-by: Pablo Neira Ayuso --- src/stats-mode.c | 55 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 26 deletions(-) (limited to 'src/stats-mode.c') diff --git a/src/stats-mode.c b/src/stats-mode.c index d340b0d..679a50c 100644 --- a/src/stats-mode.c +++ b/src/stats-mode.c @@ -22,7 +22,6 @@ #include "cache.h" #include "log.h" #include "conntrackd.h" -#include "us-conntrack.h" #include #include @@ -118,9 +117,8 @@ static int overrun_stats(enum nf_conntrack_msg_type type, nfct_attr_unset(ct, ATTR_REPL_COUNTER_PACKETS); nfct_attr_unset(ct, ATTR_USE); - if (!cache_test(STATE_STATS(cache), ct)) - if (!cache_update_force(STATE_STATS(cache), ct)) - debug_ct(ct, "overrun stats resync"); + if (!cache_update_force(STATE_STATS(cache), ct)) + debug_ct(ct, "overrun stats resync"); return NFCT_CB_CONTINUE; } @@ -128,12 +126,13 @@ static int overrun_stats(enum nf_conntrack_msg_type type, static int purge_step(void *data1, void *data2) { int ret; - struct us_conntrack *u = data2; + struct cache_object *obj = data2; - ret = nfct_query(STATE(dump), NFCT_Q_GET, u->ct); + ret = nfct_query(STATE(dump), NFCT_Q_GET, obj->ct); if (ret == -1 && errno == ENOENT) { - debug_ct(u->ct, "overrun purge stats"); - cache_del(STATE_STATS(cache), u->ct); + debug_ct(obj->ct, "overrun purge stats"); + cache_del(STATE_STATS(cache), obj); + cache_object_free(obj); } return 0; @@ -148,42 +147,46 @@ static int purge_stats(void) static void event_new_stats(struct nf_conntrack *ct) { + int id; + struct cache_object *obj; + nfct_attr_unset(ct, ATTR_TIMEOUT); - if (cache_add(STATE_STATS(cache), ct)) { - debug_ct(ct, "cache new"); - } else { - if (errno != EEXIST) { - dlog(LOG_ERR, - "can't add to cache cache: %s\n", strerror(errno)); - debug_ct(ct, "can't add"); + obj = cache_find(STATE_STATS(cache), ct, &id); + if (obj == NULL) { + obj = cache_object_new(STATE_STATS(cache), ct); + if (obj == NULL) + return; + + if (cache_add(STATE_STATS(cache), obj, id) == -1) { + cache_object_free(obj); + return; } } + return; } static void event_update_stats(struct nf_conntrack *ct) { nfct_attr_unset(ct, ATTR_TIMEOUT); - - if (!cache_update_force(STATE_STATS(cache), ct)) { - debug_ct(ct, "can't update"); - return; - } - debug_ct(ct, "update"); + cache_update_force(STATE_STATS(cache), ct); } static int event_destroy_stats(struct nf_conntrack *ct) { + int id; + struct cache_object *obj; + nfct_attr_unset(ct, ATTR_TIMEOUT); - if (cache_del(STATE_STATS(cache), ct)) { - debug_ct(ct, "cache destroy"); + obj = cache_find(STATE_STATS(cache), ct, &id); + if (obj) { + cache_del(STATE_STATS(cache), obj); dlog_ct(STATE(stats_log), ct, NFCT_O_PLAIN); + cache_object_free(obj); return 1; - } else { - debug_ct(ct, "can't destroy!"); - return 0; } + return 0; } struct ct_mode stats_mode = { -- cgit v1.2.3