summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/cache.h1
-rw-r--r--include/conntrackd.h2
-rw-r--r--src/cache_iterators.c46
-rw-r--r--src/sync-mode.c23
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));