summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog1
-rw-r--r--include/Makefile.am2
-rw-r--r--include/alarm.h2
-rw-r--r--include/conntrackd.h2
-rw-r--r--include/sync.h2
-rw-r--r--include/timer.h17
-rw-r--r--src/Makefile.am1
-rw-r--r--src/alarm.c74
-rw-r--r--src/cache_timer.c8
-rw-r--r--src/main.c2
-rw-r--r--src/run.c47
-rw-r--r--src/sync-alarm.c14
-rw-r--r--src/sync-ftfw.c60
-rw-r--r--src/sync-mode.c4
-rw-r--r--src/timer.c75
15 files changed, 103 insertions, 208 deletions
diff --git a/ChangeLog b/ChangeLog
index 6d0bdc0..8634c1e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -33,6 +33,7 @@ o obsolete `-S' option: Use information provided by the config file
o daemonize conntrackd after initialization
o rename class `buffer' to `queue' which is what it really implements
o fix logfiles permissions, do not default to umask
+o wake up the daemon iff there are real events to handle instead of polling
version 0.9.5 (2007/07/29)
------------------------------
diff --git a/include/Makefile.am b/include/Makefile.am
index 7eaca35..4322f26 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -2,5 +2,5 @@
noinst_HEADERS = alarm.h jhash.h slist.h cache.h linux_list.h \
sync.h conntrackd.h local.h us-conntrack.h \
debug.h log.h hash.h mcast.h buffer.h conntrack.h \
- state_helper.h network.h ignore.h timer.h queue.h
+ state_helper.h network.h ignore.h queue.h
diff --git a/include/alarm.h b/include/alarm.h
index 93e6482..82a1612 100644
--- a/include/alarm.h
+++ b/include/alarm.h
@@ -5,7 +5,7 @@
struct alarm_list {
struct list_head head;
- unsigned long expires;
+ struct timeval tv;
void *data;
void (*function)(struct alarm_list *a, void *data);
};
diff --git a/include/conntrackd.h b/include/conntrackd.h
index 3bfcf18..e8b90cc 100644
--- a/include/conntrackd.h
+++ b/include/conntrackd.h
@@ -159,7 +159,7 @@ extern struct ct_general_state st;
struct ct_mode {
int (*init)(void);
int (*add_fds_to_set)(fd_set *readfds);
- void (*run)(fd_set *readfds, int step);
+ void (*run)(fd_set *readfds);
int (*local)(int fd, int type, void *data);
void (*kill)(void);
void (*dump)(struct nf_conntrack *ct);
diff --git a/include/sync.h b/include/sync.h
index a27fb93..e6ce327 100644
--- a/include/sync.h
+++ b/include/sync.h
@@ -15,7 +15,7 @@ struct sync_mode {
int (*local)(int fd, int type, void *data);
int (*recv)(const struct nethdr *net);
void (*send)(struct nethdr *net, struct us_conntrack *u);
- void (*run)(int step);
+ void (*run)(void);
};
extern struct sync_mode alarm;
diff --git a/include/timer.h b/include/timer.h
deleted file mode 100644
index 37b0fc9..0000000
--- a/include/timer.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef _TIMER_H_
-#define _TIMER_H_
-
-#include <sys/time.h>
-
-struct timer {
- long credits;
- struct timeval start;
- struct timeval stop;
- struct timeval diff;
-};
-
-#define GET_CREDITS(x) x.credits
-#define GET_STARTTIME(x) x.start
-#define GET_STOPTIME(x) x.stop
-
-#endif
diff --git a/src/Makefile.am b/src/Makefile.am
index a7e82cf..c2e684a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -19,7 +19,6 @@ conntrackd_SOURCES = alarm.c main.c run.c hash.c queue.c buffer.c \
traffic_stats.c stats-mode.c \
network.c \
state_helper.c state_helper_tcp.c \
- timer.c \
build.c parse.c \
read_config_yy.y read_config_lex.l
diff --git a/src/alarm.c b/src/alarm.c
index b4db167..e1d2e24 100644
--- a/src/alarm.c
+++ b/src/alarm.c
@@ -18,6 +18,7 @@
#include <unistd.h>
#include <stdlib.h>
+#include <sys/time.h>
#include "linux_list.h"
#include "conntrackd.h"
#include "alarm.h"
@@ -25,23 +26,16 @@
#include <time.h>
#include <errno.h>
-/* alarm cascade */
-#define ALARM_CASCADE_SIZE STEPS_PER_SECONDS
-static struct list_head *alarm_cascade;
+static LIST_HEAD(alarm_list);
-struct alarm_list *create_alarm()
-{
- return (struct alarm_list *) malloc(sizeof(struct alarm_list));
-}
-
-void destroy_alarm(struct alarm_list *t)
+void set_alarm_expiration_secs(struct alarm_list *t, unsigned long expires)
{
- free(t);
+ t->tv.tv_sec = expires;
}
-void set_alarm_expiration(struct alarm_list *t, unsigned long expires)
+void set_alarm_expiration_usecs(struct alarm_list *t, unsigned long expires)
{
- t->expires = expires;
+ t->tv.tv_usec = expires;
}
void set_alarm_function(struct alarm_list *t,
@@ -59,16 +53,18 @@ void init_alarm(struct alarm_list *t)
{
INIT_LIST_HEAD(&t->head);
- t->expires = 0;
+ timerclear(&t->tv);
t->data = 0;
t->function = NULL;
}
void add_alarm(struct alarm_list *alarm)
{
- unsigned int pos = jhash(alarm, sizeof(alarm), 0) % ALARM_CASCADE_SIZE;
+ struct timeval tv;
- list_add(&alarm->head, &alarm_cascade[pos]);
+ gettimeofday(&tv, NULL);
+ alarm->tv.tv_sec += tv.tv_sec;
+ list_add_tail(&alarm->head, &alarm_list);
}
void del_alarm(struct alarm_list *alarm)
@@ -76,41 +72,35 @@ void del_alarm(struct alarm_list *alarm)
list_del(&alarm->head);
}
-int mod_alarm(struct alarm_list *alarm, unsigned long expires)
+void mod_alarm(struct alarm_list *alarm, unsigned long sc, unsigned long usc)
{
- alarm->expires = expires;
- return 0;
+ struct timeval tv;
+
+ list_del(&alarm->head);
+ INIT_LIST_HEAD(&alarm->head);
+ gettimeofday(&tv, NULL);
+ alarm->tv.tv_sec = tv.tv_sec + sc;
+ alarm->tv.tv_usec = tv.tv_usec + usc;
+ list_add_tail(&alarm->head, &alarm_list);
}
-void do_alarm_run(int step)
+void do_alarm_run(struct timeval *next_alarm)
{
struct list_head *i, *tmp;
struct alarm_list *t;
+ struct timeval tv;
- list_for_each_safe(i, tmp, &alarm_cascade[step]) {
- t = (struct alarm_list *) i;
-
- t->expires--;
- if (t->expires == 0)
- t->function(t, t->data);
- }
-}
+ gettimeofday(&tv, NULL);
-int init_alarm_scheduler()
-{
- int i;
-
- alarm_cascade = malloc(sizeof(struct list_head) * ALARM_CASCADE_SIZE);
- if (alarm_cascade == NULL)
- return -1;
+ list_for_each_safe(i, tmp, &alarm_list) {
+ t = (struct alarm_list *) i;
- for (i=0; i<ALARM_CASCADE_SIZE; i++)
- INIT_LIST_HEAD(&alarm_cascade[i]);
+ if (timercmp(&t->tv, &tv, >)) {
+ timersub(&t->tv, &tv, next_alarm);
+ break;
+ }
- return 0;
-}
-
-void destroy_alarm_scheduler()
-{
- free(alarm_cascade);
+ del_alarm(t);
+ t->function(t, t->data);
+ }
}
diff --git a/src/cache_timer.c b/src/cache_timer.c
index f3940f3..c0075f5 100644
--- a/src/cache_timer.c
+++ b/src/cache_timer.c
@@ -17,6 +17,7 @@
*/
#include <stdio.h>
+#include <sys/time.h>
#include "conntrackd.h"
#include "us-conntrack.h"
#include "cache.h"
@@ -35,7 +36,7 @@ static void timer_add(struct us_conntrack *u, void *data)
struct alarm_list *alarm = data;
init_alarm(alarm);
- set_alarm_expiration(alarm, CONFIG(cache_timeout));
+ set_alarm_expiration_secs(alarm, CONFIG(cache_timeout));
set_alarm_data(alarm, u);
set_alarm_function(alarm, timeout);
add_alarm(alarm);
@@ -55,12 +56,15 @@ static void timer_destroy(struct us_conntrack *u, void *data)
static int timer_dump(struct us_conntrack *u, void *data, char *buf, int type)
{
+ struct timeval tv, tmp;
struct alarm_list *alarm = data;
if (type == NFCT_O_XML)
return 0;
- return sprintf(buf, " [expires in %ds]", alarm->expires);
+ gettimeofday(&tv, NULL);
+ timersub(&tv, &alarm->tv, &tmp);
+ return sprintf(buf, " [expires in %ds]", tmp.tv_sec);
}
struct cache_feature timer_feature = {
diff --git a/src/main.c b/src/main.c
index 33235e9..19d999a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -246,7 +246,7 @@ int main(int argc, char *argv[])
/*
* Setting up logging
*/
- if (config_set && init_log() == -1)
+ if (init_log() == -1)
exit(EXIT_FAILURE);
if (type == REQUEST) {
diff --git a/src/run.c b/src/run.c
index 609b454..3dc8ecc 100644
--- a/src/run.c
+++ b/src/run.c
@@ -25,7 +25,6 @@
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
-#include "timer.h"
void killer(int foo)
{
@@ -38,7 +37,6 @@ void killer(int foo)
ignore_pool_destroy(STATE(ignore_pool));
local_server_destroy(STATE(local));
STATE(mode)->kill();
- destroy_alarm_scheduler();
unlink(CONFIG(lockfile));
dlog(STATE(log), LOG_NOTICE, "---- shutdown received ----");
close_log();
@@ -103,11 +101,6 @@ int init(void)
return -1;
}
- if (init_alarm_scheduler() == -1) {
- dlog(STATE(log), LOG_ERR, "can't initialize alarm scheduler");
- return -1;
- }
-
/* local UNIX socket */
STATE(local) = local_server_create(&CONFIG(local));
if (!STATE(local)) {
@@ -151,14 +144,10 @@ int init(void)
return 0;
}
-static void __run(long credit, int step)
+static int __run(struct timeval *next_alarm)
{
int max, ret;
fd_set readfds;
- struct timeval tv = {
- .tv_sec = 0,
- .tv_usec = credit,
- };
FD_ZERO(&readfds);
FD_SET(STATE(local), &readfds);
@@ -169,7 +158,7 @@ static void __run(long credit, int step)
if (STATE(mode)->add_fds_to_set)
max = MAX(max, STATE(mode)->add_fds_to_set(&readfds));
- ret = select(max+1, &readfds, NULL, NULL, &tv);
+ ret = select(max+1, &readfds, NULL, NULL, next_alarm);
if (ret == -1) {
/* interrupted syscall, retry */
if (errno == EINTR)
@@ -180,6 +169,10 @@ static void __run(long credit, int step)
return;
}
+ /* timeout expired, run the alarm list */
+ if (ret == 0)
+ return 1;
+
/* signals are racy */
sigprocmask(SIG_BLOCK, &STATE(block), NULL);
@@ -221,35 +214,25 @@ static void __run(long credit, int step)
}
if (STATE(mode)->run)
- STATE(mode)->run(&readfds, step);
+ STATE(mode)->run(&readfds);
sigprocmask(SIG_UNBLOCK, &STATE(block), NULL);
+
+ return 0;
}
void run(void)
{
- int step = 0;
- struct timer timer;
-
- timer_init(&timer);
+ struct timeval next_alarm = {
+ .tv_sec = 1,
+ .tv_usec = 0
+ };
while(1) {
- timer_start(&timer);
- __run(GET_CREDITS(timer), step);
- timer_stop(&timer);
-
- if (timer_adjust_credit(&timer)) {
- timer_start(&timer);
+ if (__run(&next_alarm)) {
sigprocmask(SIG_BLOCK, &STATE(block), NULL);
- do_alarm_run(step);
+ do_alarm_run(&next_alarm);
sigprocmask(SIG_UNBLOCK, &STATE(block), NULL);
- timer_stop(&timer);
-
- if (timer_adjust_credit(&timer))
- dlog(STATE(log), LOG_WARNING,
- "alarm run takes too long!");
-
- step = (step + 1) < STEPS_PER_SECONDS ? step + 1 : 0;
}
}
}
diff --git a/src/sync-alarm.c b/src/sync-alarm.c
index a0791ac..632eff2 100644
--- a/src/sync-alarm.c
+++ b/src/sync-alarm.c
@@ -30,7 +30,14 @@ static void refresher(struct alarm_list *a, void *data)
debug_ct(u->ct, "persistence update");
- a->expires = random() % CONFIG(refresh) + 1;
+ init_alarm(a);
+ set_alarm_expiration_secs(a, random() % CONFIG(refresh) + 1);
+ set_alarm_expiration_usecs(a, random() % 999999 + 1);
+
+ set_alarm_data(a, u);
+ set_alarm_function(a, refresher);
+ add_alarm(a);
+
net = BUILD_NETMSG(u->ct, NFCT_Q_UPDATE);
len = prepare_send_netmsg(STATE_SYNC(mcast_client), net);
mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net, len);
@@ -41,7 +48,8 @@ static void cache_alarm_add(struct us_conntrack *u, void *data)
struct alarm_list *alarm = data;
init_alarm(alarm);
- set_alarm_expiration(alarm, (random() % conf.refresh) + 1);
+ set_alarm_expiration_secs(alarm, random() % CONFIG(refresh) + 1);
+ set_alarm_expiration_usecs(alarm, random() % 999999 + 1);
set_alarm_data(alarm, u);
set_alarm_function(alarm, refresher);
add_alarm(alarm);
@@ -50,7 +58,7 @@ static void cache_alarm_add(struct us_conntrack *u, void *data)
static void cache_alarm_update(struct us_conntrack *u, void *data)
{
struct alarm_list *alarm = data;
- mod_alarm(alarm, (random() % conf.refresh) + 1);
+ mod_alarm(alarm, random() % CONFIG(refresh) + 1, random() % 999999 + 1);
}
static void cache_alarm_destroy(struct us_conntrack *u, void *data)
diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c
index c3b9f61..ac1b8b6 100644
--- a/src/sync-ftfw.c
+++ b/src/sync-ftfw.c
@@ -70,6 +70,29 @@ static struct cache_extra cache_ftfw_extra = {
.destroy = cache_ftfw_del
};
+static void tx_queue_add_ctlmsg(u_int32_t flags, u_int32_t from, u_int32_t to)
+{
+ struct nethdr_ack ack = {
+ .flags = flags,
+ .from = from,
+ .to = to,
+ };
+
+ queue_add(tx_queue, &ack, NETHDR_ACK_SIZ);
+}
+
+static struct alarm_list alive_alarm;
+
+static void do_alive_alarm(struct alarm_list *a, void *data)
+{
+ tx_queue_add_ctlmsg(NET_F_ALIVE, 0, 0);
+
+ init_alarm(&alive_alarm);
+ set_alarm_expiration_secs(&alive_alarm, 1);
+ set_alarm_function(&alive_alarm, do_alive_alarm);
+ add_alarm(&alive_alarm);
+}
+
static int ftfw_init()
{
tx_queue = queue_create(CONFIG(resend_queue_size));
@@ -87,6 +110,12 @@ static int ftfw_init()
INIT_LIST_HEAD(&tx_list);
INIT_LIST_HEAD(&rs_list);
+ /* XXX: alive message expiration configurable */
+ init_alarm(&alive_alarm);
+ set_alarm_expiration_secs(&alive_alarm, 1);
+ set_alarm_function(&alive_alarm, do_alive_alarm);
+ add_alarm(&alive_alarm);
+
return 0;
}
@@ -96,17 +125,6 @@ static void ftfw_kill()
queue_destroy(tx_queue);
}
-static void tx_queue_add_ctlmsg(u_int32_t flags, u_int32_t from, u_int32_t to)
-{
- struct nethdr_ack ack = {
- .flags = flags,
- .from = from,
- .to = to,
- };
-
- queue_add(tx_queue, &ack, NETHDR_ACK_SIZ);
-}
-
static int do_cache_to_tx(void *data1, void *data2)
{
struct us_conntrack *u = data2;
@@ -317,15 +335,7 @@ static int tx_list_xmit(struct list_head *i, struct us_conntrack *u)
return ret;
}
-static struct alarm_list alive_alarm;
-
-static void do_alive_alarm(struct alarm_list *a, void *data)
-{
- del_alarm(a);
- tx_queue_add_ctlmsg(NET_F_ALIVE, 0, 0);
-}
-
-static void ftfw_run(int step)
+static void ftfw_run()
{
struct list_head *i, *tmp;
@@ -342,15 +352,7 @@ static void ftfw_run(int step)
tx_list_xmit(i, u);
}
- if (alive_alarm.expires > 0)
- mod_alarm(&alive_alarm, 1);
- else {
- init_alarm(&alive_alarm);
- /* XXX: alive message expiration configurable */
- set_alarm_expiration(&alive_alarm, 1);
- set_alarm_function(&alive_alarm, do_alive_alarm);
- add_alarm(&alive_alarm);
- }
+ mod_alarm(&alive_alarm, 1, 0);
}
struct sync_mode ftfw = {
diff --git a/src/sync-mode.c b/src/sync-mode.c
index a90e529..3bd6f59 100644
--- a/src/sync-mode.c
+++ b/src/sync-mode.c
@@ -198,14 +198,14 @@ static int add_fds_to_set_sync(fd_set *readfds)
return STATE_SYNC(mcast_server->fd);
}
-static void run_sync(fd_set *readfds, int step)
+static void run_sync(fd_set *readfds)
{
/* multicast packet has been received */
if (FD_ISSET(STATE_SYNC(mcast_server->fd), readfds))
mcast_handler();
if (STATE_SYNC(sync)->run)
- STATE_SYNC(sync)->run(step);
+ STATE_SYNC(sync)->run();
/* flush pending messages */
mcast_buffered_pending_netmsg(STATE_SYNC(mcast_client));
diff --git a/src/timer.c b/src/timer.c
deleted file mode 100644
index b85c286..0000000
--- a/src/timer.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * (C) 2006-2007 by Pablo Neira Ayuso <pablo@netfilter.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-#include "conntrackd.h"
-#include "timer.h"
-
-#define TIMESLICE_CREDIT (1000000 / STEPS_PER_SECONDS) /* 200 ms timeslice */
-
-void timer_init(struct timer *timer)
-{
- memset(timer, 0, sizeof(struct timer));
- timer->credits = TIMESLICE_CREDIT;
-}
-
-void timer_start(struct timer *timer)
-{
- gettimeofday(&timer->start, NULL);
-}
-
-static int timeval_subtract(struct timeval *diff,
- struct timeval *start,
- struct timeval *stop)
-{
- diff->tv_sec = stop->tv_sec - start->tv_sec;
- diff->tv_usec = stop->tv_usec - start->tv_usec;
-
- if (diff->tv_usec < 0) {
- diff->tv_usec += 1000000;
- diff->tv_sec--;
- }
-
- /* Return 1 if result is negative. */
- return diff->tv_sec < 0;
-}
-
-void timer_stop(struct timer *timer)
-{
- gettimeofday(&timer->stop, NULL);
- timeval_subtract(&timer->diff, &timer->start, &timer->stop);
-}
-
-int timer_adjust_credit(struct timer *timer)
-{
- if (timer->diff.tv_sec != 0) {
- timer->credits = TIMESLICE_CREDIT;
- return 1;
- }
-
- timer->credits -= timer->diff.tv_usec;
-
- if (timer->credits < 0) {
- timer->credits += TIMESLICE_CREDIT;
- if (timer->credits < 0)
- timer->credits = TIMESLICE_CREDIT;
- return 1;
- }
- return 0;
-}