summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2009-06-11 19:34:54 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2009-06-11 19:34:54 +0200
commit6dad06ec56eeb942a1785246bf91fe7100a21c7e (patch)
tree230827bbdf7d19b36c23f3d2bad9ced109d57c27
parent5e696e022d8383bc7abe6e6ba37c2664679fe81f (diff)
downloadconntrack-tools-6dad06ec56eeb942a1785246bf91fe7100a21c7e.tar.gz
conntrack-tools-6dad06ec56eeb942a1785246bf91fe7100a21c7e.zip
conntrackd: use a permanent handler for flush operations
In 6f5666a29cb7cbff08ce926ee1edb84a311ff6ee, I moved the flush operation into a child process and to use a disposable handler to perform flush requests. This patch adds a dedicated flush 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 flush request has triggered. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--include/conntrackd.h1
-rw-r--r--src/run.c35
-rw-r--r--src/sync-mode.c23
3 files changed, 16 insertions, 43 deletions
diff --git a/include/conntrackd.h b/include/conntrackd.h
index 0546855..c5f6659 100644
--- a/include/conntrackd.h
+++ b/include/conntrackd.h
@@ -122,6 +122,7 @@ struct ct_general_state {
struct nfct_handle *resync; /* resync handler */
struct nfct_handle *get; /* get handler */
int get_retval; /* hackish */
+ struct nfct_handle *flush; /* flusher */
struct alarm_block resync_alarm;
struct alarm_block polling_alarm;
diff --git a/src/run.c b/src/run.c
index a0aea4f..fe81d54 100644
--- a/src/run.c
+++ b/src/run.c
@@ -47,6 +47,8 @@ void killer(int foo)
nfct_close(STATE(resync));
nfct_close(STATE(get));
+ origin_unregister(STATE(flush));
+ nfct_close(STATE(flush));
if (STATE(us_filter))
ct_filter_destroy(STATE(us_filter));
@@ -180,13 +182,6 @@ static void dump_stats_runtime(int fd)
send(fd, buf, size, 0);
}
-static void flush_done_cb(void *data)
-{
- struct nfct_handle *h = data;
- origin_unregister(h);
- nfct_close(h);
-}
-
void local_handler(int fd, void *data)
{
int ret;
@@ -201,30 +196,18 @@ void local_handler(int fd, void *data)
return;
switch(type) {
- case FLUSH_MASTER: {
- struct nfct_handle *h;
-
- /* disposable flusher handler */
- h = nfct_open(CONNTRACK, 0);
- if (h == NULL) {
- dlog(LOG_ERR, "cannot open flusher handler");
- return;
- }
- /* register this handler as the origin of a flush operation */
- origin_register(h, CTD_ORIGIN_FLUSH);
-
+ case FLUSH_MASTER:
STATE(stats).nl_kernel_table_flush++;
dlog(LOG_NOTICE, "flushing kernel conntrack table");
/* fork a child process that performs the flush operation,
* meanwhile the parent process handles events. */
if (fork_process_new(CTD_PROC_FLUSH, CTD_PROC_F_EXCL,
- flush_done_cb, h) == 0) {
- nl_flush_conntrack_table(h);
+ NULL, NULL) == 0) {
+ nl_flush_conntrack_table(STATE(flush));
exit(EXIT_SUCCESS);
}
return;
- }
case RESYNC_MASTER:
STATE(stats).nl_kernel_table_resync++;
dlog(LOG_NOTICE, "resync with master table");
@@ -408,6 +391,14 @@ init(void)
}
nfct_callback_register(STATE(get), NFCT_T_ALL, get_handler, NULL);
+ STATE(flush) = nfct_open(CONNTRACK, 0);
+ if (STATE(flush) == NULL) {
+ dlog(LOG_ERR, "cannot open flusher handler");
+ return -1;
+ }
+ /* register this handler as the origin of a flush operation */
+ origin_register(STATE(flush), CTD_ORIGIN_FLUSH);
+
if (CONFIG(flags) & CTD_POLL) {
init_alarm(&STATE(polling_alarm), NULL, do_polling_alarm);
add_alarm(&STATE(polling_alarm), CONFIG(poll_kernel_secs), 0);
diff --git a/src/sync-mode.c b/src/sync-mode.c
index 2da3604..102ecac 100644
--- a/src/sync-mode.c
+++ b/src/sync-mode.c
@@ -203,35 +203,16 @@ static void interface_handler(void)
interface_candidate();
}
-/* this is called once the flusher process has finished */
-static void flush_done_cb(void *data)
-{
- struct nfct_handle *h = data;
- origin_unregister(h);
- nfct_close(h);
-}
-
static void do_reset_cache_alarm(struct alarm_block *a, void *data)
{
- struct nfct_handle *h;
-
- /* disposable flusher handler */
- h = nfct_open(CONNTRACK, 0);
- if (h == NULL) {
- dlog(LOG_ERR, "cannot open flusher handler");
- return;
- }
- /* register this handler as the origin of a flush operation */
- origin_register(h, CTD_ORIGIN_FLUSH);
-
STATE(stats).nl_kernel_table_flush++;
dlog(LOG_NOTICE, "flushing kernel conntrack table (scheduled)");
/* fork a child process that performs the flush operation,
* meanwhile the parent process handles events. */
if (fork_process_new(CTD_PROC_FLUSH, CTD_PROC_F_EXCL,
- flush_done_cb, h) == 0) {
- nl_flush_conntrack_table(h);
+ NULL, NULL) == 0) {
+ nl_flush_conntrack_table(STATE(flush));
exit(EXIT_SUCCESS);
}
/* this is not required if events don't get lost */