summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2009-01-17 18:03:53 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2009-01-17 18:03:53 +0100
commit746f7031f4d1e3bccdd6db3c53835d8b85b73c90 (patch)
treea900ab9f0654dd67ae36f2c61ca4cdc3c2c7befe /src
parent05194422ee8fa038d99fe77a2e9d776d25623fd2 (diff)
src: add state polling support (oppossed to current event-driven)
This patch adds the clause PollSecs that changes the normal behaviour of conntrackd. With PollSecs set to > 0, conntrackd polls every N seconds the entries. This is the opposed behaviour of an event-driven behaviour but may be useful for those that have really strong limitations in terms of CPU consumption and want to perform a relaxed replication. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src')
-rw-r--r--src/read_config_lex.l1
-rw-r--r--src/read_config_yy.y13
-rw-r--r--src/run.c41
3 files changed, 42 insertions, 13 deletions
diff --git a/src/read_config_lex.l b/src/read_config_lex.l
index e9e5d43..4953974 100644
--- a/src/read_config_lex.l
+++ b/src/read_config_lex.l
@@ -119,6 +119,7 @@ notrack [N|n][O|o][T|t][R|r][A|a][C|c][K|k]
"Kernelspace" { return T_KERNELSPACE; }
"EventIterationLimit" { return T_EVENT_ITER_LIMIT; }
"Default" { return T_DEFAULT; }
+"PollSecs" { return T_POLL_SECS; }
{is_on} { return T_ON; }
{is_off} { return T_OFF; }
diff --git a/src/read_config_yy.y b/src/read_config_yy.y
index de6cef3..ce604d9 100644
--- a/src/read_config_yy.y
+++ b/src/read_config_yy.y
@@ -58,7 +58,7 @@ static void __max_mcast_dedicated_links_reached(void);
%token T_ESTABLISHED T_SYN_SENT T_SYN_RECV T_FIN_WAIT
%token T_CLOSE_WAIT T_LAST_ACK T_TIME_WAIT T_CLOSE T_LISTEN
%token T_SYSLOG T_WRITE_THROUGH T_STAT_BUFFER_SIZE T_DESTROY_TIMEOUT
-%token T_MCAST_RCVBUFF T_MCAST_SNDBUFF T_NOTRACK
+%token T_MCAST_RCVBUFF T_MCAST_SNDBUFF T_NOTRACK T_POLL_SECS
%token T_FILTER T_ADDRESS T_PROTOCOL T_STATE T_ACCEPT T_IGNORE
%token T_FROM T_USERSPACE T_KERNELSPACE T_EVENT_ITER_LIMIT T_DEFAULT
@@ -715,6 +715,7 @@ general_line: hashsize
| netlink_buffer_size_max_grown
| family
| event_iterations_limit
+ | poll_secs
| filter
;
@@ -741,6 +742,16 @@ event_iterations_limit : T_EVENT_ITER_LIMIT T_NUMBER
CONFIG(event_iterations_limit) = $2;
};
+poll_secs: T_POLL_SECS T_NUMBER
+{
+ conf.flags |= CTD_POLL;
+ conf.poll_kernel_secs = $2;
+ if (conf.poll_kernel_secs == 0) {
+ fprintf(stderr, "ERROR: `PollSecs' clause must be > 0\n");
+ exit(EXIT_FAILURE);
+ }
+};
+
filter : T_FILTER '{' filter_list '}'
{
CONFIG(filter_from_kernelspace) = 0;
diff --git a/src/run.c b/src/run.c
index a6dfe15..a483ab3 100644
--- a/src/run.c
+++ b/src/run.c
@@ -39,7 +39,8 @@ void killer(int foo)
/* no signals while handling signals */
sigprocmask(SIG_BLOCK, &STATE(block), NULL);
- nfct_close(STATE(event));
+ if (!(CONFIG(flags) & CTD_POLL))
+ nfct_close(STATE(event));
nfct_close(STATE(request));
if (STATE(us_filter))
@@ -204,12 +205,18 @@ void local_handler(int fd, void *data)
STATE(stats).local_unknown_request++;
}
-static void do_resync_alarm(struct alarm_block *a, void *data)
+static void do_overrun_resync_alarm(struct alarm_block *a, void *data)
{
nl_send_resync(STATE(resync));
STATE(stats).nl_kernel_table_resync++;
}
+static void do_poll_resync_alarm(struct alarm_block *a, void *data)
+{
+ nl_send_resync(STATE(resync));
+ add_alarm(&STATE(resync_alarm), CONFIG(poll_kernel_secs), 0);
+}
+
static int event_handler(enum nf_conntrack_msg_type type,
struct nf_conntrack *ct,
void *data)
@@ -297,15 +304,18 @@ init(void)
}
register_fd(STATE(local).fd, STATE(fds));
- STATE(event) = nl_init_event_handler();
- if (STATE(event) == NULL) {
- dlog(LOG_ERR, "can't open netlink handler: %s",
- strerror(errno));
- dlog(LOG_ERR, "no ctnetlink kernel support?");
- return -1;
+ if (!(CONFIG(flags) & CTD_POLL)) {
+ STATE(event) = nl_init_event_handler();
+ if (STATE(event) == NULL) {
+ dlog(LOG_ERR, "can't open netlink handler: %s",
+ strerror(errno));
+ dlog(LOG_ERR, "no ctnetlink kernel support?");
+ return -1;
+ }
+ nfct_callback_register(STATE(event), NFCT_T_ALL,
+ event_handler, NULL);
+ register_fd(nfct_fd(STATE(event)), STATE(fds));
}
- nfct_callback_register(STATE(event), NFCT_T_ALL, event_handler, NULL);
- register_fd(nfct_fd(STATE(event)), STATE(fds));
STATE(dump) = nl_init_dump_handler();
if (STATE(dump) == NULL) {
@@ -343,7 +353,13 @@ init(void)
return -1;
}
- init_alarm(&STATE(resync_alarm), NULL, do_resync_alarm);
+ if (CONFIG(flags) & CTD_POLL) {
+ init_alarm(&STATE(resync_alarm), NULL, do_poll_resync_alarm);
+ add_alarm(&STATE(resync_alarm), CONFIG(poll_kernel_secs), 0);
+ dlog(LOG_NOTICE, "running in polling mode");
+ } else {
+ init_alarm(&STATE(resync_alarm), NULL, do_overrun_resync_alarm);
+ }
/* Signals handling */
sigemptyset(&STATE(block));
@@ -397,7 +413,8 @@ static void __run(struct timeval *next_alarm)
do_local_server_step(&STATE(local), NULL, local_handler);
/* conntrack event has happened */
- if (FD_ISSET(nfct_fd(STATE(event)), &readfds)) {
+ if (!(CONFIG(flags) & CTD_POLL) &&
+ FD_ISSET(nfct_fd(STATE(event)), &readfds)) {
ret = nfct_catch(STATE(event));
if (ret == -1) {
switch(errno) {