From eec8fdf57f34fe0d80b884ad0e376ed24c63ffcc Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 25 Jan 2009 17:52:56 +0100 Subject: src: change behaviour of `-t' option With this patch, the `-t' option adds an alarm that will flush the cache after CONFIG(purge_timeout) seconds specified in the config file. This looks much cleaner and more performance that looping on the entire conntrack table to set the new timeout of every single entry. Signed-off-by: Pablo Neira Ayuso --- include/cache.h | 1 - include/conntrackd.h | 2 ++ src/cache_iterators.c | 46 ---------------------------------------------- src/sync-mode.c | 23 ++++++++++++++++++----- 4 files changed, 20 insertions(+), 52 deletions(-) diff --git a/include/cache.h b/include/cache.h index bb0ca4d..5e96dd3 100644 --- a/include/cache.h +++ b/include/cache.h @@ -126,6 +126,5 @@ void cache_dump(struct cache *c, int fd, int type); void cache_commit(struct cache *c); void cache_flush(struct cache *c); void cache_bulk(struct cache *c); -void cache_reset_timers(struct cache *c); #endif diff --git a/include/conntrackd.h b/include/conntrackd.h index 99b9caa..3e10a2f 100644 --- a/include/conntrackd.h +++ b/include/conntrackd.h @@ -158,6 +158,8 @@ struct ct_sync_state { struct nlif_handle *mcast_iface; struct queue *tx_queue; + struct alarm_block reset_cache_alarm; + struct sync_mode *sync; /* sync mode */ /* statistics */ diff --git a/src/cache_iterators.c b/src/cache_iterators.c index be69d47..4bf518a 100644 --- a/src/cache_iterators.c +++ b/src/cache_iterators.c @@ -188,52 +188,6 @@ void cache_commit(struct cache *c) res.tv_sec, res.tv_usec); } -static int do_reset_timers(void *data1, struct hashtable_node *n) -{ - int ret; - u_int32_t current_timeout; - struct nfct_handle *h = data1; - struct cache_object *obj = (struct cache_object *)n; - - ret = nl_get_conntrack(h, obj->ct); - switch (ret) { - case -1: - /* the kernel table is not in sync with internal cache */ - dlog(LOG_ERR, "reset-timers: %s", strerror(errno)); - dlog_ct(STATE(log), obj->ct, NFCT_O_PLAIN); - break; - case 1: - /* use the object that contain the current timer */ - current_timeout = nfct_get_attr_u32(obj->ct, ATTR_TIMEOUT); - /* already about to die, do not touch it */ - if (current_timeout < CONFIG(purge_timeout)) - break; - - ret = nl_update_conntrack(h, obj->ct, CONFIG(purge_timeout)); - if (ret == -1) { - if (errno == ETIME || errno == ENOENT) - break; - dlog(LOG_ERR, "reset-timers-upd: %s", strerror(errno)); - dlog_ct(STATE(log), obj->ct, NFCT_O_PLAIN); - } - break; - } - return 0; -} - -void cache_reset_timers(struct cache *c) -{ - struct nfct_handle *h; - - h = nfct_open(CONNTRACK, 0); - if (h == NULL) { - dlog(LOG_ERR, "can't create handler to reset timers"); - return; - } - hashtable_iterate(c->h, h, do_reset_timers); - nfct_close(h); -} - static int do_flush(void *data, struct hashtable_node *n) { struct cache *c = data; diff --git a/src/sync-mode.c b/src/sync-mode.c index 54d0ebb..84a4de0 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -205,6 +205,13 @@ static void mcast_iface_handler(void) mcast_iface_candidate(); } +static void do_reset_cache_alarm(struct alarm_block *a, void *data) +{ + STATE(stats).nl_kernel_table_flush++; + dlog(LOG_NOTICE, "flushing kernel conntrack table (scheduled)"); + nl_flush_conntrack_table(STATE(request)); +} + static int init_sync(void) { int i; @@ -305,6 +312,8 @@ static int init_sync(void) STATE(fds)) == -1) return -1; + init_alarm(&STATE_SYNC(reset_cache_alarm), NULL, do_reset_cache_alarm); + /* initialization of multicast sequence generation */ STATE_SYNC(last_seq_sent) = time(NULL); @@ -432,6 +441,8 @@ static int local_handler_sync(int fd, int type, void *data) } break; case COMMIT: + /* delete the reset alarm if any before committing */ + del_alarm(&STATE_SYNC(reset_cache_alarm)); ret = fork(); if (ret == 0) { dlog(LOG_NOTICE, "committing external cache"); @@ -440,14 +451,16 @@ static int local_handler_sync(int fd, int type, void *data) } break; case RESET_TIMERS: - ret = fork(); - if (ret == 0) { - dlog(LOG_NOTICE, "resetting timers"); - cache_reset_timers(STATE_SYNC(internal)); - exit(EXIT_SUCCESS); + if (!alarm_pending(&STATE_SYNC(reset_cache_alarm))) { + dlog(LOG_NOTICE, "flushing conntrack table in %d secs", + CONFIG(purge_timeout)); + add_alarm(&STATE_SYNC(reset_cache_alarm), + CONFIG(purge_timeout), 0); } break; case FLUSH_CACHE: + /* inmediate flush, remove pending flush scheduled if any */ + del_alarm(&STATE_SYNC(reset_cache_alarm)); dlog(LOG_NOTICE, "flushing caches"); cache_flush(STATE_SYNC(internal)); cache_flush(STATE_SYNC(external)); -- cgit v1.2.3