diff options
-rw-r--r-- | include/cache.h | 1 | ||||
-rw-r--r-- | include/conntrackd.h | 1 | ||||
-rw-r--r-- | src/cache_iterators.c | 34 | ||||
-rw-r--r-- | src/main.c | 4 | ||||
-rw-r--r-- | src/sync-mode.c | 8 |
5 files changed, 48 insertions, 0 deletions
diff --git a/include/cache.h b/include/cache.h index ba8d3aa..45c3b7e 100644 --- a/include/cache.h +++ b/include/cache.h @@ -97,5 +97,6 @@ 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 d2c8931..2f0d7e5 100644 --- a/include/conntrackd.h +++ b/include/conntrackd.h @@ -24,6 +24,7 @@ #define REQUEST_DUMP 23 /* request dump */ #define DUMP_INT_XML 24 /* dump internal cache in XML */ #define DUMP_EXT_XML 25 /* dump external cache in XML */ +#define RESET_TIMERS 26 /* reset kernel timers */ #define DEFAULT_CONFIGFILE "/etc/conntrackd/conntrackd.conf" #define DEFAULT_LOCKFILE "/var/lock/conntrackd.lock" diff --git a/src/cache_iterators.c b/src/cache_iterators.c index 407db0b..2abb6cd 100644 --- a/src/cache_iterators.c +++ b/src/cache_iterators.c @@ -174,6 +174,40 @@ void cache_commit(struct cache *c) "committed", commit_fail); } +static int do_reset_timers(void *data1, void *data2) +{ + int ret; + struct us_conntrack *u = data2; + struct nf_conntrack *ct = u->ct; + + /* this may increase timers but they will end up dying shortly anyway */ + nfct_set_attr_u32(ct, ATTR_TIMEOUT, CONFIG(commit_timeout)); + + ret = nl_exist_conntrack(ct); + switch (ret) { + case -1: + case 0: + /* the kernel table is not in sync with internal cache */ + dlog(LOG_ERR, "reset-timers: %s", strerror(errno)); + dlog_ct(STATE(log), ct, NFCT_O_PLAIN); + break; + case 1: + if (nl_update_conntrack(ct) == -1) { + if (errno == ETIME || errno == ENOENT) + break; + dlog(LOG_ERR, "reset-timers-upd: %s", strerror(errno)); + dlog_ct(STATE(log), ct, NFCT_O_PLAIN); + } + break; + } + return 0; +} + +void cache_reset_timers(struct cache *c) +{ + hashtable_iterate(c->h, NULL, do_reset_timers); +} + static int do_flush(void *data1, void *data2) { struct cache *c = data1; @@ -148,6 +148,10 @@ int main(int argc, char *argv[]) set_operation_mode(&type, REQUEST, argv); action = SEND_BULK; break; + case 't': + set_operation_mode(&type, REQUEST, argv); + action = RESET_TIMERS; + break; case 'k': set_operation_mode(&type, REQUEST, argv); action = KILL; diff --git a/src/sync-mode.c b/src/sync-mode.c index 56c30af..297a500 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -343,6 +343,14 @@ static int local_handler_sync(int fd, int type, void *data) exit(EXIT_SUCCESS); } break; + case RESET_TIMERS: + ret = fork(); + if (ret == 0) { + dlog(LOG_NOTICE, "resetting timers"); + cache_reset_timers(STATE_SYNC(internal)); + exit(EXIT_SUCCESS); + } + break; case FLUSH_CACHE: dlog(LOG_NOTICE, "flushing caches"); cache_flush(STATE_SYNC(internal)); |