From 9163f4673d919658c94f9de4ca32a2e9dacce2fd Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Thu, 11 Jun 2009 19:34:54 +0200 Subject: conntrackd: use a permanent handler for commit operations This patch adds a dedicated commit handler since there is a possible race condition that can happen if the child process ends before we have received all the event messages that the commit request has triggered. Signed-off-by: Pablo Neira Ayuso --- include/conntrackd.h | 2 ++ src/sync-mode.c | 35 +++++++++++++---------------------- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/include/conntrackd.h b/include/conntrackd.h index c5f6659..7a63f97 100644 --- a/include/conntrackd.h +++ b/include/conntrackd.h @@ -166,6 +166,8 @@ struct ct_sync_state { struct cache *internal; /* internal events cache (netlink) */ struct cache *external; /* external events cache (mcast) */ + struct nfct_handle *commit; + struct multichannel *channel; struct nlif_handle *interface; struct queue *tx_queue; diff --git a/src/sync-mode.c b/src/sync-mode.c index 102ecac..dca6eee 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -298,6 +298,13 @@ static int init_sync(void) STATE(fds)) == -1) return -1; + STATE_SYNC(commit) = nfct_open(CONNTRACK, 0); + if (STATE_SYNC(commit) == NULL) { + dlog(LOG_ERR, "can't create handler to commit"); + return -1; + } + origin_register(STATE_SYNC(commit), CTD_ORIGIN_COMMIT); + init_alarm(&STATE_SYNC(reset_cache_alarm), NULL, do_reset_cache_alarm); /* initialization of message sequence generation */ @@ -337,6 +344,9 @@ static void kill_sync(void) queue_destroy(STATE_SYNC(tx_queue)); + origin_unregister(STATE_SYNC(commit)); + nfct_close(STATE_SYNC(commit)); + if (STATE_SYNC(sync)->kill) STATE_SYNC(sync)->kill(); } @@ -390,14 +400,6 @@ static void dump_stats_sync_extended(int fd) send(fd, buf, size, 0); } -/* this is called once the committer process has finished */ -static void commit_done_cb(void *data) -{ - struct nfct_handle *h = data; - origin_unregister(h); - nfct_close(h); -} - /* handler for requests coming via UNIX socket */ static int local_handler_sync(int fd, int type, void *data) { @@ -432,30 +434,19 @@ static int local_handler_sync(int fd, int type, void *data) exit(EXIT_SUCCESS); } break; - case COMMIT: { - struct nfct_handle *h; - + case COMMIT: /* delete the reset alarm if any before committing */ del_alarm(&STATE_SYNC(reset_cache_alarm)); - /* disposable handler for commit operations */ - h = nfct_open(CONNTRACK, 0); - if (h == NULL) { - dlog(LOG_ERR, "can't create handler to commit"); - break; - } - origin_register(h, CTD_ORIGIN_COMMIT); - /* fork new process and insert it the process list */ ret = fork_process_new(CTD_PROC_COMMIT, CTD_PROC_F_EXCL, - commit_done_cb, h); + NULL, NULL); if (ret == 0) { dlog(LOG_NOTICE, "committing external cache"); - cache_commit(STATE_SYNC(external), h); + cache_commit(STATE_SYNC(external), STATE_SYNC(commit)); exit(EXIT_SUCCESS); } break; - } case RESET_TIMERS: if (!alarm_pending(&STATE_SYNC(reset_cache_alarm))) { dlog(LOG_NOTICE, "flushing conntrack table in %d secs", -- cgit v1.2.3