From 5bac4f06e8ebc81ed16ec93a0db8682e6a359608 Mon Sep 17 00:00:00 2001 From: "/C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org" Date: Fri, 21 Dec 2007 18:04:49 +0000 Subject: o Use more appropriate names for the existing synchronization modes: o rename `persistent' mode to `alarm' o rename `nack' mode to `ftfw' o Now default synchronization mode is ftfw instead of alarm --- src/sync-alarm.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 src/sync-alarm.c (limited to 'src/sync-alarm.c') diff --git a/src/sync-alarm.c b/src/sync-alarm.c new file mode 100644 index 0000000..a0791ac --- /dev/null +++ b/src/sync-alarm.c @@ -0,0 +1,104 @@ +/* + * (C) 2006-2007 by Pablo Neira Ayuso + * + * 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 "conntrackd.h" +#include "sync.h" +#include "network.h" +#include "us-conntrack.h" +#include "alarm.h" + +static void refresher(struct alarm_list *a, void *data) +{ + int len; + struct nethdr *net; + struct us_conntrack *u = data; + + debug_ct(u->ct, "persistence update"); + + a->expires = random() % CONFIG(refresh) + 1; + 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); +} + +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_data(alarm, u); + set_alarm_function(alarm, refresher); + add_alarm(alarm); +} + +static void cache_alarm_update(struct us_conntrack *u, void *data) +{ + struct alarm_list *alarm = data; + mod_alarm(alarm, (random() % conf.refresh) + 1); +} + +static void cache_alarm_destroy(struct us_conntrack *u, void *data) +{ + struct alarm_list *alarm = data; + del_alarm(alarm); +} + +static struct cache_extra cache_alarm_extra = { + .size = sizeof(struct alarm_list), + .add = cache_alarm_add, + .update = cache_alarm_update, + .destroy = cache_alarm_destroy +}; + +static int alarm_recv(const struct nethdr *net) +{ + unsigned int exp_seq; + + /* + * Ignore error messages: Although this message type is not ever + * generated in alarm mode, we don't want to crash the daemon + * if someone nuts mixes ftfw and alarm. + */ + if (net->flags) + return 1; + + /* + * Multicast sequence tracking: we keep track of multicast messages + * although we don't do any explicit message recovery. So, why do + * we do sequence tracking? Just to let know the sysadmin. + * + * Let t be 1 < t < RefreshTime. To ensure consistency, conntrackd + * retransmit every t seconds a message with the state of a certain + * entry even if such entry did not change. This mechanism also + * provides passive resynchronization, in other words, there is + * no facility to request a full synchronization from new nodes that + * just joined the cluster, instead they just get resynchronized in + * RefreshTime seconds at worst case. + */ + mcast_track_seq(net->seq, &exp_seq); + + return 0; +} + +struct sync_mode alarm = { + .internal_cache_flags = LIFETIME, + .external_cache_flags = TIMER | LIFETIME, + .internal_cache_extra = &cache_alarm_extra, + .recv = alarm_recv, +}; -- cgit v1.2.3 From 920b90f2b03c60b6940e83cdce8c4b4bfbbc4268 Mon Sep 17 00:00:00 2001 From: "/C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org" Date: Wed, 9 Jan 2008 22:52:31 +0000 Subject: wake up the daemon iff there are real events to handle instead of polling (Based on comments from Max Kellerman) --- ChangeLog | 1 + include/Makefile.am | 2 +- include/alarm.h | 2 +- include/conntrackd.h | 2 +- include/sync.h | 2 +- include/timer.h | 17 ------------ src/Makefile.am | 1 - src/alarm.c | 74 ++++++++++++++++++++++----------------------------- src/cache_timer.c | 8 ++++-- src/main.c | 2 +- src/run.c | 47 +++++++++++--------------------- src/sync-alarm.c | 14 +++++++--- src/sync-ftfw.c | 60 +++++++++++++++++++++-------------------- src/sync-mode.c | 4 +-- src/timer.c | 75 ---------------------------------------------------- 15 files changed, 103 insertions(+), 208 deletions(-) delete mode 100644 include/timer.h delete mode 100644 src/timer.c (limited to 'src/sync-alarm.c') 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 - -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 #include +#include #include "linux_list.h" #include "conntrackd.h" #include "alarm.h" @@ -25,23 +26,16 @@ #include #include -/* 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; itv, &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 +#include #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 #include #include -#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 - * - * 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 -#include -#include -#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; -} -- cgit v1.2.3 From 6e5b6c91625fd431ac3d1339f55a4aa278ff2604 Mon Sep 17 00:00:00 2001 From: "/C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org" Date: Mon, 14 Jan 2008 15:22:24 +0000 Subject: improve alarm framework based on suggestions from Max Duempel --- ChangeLog | 1 + include/alarm.h | 7 +++++++ src/alarm.c | 33 ++++++++++++++++++--------------- src/cache_timer.c | 2 +- src/run.c | 15 ++++++++------- src/sync-alarm.c | 10 ++++++---- src/sync-ftfw.c | 4 ++-- 7 files changed, 43 insertions(+), 29 deletions(-) (limited to 'src/sync-alarm.c') diff --git a/ChangeLog b/ChangeLog index 6d4759a..c090831 100644 --- a/ChangeLog +++ b/ChangeLog @@ -38,6 +38,7 @@ 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 o add support for tagged vlan interfaces in the config file, e.g. eth0.1 +o improve alarm framework based on suggestions from Max Duempel version 0.9.5 (2007/07/29) ------------------------------ diff --git a/include/alarm.h b/include/alarm.h index 82a1612..fbe34f6 100644 --- a/include/alarm.h +++ b/include/alarm.h @@ -10,4 +10,11 @@ struct alarm_list { void (*function)(struct alarm_list *a, void *data); }; +static inline void +set_alarm_expiration(struct alarm_list *t, long tv_sec, long tv_usec) +{ + t->tv.tv_sec = tv_sec; + t->tv.tv_usec = tv_usec; +} + #endif diff --git a/src/alarm.c b/src/alarm.c index e1d2e24..eb2226b 100644 --- a/src/alarm.c +++ b/src/alarm.c @@ -28,16 +28,6 @@ static LIST_HEAD(alarm_list); -void set_alarm_expiration_secs(struct alarm_list *t, unsigned long expires) -{ - t->tv.tv_sec = expires; -} - -void set_alarm_expiration_usecs(struct alarm_list *t, unsigned long expires) -{ - t->tv.tv_usec = expires; -} - void set_alarm_function(struct alarm_list *t, void (*fcn)(struct alarm_list *a, void *data)) { @@ -51,8 +41,6 @@ void set_alarm_data(struct alarm_list *t, void *data) void init_alarm(struct alarm_list *t) { - INIT_LIST_HEAD(&t->head); - timerclear(&t->tv); t->data = 0; t->function = NULL; @@ -77,14 +65,26 @@ void mod_alarm(struct alarm_list *alarm, unsigned long sc, unsigned long usc) 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(struct timeval *next_alarm) +int get_next_alarm(struct timeval *tv, struct timeval *next_alarm) +{ + struct list_head *i; + struct alarm_list *t; + + list_for_each(i, &alarm_list) { + t = (struct alarm_list *) i; + timersub(&t->tv, tv, next_alarm); + return 1; + } + return 0; +} + +int do_alarm_run(struct timeval *next_alarm) { struct list_head *i, *tmp; struct alarm_list *t; @@ -97,10 +97,13 @@ void do_alarm_run(struct timeval *next_alarm) if (timercmp(&t->tv, &tv, >)) { timersub(&t->tv, &tv, next_alarm); - break; + return 1; } del_alarm(t); t->function(t, t->data); } + + /* check for refreshed alarms to get the next one */ + return get_next_alarm(&tv, next_alarm); } diff --git a/src/cache_timer.c b/src/cache_timer.c index c0075f5..02f3ae4 100644 --- a/src/cache_timer.c +++ b/src/cache_timer.c @@ -36,7 +36,7 @@ static void timer_add(struct us_conntrack *u, void *data) struct alarm_list *alarm = data; init_alarm(alarm); - set_alarm_expiration_secs(alarm, CONFIG(cache_timeout)); + set_alarm_expiration(alarm, CONFIG(cache_timeout), 0); set_alarm_data(alarm, u); set_alarm_function(alarm, timeout); add_alarm(alarm); diff --git a/src/run.c b/src/run.c index eab3ad2..3481193 100644 --- a/src/run.c +++ b/src/run.c @@ -224,19 +224,20 @@ static int __run(struct timeval *next_alarm) void run(void) { - struct timeval next_alarm = { - .tv_sec = 1, - .tv_usec = 0 - }; + struct timeval next_alarm; struct timeval *next = &next_alarm; + struct timeval tv; - if (CONFIG(flags) & CTD_STATS_MODE) - next = NULL; + /* initialization: get the first alarm available */ + gettimeofday(&tv, NULL); + get_next_alarm(&tv, next); while(1) { if (__run(next)) { sigprocmask(SIG_BLOCK, &STATE(block), NULL); - do_alarm_run(next); + next = &next_alarm; + if (!do_alarm_run(next)) + next = NULL; /* no next alarms */ sigprocmask(SIG_UNBLOCK, &STATE(block), NULL); } } diff --git a/src/sync-alarm.c b/src/sync-alarm.c index 632eff2..3d20867 100644 --- a/src/sync-alarm.c +++ b/src/sync-alarm.c @@ -31,8 +31,9 @@ static void refresher(struct alarm_list *a, void *data) debug_ct(u->ct, "persistence update"); init_alarm(a); - set_alarm_expiration_secs(a, random() % CONFIG(refresh) + 1); - set_alarm_expiration_usecs(a, random() % 999999 + 1); + set_alarm_expiration(a, + random() % CONFIG(refresh) + 1, + random() % 999999 + 1); set_alarm_data(a, u); set_alarm_function(a, refresher); @@ -48,8 +49,9 @@ static void cache_alarm_add(struct us_conntrack *u, void *data) struct alarm_list *alarm = data; init_alarm(alarm); - set_alarm_expiration_secs(alarm, random() % CONFIG(refresh) + 1); - set_alarm_expiration_usecs(alarm, random() % 999999 + 1); + set_alarm_expiration(alarm, + random() % CONFIG(refresh) + 1, + random() % 999999 + 1); set_alarm_data(alarm, u); set_alarm_function(alarm, refresher); add_alarm(alarm); diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c index ac1b8b6..125e82e 100644 --- a/src/sync-ftfw.c +++ b/src/sync-ftfw.c @@ -88,7 +88,7 @@ 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_expiration(&alive_alarm, 1, 0); set_alarm_function(&alive_alarm, do_alive_alarm); add_alarm(&alive_alarm); } @@ -112,7 +112,7 @@ static int ftfw_init() /* XXX: alive message expiration configurable */ init_alarm(&alive_alarm); - set_alarm_expiration_secs(&alive_alarm, 1); + set_alarm_expiration(&alive_alarm, 1, 0); set_alarm_function(&alive_alarm, do_alive_alarm); add_alarm(&alive_alarm); -- cgit v1.2.3 From 4197eaf7b57056454cec3112683d84a3d0d7b194 Mon Sep 17 00:00:00 2001 From: "/C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org" Date: Tue, 15 Jan 2008 12:44:21 +0000 Subject: Max Kellermann : the global variable "alarm" conflicts with the alarm() function from unistd.h. resolve that conflict by giving those two global variables a better name. --- ChangeLog | 8 +++++++- include/sync.h | 4 ++-- src/sync-alarm.c | 2 +- src/sync-ftfw.c | 2 +- src/sync-mode.c | 6 +++--- 5 files changed, 14 insertions(+), 8 deletions(-) (limited to 'src/sync-alarm.c') diff --git a/ChangeLog b/ChangeLog index c090831..27f48b2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,8 @@ version 0.9.6 (yet unreleased) ------------------------------ +Pablo Neira Ayuso : + o fix compilation problem due to missing headers (Krisztian Kovacs) o include kernel options and Fedora comments in the INSTALL file o remove -lpthread during compilation @@ -38,7 +40,11 @@ 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 o add support for tagged vlan interfaces in the config file, e.g. eth0.1 -o improve alarm framework based on suggestions from Max Duempel +o improve alarm framework based on suggestions from Max Kellerman + +Max Kellermann : += conntrackd = +o resolve global variable "alarm" conflict with alarm() function in unistd.h. version 0.9.5 (2007/07/29) ------------------------------ diff --git a/include/sync.h b/include/sync.h index e6ce327..39e0f46 100644 --- a/include/sync.h +++ b/include/sync.h @@ -18,7 +18,7 @@ struct sync_mode { void (*run)(void); }; -extern struct sync_mode alarm; -extern struct sync_mode ftfw; +extern struct sync_mode sync_alarm; +extern struct sync_mode sync_ftfw; #endif diff --git a/src/sync-alarm.c b/src/sync-alarm.c index 3d20867..1dcfacd 100644 --- a/src/sync-alarm.c +++ b/src/sync-alarm.c @@ -106,7 +106,7 @@ static int alarm_recv(const struct nethdr *net) return 0; } -struct sync_mode alarm = { +struct sync_mode sync_alarm = { .internal_cache_flags = LIFETIME, .external_cache_flags = TIMER | LIFETIME, .internal_cache_extra = &cache_alarm_extra, diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c index 125e82e..23095c4 100644 --- a/src/sync-ftfw.c +++ b/src/sync-ftfw.c @@ -355,7 +355,7 @@ static void ftfw_run() mod_alarm(&alive_alarm, 1, 0); } -struct sync_mode ftfw = { +struct sync_mode sync_ftfw = { .internal_cache_flags = LIFETIME, .external_cache_flags = LIFETIME, .internal_cache_extra = &cache_ftfw_extra, diff --git a/src/sync-mode.c b/src/sync-mode.c index 16642c2..d38d91f 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -126,14 +126,14 @@ static int init_sync(void) memset(state.sync, 0, sizeof(struct ct_sync_state)); if (CONFIG(flags) & CTD_SYNC_FTFW) - STATE_SYNC(sync) = &ftfw; + STATE_SYNC(sync) = &sync_ftfw; else if (CONFIG(flags) & CTD_SYNC_ALARM) - STATE_SYNC(sync) = &alarm; + STATE_SYNC(sync) = &sync_alarm; else { fprintf(stderr, "WARNING: No synchronization mode specified. " "Defaulting to FT-FW mode.\n"); CONFIG(flags) |= CTD_SYNC_FTFW; - STATE_SYNC(sync) = &ftfw; + STATE_SYNC(sync) = &sync_ftfw; } if (STATE_SYNC(sync)->init) -- cgit v1.2.3 From a944cf07400e78ac17f559dd41a670427648c258 Mon Sep 17 00:00:00 2001 From: "/C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org" Date: Tue, 15 Jan 2008 13:10:23 +0000 Subject: Max Kellermann : set the return type of the parse functions to "void" --- ChangeLog | 1 + src/alarm.c | 19 +++++-------------- src/cache_timer.c | 4 +--- src/parse.c | 10 +++++----- src/sync-alarm.c | 8 ++------ src/sync-ftfw.c | 6 ++---- 6 files changed, 16 insertions(+), 32 deletions(-) (limited to 'src/sync-alarm.c') diff --git a/ChangeLog b/ChangeLog index 158a7d2..557ef83 100644 --- a/ChangeLog +++ b/ChangeLog @@ -54,6 +54,7 @@ o use const when possible o remove prefetch in slist.h since it confuses gcc o fix illegal use of return in the yacc code, use break instead o fix wrong invocations after prototype cleanup +o set the return type of the parse functions to "void" version 0.9.5 (2007/07/29) ------------------------------ diff --git a/src/alarm.c b/src/alarm.c index 2c65ef3..6edf68e 100644 --- a/src/alarm.c +++ b/src/alarm.c @@ -27,22 +27,13 @@ static LIST_HEAD(alarm_list); -void set_alarm_function(struct alarm_list *t, - void (*fcn)(struct alarm_list *a, void *data)) -{ - t->function = fcn; -} - -void set_alarm_data(struct alarm_list *t, void *data) -{ - t->data = data; -} - -void init_alarm(struct alarm_list *t) +void init_alarm(struct alarm_list *t, + void *data, + void (*fcn)(struct alarm_list *a, void *data)) { timerclear(&t->tv); - t->data = 0; - t->function = NULL; + t->data = data; + t->function = fcn; } void __add_alarm(struct alarm_list *alarm) diff --git a/src/cache_timer.c b/src/cache_timer.c index 2379f4b..8b4e4ea 100644 --- a/src/cache_timer.c +++ b/src/cache_timer.c @@ -35,10 +35,8 @@ static void timer_add(struct us_conntrack *u, void *data) { struct alarm_list *alarm = data; - init_alarm(alarm); + init_alarm(alarm, u, timeout); set_alarm_expiration(alarm, CONFIG(cache_timeout), 0); - set_alarm_data(alarm, u); - set_alarm_function(alarm, timeout); add_alarm(alarm); } diff --git a/src/parse.c b/src/parse.c index 0650995..c8a9704 100644 --- a/src/parse.c +++ b/src/parse.c @@ -20,27 +20,27 @@ #include #include "network.h" -static int parse_u8(struct nf_conntrack *ct, int attr, void *data) +static void parse_u8(struct nf_conntrack *ct, int attr, void *data) { u_int8_t *value = (u_int8_t *) data; nfct_set_attr_u8(ct, attr, *value); } -static int parse_u16(struct nf_conntrack *ct, int attr, void *data) +static void parse_u16(struct nf_conntrack *ct, int attr, void *data) { u_int16_t *value = (u_int16_t *) data; nfct_set_attr_u16(ct, attr, ntohs(*value)); } -static int parse_u32(struct nf_conntrack *ct, int attr, void *data) +static void parse_u32(struct nf_conntrack *ct, int attr, void *data) { u_int32_t *value = (u_int32_t *) data; nfct_set_attr_u32(ct, attr, ntohl(*value)); } -typedef int (*parse)(struct nf_conntrack *ct, int attr, void *data); +typedef void (*parse)(struct nf_conntrack *ct, int attr, void *data); -parse h[ATTR_MAX] = { +static parse h[ATTR_MAX] = { [ATTR_IPV4_SRC] = parse_u32, [ATTR_IPV4_DST] = parse_u32, [ATTR_L3PROTO] = parse_u8, diff --git a/src/sync-alarm.c b/src/sync-alarm.c index 1dcfacd..d9a8267 100644 --- a/src/sync-alarm.c +++ b/src/sync-alarm.c @@ -30,13 +30,11 @@ static void refresher(struct alarm_list *a, void *data) debug_ct(u->ct, "persistence update"); - init_alarm(a); + init_alarm(a, u, refresher); set_alarm_expiration(a, random() % CONFIG(refresh) + 1, random() % 999999 + 1); - set_alarm_data(a, u); - set_alarm_function(a, refresher); add_alarm(a); net = BUILD_NETMSG(u->ct, NFCT_Q_UPDATE); @@ -48,12 +46,10 @@ static void cache_alarm_add(struct us_conntrack *u, void *data) { struct alarm_list *alarm = data; - init_alarm(alarm); + init_alarm(alarm, u, refresher); set_alarm_expiration(alarm, random() % CONFIG(refresh) + 1, random() % 999999 + 1); - set_alarm_data(alarm, u); - set_alarm_function(alarm, refresher); add_alarm(alarm); } diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c index 0d57f36..63fd4b2 100644 --- a/src/sync-ftfw.c +++ b/src/sync-ftfw.c @@ -87,9 +87,8 @@ static void do_alive_alarm(struct alarm_list *a, void *data) { tx_queue_add_ctlmsg(NET_F_ALIVE, 0, 0); - init_alarm(&alive_alarm); + init_alarm(&alive_alarm, NULL, do_alive_alarm); set_alarm_expiration(&alive_alarm, 1, 0); - set_alarm_function(&alive_alarm, do_alive_alarm); add_alarm(&alive_alarm); } @@ -111,9 +110,8 @@ static int ftfw_init() INIT_LIST_HEAD(&rs_list); /* XXX: alive message expiration configurable */ - init_alarm(&alive_alarm); + init_alarm(&alive_alarm, NULL, do_alive_alarm); set_alarm_expiration(&alive_alarm, 1, 0); - set_alarm_function(&alive_alarm, do_alive_alarm); add_alarm(&alive_alarm); return 0; -- cgit v1.2.3 From 82290b2b0bd2ebb5539b61b98e993ae807c2e8d7 Mon Sep 17 00:00:00 2001 From: "/C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org" Date: Tue, 15 Jan 2008 14:00:14 +0000 Subject: Max Kellermann : Fix tons of gcc warnings --- ChangeLog | 3 ++- extensions/libct_proto_icmp.c | 2 +- extensions/libct_proto_tcp.c | 2 +- extensions/libct_proto_udp.c | 4 +--- include/cache.h | 2 +- include/conntrack.h | 8 ++++---- include/conntrackd.h | 4 ++++ include/debug.h | 4 ++-- include/linux_list.h | 2 +- include/log.h | 6 +++--- include/network.h | 2 +- src/alarm.c | 3 ++- src/buffer.c | 1 + src/cache.c | 28 ++++++++++++++------------- src/cache_iterators.c | 5 +++-- src/cache_lifetime.c | 2 ++ src/cache_timer.c | 2 +- src/cache_wt.c | 2 +- src/conntrack.c | 44 ++++++++++++++++++++++++++----------------- src/hash.c | 8 ++------ src/ignore_pool.c | 10 +++++++--- src/local.c | 2 +- src/log.c | 9 +++++---- src/main.c | 12 +++++++++--- src/mcast.c | 10 ++++++---- src/network.c | 5 ++--- src/read_config_yy.y | 2 +- src/run.c | 17 +++++++++++++---- src/stats-mode.c | 6 ++---- src/sync-alarm.c | 2 ++ src/sync-ftfw.c | 9 +++++---- src/sync-mode.c | 2 +- src/traffic_stats.c | 4 ++-- 33 files changed, 131 insertions(+), 93 deletions(-) (limited to 'src/sync-alarm.c') diff --git a/ChangeLog b/ChangeLog index 6543aaf..f42234a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -42,7 +42,6 @@ o wake up the daemon iff there are real events to handle instead of polling o add support for tagged vlan interfaces in the config file, e.g. eth0.1 o improve alarm framework based on suggestions from Max Kellerman o constify queue_iterate() -o use timeradd() since manipulating tv_sec directly Max Kellermann : @@ -63,6 +62,8 @@ o merge several *_alarm() functions into init_alarm() o use add_alarm() in mod_alarm() to avoid code duplication o import tcp_state_helper only once o add missing printf arguments +o use timeradd() since manipulating tv_sec directly +o fix lots of gcc warnings version 0.9.5 (2007/07/29) ------------------------------ diff --git a/extensions/libct_proto_icmp.c b/extensions/libct_proto_icmp.c index 09fd8da..7c59072 100644 --- a/extensions/libct_proto_icmp.c +++ b/extensions/libct_proto_icmp.c @@ -51,7 +51,7 @@ static char icmp_commands_v_options[NUMBER_OF_CMD][ICMP_NUMBER_OF_OPT] = /*EXP_EVENT*/ {0,0,0}, }; -static void help() +static void help(void) { fprintf(stdout, " --icmp-type\t\t\ticmp type\n"); fprintf(stdout, " --icmp-code\t\t\ticmp code\n"); diff --git a/extensions/libct_proto_tcp.c b/extensions/libct_proto_tcp.c index 1f630b3..a3b1826 100644 --- a/extensions/libct_proto_tcp.c +++ b/extensions/libct_proto_tcp.c @@ -73,7 +73,7 @@ static const char *states[] = { "LISTEN" }; -static void help() +static void help(void) { fprintf(stdout, " --orig-port-src\t\toriginal source port\n"); fprintf(stdout, " --orig-port-dst\t\toriginal destination port\n"); diff --git a/extensions/libct_proto_udp.c b/extensions/libct_proto_udp.c index 2216b71..267e3d6 100644 --- a/extensions/libct_proto_udp.c +++ b/extensions/libct_proto_udp.c @@ -38,7 +38,7 @@ static const char *udp_optflags[UDP_NUMBER_OF_OPT] = { "mask-port-dst", "tuple-port-src", "tuple-port-dst" }; -static void help() +static void help(void) { fprintf(stdout, " --orig-port-src\t\toriginal source port\n"); fprintf(stdout, " --orig-port-dst\t\toriginal destination port\n"); @@ -166,8 +166,6 @@ static void final_check(unsigned int flags, unsigned int cmd, struct nf_conntrack *ct) { - int ret = 0; - if ((flags & (UDP_ORIG_SPORT|UDP_ORIG_DPORT)) && !(flags & (UDP_REPL_SPORT|UDP_REPL_DPORT))) { nfct_set_attr_u16(ct, diff --git a/include/cache.h b/include/cache.h index 5ca6ce4..e4fb945 100644 --- a/include/cache.h +++ b/include/cache.h @@ -75,7 +75,7 @@ struct cache_extra { struct nf_conntrack; -struct cache *cache_create(char *name, unsigned int features, u_int8_t proto, struct cache_extra *extra); +struct cache *cache_create(const char *name, unsigned int features, u_int8_t proto, struct cache_extra *extra); void cache_destroy(struct cache *e); struct us_conntrack *cache_add(struct cache *c, struct nf_conntrack *ct); diff --git a/include/conntrack.h b/include/conntrack.h index 1b2581e..8f2b6a2 100644 --- a/include/conntrack.h +++ b/include/conntrack.h @@ -148,9 +148,9 @@ enum { struct ctproto_handler { struct list_head head; - char *name; + const char *name; u_int16_t protonum; - char *version; + const char *version; enum ctattr_protoinfo protoinfo_attr; @@ -164,7 +164,7 @@ struct ctproto_handler { unsigned int command, struct nf_conntrack *ct); - void (*help)(); + void (*help)(void); struct option *opts; @@ -181,7 +181,7 @@ void generic_opt_check(int options, int nops, char *optset, const char *optflg[]); -void exit_error(enum exittype status, char *msg, ...); +void exit_error(enum exittype status, const char *msg, ...); extern void register_proto(struct ctproto_handler *h); diff --git a/include/conntrackd.h b/include/conntrackd.h index 33732a4..d3f66ba 100644 --- a/include/conntrackd.h +++ b/include/conntrackd.h @@ -181,4 +181,8 @@ void local_handler(int fd, void *data); int init(void); void run(void); +/* from read_config_yy.c */ +int +init_config(char *filename); + #endif diff --git a/include/debug.h b/include/debug.h index 1ffd9ac..f205983 100644 --- a/include/debug.h +++ b/include/debug.h @@ -14,8 +14,8 @@ }) #define debug printf #else -#define debug_ct(ct, msg) -#define debug +#define debug_ct(ct, msg) do {} while (0) +#define debug(...) do {} while (0) #endif #endif diff --git a/include/linux_list.h b/include/linux_list.h index 57b56d7..b84b1c4 100644 --- a/include/linux_list.h +++ b/include/linux_list.h @@ -13,7 +13,7 @@ * */ #define container_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );}) /* diff --git a/include/log.h b/include/log.h index b5bbddb..64bf1ce 100644 --- a/include/log.h +++ b/include/log.h @@ -6,10 +6,10 @@ struct buffer; struct nf_conntrack; -int init_log(); -void dlog(FILE *fd, int priority, char *format, ...); +int init_log(void); +void dlog(FILE *fd, int priority, const char *format, ...); void dlog_buffered_ct(FILE *fd, struct buffer *b, struct nf_conntrack *ct); void dlog_buffered_ct_flush(void *buffer_data, void *data); -void close_log(); +void close_log(void); #endif diff --git a/include/network.h b/include/network.h index 88ff43b..d0b639b 100644 --- a/include/network.h +++ b/include/network.h @@ -60,7 +60,7 @@ int mcast_track_seq(u_int32_t seq, u_int32_t *exp_seq); struct mcast_conf; int mcast_buffered_init(struct mcast_conf *conf); -void mcast_buffered_destroy(); +void mcast_buffered_destroy(void); int mcast_buffered_send_netmsg(struct mcast_sock *m, void *data, int len); int mcast_buffered_pending_netmsg(struct mcast_sock *m); diff --git a/src/alarm.c b/src/alarm.c index 3467e7b..25075ef 100644 --- a/src/alarm.c +++ b/src/alarm.c @@ -36,7 +36,8 @@ void init_alarm(struct alarm_list *t, t->function = fcn; } -void __add_alarm(struct alarm_list *alarm) +static void +__add_alarm(struct alarm_list *alarm) { struct alarm_list *t; diff --git a/src/buffer.c b/src/buffer.c index 4f60123..79266a7 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -50,6 +50,7 @@ int buffer_add(struct buffer *b, void *data, unsigned int size) memcpy(b->data + b->cur_size, data, size); b->cur_size += size; + return 0; } void buffer_flush(struct buffer *b, diff --git a/src/cache.c b/src/cache.c index a0950d5..c5afb00 100644 --- a/src/cache.c +++ b/src/cache.c @@ -23,6 +23,7 @@ #include #include "us-conntrack.h" #include "cache.h" +#include static u_int32_t hash(const void *data, struct hashtable *table) { @@ -120,7 +121,7 @@ struct cache_feature *cache_feature[CACHE_MAX_FEATURE] = { [WRITE_THROUGH_FEATURE] = &writethrough_feature, }; -struct cache *cache_create(char *name, +struct cache *cache_create(const char *name, unsigned int features, u_int8_t proto, struct cache_extra *extra) @@ -209,7 +210,7 @@ void cache_destroy(struct cache *c) static struct us_conntrack *__add(struct cache *c, struct nf_conntrack *ct) { - int i; + unsigned i; size_t size = c->h->datasize; char buf[size]; struct us_conntrack *u = (struct us_conntrack *) buf; @@ -226,7 +227,7 @@ static struct us_conntrack *__add(struct cache *c, struct nf_conntrack *ct) u = hashtable_add(c->h, u); if (u) { - void *data = u->data; + char *data = u->data; for (i = 0; i < c->num_features; i++) { c->features[i]->add(u, data); @@ -234,7 +235,7 @@ static struct us_conntrack *__add(struct cache *c, struct nf_conntrack *ct) } if (c->extra && c->extra->add) - c->extra->add(u, ((void *) u) + c->extra_offset); + c->extra->add(u, ((char *) u) + c->extra_offset); return u; } @@ -268,8 +269,8 @@ static struct us_conntrack *__update(struct cache *c, struct nf_conntrack *ct) u = (struct us_conntrack *) hashtable_test(c->h, u); if (u) { - int i; - void *data = u->data; + unsigned i; + char *data = u->data; if (nfct_attr_is_set(ct, ATTR_STATUS)) nfct_set_attr_u32(u->ct, ATTR_STATUS, @@ -287,14 +288,15 @@ static struct us_conntrack *__update(struct cache *c, struct nf_conntrack *ct) } if (c->extra && c->extra->update) - c->extra->update(u, ((void *) u) + c->extra_offset); + c->extra->update(u, ((char *) u) + c->extra_offset); return u; } return NULL; } -struct us_conntrack *__cache_update(struct cache *c, struct nf_conntrack *ct) +static struct us_conntrack * +__cache_update(struct cache *c, struct nf_conntrack *ct) { struct us_conntrack *u; @@ -358,8 +360,8 @@ static int __del(struct cache *c, struct nf_conntrack *ct) u = (struct us_conntrack *) hashtable_test(c->h, u); if (u) { - int i; - void *data = u->data; + unsigned i; + char *data = u->data; struct nf_conntrack *p = u->ct; for (i = 0; i < c->num_features; i++) { @@ -368,7 +370,7 @@ static int __del(struct cache *c, struct nf_conntrack *ct) } if (c->extra && c->extra->destroy) - c->extra->destroy(u, ((void *) u) + c->extra_offset); + c->extra->destroy(u, ((char *) u) + c->extra_offset); hashtable_del(c->h, u); free(p); @@ -390,12 +392,12 @@ int cache_del(struct cache *c, struct nf_conntrack *ct) struct us_conntrack *cache_get_conntrack(struct cache *c, void *data) { - return data - c->extra_offset; + return (struct us_conntrack *)((char*)data - c->extra_offset); } void *cache_get_extra(struct cache *c, void *data) { - return data + c->extra_offset; + return (char*)data + c->extra_offset; } void cache_stats(const struct cache *c, int fd) diff --git a/src/cache_iterators.c b/src/cache_iterators.c index d43ae6f..4fdb920 100644 --- a/src/cache_iterators.c +++ b/src/cache_iterators.c @@ -19,6 +19,7 @@ #include "cache.h" #include "jhash.h" #include "hash.h" +#include "log.h" #include "conntrackd.h" #include "netlink.h" #include @@ -36,8 +37,8 @@ static int do_dump(void *data1, void *data2) int size; struct __dump_container *container = data1; struct us_conntrack *u = data2; - void *data = u->data; - int i; + char *data = u->data; + unsigned i; memset(buf, 0, sizeof(buf)); size = nfct_snprintf(buf, diff --git a/src/cache_lifetime.c b/src/cache_lifetime.c index ae54df2..26496d2 100644 --- a/src/cache_lifetime.c +++ b/src/cache_lifetime.c @@ -21,6 +21,8 @@ #include "us-conntrack.h" #include "cache.h" #include "alarm.h" +#include +#include static void lifetime_add(struct us_conntrack *u, void *data) { diff --git a/src/cache_timer.c b/src/cache_timer.c index 8b4e4ea..53ed703 100644 --- a/src/cache_timer.c +++ b/src/cache_timer.c @@ -62,7 +62,7 @@ static int timer_dump(struct us_conntrack *u, void *data, char *buf, int type) gettimeofday(&tv, NULL); timersub(&tv, &alarm->tv, &tmp); - return sprintf(buf, " [expires in %ds]", tmp.tv_sec); + return sprintf(buf, " [expires in %lds]", tmp.tv_sec); } struct cache_feature timer_feature = { diff --git a/src/cache_wt.c b/src/cache_wt.c index fee17e2..9d0af0b 100644 --- a/src/cache_wt.c +++ b/src/cache_wt.c @@ -25,7 +25,7 @@ static void add_update(struct us_conntrack *u) { char __ct[nfct_maxsize()]; - struct nf_conntrack *ct = (struct nf_conntrack *) __ct; + struct nf_conntrack *ct = (struct nf_conntrack *)(void*) __ct; memcpy(ct, u->ct, nfct_maxsize()); diff --git a/src/conntrack.c b/src/conntrack.c index 28340c1..f301a82 100644 --- a/src/conntrack.c +++ b/src/conntrack.c @@ -45,6 +45,8 @@ #include #include #include +#include +#include #ifdef HAVE_ARPA_INET_H #include #endif @@ -175,14 +177,15 @@ static struct ctproto_handler *findproto(char *name) return handler; } -void extension_help(struct ctproto_handler *h) +static void +extension_help(struct ctproto_handler *h) { fprintf(stdout, "\n"); fprintf(stdout, "Proto `%s' help:\n", h->name); h->help(); } -void +static void __attribute__((noreturn)) exit_tryhelp(int status) { fprintf(stderr, "Try `%s -h' or '%s --help' for more information.\n", @@ -190,7 +193,8 @@ exit_tryhelp(int status) exit(status); } -void exit_error(enum exittype status, char *msg, ...) +void __attribute__((noreturn)) +exit_error(enum exittype status, const char *msg, ...) { va_list args; @@ -281,7 +285,7 @@ merge_options(struct option *oldopts, const struct option *newopts, #define ENOTSUPP 524 /* Operation is not supported */ /* Translates errno numbers into more human-readable form than strerror. */ -const char * +static const char * err2str(int err, enum action command) { unsigned int i; @@ -318,7 +322,7 @@ err2str(int err, enum action command) #define PARSE_MAX 3 static struct parse_parameter { - char *parameter[6]; + const char *parameter[6]; size_t size; unsigned int value[6]; } parse_array[PARSE_MAX] = { @@ -336,7 +340,8 @@ static int do_parse_parameter(const char *str, size_t str_length, unsigned int *value, int parse_type) { - int i, ret = 0; + size_t i; + int ret = 0; struct parse_parameter *p = &parse_array[parse_type]; if (strncasecmp(str, "SRC_NAT", str_length) == 0) { @@ -384,7 +389,8 @@ add_command(unsigned int *cmd, const int newcmd, const int othercmds) *cmd |= newcmd; } -unsigned int check_type(int argc, char *argv[]) +static unsigned int +check_type(int argc, char *argv[]) { char *table = NULL; @@ -424,7 +430,8 @@ struct addr_parse { unsigned int family; }; -int parse_inetaddr(const char *cp, struct addr_parse *parse) +static int +parse_inetaddr(const char *cp, struct addr_parse *parse) { if (inet_aton(cp, &parse->addr)) return AF_INET; @@ -441,7 +448,8 @@ union ct_address { u_int32_t v6[4]; }; -int parse_addr(const char *cp, union ct_address *address) +static int +parse_addr(const char *cp, union ct_address *address) { struct addr_parse parse; int ret; @@ -458,7 +466,7 @@ int parse_addr(const char *cp, union ct_address *address) static void nat_parse(char *arg, int portok, struct nf_conntrack *obj, int type) { - char *colon, *dash, *error; + char *colon, *error; union ct_address parse; colon = strchr(arg, ':'); @@ -495,7 +503,8 @@ nat_parse(char *arg, int portok, struct nf_conntrack *obj, int type) nfct_set_attr_u32(obj, ATTR_DNAT_IPV4, parse.v4); } -static void event_sighandler(int s) +static void __attribute__((noreturn)) +event_sighandler(int s) { fprintf(stdout, "Now closing conntrack event dumping...\n"); nfct_close(cth); @@ -524,7 +533,6 @@ static const char usage_conntrack_parameters[] = " -e, --event-mask eventmask\t\tEvent mask, eg. NEW,DESTROY\n" " -z, --zero \t\t\t\tZero counters while listing\n" " -o, --output type[,...]\t\tOutput format, eg. xml\n"; - ; static const char usage_expectation_parameters[] = "Expectation parameters and options:\n" @@ -546,7 +554,9 @@ static const char usage_parameters[] = ; -void usage(char *prog) { +static void +usage(char *prog) +{ fprintf(stdout, "Command line interface for the connection " "tracking system. Version %s\n", VERSION); fprintf(stdout, "Usage: %s [commands] [options]\n", prog); @@ -662,11 +672,11 @@ int main(int argc, char *argv[]) char __obj[nfct_maxsize()]; char __exptuple[nfct_maxsize()]; char __mask[nfct_maxsize()]; - struct nf_conntrack *obj = (struct nf_conntrack *) __obj; - struct nf_conntrack *exptuple = (struct nf_conntrack *) __exptuple; - struct nf_conntrack *mask = (struct nf_conntrack *) __mask; + struct nf_conntrack *obj = (struct nf_conntrack *)(void*) __obj; + struct nf_conntrack *exptuple = (struct nf_conntrack *)(void*) __exptuple; + struct nf_conntrack *mask = (struct nf_conntrack *)(void*) __mask; char __exp[nfexp_maxsize()]; - struct nf_expect *exp = (struct nf_expect *) __exp; + struct nf_expect *exp = (struct nf_expect *)(void*) __exp; int l3protonum; union ct_address ad; unsigned int command; diff --git a/src/hash.c b/src/hash.c index 3ed6ad2..553dd1d 100644 --- a/src/hash.c +++ b/src/hash.c @@ -53,7 +53,6 @@ hashtable_create(int hashsize, int limit, int datasize, { int i; struct hashtable *h; - struct hashtype *t; int size = sizeof(struct hashtable) + hashsize * sizeof(struct slist_head); @@ -87,7 +86,6 @@ void *hashtable_add(struct hashtable *table, void *data) struct slist_head *e; struct hashtable_node *n; u_int32_t id; - int i; /* hash table is full */ if (table->count >= table->limit) { @@ -122,7 +120,6 @@ void *hashtable_test(struct hashtable *table, const void *data) struct slist_head *e; u_int32_t id; struct hashtable_node *n; - int i; id = table->hash(data, table); @@ -141,7 +138,6 @@ int hashtable_del(struct hashtable *table, void *data) struct slist_head *e, *next, *prev; u_int32_t id; struct hashtable_node *n; - int i; id = table->hash(data, table); @@ -160,7 +156,7 @@ int hashtable_del(struct hashtable *table, void *data) int hashtable_flush(struct hashtable *table) { - int i; + u_int32_t i; struct slist_head *e, *next, *prev; struct hashtable_node *n; @@ -179,7 +175,7 @@ int hashtable_flush(struct hashtable *table) int hashtable_iterate(struct hashtable *table, void *data, int (*iterate)(void *data1, void *data2)) { - int i; + u_int32_t i; struct slist_head *e, *next, *prev; struct hashtable_node *n; diff --git a/src/ignore_pool.c b/src/ignore_pool.c index ee457ba..82afa93 100644 --- a/src/ignore_pool.c +++ b/src/ignore_pool.c @@ -20,8 +20,11 @@ #include "hash.h" #include "conntrackd.h" #include "ignore.h" +#include "log.h" #include +#include + /* XXX: These should be configurable */ #define IGNORE_POOL_SIZE 128 #define IGNORE_POOL_LIMIT INT_MAX @@ -53,7 +56,6 @@ static int compare6(const void *data1, const void *data2) struct ignore_pool *ignore_pool_create(u_int8_t proto) { - int i, j = 0; struct ignore_pool *ip; ip = malloc(sizeof(struct ignore_pool)); @@ -100,7 +102,8 @@ int ignore_pool_add(struct ignore_pool *ip, void *data) return 1; } -int __ignore_pool_test_ipv4(struct ignore_pool *ip, struct nf_conntrack *ct) +static int +__ignore_pool_test_ipv4(struct ignore_pool *ip, struct nf_conntrack *ct) { return (hashtable_test(ip->h, nfct_get_attr(ct, ATTR_ORIG_IPV4_SRC)) || hashtable_test(ip->h, nfct_get_attr(ct, ATTR_ORIG_IPV4_DST)) || @@ -108,7 +111,8 @@ int __ignore_pool_test_ipv4(struct ignore_pool *ip, struct nf_conntrack *ct) hashtable_test(ip->h, nfct_get_attr(ct, ATTR_REPL_IPV4_DST))); } -int __ignore_pool_test_ipv6(struct ignore_pool *ip, struct nf_conntrack *ct) +static int +__ignore_pool_test_ipv6(struct ignore_pool *ip, struct nf_conntrack *ct) { return (hashtable_test(ip->h, nfct_get_attr(ct, ATTR_ORIG_IPV6_SRC)) || hashtable_test(ip->h, nfct_get_attr(ct, ATTR_ORIG_IPV6_DST)) || diff --git a/src/local.c b/src/local.c index be51b9e..9ff5f82 100644 --- a/src/local.c +++ b/src/local.c @@ -68,7 +68,7 @@ int do_local_server_step(int fd, void *data, { int rfd; struct sockaddr_un local; - size_t sin_size = sizeof(struct sockaddr_un); + socklen_t sin_size = sizeof(struct sockaddr_un); if ((rfd = accept(fd, (struct sockaddr *)&local, &sin_size)) == -1) return -1; diff --git a/src/log.c b/src/log.c index 51109b6..b42e049 100644 --- a/src/log.c +++ b/src/log.c @@ -18,7 +18,7 @@ * Description: Logging support for the conntrack daemon */ -#include +#include "log.h" #include #include #include @@ -26,6 +26,7 @@ #include #include #include +#include #include "buffer.h" #include "conntrackd.h" @@ -78,11 +79,11 @@ int init_log(void) return 0; } -void dlog(FILE *fd, int priority, char *format, ...) +void dlog(FILE *fd, int priority, const char *format, ...) { time_t t; char *buf; - char *prio; + const char *prio; va_list args; if (fd) { @@ -125,7 +126,7 @@ void dlog_buffered_ct_flush(void *buffer_data, void *data) { FILE *fd = data; - fprintf(fd, "%s", buffer_data); + fprintf(fd, "%s", (const char*)buffer_data); fflush(fd); } diff --git a/src/main.c b/src/main.c index 2497a7f..11974ff 100644 --- a/src/main.c +++ b/src/main.c @@ -28,6 +28,9 @@ #include "hash.h" #include "jhash.h" +#undef _POSIX_SOURCE +#include + struct ct_general_state st; union ct_state state; @@ -52,7 +55,8 @@ static const char usage_options[] = "Options:\n" " -C [configfile], configuration file path\n"; -void show_usage(char *progname) +static void +show_usage(char *progname) { fprintf(stdout, "Connection tracking userspace daemon v%s\n", VERSION); fprintf(stdout, "Usage: %s [commands] [options]\n\n", progname); @@ -61,7 +65,8 @@ void show_usage(char *progname) fprintf(stdout, "%s\n", usage_options); } -void set_operation_mode(int *current, int want, char *argv[]) +static void +set_operation_mode(int *current, int want, char *argv[]) { if (*current == NOT_SET) { *current = want; @@ -109,7 +114,7 @@ static int check_capabilities(void) int main(int argc, char *argv[]) { - int ret, i, config_set = 0, action; + int ret, i, config_set = 0, action = -1; char config_file[PATH_MAX]; int type = 0; struct utsname u; @@ -305,4 +310,5 @@ int main(int argc, char *argv[]) * run main process */ run(); + return 0; } diff --git a/src/mcast.c b/src/mcast.c index cdaed5f..cf03593 100644 --- a/src/mcast.c +++ b/src/mcast.c @@ -192,7 +192,6 @@ __mcast_client_create_ipv6(struct mcast_sock *m, struct mcast_conf *conf) struct mcast_sock *mcast_client_create(struct mcast_conf *conf) { int ret = 0; - struct sockaddr_in addr; struct mcast_sock *m; m = (struct mcast_sock *) malloc(sizeof(struct mcast_sock)); @@ -300,9 +299,12 @@ void mcast_dump_stats(int fd, struct mcast_sock *s, struct mcast_sock *r) "%20llu Pckts recv\n" "%20llu Error send " "%20llu Error recv\n\n", - s->stats.bytes, r->stats.bytes, - s->stats.messages, r->stats.messages, - s->stats.error, r->stats.error); + (unsigned long long)s->stats.bytes, + (unsigned long long)r->stats.bytes, + (unsigned long long)s->stats.messages, + (unsigned long long)r->stats.messages, + (unsigned long long)s->stats.error, + (unsigned long long)r->stats.error); send(fd, buf, size, 0); } diff --git a/src/network.c b/src/network.c index e7ffbac..9d6e6e1 100644 --- a/src/network.c +++ b/src/network.c @@ -22,6 +22,8 @@ #include "sync.h" #include "log.h" +#include + static unsigned int seq_set, cur_seq; static int __do_send(struct mcast_sock *m, void *data, int len) @@ -65,8 +67,6 @@ static int __do_prepare(struct mcast_sock *m, void *data, int len) static int __prepare_ctl(struct mcast_sock *m, void *data) { - struct nethdr_ack *nack = (struct nethdr_ack *) data; - return __do_prepare(m, data, NETHDR_ACK_SIZ); } @@ -172,7 +172,6 @@ void build_netmsg(struct nf_conntrack *ct, int query, struct nethdr *net) int handle_netmsg(struct nethdr *net) { - int ret; struct netpld *pld = NETHDR_DATA(net); /* message too small: no room for the header */ diff --git a/src/read_config_yy.y b/src/read_config_yy.y index 8f8759f..82131d7 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -639,7 +639,7 @@ buffer_size: T_STAT_BUFFER_SIZE T_NUMBER %% -int +int __attribute__((noreturn)) yyerror(char *msg) { fprintf(stderr, "Error parsing config file: "); diff --git a/src/run.c b/src/run.c index 7fbeaf5..3fd98cd 100644 --- a/src/run.c +++ b/src/run.c @@ -20,12 +20,19 @@ #include "conntrackd.h" #include "netlink.h" +#include "ignore.h" +#include "log.h" +#include "alarm.h" #include #include #include "us-conntrack.h" #include #include #include +#include +#include +#include +#include void killer(int foo) { @@ -84,7 +91,8 @@ void local_handler(int fd, void *data) dlog(STATE(log), LOG_WARNING, "unknown local request %d", type); } -int init(void) +int +init(void) { if (CONFIG(flags) & CTD_STATS_MODE) STATE(mode) = &stats_mode; @@ -164,11 +172,11 @@ static int __run(struct timeval *next_alarm) if (ret == -1) { /* interrupted syscall, retry */ if (errno == EINTR) - return; + return 0; dlog(STATE(log), LOG_WARNING, "select failed: %s", strerror(errno)); - return; + return 0; } /* timeout expired, run the alarm list */ @@ -223,7 +231,8 @@ static int __run(struct timeval *next_alarm) return 0; } -void run(void) +void __attribute__((noreturn)) +run(void) { struct timeval next_alarm; struct timeval *next = &next_alarm; diff --git a/src/stats-mode.c b/src/stats-mode.c index 0983b97..563e1f6 100644 --- a/src/stats-mode.c +++ b/src/stats-mode.c @@ -31,8 +31,6 @@ static int init_stats(void) { - int ret; - state.stats = malloc(sizeof(struct ct_stats_state)); if (!state.stats) { dlog(STATE(log), LOG_ERR, "can't allocate memory for stats"); @@ -59,7 +57,7 @@ static int init_stats(void) return 0; } -static void kill_stats() +static void kill_stats(void) { cache_destroy(STATE_STATS(cache)); /* flush the buffer before exiting */ @@ -130,7 +128,7 @@ static int overrun_cb(enum nf_conntrack_msg_type type, return NFCT_CB_CONTINUE; } -static void overrun_stats() +static void overrun_stats(void) { int ret; struct nfct_handle *h; diff --git a/src/sync-alarm.c b/src/sync-alarm.c index d9a8267..05ddf81 100644 --- a/src/sync-alarm.c +++ b/src/sync-alarm.c @@ -22,6 +22,8 @@ #include "us-conntrack.h" #include "alarm.h" +#include + static void refresher(struct alarm_list *a, void *data) { int len; diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c index 63fd4b2..d881298 100644 --- a/src/sync-ftfw.c +++ b/src/sync-ftfw.c @@ -25,13 +25,14 @@ #include "debug.h" #include "network.h" #include "alarm.h" +#include "log.h" #include #include #if 0 #define dp printf #else -#define dp +#define dp(...) #endif static LIST_HEAD(rs_list); @@ -92,7 +93,7 @@ static void do_alive_alarm(struct alarm_list *a, void *data) add_alarm(&alive_alarm); } -static int ftfw_init() +static int ftfw_init(void) { tx_queue = queue_create(CONFIG(resend_queue_size)); if (tx_queue == NULL) { @@ -117,7 +118,7 @@ static int ftfw_init() return 0; } -static void ftfw_kill() +static void ftfw_kill(void) { queue_destroy(rs_queue); queue_destroy(tx_queue); @@ -330,7 +331,7 @@ static int tx_list_xmit(struct list_head *i, struct us_conntrack *u) return ret; } -static void ftfw_run() +static void ftfw_run(void) { struct cache_ftfw *cn, *tmp; diff --git a/src/sync-mode.c b/src/sync-mode.c index 8be8c18..f2bfc9f 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -38,7 +38,7 @@ static void do_mcast_handler_step(struct nethdr *net) int query; struct netpld *pld = NETHDR_DATA(net); char __ct[nfct_maxsize()]; - struct nf_conntrack *ct = (struct nf_conntrack *) __ct; + struct nf_conntrack *ct = (struct nf_conntrack *)(void*) __ct; struct us_conntrack *u = NULL; if (STATE_SYNC(sync)->recv(net)) diff --git a/src/traffic_stats.c b/src/traffic_stats.c index b2cdaae..b6fa030 100644 --- a/src/traffic_stats.c +++ b/src/traffic_stats.c @@ -48,8 +48,8 @@ void dump_traffic_stats(int fd) STATE(packets)[NFCT_DIR_REPLY]; size = sprintf(buf, "traffic processed:\n"); - size += sprintf(buf+size, "%20llu Bytes ", bytes); - size += sprintf(buf+size, "%20llu Pckts\n\n", packets); + size += sprintf(buf+size, "%20llu Bytes ", (unsigned long long)bytes); + size += sprintf(buf+size, "%20llu Pckts\n\n", (unsigned long long)packets); send(fd, buf, size, 0); } -- cgit v1.2.3 From 001805d9998229534264758432c06295614f8e2a Mon Sep 17 00:00:00 2001 From: "/C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org" Date: Thu, 17 Jan 2008 17:36:32 +0000 Subject: Max Kellermann : import only required C headers and put local headers on top to check --- ChangeLog | 1 + extensions/libct_proto_icmp.c | 4 +++- extensions/libct_proto_udp.c | 1 - include/alarm.h | 2 ++ include/cache.h | 1 - include/conntrack.h | 1 - include/conntrackd.h | 9 +-------- include/ignore.h | 2 ++ include/linux_list.h | 2 ++ include/local.h | 2 -- include/network.h | 2 ++ include/queue.h | 3 --- src/alarm.c | 7 ------- src/buffer.c | 4 +++- src/cache.c | 6 ++++-- src/cache_iterators.c | 5 +++-- src/cache_lifetime.c | 2 -- src/cache_timer.c | 7 ++++--- src/cache_wt.c | 6 +++--- src/conntrack.c | 12 +++--------- src/hash.c | 8 +++----- src/ignore_pool.c | 5 +++-- src/local.c | 7 ++++--- src/log.c | 8 +++----- src/main.c | 8 ++++---- src/mcast.c | 10 ++++------ src/netlink.c | 8 +------- src/network.c | 5 +++-- src/parse.c | 4 ++-- src/queue.c | 4 ++++ src/read_config_lex.l | 1 - src/read_config_yy.y | 1 + src/run.c | 7 ++----- src/stats-mode.c | 11 +++++------ src/sync-alarm.c | 3 +++ src/sync-ftfw.c | 7 +++---- src/sync-mode.c | 14 +++++++------- src/traffic_stats.c | 7 ------- 38 files changed, 85 insertions(+), 112 deletions(-) (limited to 'src/sync-alarm.c') diff --git a/ChangeLog b/ChangeLog index e0a0da7..f84f7aa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -81,6 +81,7 @@ o fix harmless error condition o add buffer_destroy() to buffer.c o fix memory leaks in several error output paths o use size_t for buffer sizes +o import only required C headers and put local headers on top to check version 0.9.5 (2007/07/29) ------------------------------ diff --git a/extensions/libct_proto_icmp.c b/extensions/libct_proto_icmp.c index 7c59072..f81c3b4 100644 --- a/extensions/libct_proto_icmp.c +++ b/extensions/libct_proto_icmp.c @@ -8,6 +8,9 @@ * (at your option) any later version. * */ + +#include "conntrack.h" + #include #include #include @@ -15,7 +18,6 @@ #include #include #include -#include "conntrack.h" static struct option opts[] = { {"icmp-type", 1, 0, '1'}, diff --git a/extensions/libct_proto_udp.c b/extensions/libct_proto_udp.c index 267e3d6..a72f9cf 100644 --- a/extensions/libct_proto_udp.c +++ b/extensions/libct_proto_udp.c @@ -10,7 +10,6 @@ #include #include #include -#include #include /* For htons */ #include #include diff --git a/include/alarm.h b/include/alarm.h index 338968a..532084a 100644 --- a/include/alarm.h +++ b/include/alarm.h @@ -3,6 +3,8 @@ #include "linux_list.h" +#include + struct alarm_list { struct list_head head; struct timeval tv; diff --git a/include/cache.h b/include/cache.h index 0743d3f..a2b2005 100644 --- a/include/cache.h +++ b/include/cache.h @@ -3,7 +3,6 @@ #include #include -#include /* cache features */ enum { diff --git a/include/conntrack.h b/include/conntrack.h index d6b6150..63facf4 100644 --- a/include/conntrack.h +++ b/include/conntrack.h @@ -2,7 +2,6 @@ #define _CONNTRACK_H #include "linux_list.h" -#include #include #include diff --git a/include/conntrackd.h b/include/conntrackd.h index bb4b183..c16d3d7 100644 --- a/include/conntrackd.h +++ b/include/conntrackd.h @@ -6,14 +6,7 @@ #include #include -#include -#include "cache.h" -#include "buffer.h" -#include "debug.h" -#include -#include "state_helper.h" -#include "linux_list.h" -#include +#include #include /* UNIX facilities */ diff --git a/include/ignore.h b/include/ignore.h index f1c2846..efb375d 100644 --- a/include/ignore.h +++ b/include/ignore.h @@ -3,6 +3,8 @@ #include +struct nf_conntrack; + struct ignore_pool { struct hashtable *h; }; diff --git a/include/linux_list.h b/include/linux_list.h index b84b1c4..de182a4 100644 --- a/include/linux_list.h +++ b/include/linux_list.h @@ -1,6 +1,8 @@ #ifndef _LINUX_LIST_H #define _LINUX_LIST_H +#include + #undef offsetof #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) diff --git a/include/local.h b/include/local.h index aae73a7..be77d35 100644 --- a/include/local.h +++ b/include/local.h @@ -1,8 +1,6 @@ #ifndef _LOCAL_SOCKET_H_ #define _LOCAL_SOCKET_H_ -#include - #ifndef UNIX_PATH_MAX #define UNIX_PATH_MAX 108 #endif diff --git a/include/network.h b/include/network.h index f9976dd..6dfd79d 100644 --- a/include/network.h +++ b/include/network.h @@ -3,6 +3,8 @@ #include +struct nf_conntrack; + struct nethdr { uint16_t flags; uint16_t len; diff --git a/include/queue.h b/include/queue.h index ab04d62..9a5d7b8 100644 --- a/include/queue.h +++ b/include/queue.h @@ -1,9 +1,6 @@ #ifndef _QUEUE_H_ #define _QUEUE_H_ -#include -#include -#include #include "linux_list.h" struct queue { diff --git a/src/alarm.c b/src/alarm.c index d00e281..576839a 100644 --- a/src/alarm.c +++ b/src/alarm.c @@ -16,14 +16,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include -#include -#include "linux_list.h" -#include "conntrackd.h" #include "alarm.h" -#include "jhash.h" -#include -#include static LIST_HEAD(alarm_list); diff --git a/src/buffer.c b/src/buffer.c index 389dd38..739174a 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -15,10 +15,12 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "buffer.h" + #include #include #include -#include "buffer.h" struct buffer *buffer_create(size_t size) { diff --git a/src/cache.c b/src/cache.c index dcb0123..2f0e57a 100644 --- a/src/cache.c +++ b/src/cache.c @@ -16,14 +16,16 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "cache.h" #include "jhash.h" #include "hash.h" +#include "us-conntrack.h" #include "conntrackd.h" + #include #include -#include "us-conntrack.h" -#include "cache.h" #include +#include static uint32_t hash(const void *data, struct hashtable *table) { diff --git a/src/cache_iterators.c b/src/cache_iterators.c index 4fdb920..bf70dd1 100644 --- a/src/cache_iterators.c +++ b/src/cache_iterators.c @@ -17,14 +17,15 @@ */ #include "cache.h" -#include "jhash.h" #include "hash.h" #include "log.h" #include "conntrackd.h" #include "netlink.h" +#include "us-conntrack.h" + #include #include -#include "us-conntrack.h" +#include struct __dump_container { int fd; diff --git a/src/cache_lifetime.c b/src/cache_lifetime.c index 26496d2..ad3416a 100644 --- a/src/cache_lifetime.c +++ b/src/cache_lifetime.c @@ -17,10 +17,8 @@ */ #include -#include "conntrackd.h" #include "us-conntrack.h" #include "cache.h" -#include "alarm.h" #include #include diff --git a/src/cache_timer.c b/src/cache_timer.c index 53ed703..0fbba14 100644 --- a/src/cache_timer.c +++ b/src/cache_timer.c @@ -16,12 +16,13 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include -#include +#include "cache.h" #include "conntrackd.h" #include "us-conntrack.h" -#include "cache.h" #include "alarm.h" +#include "debug.h" + +#include static void timeout(struct alarm_list *a, void *data) { diff --git a/src/cache_wt.c b/src/cache_wt.c index 9d0af0b..8ff8fae 100644 --- a/src/cache_wt.c +++ b/src/cache_wt.c @@ -16,11 +16,11 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "cache.h" #include "netlink.h" -#include -#include "conntrackd.h" #include "us-conntrack.h" -#include "cache.h" + +#include static void add_update(struct us_conntrack *u) { diff --git a/src/conntrack.c b/src/conntrack.c index 7918b3f..5f0cb1a 100644 --- a/src/conntrack.c +++ b/src/conntrack.c @@ -33,9 +33,10 @@ * Ported to the new libnetfilter_conntrack API * */ + +#include "conntrack.h" + #include -#include -#include #include #include #include @@ -43,22 +44,15 @@ #include #include #include -#include #include #include #include #ifdef HAVE_ARPA_INET_H #include #endif -#include -#include #include #include -#include "linux_list.h" -#include "conntrack.h" #include -#include -#include static const char cmdflags[NUMBER_OF_CMD] = {'L','I','U','D','G','F','E','V','h','L','I','D','G','F','E'}; diff --git a/src/hash.c b/src/hash.c index d7724c8..cf64df4 100644 --- a/src/hash.c +++ b/src/hash.c @@ -18,14 +18,12 @@ * Description: generic hash table implementation */ -#include +#include "hash.h" +#include "slist.h" + #include #include -#include #include -#include "slist.h" -#include "hash.h" - struct hashtable_node *hashtable_alloc_node(int datasize, void *data) { diff --git a/src/ignore_pool.c b/src/ignore_pool.c index 5889398..c77a55b 100644 --- a/src/ignore_pool.c +++ b/src/ignore_pool.c @@ -16,14 +16,15 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "ignore.h" #include "jhash.h" #include "hash.h" #include "conntrackd.h" -#include "ignore.h" #include "log.h" -#include +#include #include +#include /* XXX: These should be configurable */ #define IGNORE_POOL_SIZE 128 diff --git a/src/local.c b/src/local.c index d861e12..f0aba1c 100644 --- a/src/local.c +++ b/src/local.c @@ -18,12 +18,13 @@ * Description: UNIX sockets library */ +#include "local.h" + #include #include +#include #include -#include - -#include "local.h" +#include int local_server_create(struct local_conf *conf) { diff --git a/src/log.c b/src/log.c index 35ae0c3..a2d48a4 100644 --- a/src/log.c +++ b/src/log.c @@ -19,16 +19,14 @@ */ #include "log.h" -#include -#include -#include +#include "buffer.h" +#include "conntrackd.h" + #include #include #include #include #include -#include "buffer.h" -#include "conntrackd.h" int init_log(void) { diff --git a/src/main.c b/src/main.c index b860982..3d8cfe9 100644 --- a/src/main.c +++ b/src/main.c @@ -16,17 +16,17 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include #include "conntrackd.h" #include "log.h" + #include #include #include #include #include -#include -#include "hash.h" -#include "jhash.h" +#include +#include +#include #undef _POSIX_SOURCE #include diff --git a/src/mcast.c b/src/mcast.c index 9684b61..77aa35c 100644 --- a/src/mcast.c +++ b/src/mcast.c @@ -17,19 +17,17 @@ * * Description: multicast socket library */ + +#include "mcast.h" +#include "debug.h" + #include #include -#include #include -#include -#include -#include #include #include #include #include -#include "mcast.h" -#include "debug.h" struct mcast_sock *mcast_server_create(struct mcast_conf *conf) { diff --git a/src/netlink.c b/src/netlink.c index 388407a..0457e8a 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -21,13 +21,7 @@ #include "traffic_stats.h" #include "ignore.h" #include "log.h" -#include -#include -#include -#include "us-conntrack.h" -#include -#include -#include "network.h" +#include "debug.h" int ignore_conntrack(struct nf_conntrack *ct) { diff --git a/src/network.c b/src/network.c index 939e94b..7c7a08a 100644 --- a/src/network.c +++ b/src/network.c @@ -18,11 +18,12 @@ #include "conntrackd.h" #include "network.h" -#include "us-conntrack.h" -#include "sync.h" #include "log.h" +#include "debug.h" #include +#include +#include static unsigned int seq_set, cur_seq; diff --git a/src/parse.c b/src/parse.c index a248b47..5bc71ef 100644 --- a/src/parse.c +++ b/src/parse.c @@ -16,10 +16,10 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include -#include #include "network.h" +#include + static void parse_u8(struct nf_conntrack *ct, int attr, void *data) { uint8_t *value = (uint8_t *) data; diff --git a/src/queue.c b/src/queue.c index a721760..7b20e83 100644 --- a/src/queue.c +++ b/src/queue.c @@ -18,6 +18,10 @@ #include "queue.h" +#include +#include +#include + struct queue *queue_create(size_t max_size) { struct queue *b; diff --git a/src/read_config_lex.l b/src/read_config_lex.l index 6211fee..65df1e7 100644 --- a/src/read_config_lex.l +++ b/src/read_config_lex.l @@ -20,7 +20,6 @@ */ #include "read_config_yy.h" -#include "conntrackd.h" %} %option yylineno diff --git a/src/read_config_yy.y b/src/read_config_yy.y index 82131d7..531b1fe 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -26,6 +26,7 @@ #include "conntrackd.h" #include "ignore.h" #include +#include extern struct state_replication_helper tcp_state_helper; diff --git a/src/run.c b/src/run.c index cb5116d..9076028 100644 --- a/src/run.c +++ b/src/run.c @@ -23,16 +23,13 @@ #include "ignore.h" #include "log.h" #include "alarm.h" -#include + #include -#include "us-conntrack.h" #include #include #include -#include #include -#include -#include +#include void killer(int foo) { diff --git a/src/stats-mode.c b/src/stats-mode.c index 0c42d95..0ecb2b0 100644 --- a/src/stats-mode.c +++ b/src/stats-mode.c @@ -18,16 +18,15 @@ #include "netlink.h" #include "traffic_stats.h" -#include +#include "buffer.h" +#include "debug.h" #include "cache.h" #include "log.h" #include "conntrackd.h" -#include -#include + #include -#include "us-conntrack.h" -#include -#include +#include +#include static int init_stats(void) { diff --git a/src/sync-alarm.c b/src/sync-alarm.c index 05ddf81..6ee306e 100644 --- a/src/sync-alarm.c +++ b/src/sync-alarm.c @@ -21,8 +21,11 @@ #include "network.h" #include "us-conntrack.h" #include "alarm.h" +#include "cache.h" +#include "debug.h" #include +#include static void refresher(struct alarm_list *a, void *data) { diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c index f0b3262..f6d2ed3 100644 --- a/src/sync-ftfw.c +++ b/src/sync-ftfw.c @@ -16,18 +16,17 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include #include "conntrackd.h" #include "sync.h" -#include "linux_list.h" #include "us-conntrack.h" #include "queue.h" #include "debug.h" #include "network.h" #include "alarm.h" #include "log.h" -#include -#include +#include "cache.h" + +#include #if 0 #define dp printf diff --git a/src/sync-mode.c b/src/sync-mode.c index 1632019..0a0fcc2 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -16,22 +16,22 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "sync.h" #include "netlink.h" #include "traffic_stats.h" #include "log.h" -#include +#include "state_helper.h" #include "cache.h" #include "conntrackd.h" -#include -#include -#include #include "us-conntrack.h" -#include -#include -#include "sync.h" #include "network.h" #include "debug.h" + +#include #include +#include +#include +#include static void do_mcast_handler_step(struct nethdr *net) { diff --git a/src/traffic_stats.c b/src/traffic_stats.c index 93511ce..9e40d53 100644 --- a/src/traffic_stats.c +++ b/src/traffic_stats.c @@ -17,14 +17,7 @@ */ #include "traffic_stats.h" -#include "cache.h" -#include "hash.h" #include "conntrackd.h" -#include -#include -#include -#include "us-conntrack.h" -#include void update_traffic_stats(struct nf_conntrack *ct) { -- cgit v1.2.3 From 00ad2e9e1c6cf9e14c76660f2b748247c1f4bd83 Mon Sep 17 00:00:00 2001 From: "/C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org" Date: Fri, 18 Jan 2008 13:46:30 +0000 Subject: yet another rework of the alarm scheduler --- include/alarm.h | 8 +++- src/alarm.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++-------- src/run.c | 42 +++++++++++------ src/sync-alarm.c | 4 +- src/sync-ftfw.c | 2 - 5 files changed, 157 insertions(+), 39 deletions(-) (limited to 'src/sync-alarm.c') diff --git a/include/alarm.h b/include/alarm.h index 532084a..2f78885 100644 --- a/include/alarm.h +++ b/include/alarm.h @@ -5,6 +5,8 @@ #include +extern int alarm_counter; + struct alarm_list { struct list_head head; struct timeval tv; @@ -19,6 +21,10 @@ set_alarm_expiration(struct alarm_list *t, long tv_sec, long tv_usec) t->tv.tv_usec = tv_usec; } +int init_alarm_hash(void); + +void destroy_alarm_hash(void); + void init_alarm(struct alarm_list *t, void *data, void (*fcn)(struct alarm_list *a, void *data)); @@ -29,7 +35,7 @@ void del_alarm(struct alarm_list *alarm); void mod_alarm(struct alarm_list *alarm, unsigned long sc, unsigned long usc); -int get_next_alarm(struct timeval *tv, struct timeval *next_alarm); +int get_next_alarm_run(struct timeval *next_alarm); int do_alarm_run(struct timeval *next_alarm); diff --git a/src/alarm.c b/src/alarm.c index 576839a..13a790e 100644 --- a/src/alarm.c +++ b/src/alarm.c @@ -17,8 +17,14 @@ */ #include "alarm.h" +#include "jhash.h" +#include +#include -static LIST_HEAD(alarm_list); +#define ALARM_HASH_SIZE 2048 + +static struct list_head *alarm_hash; +int alarm_counter; void init_alarm(struct alarm_list *t, void *data, @@ -35,14 +41,15 @@ static void __add_alarm(struct alarm_list *alarm) { struct alarm_list *t; + int i = jhash(alarm, sizeof(alarm), 0) % ALARM_HASH_SIZE; - list_for_each_entry(t, &alarm_list, head) { + list_for_each_entry(t, &alarm_hash[i], head) { if (timercmp(&alarm->tv, &t->tv, <)) { list_add_tail(&alarm->head, &t->head); return; } } - list_add_tail(&alarm->head, &alarm_list); + list_add_tail(&alarm->head, &alarm_hash[i]); } void add_alarm(struct alarm_list *alarm) @@ -52,50 +59,143 @@ void add_alarm(struct alarm_list *alarm) gettimeofday(&tv, NULL); timeradd(&alarm->tv, &tv, &alarm->tv); __add_alarm(alarm); + alarm_counter++; } void del_alarm(struct alarm_list *alarm) { /* don't remove a non-inserted node */ - if (!list_empty(&alarm->head)) + if (!list_empty(&alarm->head)) { list_del_init(&alarm->head); + alarm_counter--; + } } void mod_alarm(struct alarm_list *alarm, unsigned long sc, unsigned long usc) { - list_del(&alarm->head); + struct timeval tv; + set_alarm_expiration(alarm, sc, usc); - add_alarm(alarm); + gettimeofday(&tv, NULL); + timeradd(&alarm->tv, &tv, &alarm->tv); + list_del(&alarm->head); + __add_alarm(alarm); } -int get_next_alarm(struct timeval *tv, struct timeval *next_alarm) +static int +calculate_next_run(struct timeval *cand, + struct timeval *tv, + struct timeval *next_run) { + if (cand->tv_sec != LONG_MAX) { + if (timercmp(cand, tv, >)) + timersub(cand, tv, next_run); + else { + /* loop again inmediately */ + next_run->tv_sec = 0; + next_run->tv_usec = 0; + } + return 1; + } + return 0; +} + +int get_next_alarm_run(struct timeval *next_run) +{ + int i; struct alarm_list *t; + struct timeval tv; + struct timeval cand = { + .tv_sec = LONG_MAX, + .tv_usec = LONG_MAX + }; + + gettimeofday(&tv, NULL); - list_for_each_entry(t, &alarm_list, head) { - timersub(&t->tv, tv, next_alarm); + for (i=0; itv, &cand, <)) { + cand.tv_sec = t->tv.tv_sec; + cand.tv_usec = t->tv.tv_usec; + } + } + } + + return calculate_next_run(&cand, &tv, next_run); +} + +static inline int +tv_compare(struct alarm_list *a, struct timeval *cur, struct timeval *cand) +{ + if (timercmp(&a->tv, cur, >)) { + /* select the next alarm candidate */ + if (timercmp(&a->tv, cand, <)) { + cand->tv_sec = a->tv.tv_sec; + cand->tv_usec = a->tv.tv_usec; + } return 1; } return 0; } -int do_alarm_run(struct timeval *next_alarm) +int do_alarm_run(struct timeval *next_run) { - struct alarm_list *t, *tmp; + int i; + struct alarm_list *t, *next, *prev; struct timeval tv; + struct timeval cand = { + .tv_sec = LONG_MAX, + .tv_usec = LONG_MAX + }; gettimeofday(&tv, NULL); - list_for_each_entry_safe(t, tmp, &alarm_list, head) { - if (timercmp(&t->tv, &tv, >)) { - timersub(&t->tv, &tv, next_alarm); - return 1; + for (i=0; ihead.prev, + struct alarm_list, + head); + + del_alarm(t); + t->function(t, t->data); + + /* Special case: One deleted node is inserted + * again in the same place */ + if (next->head.prev == &prev->head) { + t = list_entry(next->head.prev, + struct alarm_list, + head); + if (tv_compare(t, &tv, &cand)) + break; + } } - - del_alarm(t); - t->function(t, t->data); } - /* check for refreshed alarms to get the next one */ - return get_next_alarm(&tv, next_alarm); + return calculate_next_run(&cand, &tv, next_run); +} + +int init_alarm_hash(void) +{ + int i; + + alarm_hash = malloc(sizeof(struct list_head) * ALARM_HASH_SIZE); + if (alarm_hash == NULL) + return -1; + + for (i=0; ikill(); + destroy_alarm_hash(); unlink(CONFIG(lockfile)); dlog(LOG_NOTICE, "---- shutdown received ----"); close_log(); @@ -102,6 +103,11 @@ init(void) STATE(mode) = &stats_mode; } + if (init_alarm_hash() == -1) { + dlog(LOG_ERR, "can't initialize alarm hash"); + return -1; + } + /* Initialization */ if (STATE(mode)->init() == -1) { dlog(LOG_ERR, "initialization failed"); @@ -152,10 +158,15 @@ init(void) return 0; } -static int __run(struct timeval *next_alarm) +static int __run(struct timeval *next_alarm, int *timeout) { int max, ret; fd_set readfds; + struct timeval *tmp = next_alarm; + + /* No alarms, select must block */ + if (*timeout == 0) + tmp = NULL; FD_ZERO(&readfds); FD_SET(STATE(local), &readfds); @@ -166,7 +177,7 @@ static int __run(struct timeval *next_alarm) if (STATE(mode)->add_fds_to_set) max = MAX(max, STATE(mode)->add_fds_to_set(&readfds)); - ret = select(max+1, &readfds, NULL, NULL, next_alarm); + ret = select(max+1, &readfds, NULL, NULL, tmp); if (ret == -1) { /* interrupted syscall, retry */ if (errno == EINTR) @@ -178,7 +189,7 @@ static int __run(struct timeval *next_alarm) } /* timeout expired, run the alarm list */ - if (ret == 0) + if (tmp != NULL && !timerisset(tmp)) return 1; /* signals are racy */ @@ -224,6 +235,14 @@ static int __run(struct timeval *next_alarm) if (STATE(mode)->run) STATE(mode)->run(&readfds); + /* check if we have introduced any new alarms */ + if (*timeout == 0 && alarm_counter > 0) { + *timeout = 1; + if (!get_next_alarm_run(next_alarm)) + dlog(LOG_ERR, "Bug in alarm?"); + return 0; + } + sigprocmask(SIG_UNBLOCK, &STATE(block), NULL); return 0; @@ -232,21 +251,16 @@ static int __run(struct timeval *next_alarm) void __attribute__((noreturn)) run(void) { - struct timeval next_alarm; - struct timeval *next = &next_alarm; - struct timeval tv; + int timeout; + struct timeval next_alarm; - /* initialization: get the first alarm available */ - gettimeofday(&tv, NULL); - if (!get_next_alarm(&tv, next)) - next = NULL; + /* initialization: get the next alarm available */ + timeout = get_next_alarm_run(&next_alarm); while(1) { - if (__run(next)) { + if (__run(&next_alarm, &timeout)) { sigprocmask(SIG_BLOCK, &STATE(block), NULL); - next = &next_alarm; - if (!do_alarm_run(next)) - next = NULL; /* no next alarms */ + timeout = do_alarm_run(&next_alarm); sigprocmask(SIG_UNBLOCK, &STATE(block), NULL); } } diff --git a/src/sync-alarm.c b/src/sync-alarm.c index 6ee306e..9ab9d96 100644 --- a/src/sync-alarm.c +++ b/src/sync-alarm.c @@ -38,7 +38,7 @@ static void refresher(struct alarm_list *a, void *data) init_alarm(a, u, refresher); set_alarm_expiration(a, random() % CONFIG(refresh) + 1, - random() % 999999 + 1); + ((random() % 5 + 1) * 200000) - 1); add_alarm(a); @@ -54,7 +54,7 @@ static void cache_alarm_add(struct us_conntrack *u, void *data) init_alarm(alarm, u, refresher); set_alarm_expiration(alarm, random() % CONFIG(refresh) + 1, - random() % 999999 + 1); + ((random() % 5 + 1) * 200000) - 1); add_alarm(alarm); } diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c index 94df5f9..004dd21 100644 --- a/src/sync-ftfw.c +++ b/src/sync-ftfw.c @@ -340,8 +340,6 @@ static void ftfw_run(void) u = cache_get_conntrack(STATE_SYNC(internal), cn); tx_list_xmit(&cn->tx_list, u); } - - mod_alarm(&alive_alarm, 1, 0); } struct sync_mode sync_ftfw = { -- cgit v1.2.3 From bcae271764d18e570a5fca382eeea748add4af62 Mon Sep 17 00:00:00 2001 From: "/C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org" Date: Sun, 20 Jan 2008 23:51:23 +0000 Subject: Based on patch from Max Kellermann : merge mod_alarm() into add_alarm(), remove alarm_set_expiration() --- ChangeLog | 1 + include/alarm.h | 11 +---------- src/alarm.c | 16 ++++------------ src/cache_timer.c | 5 ++--- src/sync-alarm.c | 17 +++++++---------- src/sync-ftfw.c | 6 ++---- 6 files changed, 17 insertions(+), 39 deletions(-) (limited to 'src/sync-alarm.c') diff --git a/ChangeLog b/ChangeLog index 815da0d..2dad662 100644 --- a/ChangeLog +++ b/ChangeLog @@ -88,6 +88,7 @@ o remove capability code and rely on the error returned by the syscall o major simplification of the logging infrastructure o use fputs() instead of fprintf() in log.c o improve error message if netlink initialization fails +o merge mod_alarm() into add_alarm(), remove alarm_set_expiration() version 0.9.5 (2007/07/29) ------------------------------ diff --git a/include/alarm.h b/include/alarm.h index 2f78885..f0bbb95 100644 --- a/include/alarm.h +++ b/include/alarm.h @@ -14,13 +14,6 @@ struct alarm_list { void (*function)(struct alarm_list *a, void *data); }; -static inline void -set_alarm_expiration(struct alarm_list *t, long tv_sec, long tv_usec) -{ - t->tv.tv_sec = tv_sec; - t->tv.tv_usec = tv_usec; -} - int init_alarm_hash(void); void destroy_alarm_hash(void); @@ -29,12 +22,10 @@ void init_alarm(struct alarm_list *t, void *data, void (*fcn)(struct alarm_list *a, void *data)); -void add_alarm(struct alarm_list *alarm); +void add_alarm(struct alarm_list *alarm, unsigned long sc, unsigned long usc); void del_alarm(struct alarm_list *alarm); -void mod_alarm(struct alarm_list *alarm, unsigned long sc, unsigned long usc); - int get_next_alarm_run(struct timeval *next_alarm); int do_alarm_run(struct timeval *next_alarm); diff --git a/src/alarm.c b/src/alarm.c index 13a790e..2190bb6 100644 --- a/src/alarm.c +++ b/src/alarm.c @@ -52,10 +52,13 @@ __add_alarm(struct alarm_list *alarm) list_add_tail(&alarm->head, &alarm_hash[i]); } -void add_alarm(struct alarm_list *alarm) +void add_alarm(struct alarm_list *alarm, unsigned long sc, unsigned long usc) { struct timeval tv; + del_alarm(alarm); + alarm->tv.tv_sec = sc; + alarm->tv.tv_usec = usc; gettimeofday(&tv, NULL); timeradd(&alarm->tv, &tv, &alarm->tv); __add_alarm(alarm); @@ -71,17 +74,6 @@ void del_alarm(struct alarm_list *alarm) } } -void mod_alarm(struct alarm_list *alarm, unsigned long sc, unsigned long usc) -{ - struct timeval tv; - - set_alarm_expiration(alarm, sc, usc); - gettimeofday(&tv, NULL); - timeradd(&alarm->tv, &tv, &alarm->tv); - list_del(&alarm->head); - __add_alarm(alarm); -} - static int calculate_next_run(struct timeval *cand, struct timeval *tv, diff --git a/src/cache_timer.c b/src/cache_timer.c index 0fbba14..86bb8fc 100644 --- a/src/cache_timer.c +++ b/src/cache_timer.c @@ -37,14 +37,13 @@ static void timer_add(struct us_conntrack *u, void *data) struct alarm_list *alarm = data; init_alarm(alarm, u, timeout); - set_alarm_expiration(alarm, CONFIG(cache_timeout), 0); - add_alarm(alarm); + add_alarm(alarm, CONFIG(cache_timeout), 0); } static void timer_update(struct us_conntrack *u, void *data) { struct alarm_list *alarm = data; - mod_alarm(alarm, CONFIG(cache_timeout), 0); + add_alarm(alarm, CONFIG(cache_timeout), 0); } static void timer_destroy(struct us_conntrack *u, void *data) diff --git a/src/sync-alarm.c b/src/sync-alarm.c index 9ab9d96..1f164b2 100644 --- a/src/sync-alarm.c +++ b/src/sync-alarm.c @@ -36,11 +36,9 @@ static void refresher(struct alarm_list *a, void *data) debug_ct(u->ct, "persistence update"); init_alarm(a, u, refresher); - set_alarm_expiration(a, - random() % CONFIG(refresh) + 1, - ((random() % 5 + 1) * 200000) - 1); - - add_alarm(a); + add_alarm(a, + random() % CONFIG(refresh) + 1, + ((random() % 5 + 1) * 200000) - 1); net = BUILD_NETMSG(u->ct, NFCT_Q_UPDATE); len = prepare_send_netmsg(STATE_SYNC(mcast_client), net); @@ -52,16 +50,15 @@ static void cache_alarm_add(struct us_conntrack *u, void *data) struct alarm_list *alarm = data; init_alarm(alarm, u, refresher); - set_alarm_expiration(alarm, - random() % CONFIG(refresh) + 1, - ((random() % 5 + 1) * 200000) - 1); - add_alarm(alarm); + add_alarm(alarm, + random() % CONFIG(refresh) + 1, + ((random() % 5 + 1) * 200000) - 1); } static void cache_alarm_update(struct us_conntrack *u, void *data) { struct alarm_list *alarm = data; - mod_alarm(alarm, random() % CONFIG(refresh) + 1, random() % 999999 + 1); + add_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 004dd21..dc3bf44 100644 --- a/src/sync-ftfw.c +++ b/src/sync-ftfw.c @@ -90,8 +90,7 @@ static void do_alive_alarm(struct alarm_list *a, void *data) tx_queue_add_ctlmsg(NET_F_ALIVE, 0, 0); init_alarm(&alive_alarm, NULL, do_alive_alarm); - set_alarm_expiration(&alive_alarm, 1, 0); - add_alarm(&alive_alarm); + add_alarm(&alive_alarm, 1, 0); } static int ftfw_init(void) @@ -113,8 +112,7 @@ static int ftfw_init(void) /* XXX: alive message expiration configurable */ init_alarm(&alive_alarm, NULL, do_alive_alarm); - set_alarm_expiration(&alive_alarm, 1, 0); - add_alarm(&alive_alarm); + add_alarm(&alive_alarm, 1, 0); return 0; } -- cgit v1.2.3 From d6f29c81c1452db525d12110d5f15f7f39df9b86 Mon Sep 17 00:00:00 2001 From: "/C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org" Date: Sun, 20 Jan 2008 23:56:55 +0000 Subject: Max Kellermann : remove init_alarm() before add_alarm() --- ChangeLog | 1 + src/sync-alarm.c | 1 - src/sync-ftfw.c | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) (limited to 'src/sync-alarm.c') diff --git a/ChangeLog b/ChangeLog index 2dad662..3ca5746 100644 --- a/ChangeLog +++ b/ChangeLog @@ -89,6 +89,7 @@ o major simplification of the logging infrastructure o use fputs() instead of fprintf() in log.c o improve error message if netlink initialization fails o merge mod_alarm() into add_alarm(), remove alarm_set_expiration() +o remove init_alarm() before add_alarm() version 0.9.5 (2007/07/29) ------------------------------ diff --git a/src/sync-alarm.c b/src/sync-alarm.c index 1f164b2..f7a1536 100644 --- a/src/sync-alarm.c +++ b/src/sync-alarm.c @@ -35,7 +35,6 @@ static void refresher(struct alarm_list *a, void *data) debug_ct(u->ct, "persistence update"); - init_alarm(a, u, refresher); add_alarm(a, random() % CONFIG(refresh) + 1, ((random() % 5 + 1) * 200000) - 1); diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c index dc3bf44..1d12002 100644 --- a/src/sync-ftfw.c +++ b/src/sync-ftfw.c @@ -89,7 +89,6 @@ static void do_alive_alarm(struct alarm_list *a, void *data) { tx_queue_add_ctlmsg(NET_F_ALIVE, 0, 0); - init_alarm(&alive_alarm, NULL, do_alive_alarm); add_alarm(&alive_alarm, 1, 0); } -- cgit v1.2.3 From 9e0585bb826cf7bb879ed3ad68a26767d3e33379 Mon Sep 17 00:00:00 2001 From: "/C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org" Date: Tue, 22 Jan 2008 01:45:57 +0000 Subject: fix inconsistent alarm update in cache_alarm_update --- src/sync-alarm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/sync-alarm.c') diff --git a/src/sync-alarm.c b/src/sync-alarm.c index f7a1536..66727e7 100644 --- a/src/sync-alarm.c +++ b/src/sync-alarm.c @@ -57,7 +57,9 @@ 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; - add_alarm(alarm, random() % CONFIG(refresh) + 1, random() % 999999 + 1); + add_alarm(alarm, + random() % CONFIG(refresh) + 1, + ((random() % 5 + 1) * 200000) - 1); } static void cache_alarm_destroy(struct us_conntrack *u, void *data) -- cgit v1.2.3 From 379125b1f618b3102015a64b1e9be0bdbe883930 Mon Sep 17 00:00:00 2001 From: "/C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org" Date: Wed, 23 Jan 2008 12:30:36 +0000 Subject: Max Kellermann : use size_t --- ChangeLog | 1 + include/mcast.h | 4 ++-- include/network.h | 7 ++++--- src/build.c | 2 +- src/local.c | 4 ++-- src/mcast.c | 8 ++++---- src/network.c | 22 +++++++++++----------- src/sync-alarm.c | 2 +- src/sync-ftfw.c | 4 ++-- src/sync-mode.c | 9 +++++---- 10 files changed, 33 insertions(+), 30 deletions(-) (limited to 'src/sync-alarm.c') diff --git a/ChangeLog b/ChangeLog index 5010775..4cd5eff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -95,6 +95,7 @@ o added struct local_server, several cleanups in local socket infrastructure o remove unused prototypes in network.h o check if the received packet is large enough o introduce alarm_pending() +o cleanup: use size_t instead of integer version 0.9.5 (2007/07/29) ------------------------------ diff --git a/include/mcast.h b/include/mcast.h index e3cdb38..4e89c72 100644 --- a/include/mcast.h +++ b/include/mcast.h @@ -43,8 +43,8 @@ void mcast_server_destroy(struct mcast_sock *m); struct mcast_sock *mcast_client_create(struct mcast_conf *conf); void mcast_client_destroy(struct mcast_sock *m); -int mcast_send(struct mcast_sock *m, void *data, int size); -int mcast_recv(struct mcast_sock *m, void *data, int size); +ssize_t mcast_send(struct mcast_sock *m, void *data, int size); +ssize_t mcast_recv(struct mcast_sock *m, void *data, int size); struct mcast_stats *mcast_get_stats(struct mcast_sock *m); void mcast_dump_stats(int fd, struct mcast_sock *s, struct mcast_sock *r); diff --git a/include/network.h b/include/network.h index e3e9ce1..92a8490 100644 --- a/include/network.h +++ b/include/network.h @@ -2,6 +2,7 @@ #define _NETWORK_H_ #include +#include struct nf_conntrack; @@ -53,7 +54,7 @@ struct us_conntrack; struct mcast_sock; void build_netmsg(struct nf_conntrack *ct, int query, struct nethdr *net); -int prepare_send_netmsg(struct mcast_sock *m, void *data); +size_t prepare_send_netmsg(struct mcast_sock *m, void *data); int mcast_send_netmsg(struct mcast_sock *m, void *data); int handle_netmsg(struct nethdr *net); int mcast_track_seq(uint32_t seq, uint32_t *exp_seq); @@ -62,8 +63,8 @@ struct mcast_conf; int mcast_buffered_init(struct mcast_conf *conf); void mcast_buffered_destroy(void); -int mcast_buffered_send_netmsg(struct mcast_sock *m, void *data, int len); -int mcast_buffered_pending_netmsg(struct mcast_sock *m); +int mcast_buffered_send_netmsg(struct mcast_sock *m, void *data, size_t len); +ssize_t mcast_buffered_pending_netmsg(struct mcast_sock *m); #define IS_DATA(x) ((x->flags & ~NET_F_HELLO) == 0) #define IS_ACK(x) (x->flags & NET_F_ACK) diff --git a/src/build.c b/src/build.c index c99990b..3de1c25 100644 --- a/src/build.c +++ b/src/build.c @@ -20,7 +20,7 @@ #include #include "network.h" -static void addattr(struct netpld *pld, int attr, const void *data, int len) +static void addattr(struct netpld *pld, int attr, const void *data, size_t len) { struct netattr *nta; int tlen = NTA_LENGTH(len); diff --git a/src/local.c b/src/local.c index 258605f..e2c3599 100644 --- a/src/local.c +++ b/src/local.c @@ -29,7 +29,7 @@ int local_server_create(struct local_server *server, struct local_conf *conf) { int fd; - int len; + socklen_t len; struct sockaddr_un local; if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) @@ -90,7 +90,7 @@ int do_local_server_step(struct local_server *server, void *data, int local_client_create(struct local_conf *conf) { - int len; + socklen_t len; struct sockaddr_un local; int fd; diff --git a/src/mcast.c b/src/mcast.c index e977c0b..8307f26 100644 --- a/src/mcast.c +++ b/src/mcast.c @@ -238,9 +238,9 @@ void mcast_client_destroy(struct mcast_sock *m) free(m); } -int mcast_send(struct mcast_sock *m, void *data, int size) +ssize_t mcast_send(struct mcast_sock *m, void *data, int size) { - int ret; + ssize_t ret; ret = sendto(m->fd, data, @@ -260,9 +260,9 @@ int mcast_send(struct mcast_sock *m, void *data, int size) return ret; } -int mcast_recv(struct mcast_sock *m, void *data, int size) +ssize_t mcast_recv(struct mcast_sock *m, void *data, int size) { - int ret; + ssize_t ret; socklen_t sin_size = sizeof(struct sockaddr_in); ret = recvfrom(m->fd, diff --git a/src/network.c b/src/network.c index da26545..92999a1 100644 --- a/src/network.c +++ b/src/network.c @@ -27,7 +27,7 @@ static unsigned int seq_set, cur_seq; -static int __do_send(struct mcast_sock *m, void *data, int len) +static size_t __do_send(struct mcast_sock *m, void *data, size_t len) { struct nethdr *net = data; @@ -50,7 +50,7 @@ static int __do_send(struct mcast_sock *m, void *data, int len) return mcast_send(m, net, len); } -static int __do_prepare(struct mcast_sock *m, void *data, int len) +static size_t __do_prepare(struct mcast_sock *m, void *data, size_t len) { struct nethdr *net = data; @@ -66,12 +66,12 @@ static int __do_prepare(struct mcast_sock *m, void *data, int len) return len; } -static int __prepare_ctl(struct mcast_sock *m, void *data) +static size_t __prepare_ctl(struct mcast_sock *m, void *data) { return __do_prepare(m, data, NETHDR_ACK_SIZ); } -static int __prepare_data(struct mcast_sock *m, void *data) +static size_t __prepare_data(struct mcast_sock *m, void *data) { struct nethdr *net = (struct nethdr *) data; struct netpld *pld = NETHDR_DATA(net); @@ -79,7 +79,7 @@ static int __prepare_data(struct mcast_sock *m, void *data) return __do_prepare(m, data, ntohs(pld->len) + NETPLD_SIZ + NETHDR_SIZ); } -int prepare_send_netmsg(struct mcast_sock *m, void *data) +size_t prepare_send_netmsg(struct mcast_sock *m, void *data) { int ret = 0; struct nethdr *net = (struct nethdr *) data; @@ -92,8 +92,8 @@ int prepare_send_netmsg(struct mcast_sock *m, void *data) return ret; } -static int tx_buflenmax; -static int tx_buflen = 0; +static size_t tx_buflenmax; +static size_t tx_buflen = 0; static char *tx_buf; #define HEADERSIZ 28 /* IP header (20 bytes) + UDP header 8 (bytes) */ @@ -121,7 +121,7 @@ void mcast_buffered_destroy(void) } /* return 0 if it is not sent, otherwise return 1 */ -int mcast_buffered_send_netmsg(struct mcast_sock *m, void *data, int len) +int mcast_buffered_send_netmsg(struct mcast_sock *m, void *data, size_t len) { int ret = 0; struct nethdr *net = data; @@ -140,9 +140,9 @@ retry: return ret; } -int mcast_buffered_pending_netmsg(struct mcast_sock *m) +ssize_t mcast_buffered_pending_netmsg(struct mcast_sock *m) { - int ret; + ssize_t ret; if (tx_buflen == 0) return 0; @@ -156,7 +156,7 @@ int mcast_buffered_pending_netmsg(struct mcast_sock *m) int mcast_send_netmsg(struct mcast_sock *m, void *data) { int ret; - int len = prepare_send_netmsg(m, data); + size_t len = prepare_send_netmsg(m, data); ret = mcast_buffered_send_netmsg(m, data, len); mcast_buffered_pending_netmsg(m); diff --git a/src/sync-alarm.c b/src/sync-alarm.c index 66727e7..c7cecc8 100644 --- a/src/sync-alarm.c +++ b/src/sync-alarm.c @@ -29,7 +29,7 @@ static void refresher(struct alarm_list *a, void *data) { - int len; + size_t len; struct nethdr *net; struct us_conntrack *u = data; diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c index 1d12002..49c0b2c 100644 --- a/src/sync-ftfw.c +++ b/src/sync-ftfw.c @@ -285,7 +285,7 @@ static void ftfw_send(struct nethdr *net, struct us_conntrack *u) static int tx_queue_xmit(void *data1, const void *data2) { struct nethdr *net = data1; - int len = prepare_send_netmsg(STATE_SYNC(mcast_client), net); + size_t len = prepare_send_netmsg(STATE_SYNC(mcast_client), net); dp("tx_queue sq: %u fl:%u len:%u\n", ntohl(net->seq), ntohs(net->flags), ntohs(net->len)); @@ -307,7 +307,7 @@ static int tx_list_xmit(struct list_head *i, struct us_conntrack *u) { int ret; struct nethdr *net = BUILD_NETMSG(u->ct, NFCT_Q_UPDATE); - int len = prepare_send_netmsg(STATE_SYNC(mcast_client), net); + size_t len = prepare_send_netmsg(STATE_SYNC(mcast_client), net); dp("tx_list sq: %u fl:%u len:%u\n", ntohl(net->seq), ntohs(net->flags), diff --git a/src/sync-mode.c b/src/sync-mode.c index 5974474..b4972a8 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -88,7 +88,8 @@ retry: /* handler for multicast messages received */ static void mcast_handler(void) { - int numbytes, remain; + ssize_t numbytes; + ssize_t remain; char __net[65536], *ptr = __net; /* XXX: maximum MTU for IPv4 */ numbytes = mcast_recv(STATE_SYNC(mcast_server), __net, sizeof(__net)); @@ -339,7 +340,7 @@ static void mcast_send_sync(struct us_conntrack *u, struct nf_conntrack *ct, int query) { - int len; + size_t len; struct nethdr *net; if (!state_helper_verdict(query, ct)) @@ -373,7 +374,7 @@ static int overrun_cb(enum nf_conntrack_msg_type type, if (!cache_test(STATE_SYNC(internal), ct)) { if ((u = cache_update_force(STATE_SYNC(internal), ct))) { - int len; + size_t len; debug_ct(u->ct, "overrun resync"); @@ -397,7 +398,7 @@ static int overrun_purge_step(void *data1, void *data2) ret = nfct_query(h, NFCT_Q_GET, u->ct); if (ret == -1 && errno == ENOENT) { - int len; + size_t len; struct nethdr *net = BUILD_NETMSG(u->ct, NFCT_Q_DESTROY); debug_ct(u->ct, "overrun purge resync"); -- cgit v1.2.3 From c66ed8fdb8b64fcb8973f6b60a9696b59ba29ee6 Mon Sep 17 00:00:00 2001 From: "/C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org" Date: Tue, 29 Jan 2008 13:54:24 +0000 Subject: implement a rb-tree based alarm framework --- ChangeLog | 2 +- include/Makefile.am | 2 +- include/alarm.h | 26 ++-- include/linux_rbtree.h | 160 ++++++++++++++++++++ src/Makefile.am | 2 +- src/alarm.c | 156 +++++++------------- src/cache_timer.c | 12 +- src/rbtree.c | 389 +++++++++++++++++++++++++++++++++++++++++++++++++ src/run.c | 6 - src/sync-alarm.c | 10 +- src/sync-ftfw.c | 4 +- 11 files changed, 631 insertions(+), 138 deletions(-) create mode 100644 include/linux_rbtree.h create mode 100644 src/rbtree.c (limited to 'src/sync-alarm.c') diff --git a/ChangeLog b/ChangeLog index 4cd5eff..dc4efab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -39,7 +39,7 @@ 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 o add support for tagged vlan interfaces in the config file, e.g. eth0.1 -o improve alarm framework based on suggestions from Max Kellerman +o implement a rb-tree based alarm framework o constify queue_iterate() o use list_del_init() and list_empty() to check if a node is in the list o remove unix socket file on exit diff --git a/include/Makefile.am b/include/Makefile.am index e8e7f81..d7f27a9 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1,5 +1,5 @@ -noinst_HEADERS = alarm.h jhash.h slist.h cache.h linux_list.h \ +noinst_HEADERS = alarm.h jhash.h slist.h cache.h linux_list.h linux_rbtree.h \ sync.h conntrackd.h local.h us-conntrack.h \ debug.h log.h hash.h mcast.h conntrack.h \ state_helper.h network.h ignore.h queue.h \ diff --git a/include/alarm.h b/include/alarm.h index e3e08c1..38aaa01 100644 --- a/include/alarm.h +++ b/include/alarm.h @@ -1,30 +1,28 @@ -#ifndef _TIMER_H_ -#define _TIMER_H_ +#ifndef _ALARM_H_ +#define _ALARM_H_ +#include "linux_rbtree.h" #include "linux_list.h" #include -struct alarm_list { - struct list_head head; +struct alarm_block { + struct rb_node node; + struct list_head list; struct timeval tv; void *data; - void (*function)(struct alarm_list *a, void *data); + void (*function)(struct alarm_block *a, void *data); }; -int init_alarm_hash(void); - -void destroy_alarm_hash(void); - -void init_alarm(struct alarm_list *t, +void init_alarm(struct alarm_block *t, void *data, - void (*fcn)(struct alarm_list *a, void *data)); + void (*fcn)(struct alarm_block *a, void *data)); -void add_alarm(struct alarm_list *alarm, unsigned long sc, unsigned long usc); +void add_alarm(struct alarm_block *alarm, unsigned long sc, unsigned long usc); -void del_alarm(struct alarm_list *alarm); +void del_alarm(struct alarm_block *alarm); -int alarm_pending(struct alarm_list *alarm); +int alarm_pending(struct alarm_block *alarm); struct timeval * get_next_alarm_run(struct timeval *next_alarm); diff --git a/include/linux_rbtree.h b/include/linux_rbtree.h new file mode 100644 index 0000000..ee98891 --- /dev/null +++ b/include/linux_rbtree.h @@ -0,0 +1,160 @@ +/* + Red Black Trees + (C) 1999 Andrea Arcangeli + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + linux/include/linux/rbtree.h + + To use rbtrees you'll have to implement your own insert and search cores. + This will avoid us to use callbacks and to drop drammatically performances. + I know it's not the cleaner way, but in C (not in C++) to get + performances and genericity... + + Some example of insert and search follows here. The search is a plain + normal search over an ordered tree. The insert instead must be implemented + int two steps: as first thing the code must insert the element in + order as a red leaf in the tree, then the support library function + rb_insert_color() must be called. Such function will do the + not trivial work to rebalance the rbtree if necessary. + +----------------------------------------------------------------------- +static inline struct page * rb_search_page_cache(struct inode * inode, + unsigned long offset) +{ + struct rb_node * n = inode->i_rb_page_cache.rb_node; + struct page * page; + + while (n) + { + page = rb_entry(n, struct page, rb_page_cache); + + if (offset < page->offset) + n = n->rb_left; + else if (offset > page->offset) + n = n->rb_right; + else + return page; + } + return NULL; +} + +static inline struct page * __rb_insert_page_cache(struct inode * inode, + unsigned long offset, + struct rb_node * node) +{ + struct rb_node ** p = &inode->i_rb_page_cache.rb_node; + struct rb_node * parent = NULL; + struct page * page; + + while (*p) + { + parent = *p; + page = rb_entry(parent, struct page, rb_page_cache); + + if (offset < page->offset) + p = &(*p)->rb_left; + else if (offset > page->offset) + p = &(*p)->rb_right; + else + return page; + } + + rb_link_node(node, parent, p); + + return NULL; +} + +static inline struct page * rb_insert_page_cache(struct inode * inode, + unsigned long offset, + struct rb_node * node) +{ + struct page * ret; + if ((ret = __rb_insert_page_cache(inode, offset, node))) + goto out; + rb_insert_color(node, &inode->i_rb_page_cache); + out: + return ret; +} +----------------------------------------------------------------------- +*/ + +#ifndef _LINUX_RBTREE_H +#define _LINUX_RBTREE_H + +#include + +struct rb_node +{ + unsigned long rb_parent_color; +#define RB_RED 0 +#define RB_BLACK 1 + struct rb_node *rb_right; + struct rb_node *rb_left; +} __attribute__((aligned(sizeof(long)))); + /* The alignment might seem pointless, but allegedly CRIS needs it */ + +struct rb_root +{ + struct rb_node *rb_node; +}; + + +#define rb_parent(r) ((struct rb_node *)((r)->rb_parent_color & ~3)) +#define rb_color(r) ((r)->rb_parent_color & 1) +#define rb_is_red(r) (!rb_color(r)) +#define rb_is_black(r) rb_color(r) +#define rb_set_red(r) do { (r)->rb_parent_color &= ~1; } while (0) +#define rb_set_black(r) do { (r)->rb_parent_color |= 1; } while (0) + +static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p) +{ + rb->rb_parent_color = (rb->rb_parent_color & 3) | (unsigned long)p; +} +static inline void rb_set_color(struct rb_node *rb, int color) +{ + rb->rb_parent_color = (rb->rb_parent_color & ~1) | color; +} + +#define RB_ROOT { NULL, } +#define rb_entry(ptr, type, member) container_of(ptr, type, member) + +#define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL) +#define RB_EMPTY_NODE(node) (rb_parent(node) == node) +#define RB_CLEAR_NODE(node) (rb_set_parent(node, node)) + +extern void rb_insert_color(struct rb_node *, struct rb_root *); +extern void rb_erase(struct rb_node *, struct rb_root *); + +/* Find logical next and previous nodes in a tree */ +extern struct rb_node *rb_next(struct rb_node *); +extern struct rb_node *rb_prev(struct rb_node *); +extern struct rb_node *rb_first(struct rb_root *); +extern struct rb_node *rb_last(struct rb_root *); + +/* Fast replacement of a single node without remove/rebalance/add/rebalance */ +extern void rb_replace_node(struct rb_node *victim, struct rb_node *new, + struct rb_root *root); + +static inline void rb_link_node(struct rb_node * node, struct rb_node * parent, + struct rb_node ** rb_link) +{ + node->rb_parent_color = (unsigned long )parent; + node->rb_left = node->rb_right = NULL; + + *rb_link = node; +} + +#endif /* _LINUX_RBTREE_H */ diff --git a/src/Makefile.am b/src/Makefile.am index 15628b7..7274a14 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -10,7 +10,7 @@ conntrack_SOURCES = conntrack.c conntrack_LDADD = ../extensions/libct_proto_tcp.la ../extensions/libct_proto_udp.la ../extensions/libct_proto_icmp.la conntrack_LDFLAGS = $(all_libraries) @LIBNETFILTER_CONNTRACK_LIBS@ -conntrackd_SOURCES = alarm.c main.c run.c hash.c queue.c \ +conntrackd_SOURCES = alarm.c main.c run.c hash.c queue.c rbtree.c \ local.c log.c mcast.c netlink.c \ ignore_pool.c \ cache.c cache_iterators.c \ diff --git a/src/alarm.c b/src/alarm.c index 4b23bd1..5013735 100644 --- a/src/alarm.c +++ b/src/alarm.c @@ -1,5 +1,5 @@ /* - * (C) 2006 by Pablo Neira Ayuso + * (C) 2006-2008 by Pablo Neira Ayuso * * 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 @@ -17,41 +17,45 @@ */ #include "alarm.h" -#include "jhash.h" #include #include -#define ALARM_HASH_SIZE 2048 +static struct rb_root alarm_root = RB_ROOT; +static LIST_HEAD(alarm_run_queue); -static struct list_head *alarm_hash; - -void init_alarm(struct alarm_list *t, +void init_alarm(struct alarm_block *t, void *data, - void (*fcn)(struct alarm_list *a, void *data)) + void (*fcn)(struct alarm_block *a, void *data)) { /* initialize the head to check whether a node is inserted */ - INIT_LIST_HEAD(&t->head); + RB_CLEAR_NODE(&t->node); timerclear(&t->tv); t->data = data; t->function = fcn; } -static void -__add_alarm(struct alarm_list *alarm) +static void __add_alarm(struct alarm_block *alarm) { - struct alarm_list *t; - int i = jhash(alarm, sizeof(alarm), 0) % ALARM_HASH_SIZE; + struct rb_node **new = &(alarm_root.rb_node); + struct rb_node *parent = NULL; - list_for_each_entry(t, &alarm_hash[i], head) { - if (timercmp(&alarm->tv, &t->tv, <)) { - list_add_tail(&alarm->head, &t->head); - return; - } + while (*new) { + struct alarm_block *this; + + this = container_of(*new, struct alarm_block, node); + + parent = *new; + if (timercmp(&alarm->tv, &this->tv, <)) + new = &((*new)->rb_left); + else + new = &((*new)->rb_right); } - list_add_tail(&alarm->head, &alarm_hash[i]); + + rb_link_node(&alarm->node, parent, new); + rb_insert_color(&alarm->node, &alarm_root); } -void add_alarm(struct alarm_list *alarm, unsigned long sc, unsigned long usc) +void add_alarm(struct alarm_block *alarm, unsigned long sc, unsigned long usc) { struct timeval tv; @@ -63,16 +67,18 @@ void add_alarm(struct alarm_list *alarm, unsigned long sc, unsigned long usc) __add_alarm(alarm); } -void del_alarm(struct alarm_list *alarm) +void del_alarm(struct alarm_block *alarm) { /* don't remove a non-inserted node */ - if (!list_empty(&alarm->head)) - list_del_init(&alarm->head); + if (!RB_EMPTY_NODE(&alarm->node)) { + rb_erase(&alarm->node, &alarm_root); + RB_CLEAR_NODE(&alarm->node); + } } -int alarm_pending(struct alarm_list *alarm) +int alarm_pending(struct alarm_block *alarm) { - if (list_empty(&alarm->head)) + if (RB_EMPTY_NODE(&alarm->node)) return 0; return 1; @@ -99,101 +105,47 @@ calculate_next_run(struct timeval *cand, struct timeval * get_next_alarm_run(struct timeval *next_run) { - int i; - struct alarm_list *t; + struct rb_node *node = alarm_root.rb_node; struct timeval tv; - struct timeval cand = { - .tv_sec = LONG_MAX, - .tv_usec = LONG_MAX - }; gettimeofday(&tv, NULL); - for (i=0; itv, &cand, <)) { - cand.tv_sec = t->tv.tv_sec; - cand.tv_usec = t->tv.tv_usec; - } - } + node = rb_first(&alarm_root); + if (node) { + struct alarm_block *this; + this = container_of(node, struct alarm_block, node); + return calculate_next_run(&this->tv, &tv, next_run); } - - return calculate_next_run(&cand, &tv, next_run); -} - -static inline int -tv_compare(struct alarm_list *a, struct timeval *cur, struct timeval *cand) -{ - if (timercmp(&a->tv, cur, >)) { - /* select the next alarm candidate */ - if (timercmp(&a->tv, cand, <)) { - cand->tv_sec = a->tv.tv_sec; - cand->tv_usec = a->tv.tv_usec; - } - return 1; - } - return 0; + return NULL; } struct timeval * do_alarm_run(struct timeval *next_run) { - int i; - struct alarm_list *t, *next, *prev; + struct rb_node *node = alarm_root.rb_node; + struct alarm_block *this, *tmp; struct timeval tv; - struct timeval cand = { - .tv_sec = LONG_MAX, - .tv_usec = LONG_MAX - }; gettimeofday(&tv, NULL); - for (i=0; ihead.prev, - struct alarm_list, - head); - - del_alarm(t); - t->function(t, t->data); - - /* Special case: One deleted node is inserted - * again in the same place */ - if (next->head.prev == &prev->head) { - t = list_entry(next->head.prev, - struct alarm_list, - head); - if (tv_compare(t, &tv, &cand)) - break; - } - } - } + node = rb_first(&alarm_root); + while (node) { + this = container_of(node, struct alarm_block, node); - return calculate_next_run(&cand, &tv, next_run); -} + if (timercmp(&this->tv, &tv, >)) + break; -int init_alarm_hash(void) -{ - int i; + node = rb_next(node); - alarm_hash = malloc(sizeof(struct list_head) * ALARM_HASH_SIZE); - if (alarm_hash == NULL) - return -1; - - for (i=0; ilist, &alarm_run_queue); + } - return 0; -} + list_for_each_entry_safe(this, tmp, &alarm_run_queue, list) { + list_del(&this->list); + rb_erase(&this->node, &alarm_root); + RB_CLEAR_NODE(&this->node); + this->function(this, this->data); + } -void destroy_alarm_hash(void) -{ - free(alarm_hash); + return get_next_alarm_run(next_run); } diff --git a/src/cache_timer.c b/src/cache_timer.c index fe997ec..6619c2c 100644 --- a/src/cache_timer.c +++ b/src/cache_timer.c @@ -24,7 +24,7 @@ #include -static void timeout(struct alarm_list *a, void *data) +static void timeout(struct alarm_block *a, void *data) { struct us_conntrack *u = data; @@ -34,7 +34,7 @@ static void timeout(struct alarm_list *a, void *data) static void timer_add(struct us_conntrack *u, void *data) { - struct alarm_list *alarm = data; + struct alarm_block *alarm = data; init_alarm(alarm, u, timeout); add_alarm(alarm, CONFIG(cache_timeout), 0); @@ -42,20 +42,20 @@ static void timer_add(struct us_conntrack *u, void *data) static void timer_update(struct us_conntrack *u, void *data) { - struct alarm_list *alarm = data; + struct alarm_block *alarm = data; add_alarm(alarm, CONFIG(cache_timeout), 0); } static void timer_destroy(struct us_conntrack *u, void *data) { - struct alarm_list *alarm = data; + struct alarm_block *alarm = data; del_alarm(alarm); } static int timer_dump(struct us_conntrack *u, void *data, char *buf, int type) { struct timeval tv, tmp; - struct alarm_list *alarm = data; + struct alarm_block *alarm = data; if (type == NFCT_O_XML) return 0; @@ -69,7 +69,7 @@ static int timer_dump(struct us_conntrack *u, void *data, char *buf, int type) } struct cache_feature timer_feature = { - .size = sizeof(struct alarm_list), + .size = sizeof(struct alarm_block), .add = timer_add, .update = timer_update, .destroy = timer_destroy, diff --git a/src/rbtree.c b/src/rbtree.c new file mode 100644 index 0000000..199e2bb --- /dev/null +++ b/src/rbtree.c @@ -0,0 +1,389 @@ +/* + Red Black Trees + (C) 1999 Andrea Arcangeli + (C) 2002 David Woodhouse + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + linux/lib/rbtree.c +*/ + +#include "linux_rbtree.h" + +static void __rb_rotate_left(struct rb_node *node, struct rb_root *root) +{ + struct rb_node *right = node->rb_right; + struct rb_node *parent = rb_parent(node); + + if ((node->rb_right = right->rb_left)) + rb_set_parent(right->rb_left, node); + right->rb_left = node; + + rb_set_parent(right, parent); + + if (parent) + { + if (node == parent->rb_left) + parent->rb_left = right; + else + parent->rb_right = right; + } + else + root->rb_node = right; + rb_set_parent(node, right); +} + +static void __rb_rotate_right(struct rb_node *node, struct rb_root *root) +{ + struct rb_node *left = node->rb_left; + struct rb_node *parent = rb_parent(node); + + if ((node->rb_left = left->rb_right)) + rb_set_parent(left->rb_right, node); + left->rb_right = node; + + rb_set_parent(left, parent); + + if (parent) + { + if (node == parent->rb_right) + parent->rb_right = left; + else + parent->rb_left = left; + } + else + root->rb_node = left; + rb_set_parent(node, left); +} + +void rb_insert_color(struct rb_node *node, struct rb_root *root) +{ + struct rb_node *parent, *gparent; + + while ((parent = rb_parent(node)) && rb_is_red(parent)) + { + gparent = rb_parent(parent); + + if (parent == gparent->rb_left) + { + { + register struct rb_node *uncle = gparent->rb_right; + if (uncle && rb_is_red(uncle)) + { + rb_set_black(uncle); + rb_set_black(parent); + rb_set_red(gparent); + node = gparent; + continue; + } + } + + if (parent->rb_right == node) + { + register struct rb_node *tmp; + __rb_rotate_left(parent, root); + tmp = parent; + parent = node; + node = tmp; + } + + rb_set_black(parent); + rb_set_red(gparent); + __rb_rotate_right(gparent, root); + } else { + { + register struct rb_node *uncle = gparent->rb_left; + if (uncle && rb_is_red(uncle)) + { + rb_set_black(uncle); + rb_set_black(parent); + rb_set_red(gparent); + node = gparent; + continue; + } + } + + if (parent->rb_left == node) + { + register struct rb_node *tmp; + __rb_rotate_right(parent, root); + tmp = parent; + parent = node; + node = tmp; + } + + rb_set_black(parent); + rb_set_red(gparent); + __rb_rotate_left(gparent, root); + } + } + + rb_set_black(root->rb_node); +} + +static void __rb_erase_color(struct rb_node *node, struct rb_node *parent, + struct rb_root *root) +{ + struct rb_node *other; + + while ((!node || rb_is_black(node)) && node != root->rb_node) + { + if (parent->rb_left == node) + { + other = parent->rb_right; + if (rb_is_red(other)) + { + rb_set_black(other); + rb_set_red(parent); + __rb_rotate_left(parent, root); + other = parent->rb_right; + } + if ((!other->rb_left || rb_is_black(other->rb_left)) && + (!other->rb_right || rb_is_black(other->rb_right))) + { + rb_set_red(other); + node = parent; + parent = rb_parent(node); + } + else + { + if (!other->rb_right || rb_is_black(other->rb_right)) + { + struct rb_node *o_left; + if ((o_left = other->rb_left)) + rb_set_black(o_left); + rb_set_red(other); + __rb_rotate_right(other, root); + other = parent->rb_right; + } + rb_set_color(other, rb_color(parent)); + rb_set_black(parent); + if (other->rb_right) + rb_set_black(other->rb_right); + __rb_rotate_left(parent, root); + node = root->rb_node; + break; + } + } + else + { + other = parent->rb_left; + if (rb_is_red(other)) + { + rb_set_black(other); + rb_set_red(parent); + __rb_rotate_right(parent, root); + other = parent->rb_left; + } + if ((!other->rb_left || rb_is_black(other->rb_left)) && + (!other->rb_right || rb_is_black(other->rb_right))) + { + rb_set_red(other); + node = parent; + parent = rb_parent(node); + } + else + { + if (!other->rb_left || rb_is_black(other->rb_left)) + { + register struct rb_node *o_right; + if ((o_right = other->rb_right)) + rb_set_black(o_right); + rb_set_red(other); + __rb_rotate_left(other, root); + other = parent->rb_left; + } + rb_set_color(other, rb_color(parent)); + rb_set_black(parent); + if (other->rb_left) + rb_set_black(other->rb_left); + __rb_rotate_right(parent, root); + node = root->rb_node; + break; + } + } + } + if (node) + rb_set_black(node); +} + +void rb_erase(struct rb_node *node, struct rb_root *root) +{ + struct rb_node *child, *parent; + int color; + + if (!node->rb_left) + child = node->rb_right; + else if (!node->rb_right) + child = node->rb_left; + else + { + struct rb_node *old = node, *left; + + node = node->rb_right; + while ((left = node->rb_left) != NULL) + node = left; + child = node->rb_right; + parent = rb_parent(node); + color = rb_color(node); + + if (child) + rb_set_parent(child, parent); + if (parent == old) { + parent->rb_right = child; + parent = node; + } else + parent->rb_left = child; + + node->rb_parent_color = old->rb_parent_color; + node->rb_right = old->rb_right; + node->rb_left = old->rb_left; + + if (rb_parent(old)) + { + if (rb_parent(old)->rb_left == old) + rb_parent(old)->rb_left = node; + else + rb_parent(old)->rb_right = node; + } else + root->rb_node = node; + + rb_set_parent(old->rb_left, node); + if (old->rb_right) + rb_set_parent(old->rb_right, node); + goto color; + } + + parent = rb_parent(node); + color = rb_color(node); + + if (child) + rb_set_parent(child, parent); + if (parent) + { + if (parent->rb_left == node) + parent->rb_left = child; + else + parent->rb_right = child; + } + else + root->rb_node = child; + + color: + if (color == RB_BLACK) + __rb_erase_color(child, parent, root); +} + +/* + * This function returns the first node (in sort order) of the tree. + */ +struct rb_node *rb_first(struct rb_root *root) +{ + struct rb_node *n; + + n = root->rb_node; + if (!n) + return NULL; + while (n->rb_left) + n = n->rb_left; + return n; +} + +struct rb_node *rb_last(struct rb_root *root) +{ + struct rb_node *n; + + n = root->rb_node; + if (!n) + return NULL; + while (n->rb_right) + n = n->rb_right; + return n; +} + +struct rb_node *rb_next(struct rb_node *node) +{ + struct rb_node *parent; + + if (rb_parent(node) == node) + return NULL; + + /* If we have a right-hand child, go down and then left as far + as we can. */ + if (node->rb_right) { + node = node->rb_right; + while (node->rb_left) + node=node->rb_left; + return node; + } + + /* No right-hand children. Everything down and left is + smaller than us, so any 'next' node must be in the general + direction of our parent. Go up the tree; any time the + ancestor is a right-hand child of its parent, keep going + up. First time it's a left-hand child of its parent, said + parent is our 'next' node. */ + while ((parent = rb_parent(node)) && node == parent->rb_right) + node = parent; + + return parent; +} + +struct rb_node *rb_prev(struct rb_node *node) +{ + struct rb_node *parent; + + if (rb_parent(node) == node) + return NULL; + + /* If we have a left-hand child, go down and then right as far + as we can. */ + if (node->rb_left) { + node = node->rb_left; + while (node->rb_right) + node=node->rb_right; + return node; + } + + /* No left-hand children. Go up till we find an ancestor which + is a right-hand child of its parent */ + while ((parent = rb_parent(node)) && node == parent->rb_left) + node = parent; + + return parent; +} + +void rb_replace_node(struct rb_node *victim, struct rb_node *new, + struct rb_root *root) +{ + struct rb_node *parent = rb_parent(victim); + + /* Set the surrounding nodes to point to the replacement */ + if (parent) { + if (victim == parent->rb_left) + parent->rb_left = new; + else + parent->rb_right = new; + } else { + root->rb_node = new; + } + if (victim->rb_left) + rb_set_parent(victim->rb_left, new); + if (victim->rb_right) + rb_set_parent(victim->rb_right, new); + + /* Copy the pointers/colour from the victim to the replacement */ + *new = *victim; +} diff --git a/src/run.c b/src/run.c index 876e131..f5832bc 100644 --- a/src/run.c +++ b/src/run.c @@ -42,7 +42,6 @@ void killer(int foo) ignore_pool_destroy(STATE(ignore_pool)); local_server_destroy(&STATE(local)); STATE(mode)->kill(); - destroy_alarm_hash(); unlink(CONFIG(lockfile)); dlog(LOG_NOTICE, "---- shutdown received ----"); close_log(); @@ -103,11 +102,6 @@ init(void) STATE(mode) = &stats_mode; } - if (init_alarm_hash() == -1) { - dlog(LOG_ERR, "can't initialize alarm hash"); - return -1; - } - /* Initialization */ if (STATE(mode)->init() == -1) { dlog(LOG_ERR, "initialization failed"); diff --git a/src/sync-alarm.c b/src/sync-alarm.c index c7cecc8..4473af2 100644 --- a/src/sync-alarm.c +++ b/src/sync-alarm.c @@ -27,7 +27,7 @@ #include #include -static void refresher(struct alarm_list *a, void *data) +static void refresher(struct alarm_block *a, void *data) { size_t len; struct nethdr *net; @@ -46,7 +46,7 @@ static void refresher(struct alarm_list *a, void *data) static void cache_alarm_add(struct us_conntrack *u, void *data) { - struct alarm_list *alarm = data; + struct alarm_block *alarm = data; init_alarm(alarm, u, refresher); add_alarm(alarm, @@ -56,7 +56,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; + struct alarm_block *alarm = data; add_alarm(alarm, random() % CONFIG(refresh) + 1, ((random() % 5 + 1) * 200000) - 1); @@ -64,12 +64,12 @@ static void cache_alarm_update(struct us_conntrack *u, void *data) static void cache_alarm_destroy(struct us_conntrack *u, void *data) { - struct alarm_list *alarm = data; + struct alarm_block *alarm = data; del_alarm(alarm); } static struct cache_extra cache_alarm_extra = { - .size = sizeof(struct alarm_list), + .size = sizeof(struct alarm_block), .add = cache_alarm_add, .update = cache_alarm_update, .destroy = cache_alarm_destroy diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c index 49c0b2c..cac25d0 100644 --- a/src/sync-ftfw.c +++ b/src/sync-ftfw.c @@ -83,9 +83,9 @@ static void tx_queue_add_ctlmsg(uint32_t flags, uint32_t from, uint32_t to) queue_add(tx_queue, &ack, NETHDR_ACK_SIZ); } -static struct alarm_list alive_alarm; +static struct alarm_block alive_alarm; -static void do_alive_alarm(struct alarm_list *a, void *data) +static void do_alive_alarm(struct alarm_block *a, void *data) { tx_queue_add_ctlmsg(NET_F_ALIVE, 0, 0); -- cgit v1.2.3 From 2d92fdb0912f3546492b114485951287fca4e5ab Mon Sep 17 00:00:00 2001 From: "/C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org" Date: Sat, 8 Mar 2008 11:28:05 +0000 Subject: relicense conntrack-tools as GPLv3+, so far the most significant contributor has been Max Kellermann and has no issues with relicensing their contributions. --- COPYING | 913 +++++++++++++++++++++++++++++++++---------------- src/alarm.c | 2 +- src/build.c | 2 +- src/cache.c | 2 +- src/cache_iterators.c | 2 +- src/cache_lifetime.c | 2 +- src/cache_timer.c | 2 +- src/cache_wt.c | 2 +- src/conntrack.c | 2 +- src/fds.c | 2 +- src/hash.c | 2 +- src/ignore_pool.c | 2 +- src/local.c | 2 +- src/log.c | 2 +- src/main.c | 2 +- src/mcast.c | 2 +- src/netlink.c | 2 +- src/network.c | 2 +- src/parse.c | 2 +- src/queue.c | 2 +- src/rbtree.c | 2 +- src/read_config_lex.l | 2 +- src/read_config_yy.y | 2 +- src/run.c | 2 +- src/state_helper.c | 2 +- src/state_helper_tcp.c | 2 +- src/stats-mode.c | 2 +- src/sync-alarm.c | 2 +- src/sync-ftfw.c | 2 +- src/sync-mode.c | 2 +- src/traffic_stats.c | 2 +- 31 files changed, 654 insertions(+), 319 deletions(-) (limited to 'src/sync-alarm.c') diff --git a/COPYING b/COPYING index a43ea21..94a9ed0 100644 --- a/COPYING +++ b/COPYING @@ -1,285 +1,626 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA + Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. - Preamble + Preamble - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of this License. - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Programs + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it @@ -287,15 +628,15 @@ free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least +state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. - Copyright (C) 19yy + Copyright (C) - This program is free software; you can redistribute it and/or modify + 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 + the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -304,36 +645,30 @@ the "copyright" line and a pointer to where the full notice is found. 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. + along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/src/alarm.c b/src/alarm.c index 91ee2ca..db3f105 100644 --- a/src/alarm.c +++ b/src/alarm.c @@ -3,7 +3,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/src/build.c b/src/build.c index 6363458..1ab0ed4 100644 --- a/src/build.c +++ b/src/build.c @@ -3,7 +3,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/src/cache.c b/src/cache.c index 73d539a..6f81725 100644 --- a/src/cache.c +++ b/src/cache.c @@ -3,7 +3,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/src/cache_iterators.c b/src/cache_iterators.c index 92b7b7f..662e4a9 100644 --- a/src/cache_iterators.c +++ b/src/cache_iterators.c @@ -3,7 +3,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/src/cache_lifetime.c b/src/cache_lifetime.c index ad3416a..989e069 100644 --- a/src/cache_lifetime.c +++ b/src/cache_lifetime.c @@ -3,7 +3,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/src/cache_timer.c b/src/cache_timer.c index 6619c2c..aba342c 100644 --- a/src/cache_timer.c +++ b/src/cache_timer.c @@ -3,7 +3,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/src/cache_wt.c b/src/cache_wt.c index 8ff8fae..bf683b0 100644 --- a/src/cache_wt.c +++ b/src/cache_wt.c @@ -3,7 +3,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/src/conntrack.c b/src/conntrack.c index 82ff544..e0ff92d 100644 --- a/src/conntrack.c +++ b/src/conntrack.c @@ -3,7 +3,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/src/fds.c b/src/fds.c index 908f048..ccb639b 100644 --- a/src/fds.c +++ b/src/fds.c @@ -3,7 +3,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/src/hash.c b/src/hash.c index cf64df4..5df33dd 100644 --- a/src/hash.c +++ b/src/hash.c @@ -3,7 +3,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/src/ignore_pool.c b/src/ignore_pool.c index 027d628..7540b3a 100644 --- a/src/ignore_pool.c +++ b/src/ignore_pool.c @@ -3,7 +3,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/src/local.c b/src/local.c index e2c3599..a67b2fb 100644 --- a/src/local.c +++ b/src/local.c @@ -3,7 +3,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/src/log.c b/src/log.c index 51e757f..1638dc2 100644 --- a/src/log.c +++ b/src/log.c @@ -3,7 +3,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/src/main.c b/src/main.c index 2e1ccd8..fa05da0 100644 --- a/src/main.c +++ b/src/main.c @@ -3,7 +3,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/src/mcast.c b/src/mcast.c index f945511..30313bc 100644 --- a/src/mcast.c +++ b/src/mcast.c @@ -3,7 +3,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/src/netlink.c b/src/netlink.c index f6a2378..8ac6f93 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -3,7 +3,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/src/network.c b/src/network.c index 92999a1..f5b0909 100644 --- a/src/network.c +++ b/src/network.c @@ -3,7 +3,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/src/parse.c b/src/parse.c index 8ef2e8d..1e5fdf6 100644 --- a/src/parse.c +++ b/src/parse.c @@ -3,7 +3,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/src/queue.c b/src/queue.c index 7b20e83..22460e3 100644 --- a/src/queue.c +++ b/src/queue.c @@ -3,7 +3,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/src/rbtree.c b/src/rbtree.c index 199e2bb..2228f98 100644 --- a/src/rbtree.c +++ b/src/rbtree.c @@ -5,7 +5,7 @@ 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 + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/src/read_config_lex.l b/src/read_config_lex.l index 65df1e7..4f0d864 100644 --- a/src/read_config_lex.l +++ b/src/read_config_lex.l @@ -4,7 +4,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/src/read_config_yy.y b/src/read_config_yy.y index 86fee9b..f89677a 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -4,7 +4,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/src/run.c b/src/run.c index b259f2e..0d91f4d 100644 --- a/src/run.c +++ b/src/run.c @@ -3,7 +3,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/src/state_helper.c b/src/state_helper.c index 9034864..2fa0e02 100644 --- a/src/state_helper.c +++ b/src/state_helper.c @@ -3,7 +3,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/src/state_helper_tcp.c b/src/state_helper_tcp.c index 88af35e..625928c 100644 --- a/src/state_helper_tcp.c +++ b/src/state_helper_tcp.c @@ -3,7 +3,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/src/stats-mode.c b/src/stats-mode.c index 42fa35a..06962d2 100644 --- a/src/stats-mode.c +++ b/src/stats-mode.c @@ -3,7 +3,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/src/sync-alarm.c b/src/sync-alarm.c index 4473af2..709e27b 100644 --- a/src/sync-alarm.c +++ b/src/sync-alarm.c @@ -3,7 +3,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c index cac25d0..4ed8928 100644 --- a/src/sync-ftfw.c +++ b/src/sync-ftfw.c @@ -3,7 +3,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/src/sync-mode.c b/src/sync-mode.c index 79afcdf..86ac5e8 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -3,7 +3,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/src/traffic_stats.c b/src/traffic_stats.c index 9e40d53..b5a97ec 100644 --- a/src/traffic_stats.c +++ b/src/traffic_stats.c @@ -3,7 +3,7 @@ * * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, -- cgit v1.2.3 From 4f0edbba3cca03e4816c015cbf2c1a29fb62d073 Mon Sep 17 00:00:00 2001 From: "/C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org" Date: Sat, 8 Mar 2008 11:35:02 +0000 Subject: revert relicensing... still we use linux_list.h code which seems to be GPLv2 only which is incompatible AFAIK --- COPYING | 913 ++++++++++++++++--------------------------------- src/alarm.c | 2 +- src/build.c | 2 +- src/cache.c | 2 +- src/cache_iterators.c | 2 +- src/cache_lifetime.c | 2 +- src/cache_timer.c | 2 +- src/cache_wt.c | 2 +- src/conntrack.c | 2 +- src/fds.c | 2 +- src/hash.c | 2 +- src/ignore_pool.c | 2 +- src/local.c | 2 +- src/log.c | 2 +- src/main.c | 2 +- src/mcast.c | 2 +- src/netlink.c | 2 +- src/network.c | 2 +- src/parse.c | 2 +- src/queue.c | 2 +- src/rbtree.c | 2 +- src/read_config_lex.l | 2 +- src/read_config_yy.y | 2 +- src/run.c | 2 +- src/state_helper.c | 2 +- src/state_helper_tcp.c | 2 +- src/stats-mode.c | 2 +- src/sync-alarm.c | 2 +- src/sync-ftfw.c | 2 +- src/sync-mode.c | 2 +- src/traffic_stats.c | 2 +- 31 files changed, 319 insertions(+), 654 deletions(-) (limited to 'src/sync-alarm.c') diff --git a/COPYING b/COPYING index 94a9ed0..a43ea21 100644 --- a/COPYING +++ b/COPYING @@ -1,626 +1,285 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. - Preamble + Preamble - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to this License. - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it @@ -628,15 +287,15 @@ free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least +convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. - Copyright (C) + Copyright (C) 19yy - This program is free software: you can redistribute it and/or modify + 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 3 of the License, or + 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, @@ -645,30 +304,36 @@ the "copyright" line and a pointer to where the full notice is found. 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, see . + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/src/alarm.c b/src/alarm.c index db3f105..91ee2ca 100644 --- a/src/alarm.c +++ b/src/alarm.c @@ -3,7 +3,7 @@ * * 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 3 of the License, or + * 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, diff --git a/src/build.c b/src/build.c index 1ab0ed4..6363458 100644 --- a/src/build.c +++ b/src/build.c @@ -3,7 +3,7 @@ * * 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 3 of the License, or + * 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, diff --git a/src/cache.c b/src/cache.c index 6f81725..73d539a 100644 --- a/src/cache.c +++ b/src/cache.c @@ -3,7 +3,7 @@ * * 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 3 of the License, or + * 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, diff --git a/src/cache_iterators.c b/src/cache_iterators.c index 662e4a9..92b7b7f 100644 --- a/src/cache_iterators.c +++ b/src/cache_iterators.c @@ -3,7 +3,7 @@ * * 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 3 of the License, or + * 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, diff --git a/src/cache_lifetime.c b/src/cache_lifetime.c index 989e069..ad3416a 100644 --- a/src/cache_lifetime.c +++ b/src/cache_lifetime.c @@ -3,7 +3,7 @@ * * 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 3 of the License, or + * 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, diff --git a/src/cache_timer.c b/src/cache_timer.c index aba342c..6619c2c 100644 --- a/src/cache_timer.c +++ b/src/cache_timer.c @@ -3,7 +3,7 @@ * * 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 3 of the License, or + * 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, diff --git a/src/cache_wt.c b/src/cache_wt.c index bf683b0..8ff8fae 100644 --- a/src/cache_wt.c +++ b/src/cache_wt.c @@ -3,7 +3,7 @@ * * 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 3 of the License, or + * 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, diff --git a/src/conntrack.c b/src/conntrack.c index e0ff92d..82ff544 100644 --- a/src/conntrack.c +++ b/src/conntrack.c @@ -3,7 +3,7 @@ * * 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 3 of the License, or + * 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, diff --git a/src/fds.c b/src/fds.c index ccb639b..908f048 100644 --- a/src/fds.c +++ b/src/fds.c @@ -3,7 +3,7 @@ * * 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 3 of the License, or + * 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, diff --git a/src/hash.c b/src/hash.c index 5df33dd..cf64df4 100644 --- a/src/hash.c +++ b/src/hash.c @@ -3,7 +3,7 @@ * * 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 3 of the License, or + * 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, diff --git a/src/ignore_pool.c b/src/ignore_pool.c index 7540b3a..027d628 100644 --- a/src/ignore_pool.c +++ b/src/ignore_pool.c @@ -3,7 +3,7 @@ * * 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 3 of the License, or + * 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, diff --git a/src/local.c b/src/local.c index a67b2fb..e2c3599 100644 --- a/src/local.c +++ b/src/local.c @@ -3,7 +3,7 @@ * * 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 3 of the License, or + * 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, diff --git a/src/log.c b/src/log.c index 1638dc2..51e757f 100644 --- a/src/log.c +++ b/src/log.c @@ -3,7 +3,7 @@ * * 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 3 of the License, or + * 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, diff --git a/src/main.c b/src/main.c index fa05da0..2e1ccd8 100644 --- a/src/main.c +++ b/src/main.c @@ -3,7 +3,7 @@ * * 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 3 of the License, or + * 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, diff --git a/src/mcast.c b/src/mcast.c index 30313bc..f945511 100644 --- a/src/mcast.c +++ b/src/mcast.c @@ -3,7 +3,7 @@ * * 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 3 of the License, or + * 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, diff --git a/src/netlink.c b/src/netlink.c index 8ac6f93..f6a2378 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -3,7 +3,7 @@ * * 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 3 of the License, or + * 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, diff --git a/src/network.c b/src/network.c index f5b0909..92999a1 100644 --- a/src/network.c +++ b/src/network.c @@ -3,7 +3,7 @@ * * 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 3 of the License, or + * 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, diff --git a/src/parse.c b/src/parse.c index 1e5fdf6..8ef2e8d 100644 --- a/src/parse.c +++ b/src/parse.c @@ -3,7 +3,7 @@ * * 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 3 of the License, or + * 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, diff --git a/src/queue.c b/src/queue.c index 22460e3..7b20e83 100644 --- a/src/queue.c +++ b/src/queue.c @@ -3,7 +3,7 @@ * * 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 3 of the License, or + * 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, diff --git a/src/rbtree.c b/src/rbtree.c index 2228f98..199e2bb 100644 --- a/src/rbtree.c +++ b/src/rbtree.c @@ -5,7 +5,7 @@ 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 3 of the License, or + 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, diff --git a/src/read_config_lex.l b/src/read_config_lex.l index 4f0d864..65df1e7 100644 --- a/src/read_config_lex.l +++ b/src/read_config_lex.l @@ -4,7 +4,7 @@ * * 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 3 of the License, or + * 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, diff --git a/src/read_config_yy.y b/src/read_config_yy.y index f89677a..86fee9b 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -4,7 +4,7 @@ * * 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 3 of the License, or + * 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, diff --git a/src/run.c b/src/run.c index 0d91f4d..b259f2e 100644 --- a/src/run.c +++ b/src/run.c @@ -3,7 +3,7 @@ * * 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 3 of the License, or + * 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, diff --git a/src/state_helper.c b/src/state_helper.c index 2fa0e02..9034864 100644 --- a/src/state_helper.c +++ b/src/state_helper.c @@ -3,7 +3,7 @@ * * 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 3 of the License, or + * 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, diff --git a/src/state_helper_tcp.c b/src/state_helper_tcp.c index 625928c..88af35e 100644 --- a/src/state_helper_tcp.c +++ b/src/state_helper_tcp.c @@ -3,7 +3,7 @@ * * 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 3 of the License, or + * 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, diff --git a/src/stats-mode.c b/src/stats-mode.c index 06962d2..42fa35a 100644 --- a/src/stats-mode.c +++ b/src/stats-mode.c @@ -3,7 +3,7 @@ * * 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 3 of the License, or + * 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, diff --git a/src/sync-alarm.c b/src/sync-alarm.c index 709e27b..4473af2 100644 --- a/src/sync-alarm.c +++ b/src/sync-alarm.c @@ -3,7 +3,7 @@ * * 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 3 of the License, or + * 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, diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c index 4ed8928..cac25d0 100644 --- a/src/sync-ftfw.c +++ b/src/sync-ftfw.c @@ -3,7 +3,7 @@ * * 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 3 of the License, or + * 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, diff --git a/src/sync-mode.c b/src/sync-mode.c index 86ac5e8..79afcdf 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -3,7 +3,7 @@ * * 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 3 of the License, or + * 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, diff --git a/src/traffic_stats.c b/src/traffic_stats.c index b5a97ec..9e40d53 100644 --- a/src/traffic_stats.c +++ b/src/traffic_stats.c @@ -3,7 +3,7 @@ * * 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 3 of the License, or + * 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, -- cgit v1.2.3 From bf6cfeb1dc6652eaff1b7c4edda45e15f5abf361 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 8 Dec 2008 11:09:02 +0100 Subject: network: remove length parameter of mcast_buffered_send_netmsg() This patch simplifies mcast_buffered_send_netmsg() by removing the length parameter. Instead, we use the length field in the nethdr to know the message size to be sent. Signed-off-by: Pablo Neira Ayuso --- include/network.h | 2 +- src/network.c | 5 ++--- src/sync-alarm.c | 2 +- src/sync-ftfw.c | 4 ++-- src/sync-mode.c | 2 +- src/sync-notrack.c | 4 ++-- 6 files changed, 9 insertions(+), 10 deletions(-) (limited to 'src/sync-alarm.c') diff --git a/include/network.h b/include/network.h index b64753c..1195303 100644 --- a/include/network.h +++ b/include/network.h @@ -76,7 +76,7 @@ struct mcast_conf; int mcast_buffered_init(int mtu); void mcast_buffered_destroy(void); -int mcast_buffered_send_netmsg(struct mcast_sock *m, void *data, size_t len); +int mcast_buffered_send_netmsg(struct mcast_sock *m, const struct nethdr *net); ssize_t mcast_buffered_pending_netmsg(struct mcast_sock *m); #define IS_DATA(x) ((x->flags & ~(NET_F_HELLO | NET_F_HELLO_BACK)) == 0) diff --git a/src/network.c b/src/network.c index 2f83d3b..a6ecb7e 100644 --- a/src/network.c +++ b/src/network.c @@ -108,10 +108,9 @@ void mcast_buffered_destroy(void) } /* return 0 if it is not sent, otherwise return 1 */ -int mcast_buffered_send_netmsg(struct mcast_sock *m, void *data, size_t len) +int mcast_buffered_send_netmsg(struct mcast_sock *m, const struct nethdr *net) { - int ret = 0; - struct nethdr *net = data; + int ret = 0, len = ntohs(net->len); retry: if (tx_buflen + len < tx_buflenmax) { diff --git a/src/sync-alarm.c b/src/sync-alarm.c index 4473af2..377af16 100644 --- a/src/sync-alarm.c +++ b/src/sync-alarm.c @@ -41,7 +41,7 @@ static void refresher(struct alarm_block *a, void *data) 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); + mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net); } static void cache_alarm_add(struct us_conntrack *u, void *data) diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c index abba1fe..293f9ab 100644 --- a/src/sync-ftfw.c +++ b/src/sync-ftfw.c @@ -495,7 +495,7 @@ static int tx_queue_xmit(void *data1, const void *data2) dp("tx_queue sq: %u fl:%u len:%u\n", ntohl(net->seq), net->flags, ntohs(net->len)); - mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net, len); + mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net); HDR_NETWORK2HOST(net); if (IS_DATA(net) || IS_ACK(net) || IS_NACK(net)) @@ -518,7 +518,7 @@ static int tx_list_xmit(struct list_head *i, struct us_conntrack *u, int type) list_del_init(i); tx_list_len--; - ret = mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net, len); + ret = mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net); ftfw_send(net, u); return ret; diff --git a/src/sync-mode.c b/src/sync-mode.c index 98867b2..ac9d3f3 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -406,7 +406,7 @@ static void mcast_send_sync(struct us_conntrack *u, int query) if (STATE_SYNC(sync)->send) STATE_SYNC(sync)->send(net, u); - mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net, len); + mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net); } static int purge_step(void *data1, void *data2) diff --git a/src/sync-notrack.c b/src/sync-notrack.c index c7ac9b5..c5ea1e6 100644 --- a/src/sync-notrack.c +++ b/src/sync-notrack.c @@ -157,7 +157,7 @@ static int tx_queue_xmit(void *data1, const void *data2) struct nethdr *net = data1; size_t len = prepare_send_netmsg(STATE_SYNC(mcast_client), net); - mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net, len); + mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net); queue_del(tx_queue, net); return 0; @@ -172,7 +172,7 @@ static int tx_list_xmit(struct list_head *i, struct us_conntrack *u, int type) list_del_init(i); tx_list_len--; - ret = mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net, len); + ret = mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net); return ret; } -- cgit v1.2.3 From a516e5f8e550a6073aae96491372c45ce340da88 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 8 Dec 2008 11:10:47 +0100 Subject: network: remove the netpld header from the messages This patch simplifies the message format of the replication messages. As a result, we save four bytes. The netpld header was introduced in the early protocol design. Today, it does not have any reason to exist. Signed-off-by: Pablo Neira Ayuso --- include/network.h | 47 +++++++++++++++++------------------ src/build.c | 72 ++++++++++++++++++++++++++---------------------------- src/network.c | 55 +++++++++++++++-------------------------- src/parse.c | 23 +++-------------- src/sync-alarm.c | 2 -- src/sync-ftfw.c | 8 +++--- src/sync-mode.c | 11 +++------ src/sync-notrack.c | 5 ++-- 8 files changed, 90 insertions(+), 133 deletions(-) (limited to 'src/sync-alarm.c') diff --git a/include/network.h b/include/network.h index 1195303..11e65c7 100644 --- a/include/network.h +++ b/include/network.h @@ -9,25 +9,34 @@ struct nf_conntrack; struct nethdr { - uint8_t version; + uint8_t version:4, + type:4; uint8_t flags; uint16_t len; uint32_t seq; }; -#define NETHDR_SIZ sizeof(struct nethdr) +#define NETHDR_SIZ nethdr_align(sizeof(struct nethdr)) + +int nethdr_align(int len); +int nethdr_size(int len); +void nethdr_set(struct nethdr *net, int type); +void nethdr_set_ack(struct nethdr *net); #define NETHDR_DATA(x) \ - (struct netpld *)(((char *)x) + sizeof(struct nethdr)) + (struct netattr *)(((char *)x) + NETHDR_SIZ) +#define NETHDR_TAIL(x) \ + (struct netattr *)(((char *)x) + x->len) struct nethdr_ack { - uint8_t version; + uint8_t version:4, + type:4; uint8_t flags; uint16_t len; uint32_t seq; uint32_t from; uint32_t to; }; -#define NETHDR_ACK_SIZ sizeof(struct nethdr_ack) +#define NETHDR_ACK_SIZ nethdr_align(sizeof(struct nethdr_ack)) enum { NET_F_UNUSED = (1 << 0), @@ -49,17 +58,17 @@ enum { #define BUILD_NETMSG(ct, query) \ ({ \ char __net[4096]; \ - memset(__net, 0, NETHDR_SIZ + NETPLD_SIZ); \ - build_netmsg(ct, query, (struct nethdr *) __net); \ - (struct nethdr *) __net; \ + struct nethdr *__hdr = (struct nethdr *) __net; \ + memset(__hdr, 0, NETHDR_SIZ); \ + nethdr_set(__hdr, query); \ + build_payload(ct, __hdr); \ + HDR_HOST2NETWORK(__hdr); \ + __hdr; \ }) struct us_conntrack; struct mcast_sock; -void build_netmsg(struct nf_conntrack *ct, int query, struct nethdr *net); -size_t prepare_send_netmsg(struct mcast_sock *m, void *data); - enum { SEQ_UNKNOWN, SEQ_UNSET, @@ -129,12 +138,6 @@ static inline int between(uint32_t seq1, uint32_t seq2, uint32_t seq3) return seq3 - seq2 >= seq1 - seq2; } -struct netpld { - uint16_t len; - uint16_t query; -}; -#define NETPLD_SIZ sizeof(struct netpld) - #define PLD_NETWORK2HOST(x) \ ({ \ x->len = ntohs(x->len); \ @@ -158,12 +161,6 @@ struct netattr { x->nta_attr = ntohs(x->nta_attr); \ }) -#define PLD_DATA(x) \ - (struct netattr *)(((char *)x) + sizeof(struct netpld)) - -#define PLD_TAIL(x) \ - (struct netattr *)(((char *)x) + sizeof(struct netpld) + x->len) - #define NTA_DATA(x) \ (void *)(((char *)x) + sizeof(struct netattr)) @@ -207,8 +204,8 @@ struct nta_attr_natseqadj { uint32_t repl_seq_offset_after; }; -void build_netpld(struct nf_conntrack *ct, struct netpld *pld, int query); +void build_payload(const struct nf_conntrack *ct, struct nethdr *n); -int parse_netpld(struct nf_conntrack *ct, struct nethdr *net, int *query, size_t remain); +int parse_payload(struct nf_conntrack *ct, struct nethdr *n, size_t remain); #endif diff --git a/src/build.c b/src/build.c index 84515cf..e094aa0 100644 --- a/src/build.c +++ b/src/build.c @@ -21,12 +21,12 @@ #include "network.h" static inline void * -put_header(struct netpld *pld, int attr, size_t len) +put_header(struct nethdr *n, int attr, size_t len) { - struct netattr *nta = PLD_TAIL(pld); + struct netattr *nta = NETHDR_TAIL(n); int total_size = NTA_ALIGN(NTA_LENGTH(len)); int attr_size = NTA_LENGTH(len); - pld->len += total_size; + n->len += total_size; nta->nta_attr = htons(attr); nta->nta_len = htons(attr_size); memset((unsigned char *)nta + attr_size, 0, total_size - attr_size); @@ -34,45 +34,45 @@ put_header(struct netpld *pld, int attr, size_t len) } static inline void -addattr(struct netpld *pld, int attr, const void *data, size_t len) +addattr(struct nethdr *n, int attr, const void *data, size_t len) { - void *ptr = put_header(pld, attr, len); + void *ptr = put_header(n, attr, len); memcpy(ptr, data, len); } static inline void -__build_u8(const struct nf_conntrack *ct, int a, struct netpld *pld, int b) +__build_u8(const struct nf_conntrack *ct, int a, struct nethdr *n, int b) { - void *ptr = put_header(pld, b, sizeof(uint8_t)); + void *ptr = put_header(n, b, sizeof(uint8_t)); memcpy(ptr, nfct_get_attr(ct, a), sizeof(uint8_t)); } static inline void -__build_u16(const struct nf_conntrack *ct, int a, struct netpld *pld, int b) +__build_u16(const struct nf_conntrack *ct, int a, struct nethdr *n, int b) { uint32_t data = nfct_get_attr_u16(ct, a); data = htons(data); - addattr(pld, b, &data, sizeof(uint16_t)); + addattr(n, b, &data, sizeof(uint16_t)); } static inline void -__build_u32(const struct nf_conntrack *ct, int a, struct netpld *pld, int b) +__build_u32(const struct nf_conntrack *ct, int a, struct nethdr *n, int b) { uint32_t data = nfct_get_attr_u32(ct, a); data = htonl(data); - addattr(pld, b, &data, sizeof(uint32_t)); + addattr(n, b, &data, sizeof(uint32_t)); } static inline void -__build_group(const struct nf_conntrack *ct, int a, struct netpld *pld, +__build_group(const struct nf_conntrack *ct, int a, struct nethdr *n, int b, int size) { - void *ptr = put_header(pld, b, size); + void *ptr = put_header(n, b, size); nfct_get_attr_grp(ct, a, ptr); } static inline void -__build_natseqadj(const struct nf_conntrack *ct, struct netpld *pld) +__build_natseqadj(const struct nf_conntrack *ct, struct nethdr *n) { struct nta_attr_natseqadj data = { .orig_seq_correction_pos = @@ -88,7 +88,7 @@ __build_natseqadj(const struct nf_conntrack *ct, struct netpld *pld) .repl_seq_offset_after = htonl(nfct_get_attr_u32(ct, ATTR_REPL_NAT_SEQ_OFFSET_AFTER)) }; - addattr(pld, NTA_NAT_SEQ_ADJ, &data, sizeof(struct nta_attr_natseqadj)); + addattr(n, NTA_NAT_SEQ_ADJ, &data, sizeof(struct nta_attr_natseqadj)); } static enum nf_conntrack_attr nat_type[] = @@ -97,65 +97,61 @@ static enum nf_conntrack_attr nat_type[] = ATTR_REPL_NAT_SEQ_OFFSET_BEFORE, ATTR_REPL_NAT_SEQ_OFFSET_AFTER }; /* XXX: ICMP not supported */ -void build_netpld(struct nf_conntrack *ct, struct netpld *pld, int query) +void build_payload(const struct nf_conntrack *ct, struct nethdr *n) { if (nfct_attr_grp_is_set(ct, ATTR_GRP_ORIG_IPV4)) { - __build_group(ct, ATTR_GRP_ORIG_IPV4, pld, NTA_IPV4, + __build_group(ct, ATTR_GRP_ORIG_IPV4, n, NTA_IPV4, sizeof(struct nfct_attr_grp_ipv4)); } else if (nfct_attr_grp_is_set(ct, ATTR_GRP_ORIG_IPV6)) { - __build_group(ct, ATTR_GRP_ORIG_IPV6, pld, NTA_IPV6, + __build_group(ct, ATTR_GRP_ORIG_IPV6, n, NTA_IPV6, sizeof(struct nfct_attr_grp_ipv6)); } - __build_u8(ct, ATTR_L4PROTO, pld, NTA_L4PROTO); + __build_u8(ct, ATTR_L4PROTO, n, NTA_L4PROTO); if (nfct_attr_grp_is_set(ct, ATTR_GRP_ORIG_PORT)) { - __build_group(ct, ATTR_GRP_ORIG_PORT, pld, NTA_PORT, + __build_group(ct, ATTR_GRP_ORIG_PORT, n, NTA_PORT, sizeof(struct nfct_attr_grp_port)); } - __build_u32(ct, ATTR_STATUS, pld, NTA_STATUS); + __build_u32(ct, ATTR_STATUS, n, NTA_STATUS); if (nfct_attr_is_set(ct, ATTR_TCP_STATE)) - __build_u8(ct, ATTR_TCP_STATE, pld, NTA_STATE); + __build_u8(ct, ATTR_TCP_STATE, n, NTA_STATE); if (nfct_attr_is_set(ct, ATTR_MARK)) - __build_u32(ct, ATTR_MARK, pld, NTA_MARK); + __build_u32(ct, ATTR_MARK, n, NTA_MARK); /* setup the master conntrack */ if (nfct_attr_grp_is_set(ct, ATTR_GRP_MASTER_IPV4)) { - __build_group(ct, ATTR_GRP_MASTER_IPV4, pld, NTA_MASTER_IPV4, + __build_group(ct, ATTR_GRP_MASTER_IPV4, n, NTA_MASTER_IPV4, sizeof(struct nfct_attr_grp_ipv4)); - __build_u8(ct, ATTR_MASTER_L4PROTO, pld, NTA_MASTER_L4PROTO); + __build_u8(ct, ATTR_MASTER_L4PROTO, n, NTA_MASTER_L4PROTO); if (nfct_attr_grp_is_set(ct, ATTR_GRP_MASTER_PORT)) { __build_group(ct, ATTR_GRP_MASTER_PORT, - pld, NTA_MASTER_PORT, + n, NTA_MASTER_PORT, sizeof(struct nfct_attr_grp_port)); } } else if (nfct_attr_grp_is_set(ct, ATTR_GRP_MASTER_IPV6)) { - __build_group(ct, ATTR_GRP_MASTER_IPV6, pld, NTA_MASTER_IPV6, + __build_group(ct, ATTR_GRP_MASTER_IPV6, n, NTA_MASTER_IPV6, sizeof(struct nfct_attr_grp_ipv6)); - __build_u8(ct, ATTR_MASTER_L4PROTO, pld, NTA_MASTER_L4PROTO); + __build_u8(ct, ATTR_MASTER_L4PROTO, n, NTA_MASTER_L4PROTO); if (nfct_attr_grp_is_set(ct, ATTR_GRP_MASTER_PORT)) { __build_group(ct, ATTR_GRP_MASTER_PORT, - pld, NTA_MASTER_PORT, + n, NTA_MASTER_PORT, sizeof(struct nfct_attr_grp_port)); } } /* NAT */ if (nfct_getobjopt(ct, NFCT_GOPT_IS_SNAT)) - __build_u32(ct, ATTR_REPL_IPV4_DST, pld, NTA_SNAT_IPV4); + __build_u32(ct, ATTR_REPL_IPV4_DST, n, NTA_SNAT_IPV4); if (nfct_getobjopt(ct, NFCT_GOPT_IS_DNAT)) - __build_u32(ct, ATTR_REPL_IPV4_SRC, pld, NTA_DNAT_IPV4); + __build_u32(ct, ATTR_REPL_IPV4_SRC, n, NTA_DNAT_IPV4); if (nfct_getobjopt(ct, NFCT_GOPT_IS_SPAT)) - __build_u16(ct, ATTR_REPL_PORT_DST, pld, NTA_SPAT_PORT); + __build_u16(ct, ATTR_REPL_PORT_DST, n, NTA_SPAT_PORT); if (nfct_getobjopt(ct, NFCT_GOPT_IS_DPAT)) - __build_u16(ct, ATTR_REPL_PORT_SRC, pld, NTA_DPAT_PORT); + __build_u16(ct, ATTR_REPL_PORT_SRC, n, NTA_DPAT_PORT); /* NAT sequence adjustment */ if (nfct_attr_is_set_array(ct, nat_type, 6)) - __build_natseqadj(ct, pld); - - pld->query = query; - - PLD_HOST2NETWORK(pld); + __build_natseqadj(ct, n); } diff --git a/src/network.c b/src/network.c index ca00881..34992ec 100644 --- a/src/network.c +++ b/src/network.c @@ -25,48 +25,40 @@ #include #include +#define NETHDR_ALIGNTO 4 + static unsigned int seq_set, cur_seq; -static size_t __do_prepare(struct mcast_sock *m, void *data, size_t len) +int nethdr_align(int value) { - struct nethdr *net = data; + return (value + NETHDR_ALIGNTO - 1) & ~(NETHDR_ALIGNTO - 1); +} +int nethdr_size(int len) +{ + return NETHDR_SIZ + len; +} + +static inline void __nethdr_set(struct nethdr *net, int len, int type) +{ if (!seq_set) { seq_set = 1; cur_seq = time(NULL); } - net->version = CONNTRACKD_PROTOCOL_VERSION; - net->len = len; - net->seq = cur_seq++; - HDR_HOST2NETWORK(net); - - return len; + net->version = CONNTRACKD_PROTOCOL_VERSION; + net->type = type; + net->len = len; + net->seq = cur_seq++; } -static size_t __prepare_ctl(struct mcast_sock *m, void *data) +void nethdr_set(struct nethdr *net, int type) { - return __do_prepare(m, data, NETHDR_ACK_SIZ); + __nethdr_set(net, NETHDR_SIZ, type); } -static size_t __prepare_data(struct mcast_sock *m, void *data) +void nethdr_set_ack(struct nethdr *net) { - struct nethdr *net = (struct nethdr *) data; - struct netpld *pld = NETHDR_DATA(net); - - return __do_prepare(m, data, ntohs(pld->len) + NETPLD_SIZ + NETHDR_SIZ); -} - -size_t prepare_send_netmsg(struct mcast_sock *m, void *data) -{ - int ret = 0; - struct nethdr *net = (struct nethdr *) data; - - if (IS_DATA(net)) - ret = __prepare_data(m, data); - else if (IS_CTL(net)) - ret = __prepare_ctl(m, data); - - return ret; + __nethdr_set(net, NETHDR_ACK_SIZ, 0); } static size_t tx_buflenmax; @@ -129,13 +121,6 @@ ssize_t mcast_buffered_pending_netmsg(struct mcast_sock *m) return ret; } -void build_netmsg(struct nf_conntrack *ct, int query, struct nethdr *net) -{ - struct netpld *pld = NETHDR_DATA(net); - - build_netpld(ct, pld, query); -} - static int local_seq_set = 0; /* this function only tracks, it does not update the last sequence received */ diff --git a/src/parse.c b/src/parse.c index 4eb74b2..17a0107 100644 --- a/src/parse.c +++ b/src/parse.c @@ -150,30 +150,16 @@ parse_nat_seq_adj(struct nf_conntrack *ct, int attr, void *data) ntohl(this->orig_seq_correction_pos)); } -int -parse_netpld(struct nf_conntrack *ct, - struct nethdr *net, - int *query, - size_t remain) +int parse_payload(struct nf_conntrack *ct, struct nethdr *net, size_t remain) { int len; struct netattr *attr; - struct netpld *pld; - if (remain < NETHDR_SIZ + sizeof(struct netpld)) + if (remain < net->len) return -1; - pld = NETHDR_DATA(net); - - if (remain < NETHDR_SIZ + sizeof(struct netpld) + ntohs(pld->len)) - return -1; - - if (net->len < NETHDR_SIZ + sizeof(struct netpld) + ntohs(pld->len)) - return -1; - - PLD_NETWORK2HOST(pld); - len = pld->len; - attr = PLD_DATA(pld); + len = net->len - NETHDR_SIZ; + attr = NETHDR_DATA(net); while (len > ssizeof(struct netattr)) { ATTR_NETWORK2HOST(attr); @@ -187,6 +173,5 @@ parse_netpld(struct nf_conntrack *ct, attr = NTA_NEXT(attr, len); } - *query = pld->query; return 0; } diff --git a/src/sync-alarm.c b/src/sync-alarm.c index 377af16..fe3d9af 100644 --- a/src/sync-alarm.c +++ b/src/sync-alarm.c @@ -29,7 +29,6 @@ static void refresher(struct alarm_block *a, void *data) { - size_t len; struct nethdr *net; struct us_conntrack *u = data; @@ -40,7 +39,6 @@ static void refresher(struct alarm_block *a, void *data) ((random() % 5 + 1) * 200000) - 1); 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); } diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c index 293f9ab..a4895d4 100644 --- a/src/sync-ftfw.c +++ b/src/sync-ftfw.c @@ -451,10 +451,9 @@ out: static void ftfw_send(struct nethdr *net, struct us_conntrack *u) { - struct netpld *pld = NETHDR_DATA(net); struct cache_ftfw *cn; - switch(ntohs(pld->query)) { + switch(net->type) { case NFCT_Q_CREATE: case NFCT_Q_UPDATE: case NFCT_Q_DESTROY: @@ -490,7 +489,9 @@ static void ftfw_send(struct nethdr *net, struct us_conntrack *u) static int tx_queue_xmit(void *data1, const void *data2) { struct nethdr *net = data1; - size_t len = prepare_send_netmsg(STATE_SYNC(mcast_client), net); + + nethdr_set_ack(net); + HDR_HOST2NETWORK(net); dp("tx_queue sq: %u fl:%u len:%u\n", ntohl(net->seq), net->flags, ntohs(net->len)); @@ -510,7 +511,6 @@ static int tx_list_xmit(struct list_head *i, struct us_conntrack *u, int type) { int ret; struct nethdr *net = BUILD_NETMSG(u->ct, type); - size_t len = prepare_send_netmsg(STATE_SYNC(mcast_client), net); dp("tx_list sq: %u fl:%u len:%u\n", ntohl(net->seq), net->flags, ntohs(net->len)); diff --git a/src/sync-mode.c b/src/sync-mode.c index ac9d3f3..cfed7f4 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -36,7 +36,6 @@ static void do_mcast_handler_step(struct nethdr *net, size_t remain) { - int query; char __ct[nfct_maxsize()]; struct nf_conntrack *ct = (struct nf_conntrack *)(void*) __ct; struct us_conntrack *u; @@ -62,13 +61,13 @@ static void do_mcast_handler_step(struct nethdr *net, size_t remain) memset(ct, 0, sizeof(__ct)); - if (parse_netpld(ct, net, &query, remain) == -1) { + if (parse_payload(ct, net, remain) == -1) { STATE(malformed)++; dlog(LOG_ERR, "parsing failed: malformed message"); return; } - switch(query) { + switch(net->type) { case NFCT_Q_CREATE: retry: if ((u = cache_add(STATE_SYNC(external), ct))) { @@ -100,7 +99,7 @@ retry: break; default: STATE(malformed)++; - dlog(LOG_ERR, "mcast unknown query %d\n", query); + dlog(LOG_ERR, "mcast unknown query %d\n", net->type); break; } } @@ -109,7 +108,7 @@ retry: static void mcast_handler(void) { ssize_t numbytes; - size_t remain; + ssize_t remain; char __net[65536], *ptr = __net; /* XXX: maximum MTU for IPv4 */ numbytes = mcast_recv(STATE_SYNC(mcast_server), __net, sizeof(__net)); @@ -397,11 +396,9 @@ static void dump_sync(struct nf_conntrack *ct) static void mcast_send_sync(struct us_conntrack *u, int query) { - size_t len; struct nethdr *net; net = BUILD_NETMSG(u->ct, query); - len = prepare_send_netmsg(STATE_SYNC(mcast_client), net); if (STATE_SYNC(sync)->send) STATE_SYNC(sync)->send(net, u); diff --git a/src/sync-notrack.c b/src/sync-notrack.c index c5ea1e6..fdb0c43 100644 --- a/src/sync-notrack.c +++ b/src/sync-notrack.c @@ -155,8 +155,8 @@ static int notrack_recv(const struct nethdr *net) static int tx_queue_xmit(void *data1, const void *data2) { struct nethdr *net = data1; - size_t len = prepare_send_netmsg(STATE_SYNC(mcast_client), net); - + nethdr_set_ack(net); + HDR_HOST2NETWORK(net); mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net); queue_del(tx_queue, net); @@ -167,7 +167,6 @@ static int tx_list_xmit(struct list_head *i, struct us_conntrack *u, int type) { int ret; struct nethdr *net = BUILD_NETMSG(u->ct, type); - size_t len = prepare_send_netmsg(STATE_SYNC(mcast_client), net); list_del_init(i); tx_list_len--; -- cgit v1.2.3 From 8d6efef0daed05925bf9b13c21948afa651482a5 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sat, 13 Dec 2008 16:15:18 +0100 Subject: network: use NET_T_* instead of NFCT_Q_* This patch replaces the use of NFCT_Q_* in the message type by specific network message type NET_T_*. The query types are reserved for libnetfilter_conntrack operations. Signed-off-by: Pablo Neira Ayuso --- include/network.h | 7 +++++++ src/sync-alarm.c | 2 +- src/sync-ftfw.c | 10 +++++----- src/sync-mode.c | 16 ++++++++-------- src/sync-notrack.c | 2 +- 5 files changed, 22 insertions(+), 15 deletions(-) (limited to 'src/sync-alarm.c') diff --git a/include/network.h b/include/network.h index 9098e5c..b6722bd 100644 --- a/include/network.h +++ b/include/network.h @@ -17,6 +17,13 @@ struct nethdr { }; #define NETHDR_SIZ nethdr_align(sizeof(struct nethdr)) +enum nethdr_type { + NET_T_STATE_NEW = 0, + NET_T_STATE_UPD, + NET_T_STATE_DEL, + NET_T_STATE_MAX = NET_T_STATE_DEL, +}; + int nethdr_align(int len); int nethdr_size(int len); void nethdr_set(struct nethdr *net, int type); diff --git a/src/sync-alarm.c b/src/sync-alarm.c index fe3d9af..d871b75 100644 --- a/src/sync-alarm.c +++ b/src/sync-alarm.c @@ -38,7 +38,7 @@ static void refresher(struct alarm_block *a, void *data) random() % CONFIG(refresh) + 1, ((random() % 5 + 1) * 200000) - 1); - net = BUILD_NETMSG(u->ct, NFCT_Q_UPDATE); + net = BUILD_NETMSG(u->ct, NET_T_STATE_UPD); mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net); } diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c index a4895d4..05475ab 100644 --- a/src/sync-ftfw.c +++ b/src/sync-ftfw.c @@ -454,9 +454,9 @@ static void ftfw_send(struct nethdr *net, struct us_conntrack *u) struct cache_ftfw *cn; switch(net->type) { - case NFCT_Q_CREATE: - case NFCT_Q_UPDATE: - case NFCT_Q_DESTROY: + case NET_T_STATE_NEW: + case NET_T_STATE_UPD: + case NET_T_STATE_DEL: cn = (struct cache_ftfw *) cache_get_extra(STATE_SYNC(internal), u); @@ -537,9 +537,9 @@ static void ftfw_run(void) u = cache_get_conntrack(STATE_SYNC(internal), cn); if (alarm_pending(&u->alarm)) - tx_list_xmit(&cn->tx_list, u, NFCT_Q_DESTROY); + tx_list_xmit(&cn->tx_list, u, NET_T_STATE_DEL); else - tx_list_xmit(&cn->tx_list, u, NFCT_Q_UPDATE); + tx_list_xmit(&cn->tx_list, u, NET_T_STATE_UPD); } /* reset alive alarm */ diff --git a/src/sync-mode.c b/src/sync-mode.c index cfed7f4..d5355a7 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -68,7 +68,7 @@ static void do_mcast_handler_step(struct nethdr *net, size_t remain) } switch(net->type) { - case NFCT_Q_CREATE: + case NET_T_STATE_NEW: retry: if ((u = cache_add(STATE_SYNC(external), ct))) { debug_ct(u->ct, "external new"); @@ -85,13 +85,13 @@ retry: debug_ct(ct, "can't add"); } break; - case NFCT_Q_UPDATE: + case NET_T_STATE_UPD: if ((u = cache_update_force(STATE_SYNC(external), ct))) { debug_ct(u->ct, "external update"); } else debug_ct(ct, "can't update"); break; - case NFCT_Q_DESTROY: + case NET_T_STATE_DEL: if (cache_del(STATE_SYNC(external), ct)) debug_ct(ct, "external destroy"); else @@ -415,7 +415,7 @@ static int purge_step(void *data1, void *data2) ret = nfct_query(h, NFCT_Q_GET, u->ct); if (ret == -1 && errno == ENOENT) { debug_ct(u->ct, "overrun purge resync"); - mcast_send_sync(u, NFCT_Q_DESTROY); + mcast_send_sync(u, NET_T_STATE_DEL); __cache_del_timer(STATE_SYNC(internal), u, CONFIG(del_timeout)); } @@ -448,7 +448,7 @@ static int overrun_sync(enum nf_conntrack_msg_type type, if (!cache_test(STATE_SYNC(internal), ct)) { if ((u = cache_update_force(STATE_SYNC(internal), ct))) { debug_ct(u->ct, "overrun resync"); - mcast_send_sync(u, NFCT_Q_UPDATE); + mcast_send_sync(u, NET_T_STATE_UPD); } } @@ -466,7 +466,7 @@ static void event_new_sync(struct nf_conntrack *ct) nfct_attr_unset(ct, ATTR_REPL_COUNTER_PACKETS); retry: if ((u = cache_add(STATE_SYNC(internal), ct))) { - mcast_send_sync(u, NFCT_Q_CREATE); + mcast_send_sync(u, NET_T_STATE_NEW); debug_ct(u->ct, "internal new"); } else { if (errno == EEXIST) { @@ -489,7 +489,7 @@ static void event_update_sync(struct nf_conntrack *ct) return; } debug_ct(u->ct, "internal update"); - mcast_send_sync(u, NFCT_Q_UPDATE); + mcast_send_sync(u, NET_T_STATE_UPD); } static int event_destroy_sync(struct nf_conntrack *ct) @@ -502,7 +502,7 @@ static int event_destroy_sync(struct nf_conntrack *ct) return 0; } - mcast_send_sync(u, NFCT_Q_DESTROY); + mcast_send_sync(u, NET_T_STATE_DEL); __cache_del_timer(STATE_SYNC(internal), u, CONFIG(del_timeout)); debug_ct(ct, "internal destroy"); return 1; diff --git a/src/sync-notrack.c b/src/sync-notrack.c index fdb0c43..8e6601a 100644 --- a/src/sync-notrack.c +++ b/src/sync-notrack.c @@ -188,7 +188,7 @@ static void notrack_run(void) struct us_conntrack *u; u = cache_get_conntrack(STATE_SYNC(internal), cn); - tx_list_xmit(&cn->tx_list, u, NFCT_Q_UPDATE); + tx_list_xmit(&cn->tx_list, u, NET_T_STATE_UPD); } } -- cgit v1.2.3 From 50339f96638eed35dac2b673b64cc6f1eb96406c Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Thu, 15 Jan 2009 23:19:57 +0100 Subject: src: rework of the hash-cache infrastructure Currently, the caching system is implemented in a two layer architecture: hashtable (inner layer) and cache (upper layer). This patch reworks the hash-cache infrastructure to solve some initial design problems to make it more flexible, the main strong points of this patch are: * Memory handling is done in the cache layer, not in the inner hashtable layer. This removes one of the main dependencies between the hashtable and the cache classes. * Remove excessive encapsulation: the former cache used to hide a lot of details of the inner hashtable implementation. * Fix over-hashing of some operations: lookup-delete-add required three hash calculations. Similarly, the update-or-add operation required two hash calculations. Now, we calculate the hash once and re-use the value how many times as we need. This patch simplifies the caching system. As a result, we save ~130 lines of code. Small code means and less complexity means less chance to have bugs. Signed-off-by: Pablo Neira Ayuso --- include/Makefile.am | 4 +- include/cache.h | 43 +++++--- include/filter.h | 11 ++ include/hash.h | 22 ++-- include/network.h | 1 - include/slist.h | 41 -------- include/sync.h | 4 +- include/us-conntrack.h | 14 --- src/cache.c | 273 +++++++++++++++++++------------------------------ src/cache_iterators.c | 65 ++++++------ src/cache_lifetime.c | 10 +- src/cache_timer.c | 36 +++---- src/cache_wt.c | 33 +++--- src/filter.c | 57 +++++++++-- src/hash.c | 136 +++++++----------------- src/stats-mode.c | 55 +++++----- src/sync-alarm.c | 27 +++-- src/sync-ftfw.c | 40 ++++---- src/sync-mode.c | 116 +++++++++++---------- src/sync-notrack.c | 19 ++-- 20 files changed, 440 insertions(+), 567 deletions(-) delete mode 100644 include/slist.h delete mode 100644 include/us-conntrack.h (limited to 'src/sync-alarm.c') diff --git a/include/Makefile.am b/include/Makefile.am index 13f7e37..c3f8904 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1,6 +1,6 @@ -noinst_HEADERS = alarm.h jhash.h slist.h cache.h linux_list.h linux_rbtree.h \ - sync.h conntrackd.h local.h us-conntrack.h \ +noinst_HEADERS = alarm.h jhash.h cache.h linux_list.h linux_rbtree.h \ + sync.h conntrackd.h local.h \ debug.h log.h hash.h mcast.h conntrack.h \ network.h filter.h queue.h vector.h cidr.h \ traffic_stats.h netlink.h fds.h event.h bitops.h diff --git a/include/cache.h b/include/cache.h index ebed70a..dcd6bcd 100644 --- a/include/cache.h +++ b/include/cache.h @@ -3,6 +3,8 @@ #include #include +#include "hash.h" +#include "alarm.h" /* cache features */ enum { @@ -22,14 +24,20 @@ enum { #define CACHE_MAX_FEATURE __CACHE_MAX_FEATURE struct cache; -struct us_conntrack; +struct cache_object { + struct hashtable_node hashnode; + struct nf_conntrack *ct; + struct cache *cache; + struct alarm_block alarm; + char data[0]; +}; struct cache_feature { size_t size; - void (*add)(struct us_conntrack *u, void *data); - void (*update)(struct us_conntrack *u, void *data); - void (*destroy)(struct us_conntrack *u, void *data); - int (*dump)(struct us_conntrack *u, void *data, char *buf, int type); + void (*add)(struct cache_object *obj, void *data); + void (*update)(struct cache_object *obj, void *data); + void (*destroy)(struct cache_object *obj, void *data); + int (*dump)(struct cache_object *obj, void *data, char *buf, int type); }; extern struct cache_feature lifetime_feature; @@ -48,6 +56,7 @@ struct cache { unsigned int *feature_offset; struct cache_extra *extra; unsigned int extra_offset; + size_t object_size; /* statistics */ struct { @@ -77,9 +86,9 @@ struct cache { struct cache_extra { unsigned int size; - void (*add)(struct us_conntrack *u, void *data); - void (*update)(struct us_conntrack *u, void *data); - void (*destroy)(struct us_conntrack *u, void *data); + void (*add)(struct cache_object *obj, void *data); + void (*update)(struct cache_object *obj, void *data); + void (*destroy)(struct cache_object *obj, void *data); }; struct nf_conntrack; @@ -87,16 +96,18 @@ struct nf_conntrack; struct cache *cache_create(const char *name, unsigned int features, struct cache_extra *extra); void cache_destroy(struct cache *e); -struct us_conntrack *cache_add(struct cache *c, struct nf_conntrack *ct); -struct us_conntrack *cache_update(struct cache *c, struct nf_conntrack *ct); -struct us_conntrack *cache_update_force(struct cache *c, struct nf_conntrack *ct); -int cache_del(struct cache *c, struct nf_conntrack *ct); -int __cache_del_timer(struct cache *c, struct us_conntrack *u, int timeout); -struct us_conntrack *cache_find(struct cache *c, struct nf_conntrack *ct); -int cache_test(struct cache *c, struct nf_conntrack *ct); +struct cache_object *cache_object_new(struct cache *c, struct nf_conntrack *ct); +void cache_object_free(struct cache_object *obj); + +int cache_add(struct cache *c, struct cache_object *obj, int id); +void cache_update(struct cache *c, struct cache_object *obj, int id, struct nf_conntrack *ct); +struct cache_object *cache_update_force(struct cache *c, struct nf_conntrack *ct); +void cache_del(struct cache *c, struct cache_object *obj); +int cache_del_timer(struct cache *c, struct cache_object *obj, int timeout); +struct cache_object *cache_find(struct cache *c, struct nf_conntrack *ct, int *pos); void cache_stats(const struct cache *c, int fd); void cache_stats_extended(const struct cache *c, int fd); -struct us_conntrack *cache_get_conntrack(struct cache *, void *); +struct cache_object *cache_data_get_object(struct cache *c, void *data); void *cache_get_extra(struct cache *, void *); void cache_iterate(struct cache *c, void *data, int (*iterate)(void *data1, void *data2)); diff --git a/include/filter.h b/include/filter.h index 9c2cf66..72c2aa4 100644 --- a/include/filter.h +++ b/include/filter.h @@ -4,6 +4,7 @@ #include #include #include +#include enum ct_filter_type { CT_FILTER_L4PROTO, @@ -17,6 +18,16 @@ enum ct_filter_logic { CT_FILTER_POSITIVE = 1, }; +struct ct_filter_ipv4_hnode { + struct hashtable_node node; + uint32_t ip; +}; + +struct ct_filter_ipv6_hnode { + struct hashtable_node node; + uint32_t ipv6[4]; +}; + struct ct_filter_netmask_ipv4 { uint32_t ip; uint32_t mask; diff --git a/include/hash.h b/include/hash.h index 2fb0a27..68d618b 100644 --- a/include/hash.h +++ b/include/hash.h @@ -2,7 +2,6 @@ #define _NF_SET_HASH_H_ #include -#include "slist.h" #include "linux_list.h" #include @@ -15,35 +14,30 @@ struct hashtable { uint32_t limit; uint32_t count; uint32_t initval; - uint32_t datasize; uint32_t (*hash)(const void *data, const struct hashtable *table); int (*compare)(const void *data1, const void *data2); - struct slist_head members[0]; + struct list_head members[0]; }; struct hashtable_node { - struct slist_head head; - char data[0]; + struct list_head head; }; -struct hashtable_node *hashtable_alloc_node(int datasize, void *data); -void hashtable_destroy_node(struct hashtable_node *h); - struct hashtable * -hashtable_create(int hashsize, int limit, int datasize, +hashtable_create(int hashsize, int limit, uint32_t (*hash)(const void *data, const struct hashtable *table), int (*compare)(const void *data1, const void *data2)); void hashtable_destroy(struct hashtable *h); - -void *hashtable_add(struct hashtable *table, void *data); -void *hashtable_find(struct hashtable *table, const void *data); -int hashtable_del(struct hashtable *table, void *data); +int hashtable_hash(const struct hashtable *table, const void *data); +struct hashtable_node *hashtable_find(const struct hashtable *table, const void *data, int id); +int hashtable_add(struct hashtable *table, struct hashtable_node *n, int id); +void hashtable_del(struct hashtable *table, struct hashtable_node *node); int hashtable_flush(struct hashtable *table); int hashtable_iterate(struct hashtable *table, void *data, - int (*iterate)(void *data1, void *data2)); + int (*iterate)(void *data, struct hashtable_node *n)); unsigned int hashtable_counter(const struct hashtable *table); #endif diff --git a/include/network.h b/include/network.h index 40bb2b2..619ce3e 100644 --- a/include/network.h +++ b/include/network.h @@ -75,7 +75,6 @@ enum { __hdr; \ }) -struct us_conntrack; struct mcast_sock; enum { diff --git a/include/slist.h b/include/slist.h deleted file mode 100644 index 257b627..0000000 --- a/include/slist.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef _SLIST_H_ -#define _SLIST_H_ - -#include "linux_list.h" - -#define INIT_SLIST_HEAD(ptr) ((ptr).next = NULL) - -struct slist_head { - struct slist_head *next; -}; - -static inline int slist_empty(const struct slist_head *h) -{ - return !h->next; -} - -static inline void slist_del(struct slist_head *t, struct slist_head *prev) -{ - prev->next = t->next; - t->next = LIST_POISON1; -} - -static inline void slist_add(struct slist_head *head, struct slist_head *t) -{ - struct slist_head *tmp = head->next; - head->next = t; - t->next = tmp; -} - -#define slist_entry(ptr, type, member) container_of(ptr,type,member) - -#define slist_for_each(pos, head) \ - for (pos = (head)->next; pos; \ - pos = pos->next) - -#define slist_for_each_safe(pos, prev, next, head) \ - for (pos = (head)->next, prev = (head); \ - pos && ({ next = pos->next; 1; }); \ - ({ prev = (prev->next != next) ? prev->next : prev; }), pos = next) - -#endif diff --git a/include/sync.h b/include/sync.h index fc06c93..60c9fae 100644 --- a/include/sync.h +++ b/include/sync.h @@ -2,7 +2,7 @@ #define _SYNC_HOOKS_H_ struct nethdr; -struct us_conntrack; +struct cache_object; struct sync_mode { int internal_cache_flags; @@ -14,7 +14,7 @@ struct sync_mode { void (*kill)(void); int (*local)(int fd, int type, void *data); int (*recv)(const struct nethdr *net); - void (*send)(struct nethdr *net, struct us_conntrack *u); + void (*send)(struct nethdr *net, struct cache_object *obj); void (*run)(void); }; diff --git a/include/us-conntrack.h b/include/us-conntrack.h deleted file mode 100644 index 9eafa3b..0000000 --- a/include/us-conntrack.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _US_CONNTRACK_H_ -#define _US_CONNTRACK_H_ - -#include "alarm.h" -#include - -struct us_conntrack { - struct nf_conntrack *ct; - struct cache *cache; - struct alarm_block alarm; - char data[0]; -}; - -#endif diff --git a/src/cache.c b/src/cache.c index 553dddf..621a3f4 100644 --- a/src/cache.c +++ b/src/cache.c @@ -1,5 +1,5 @@ /* - * (C) 2006-2007 by Pablo Neira Ayuso + * (C) 2006-2009 by Pablo Neira Ayuso * * 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 @@ -20,7 +20,6 @@ #include "jhash.h" #include "hash.h" #include "log.h" -#include "us-conntrack.h" #include "conntrackd.h" #include @@ -68,14 +67,14 @@ __hash6(const struct nf_conntrack *ct, const struct hashtable *table) static uint32_t hash(const void *data, const struct hashtable *table) { int ret = 0; - const struct us_conntrack *u = data; + const struct nf_conntrack *ct = data; - switch(nfct_get_attr_u8(u->ct, ATTR_L3PROTO)) { + switch(nfct_get_attr_u8(ct, ATTR_L3PROTO)) { case AF_INET: - ret = __hash4(u->ct, table); + ret = __hash4(ct, table); break; case AF_INET6: - ret = __hash6(u->ct, table); + ret = __hash6(ct, table); break; default: dlog(LOG_ERR, "unknown layer 3 proto in hash"); @@ -87,10 +86,10 @@ static uint32_t hash(const void *data, const struct hashtable *table) static int compare(const void *data1, const void *data2) { - const struct us_conntrack *u1 = data1; - const struct us_conntrack *u2 = data2; + const struct cache_object *obj = data1; + const struct nf_conntrack *ct = data2; - return nfct_cmp(u1->ct, u2->ct, NFCT_CMP_ORIG); + return nfct_cmp(obj->ct, ct, NFCT_CMP_ORIG); } struct cache_feature *cache_feature[CACHE_MAX_FEATURE] = { @@ -103,7 +102,7 @@ struct cache *cache_create(const char *name, unsigned int features, struct cache_extra *extra) { - size_t size = sizeof(struct us_conntrack); + size_t size = sizeof(struct cache_object); int i, j = 0; struct cache *c; struct cache_feature *feature_array[CACHE_MAX_FEATURE] = {}; @@ -152,7 +151,6 @@ struct cache *cache_create(const char *name, c->h = hashtable_create(CONFIG(hashsize), CONFIG(limit), - size, hash, compare); @@ -162,6 +160,7 @@ struct cache *cache_create(const char *name, free(c); return NULL; } + c->object_size = size; return c; } @@ -177,225 +176,165 @@ void cache_destroy(struct cache *c) static void __del_timeout(struct alarm_block *a, void *data); -static struct us_conntrack *__add(struct cache *c, struct nf_conntrack *ct) +struct cache_object *cache_object_new(struct cache *c, struct nf_conntrack *ct) { - unsigned i; - size_t size = c->h->datasize; - char buf[size]; - struct us_conntrack *u = (struct us_conntrack *) buf; - struct nf_conntrack *newct; + struct cache_object *obj; - memset(u, 0, size); + obj = calloc(c->object_size, 1); + if (obj == NULL) { + errno = ENOMEM; + c->stats.add_fail_enomem++; + return NULL; + } + obj->cache = c; + init_alarm(&obj->alarm, obj, __del_timeout); - u->cache = c; - if ((u->ct = newct = nfct_new()) == NULL) { + if ((obj->ct = nfct_new()) == NULL) { + free(obj); errno = ENOMEM; - return 0; + c->stats.add_fail_enomem++; + return NULL; } - memcpy(u->ct, ct, nfct_sizeof(ct)); + memcpy(obj->ct, ct, nfct_sizeof(ct)); - u = hashtable_add(c->h, u); - if (u) { - char *data = u->data; + return obj; +} - init_alarm(&u->alarm, u, __del_timeout); +void cache_object_free(struct cache_object *obj) +{ + nfct_destroy(obj->ct); + free(obj); +} - for (i = 0; i < c->num_features; i++) { - c->features[i]->add(u, data); - data += c->features[i]->size; - } +static int __add(struct cache *c, struct cache_object *obj, int id) +{ + int ret; + unsigned int i; + char *data = obj->data; - if (c->extra && c->extra->add) - c->extra->add(u, ((char *) u) + c->extra_offset); + ret = hashtable_add(c->h, &obj->hashnode, id); + if (ret == -1) + return -1; - c->stats.active++; - return u; + for (i = 0; i < c->num_features; i++) { + c->features[i]->add(obj, data); + data += c->features[i]->size; } - free(newct); - return NULL; + if (c->extra && c->extra->add) + c->extra->add(obj, ((char *) obj) + c->extra_offset); + + c->stats.active++; + return 0; } -struct us_conntrack *cache_add(struct cache *c, struct nf_conntrack *ct) +int cache_add(struct cache *c, struct cache_object *obj, int id) { - struct us_conntrack *u; + int ret; - u = __add(c, ct); - if (u) { - c->stats.add_ok++; - return u; - } - if (errno != EEXIST) { + ret = __add(c, obj, id); + if (ret == -1) { c->stats.add_fail++; if (errno == ENOSPC) c->stats.add_fail_enospc++; - if (errno == ENOMEM) - c->stats.add_fail_enomem++; + return -1; } - - return NULL; + c->stats.add_ok++; + return 0; } -static void -__cache_update(struct cache *c, struct us_conntrack *u, struct nf_conntrack *ct) +void cache_update(struct cache *c, struct cache_object *obj, int id, + struct nf_conntrack *ct) { - unsigned i; - char *data = u->data; + char *data = obj->data; + unsigned int i; - nfct_copy(u->ct, ct, NFCT_CP_META); + nfct_copy(obj->ct, ct, NFCT_CP_META); for (i = 0; i < c->num_features; i++) { - c->features[i]->update(u, data); + c->features[i]->update(obj, data); data += c->features[i]->size; } if (c->extra && c->extra->update) - c->extra->update(u, ((char *) u) + c->extra_offset); -} - -static struct us_conntrack *__update(struct cache *c, struct nf_conntrack *ct) -{ - size_t size = c->h->datasize; - char buf[size]; - struct us_conntrack *u = (struct us_conntrack *) buf; - - u->ct = ct; - - u = (struct us_conntrack *) hashtable_find(c->h, u); - if (u) { - __cache_update(c, u, ct); - return u; - } - return NULL; -} + c->extra->update(obj, ((char *) obj) + c->extra_offset); -struct us_conntrack *cache_update(struct cache *c, struct nf_conntrack *ct) -{ - struct us_conntrack *u; - - u = __update(c, ct); - if (u) { - c->stats.upd_ok++; - return u; - } - c->stats.upd_fail++; - if (errno == ENOENT) - c->stats.upd_fail_enoent++; - - return NULL; + c->stats.upd_ok++; } -static void __del(struct cache *c, struct us_conntrack *u) +static void __del(struct cache *c, struct cache_object *obj) { unsigned i; - char *data = u->data; - struct nf_conntrack *p = u->ct; + char *data = obj->data; for (i = 0; i < c->num_features; i++) { - c->features[i]->destroy(u, data); + c->features[i]->destroy(obj, data); data += c->features[i]->size; } if (c->extra && c->extra->destroy) - c->extra->destroy(u, ((char *) u) + c->extra_offset); + c->extra->destroy(obj, ((char *) obj) + c->extra_offset); - hashtable_del(c->h, u); - free(p); + hashtable_del(c->h, &obj->hashnode); } -static void __cache_del(struct cache *c, struct us_conntrack *u) +void cache_del(struct cache *c, struct cache_object *obj) { /* * Do not increase stats if we are trying to * kill an entry was previously deleted via * __cache_del_timer. */ - if (!alarm_pending(&u->alarm)) { + if (!alarm_pending(&obj->alarm)) { c->stats.del_ok++; c->stats.active--; } - del_alarm(&u->alarm); - __del(c, u); + del_alarm(&obj->alarm); + __del(c, obj); } -struct us_conntrack *cache_update_force(struct cache *c, - struct nf_conntrack *ct) +struct cache_object * +cache_update_force(struct cache *c, struct nf_conntrack *ct) { - struct us_conntrack *u; - - u = cache_find(c, ct); - if (u) { - if (!alarm_pending(&u->alarm)) { - c->stats.upd_ok++; - __cache_update(c, u, ct); - return u; + struct cache_object *obj; + int id; + + obj = cache_find(c, ct, &id); + if (obj) { + if (!alarm_pending(&obj->alarm)) { + cache_update(c, obj, id, ct); + return obj; } else { - __cache_del(c, u); + cache_del(c, obj); + cache_object_free(obj); } } - if ((u = __add(c, ct)) != NULL) { - c->stats.add_ok++; - return u; - } - c->stats.add_fail++; - if (errno == ENOSPC) - c->stats.add_fail_enospc++; - if (errno == ENOMEM) - c->stats.add_fail_enomem++; - - return NULL; -} - -int cache_test(struct cache *c, struct nf_conntrack *ct) -{ - size_t size = c->h->datasize; - char buf[size]; - struct us_conntrack *u = (struct us_conntrack *) buf; - void *ret; - - u->ct = ct; - - ret = hashtable_find(c->h, u); - - return ret != NULL; -} - -int cache_del(struct cache *c, struct nf_conntrack *ct) -{ - size_t size = c->h->datasize; - char buf[size]; - struct us_conntrack *u = (struct us_conntrack *) buf; - - u->ct = ct; + obj = cache_object_new(c, ct); + if (obj == NULL) + return NULL; - u = (struct us_conntrack *) hashtable_find(c->h, u); - if (u) { - __cache_del(c, u); - return 1; - } - c->stats.del_fail++; - if (errno == ENOENT) - c->stats.del_fail_enoent++; + if (cache_add(c, obj, id) == -1) + return NULL; - return 0; + return obj; } static void __del_timeout(struct alarm_block *a, void *data) { - struct us_conntrack *u = (struct us_conntrack *) data; - - __del(u->cache, u); + struct cache_object *obj = (struct cache_object *) data; + __del(obj->cache, obj); + cache_object_free(obj); } -int -__cache_del_timer(struct cache *c, struct us_conntrack *u, int timeout) +int cache_del_timer(struct cache *c, struct cache_object *obj, int timeout) { if (timeout <= 0) { - __cache_del(c, u); + cache_del(c, obj); + cache_object_free(obj); return 1; } - if (!alarm_pending(&u->alarm)) { - add_alarm(&u->alarm, timeout, 0); + if (!alarm_pending(&obj->alarm)) { + add_alarm(&obj->alarm, timeout, 0); /* * increase stats even if this entry was not really * removed yet. We do not want to make people think @@ -409,20 +348,16 @@ __cache_del_timer(struct cache *c, struct us_conntrack *u, int timeout) return 0; } -struct us_conntrack *cache_find(struct cache *c, struct nf_conntrack *ct) +struct cache_object * +cache_find(struct cache *c, struct nf_conntrack *ct, int *id) { - size_t size = c->h->datasize; - char buf[size]; - struct us_conntrack *u = (struct us_conntrack *) buf; - - u->ct = ct; - - return ((struct us_conntrack *) hashtable_find(c->h, u)); + *id = hashtable_hash(c->h, ct); + return ((struct cache_object *) hashtable_find(c->h, ct, *id)); } -struct us_conntrack *cache_get_conntrack(struct cache *c, void *data) +struct cache_object *cache_data_get_object(struct cache *c, void *data) { - return (struct us_conntrack *)((char*)data - c->extra_offset); + return (struct cache_object *)((char*)data - c->extra_offset); } void *cache_get_extra(struct cache *c, void *data) diff --git a/src/cache_iterators.c b/src/cache_iterators.c index a14f428..4773889 100644 --- a/src/cache_iterators.c +++ b/src/cache_iterators.c @@ -21,7 +21,6 @@ #include "log.h" #include "conntrackd.h" #include "netlink.h" -#include "us-conntrack.h" #include #include @@ -33,13 +32,13 @@ struct __dump_container { int type; }; -static int do_dump(void *data1, void *data2) +static int do_dump(void *data1, struct hashtable_node *n) { char buf[1024]; int size; struct __dump_container *container = data1; - struct us_conntrack *u = data2; - char *data = u->data; + struct cache_object *obj = (struct cache_object *)n; + char *data = obj->data; unsigned i; /* @@ -52,28 +51,28 @@ static int do_dump(void *data1, void *data2) * specific and it breaks conntrackd modularity. Probably * there's a nicer way to do this but until I come up with it... */ - if (CONFIG(flags) & CTD_SYNC_FTFW && alarm_pending(&u->alarm)) + if (CONFIG(flags) & CTD_SYNC_FTFW && alarm_pending(&obj->alarm)) return 0; /* do not show cached timeout, this may confuse users */ - if (nfct_attr_is_set(u->ct, ATTR_TIMEOUT)) - nfct_attr_unset(u->ct, ATTR_TIMEOUT); + if (nfct_attr_is_set(obj->ct, ATTR_TIMEOUT)) + nfct_attr_unset(obj->ct, ATTR_TIMEOUT); memset(buf, 0, sizeof(buf)); size = nfct_snprintf(buf, sizeof(buf), - u->ct, + obj->ct, NFCT_T_UNKNOWN, container->type, 0); - for (i = 0; i < u->cache->num_features; i++) { - if (u->cache->features[i]->dump) { - size += u->cache->features[i]->dump(u, - data, - buf+size, - container->type); - data += u->cache->features[i]->size; + for (i = 0; i < obj->cache->num_features; i++) { + if (obj->cache->features[i]->dump) { + size += obj->cache->features[i]->dump(obj, + data, + buf+size, + container->type); + data += obj->cache->features[i]->size; } } size += sprintf(buf+size, "\n"); @@ -101,10 +100,10 @@ struct __commit_container { }; static void -__do_commit_step(struct __commit_container *tmp, struct us_conntrack *u) +__do_commit_step(struct __commit_container *tmp, struct cache_object *obj) { int ret, retry = 1; - struct nf_conntrack *ct = u->ct; + struct nf_conntrack *ct = obj->ct; /* * Set a reduced timeout for candidate-to-be-committed @@ -166,25 +165,25 @@ try_again: } } -static int do_commit_related(void *data1, void *data2) +static int do_commit_related(void *data, struct hashtable_node *n) { - struct us_conntrack *u = data2; + struct cache_object *obj = (struct cache_object *)n; - if (ct_is_related(u->ct)) - __do_commit_step(data1, u); + if (ct_is_related(obj->ct)) + __do_commit_step(data, obj); /* keep iterating even if we have found errors */ return 0; } -static int do_commit_master(void *data1, void *data2) +static int do_commit_master(void *data, struct hashtable_node *n) { - struct us_conntrack *u = data2; + struct cache_object *obj = (struct cache_object *)n; - if (ct_is_related(u->ct)) + if (ct_is_related(obj->ct)) return 0; - __do_commit_step(data1, u); + __do_commit_step(data, obj); return 0; } @@ -231,13 +230,13 @@ void cache_commit(struct cache *c) res.tv_sec, res.tv_usec); } -static int do_reset_timers(void *data1, void *data2) +static int do_reset_timers(void *data1, struct hashtable_node *n) { int ret; u_int32_t current_timeout; struct nfct_handle *h = data1; - struct us_conntrack *u = data2; - struct nf_conntrack *ct = u->ct; + struct cache_object *obj = (struct cache_object *)n; + struct nf_conntrack *ct = obj->ct; char __tmp[nfct_maxsize()]; struct nf_conntrack *tmp = (struct nf_conntrack *) (void *)__tmp; @@ -286,13 +285,13 @@ void cache_reset_timers(struct cache *c) nfct_close(h); } -static int do_flush(void *data1, void *data2) +static int do_flush(void *data, struct hashtable_node *n) { - struct cache *c = data1; - struct us_conntrack *u = data2; - - cache_del(c, u->ct); + struct cache *c = data; + struct cache_object *obj = (struct cache_object *)n; + cache_del(c, obj); + cache_object_free(obj); return 0; } diff --git a/src/cache_lifetime.c b/src/cache_lifetime.c index ad3416a..639d8c1 100644 --- a/src/cache_lifetime.c +++ b/src/cache_lifetime.c @@ -17,12 +17,12 @@ */ #include -#include "us-conntrack.h" #include "cache.h" #include #include +#include -static void lifetime_add(struct us_conntrack *u, void *data) +static void lifetime_add(struct cache_object *obj, void *data) { long *lifetime = data; struct timeval tv; @@ -32,15 +32,15 @@ static void lifetime_add(struct us_conntrack *u, void *data) *lifetime = tv.tv_sec; } -static void lifetime_update(struct us_conntrack *u, void *data) +static void lifetime_update(struct cache_object *obj, void *data) { } -static void lifetime_destroy(struct us_conntrack *u, void *data) +static void lifetime_destroy(struct cache_object *obj, void *data) { } -static int lifetime_dump(struct us_conntrack *u, +static int lifetime_dump(struct cache_object *obj, void *data, char *buf, int type) diff --git a/src/cache_timer.c b/src/cache_timer.c index 44482b7..a9e3e3d 100644 --- a/src/cache_timer.c +++ b/src/cache_timer.c @@ -18,7 +18,6 @@ #include "cache.h" #include "conntrackd.h" -#include "us-conntrack.h" #include "alarm.h" #include "debug.h" @@ -26,45 +25,46 @@ static void timeout(struct alarm_block *a, void *data) { - struct us_conntrack *u = data; + struct cache_object *obj = data; - debug_ct(u->ct, "expired timeout"); - cache_del(u->cache, u->ct); + debug_ct(obj->ct, "expired timeout"); + cache_del(obj->cache, obj); + cache_object_free(obj); } -static void timer_add(struct us_conntrack *u, void *data) +static void timer_add(struct cache_object *obj, void *data) { - struct alarm_block *alarm = data; + struct alarm_block *a = data; - init_alarm(alarm, u, timeout); - add_alarm(alarm, CONFIG(cache_timeout), 0); + init_alarm(a, obj, timeout); + add_alarm(a, CONFIG(cache_timeout), 0); } -static void timer_update(struct us_conntrack *u, void *data) +static void timer_update(struct cache_object *obj, void *data) { - struct alarm_block *alarm = data; - add_alarm(alarm, CONFIG(cache_timeout), 0); + struct alarm_block *a = data; + add_alarm(a, CONFIG(cache_timeout), 0); } -static void timer_destroy(struct us_conntrack *u, void *data) +static void timer_destroy(struct cache_object *obj, void *data) { - struct alarm_block *alarm = data; - del_alarm(alarm); + struct alarm_block *a = data; + del_alarm(a); } -static int timer_dump(struct us_conntrack *u, void *data, char *buf, int type) +static int timer_dump(struct cache_object *obj, void *data, char *buf, int type) { struct timeval tv, tmp; - struct alarm_block *alarm = data; + struct alarm_block *a = data; if (type == NFCT_O_XML) return 0; - if (!alarm_pending(alarm)) + if (!alarm_pending(a)) return 0; gettimeofday(&tv, NULL); - timersub(&alarm->tv, &tv, &tmp); + timersub(&a->tv, &tv, &tmp); return sprintf(buf, " [expires in %lds]", tmp.tv_sec); } diff --git a/src/cache_wt.c b/src/cache_wt.c index d0ae8bb..84a816f 100644 --- a/src/cache_wt.c +++ b/src/cache_wt.c @@ -19,67 +19,66 @@ #include "conntrackd.h" #include "cache.h" #include "netlink.h" -#include "us-conntrack.h" #include "log.h" #include #include -static void add_wt(struct us_conntrack *u) +static void add_wt(struct cache_object *obj) { int ret; char __ct[nfct_maxsize()]; struct nf_conntrack *ct = (struct nf_conntrack *)(void*) __ct; - ret = nl_exist_conntrack(STATE(request), u->ct); + ret = nl_exist_conntrack(STATE(request), obj->ct); switch (ret) { case -1: dlog(LOG_ERR, "cache_wt problem: %s", strerror(errno)); - dlog_ct(STATE(log), u->ct, NFCT_O_PLAIN); + dlog_ct(STATE(log), obj->ct, NFCT_O_PLAIN); break; case 0: - memcpy(ct, u->ct, nfct_maxsize()); + memcpy(ct, obj->ct, nfct_maxsize()); if (nl_create_conntrack(STATE(dump), ct) == -1) { dlog(LOG_ERR, "cache_wt create: %s", strerror(errno)); - dlog_ct(STATE(log), u->ct, NFCT_O_PLAIN); + dlog_ct(STATE(log), obj->ct, NFCT_O_PLAIN); } break; case 1: - memcpy(ct, u->ct, nfct_maxsize()); + memcpy(ct, obj->ct, nfct_maxsize()); if (nl_update_conntrack(STATE(dump), ct) == -1) { dlog(LOG_ERR, "cache_wt crt-upd: %s", strerror(errno)); - dlog_ct(STATE(log), u->ct, NFCT_O_PLAIN); + dlog_ct(STATE(log), obj->ct, NFCT_O_PLAIN); } break; } } -static void upd_wt(struct us_conntrack *u) +static void upd_wt(struct cache_object *obj) { char __ct[nfct_maxsize()]; struct nf_conntrack *ct = (struct nf_conntrack *)(void*) __ct; - memcpy(ct, u->ct, nfct_maxsize()); + memcpy(ct, obj->ct, nfct_maxsize()); if (nl_update_conntrack(STATE(dump), ct) == -1) { dlog(LOG_ERR, "cache_wt update:%s", strerror(errno)); - dlog_ct(STATE(log), u->ct, NFCT_O_PLAIN); + dlog_ct(STATE(log), obj->ct, NFCT_O_PLAIN); } } -static void writethrough_add(struct us_conntrack *u, void *data) +static void writethrough_add(struct cache_object *obj, void *data) { - add_wt(u); + add_wt(obj); } -static void writethrough_update(struct us_conntrack *u, void *data) +static void writethrough_update(struct cache_object *obj, void *data) { - upd_wt(u); + upd_wt(obj); } -static void writethrough_destroy(struct us_conntrack *u, void *data) +static void writethrough_destroy(struct cache_object *obj, void *data) { - nl_destroy_conntrack(STATE(dump), u->ct); + nl_destroy_conntrack(STATE(dump), obj->ct); } struct cache_feature writethrough_feature = { diff --git a/src/filter.c b/src/filter.c index c6e24a9..6a09c77 100644 --- a/src/filter.c +++ b/src/filter.c @@ -58,15 +58,17 @@ static uint32_t ct_filter_hash6(const void *data, const struct hashtable *table) static int ct_filter_compare(const void *data1, const void *data2) { - const uint32_t *f1 = data1; + const struct ct_filter_ipv4_hnode *f1 = data1; const uint32_t *f2 = data2; - return *f1 == *f2; + return f1->ip == *f2; } static int ct_filter_compare6(const void *data1, const void *data2) { - return memcmp(data1, data2, sizeof(uint32_t)*4) == 0; + const struct ct_filter_ipv6_hnode *f = data1; + + return memcmp(f->ipv6, data2, sizeof(uint32_t)*4) == 0; } struct ct_filter *ct_filter_create(void) @@ -80,7 +82,6 @@ struct ct_filter *ct_filter_create(void) filter->h = hashtable_create(FILTER_POOL_SIZE, FILTER_POOL_LIMIT, - sizeof(uint32_t), ct_filter_hash, ct_filter_compare); if (!filter->h) { @@ -90,7 +91,6 @@ struct ct_filter *ct_filter_create(void) filter->h6 = hashtable_create(FILTER_POOL_SIZE, FILTER_POOL_LIMIT, - sizeof(uint32_t)*4, ct_filter_hash6, ct_filter_compare6); if (!filter->h6) { @@ -155,16 +155,33 @@ void ct_filter_set_logic(struct ct_filter *filter, int ct_filter_add_ip(struct ct_filter *filter, void *data, uint8_t family) { + int id; filter = __filter_alloc(filter); switch(family) { case AF_INET: - if (!hashtable_add(filter->h, data)) + id = hashtable_hash(filter->h, data); + if (!hashtable_find(filter->h, data, id)) { + struct ct_filter_ipv4_hnode *n; + n = malloc(sizeof(struct ct_filter_ipv4_hnode)); + if (n == NULL) + return 0; + memcpy(&n->ip, data, sizeof(uint32_t)); + hashtable_add(filter->h, &n->node, id); return 0; + } break; case AF_INET6: - if (!hashtable_add(filter->h6, data)) + id = hashtable_hash(filter->h6, data); + if (!hashtable_find(filter->h6, data, id)) { + struct ct_filter_ipv6_hnode *n; + n = malloc(sizeof(struct ct_filter_ipv6_hnode)); + if (n == NULL) + return 0; + memcpy(n->ipv6, data, sizeof(uint32_t)*4); + hashtable_add(filter->h6, &n->node, id); return 0; + } break; } return 1; @@ -220,16 +237,34 @@ void ct_filter_add_state(struct ct_filter *f, int protonum, int val) static inline int __ct_filter_test_ipv4(struct ct_filter *f, struct nf_conntrack *ct) { + int id_src, id_dst; + uint32_t src, dst; + /* we only use the real source and destination address */ - return (hashtable_find(f->h, nfct_get_attr(ct, ATTR_ORIG_IPV4_SRC)) || - hashtable_find(f->h, nfct_get_attr(ct, ATTR_REPL_IPV4_SRC))); + src = nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_SRC); + dst = nfct_get_attr_u32(ct, ATTR_REPL_IPV4_SRC); + + id_src = hashtable_hash(f->h, &src); + id_dst = hashtable_hash(f->h, &dst); + + return hashtable_find(f->h, &src, id_src) || + hashtable_find(f->h, &dst, id_dst); } static inline int __ct_filter_test_ipv6(struct ct_filter *f, struct nf_conntrack *ct) { - return (hashtable_find(f->h6, nfct_get_attr(ct, ATTR_ORIG_IPV6_SRC)) || - hashtable_find(f->h6, nfct_get_attr(ct, ATTR_REPL_IPV6_SRC))); + int id_src, id_dst; + const uint32_t *src, *dst; + + src = nfct_get_attr(ct, ATTR_ORIG_IPV6_SRC); + dst = nfct_get_attr(ct, ATTR_REPL_IPV6_SRC); + + id_src = hashtable_hash(f->h6, src); + id_dst = hashtable_hash(f->h6, dst); + + return hashtable_find(f->h6, src, id_src) || + hashtable_find(f->h6, dst, id_dst); } static int diff --git a/src/hash.c b/src/hash.c index 1edb977..9c9ea5b 100644 --- a/src/hash.c +++ b/src/hash.c @@ -1,5 +1,5 @@ /* - * (C) 2006-2007 by Pablo Neira Ayuso + * (C) 2006-2009 by Pablo Neira Ayuso * * 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 @@ -19,32 +19,13 @@ */ #include "hash.h" -#include "slist.h" #include #include #include -struct hashtable_node *hashtable_alloc_node(int datasize, void *data) -{ - struct hashtable_node *n; - int size = sizeof(struct hashtable_node) + datasize; - - n = calloc(size, 1); - if (n == NULL) - return NULL; - memcpy(n->data, data, datasize); - - return n; -} - -void hashtable_destroy_node(struct hashtable_node *h) -{ - free(h); -} - struct hashtable * -hashtable_create(int hashsize, int limit, int datasize, +hashtable_create(int hashsize, int limit, uint32_t (*hash)(const void *data, const struct hashtable *table), int (*compare)(const void *data1, const void *data2)) @@ -52,7 +33,7 @@ hashtable_create(int hashsize, int limit, int datasize, int i; struct hashtable *h; int size = sizeof(struct hashtable) - + hashsize * sizeof(struct slist_head); + + hashsize * sizeof(struct list_head); h = (struct hashtable *) calloc(size, 1); if (h == NULL) { @@ -61,11 +42,10 @@ hashtable_create(int hashsize, int limit, int datasize, } for (i=0; imembers[i]); + INIT_LIST_HEAD(&h->members[i]); h->hashsize = hashsize; h->limit = limit; - h->datasize = datasize; h->hash = hash; h->compare = compare; @@ -74,112 +54,74 @@ hashtable_create(int hashsize, int limit, int datasize, void hashtable_destroy(struct hashtable *h) { - hashtable_flush(h); free(h); } -void *hashtable_add(struct hashtable *table, void *data) +int hashtable_hash(const struct hashtable *table, const void *data) { - struct slist_head *e; - struct hashtable_node *n; - uint32_t id; - - /* hash table is full */ - if (table->count >= table->limit) { - errno = ENOSPC; - return NULL; - } - - id = table->hash(data, table); - - slist_for_each(e, &table->members[id]) { - n = slist_entry(e, struct hashtable_node, head); - if (table->compare(n->data, data)) { - errno = EEXIST; - return NULL; - } - } - - n = hashtable_alloc_node(table->datasize, data); - if (n == NULL) { - errno = ENOMEM; - return NULL; - } - - slist_add(&table->members[id], &n->head); - table->count++; - - return n->data; + return table->hash(data, table); } -void *hashtable_find(struct hashtable *table, const void *data) +struct hashtable_node * +hashtable_find(const struct hashtable *table, const void *data, int id) { - struct slist_head *e; - uint32_t id; + struct list_head *e; struct hashtable_node *n; - id = table->hash(data, table); - - slist_for_each(e, &table->members[id]) { - n = slist_entry(e, struct hashtable_node, head); - if (table->compare(n->data, data)) - return n->data; + list_for_each(e, &table->members[id]) { + n = list_entry(e, struct hashtable_node, head); + if (table->compare(n, data)) { + return n; + } } - errno = ENOENT; return NULL; } -int hashtable_del(struct hashtable *table, void *data) +int hashtable_add(struct hashtable *table, struct hashtable_node *n, int id) { - struct slist_head *e, *next, *prev; - uint32_t id; - struct hashtable_node *n; - - id = table->hash(data, table); - - slist_for_each_safe(e, prev, next, &table->members[id]) { - n = slist_entry(e, struct hashtable_node, head); - if (table->compare(n->data, data)) { - slist_del(e, prev); - hashtable_destroy_node(n); - table->count--; - return 0; - } + /* hash table is full */ + if (table->count >= table->limit) { + errno = ENOSPC; + return -1; } - errno = ENOENT; - return -1; + list_add(&n->head, &table->members[id]); + table->count++; + return 0; +} + +void hashtable_del(struct hashtable *table, struct hashtable_node *n) +{ + list_del(&n->head); + table->count--; } int hashtable_flush(struct hashtable *table) { uint32_t i; - struct slist_head *e, *next, *prev; + struct list_head *e, *tmp; struct hashtable_node *n; - for (i=0; i < table->hashsize; i++) - slist_for_each_safe(e, prev, next, &table->members[i]) { - n = slist_entry(e, struct hashtable_node, head); - slist_del(e, prev); - hashtable_destroy_node(n); + for (i=0; i < table->hashsize; i++) { + list_for_each_safe(e, tmp, &table->members[i]) { + n = list_entry(e, struct hashtable_node, head); + free(n); } - - table->count = 0; - + } return 0; } int hashtable_iterate(struct hashtable *table, void *data, - int (*iterate)(void *data1, void *data2)) + int (*iterate)(void *data1, struct hashtable_node *n)) { uint32_t i; - struct slist_head *e, *next, *prev; + struct list_head *e, *tmp; struct hashtable_node *n; for (i=0; i < table->hashsize; i++) { - slist_for_each_safe(e, prev, next, &table->members[i]) { - n = slist_entry(e, struct hashtable_node, head); - if (iterate(data, n->data) == -1) + list_for_each_safe(e, tmp, &table->members[i]) { + n = list_entry(e, struct hashtable_node, head); + if (iterate(data, n) == -1) return -1; } } diff --git a/src/stats-mode.c b/src/stats-mode.c index d340b0d..679a50c 100644 --- a/src/stats-mode.c +++ b/src/stats-mode.c @@ -22,7 +22,6 @@ #include "cache.h" #include "log.h" #include "conntrackd.h" -#include "us-conntrack.h" #include #include @@ -118,9 +117,8 @@ static int overrun_stats(enum nf_conntrack_msg_type type, nfct_attr_unset(ct, ATTR_REPL_COUNTER_PACKETS); nfct_attr_unset(ct, ATTR_USE); - if (!cache_test(STATE_STATS(cache), ct)) - if (!cache_update_force(STATE_STATS(cache), ct)) - debug_ct(ct, "overrun stats resync"); + if (!cache_update_force(STATE_STATS(cache), ct)) + debug_ct(ct, "overrun stats resync"); return NFCT_CB_CONTINUE; } @@ -128,12 +126,13 @@ static int overrun_stats(enum nf_conntrack_msg_type type, static int purge_step(void *data1, void *data2) { int ret; - struct us_conntrack *u = data2; + struct cache_object *obj = data2; - ret = nfct_query(STATE(dump), NFCT_Q_GET, u->ct); + ret = nfct_query(STATE(dump), NFCT_Q_GET, obj->ct); if (ret == -1 && errno == ENOENT) { - debug_ct(u->ct, "overrun purge stats"); - cache_del(STATE_STATS(cache), u->ct); + debug_ct(obj->ct, "overrun purge stats"); + cache_del(STATE_STATS(cache), obj); + cache_object_free(obj); } return 0; @@ -148,42 +147,46 @@ static int purge_stats(void) static void event_new_stats(struct nf_conntrack *ct) { + int id; + struct cache_object *obj; + nfct_attr_unset(ct, ATTR_TIMEOUT); - if (cache_add(STATE_STATS(cache), ct)) { - debug_ct(ct, "cache new"); - } else { - if (errno != EEXIST) { - dlog(LOG_ERR, - "can't add to cache cache: %s\n", strerror(errno)); - debug_ct(ct, "can't add"); + obj = cache_find(STATE_STATS(cache), ct, &id); + if (obj == NULL) { + obj = cache_object_new(STATE_STATS(cache), ct); + if (obj == NULL) + return; + + if (cache_add(STATE_STATS(cache), obj, id) == -1) { + cache_object_free(obj); + return; } } + return; } static void event_update_stats(struct nf_conntrack *ct) { nfct_attr_unset(ct, ATTR_TIMEOUT); - - if (!cache_update_force(STATE_STATS(cache), ct)) { - debug_ct(ct, "can't update"); - return; - } - debug_ct(ct, "update"); + cache_update_force(STATE_STATS(cache), ct); } static int event_destroy_stats(struct nf_conntrack *ct) { + int id; + struct cache_object *obj; + nfct_attr_unset(ct, ATTR_TIMEOUT); - if (cache_del(STATE_STATS(cache), ct)) { - debug_ct(ct, "cache destroy"); + obj = cache_find(STATE_STATS(cache), ct, &id); + if (obj) { + cache_del(STATE_STATS(cache), obj); dlog_ct(STATE(stats_log), ct, NFCT_O_PLAIN); + cache_object_free(obj); return 1; - } else { - debug_ct(ct, "can't destroy!"); - return 0; } + return 0; } struct ct_mode stats_mode = { diff --git a/src/sync-alarm.c b/src/sync-alarm.c index d871b75..34937fe 100644 --- a/src/sync-alarm.c +++ b/src/sync-alarm.c @@ -19,7 +19,6 @@ #include "conntrackd.h" #include "sync.h" #include "network.h" -#include "us-conntrack.h" #include "alarm.h" #include "cache.h" #include "debug.h" @@ -30,40 +29,40 @@ static void refresher(struct alarm_block *a, void *data) { struct nethdr *net; - struct us_conntrack *u = data; + struct cache_object *obj = data; - debug_ct(u->ct, "persistence update"); + debug_ct(obj->ct, "persistence update"); add_alarm(a, random() % CONFIG(refresh) + 1, ((random() % 5 + 1) * 200000) - 1); - net = BUILD_NETMSG(u->ct, NET_T_STATE_UPD); + net = BUILD_NETMSG(obj->ct, NET_T_STATE_UPD); mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net); } -static void cache_alarm_add(struct us_conntrack *u, void *data) +static void cache_alarm_add(struct cache_object *obj, void *data) { - struct alarm_block *alarm = data; + struct alarm_block *a = data; - init_alarm(alarm, u, refresher); - add_alarm(alarm, + init_alarm(a, obj, refresher); + add_alarm(a, random() % CONFIG(refresh) + 1, ((random() % 5 + 1) * 200000) - 1); } -static void cache_alarm_update(struct us_conntrack *u, void *data) +static void cache_alarm_update(struct cache_object *obj, void *data) { - struct alarm_block *alarm = data; - add_alarm(alarm, + struct alarm_block *a = data; + add_alarm(a, random() % CONFIG(refresh) + 1, ((random() % 5 + 1) * 200000) - 1); } -static void cache_alarm_destroy(struct us_conntrack *u, void *data) +static void cache_alarm_destroy(struct cache_object *obj, void *data) { - struct alarm_block *alarm = data; - del_alarm(alarm); + struct alarm_block *a = data; + del_alarm(a); } static struct cache_extra cache_alarm_extra = { diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c index 44e8f2f..bddc18c 100644 --- a/src/sync-ftfw.c +++ b/src/sync-ftfw.c @@ -18,7 +18,6 @@ #include "conntrackd.h" #include "sync.h" -#include "us-conntrack.h" #include "queue.h" #include "debug.h" #include "network.h" @@ -64,7 +63,7 @@ struct cache_ftfw { uint32_t seq; }; -static void cache_ftfw_add(struct us_conntrack *u, void *data) +static void cache_ftfw_add(struct cache_object *obj, void *data) { struct cache_ftfw *cn = data; /* These nodes are not inserted in the list */ @@ -72,7 +71,7 @@ static void cache_ftfw_add(struct us_conntrack *u, void *data) INIT_LIST_HEAD(&cn->tx_list); } -static void cache_ftfw_del(struct us_conntrack *u, void *data) +static void cache_ftfw_del(struct cache_object *obj, void *data) { struct cache_ftfw *cn = data; @@ -190,8 +189,8 @@ static void ftfw_kill(void) static int do_cache_to_tx(void *data1, void *data2) { - struct us_conntrack *u = data2; - struct cache_ftfw *cn = cache_get_extra(STATE_SYNC(internal), u); + struct cache_object *obj = data2; + struct cache_ftfw *cn = cache_get_extra(STATE_SYNC(internal), obj); /* repeated request for resync? */ if (!list_empty(&cn->tx_list)) @@ -226,9 +225,6 @@ static void debug_rs_dump(int fd) size = sprintf(buf, "resent list (len=%u):\n", rs_list_len); send(fd, buf, size, 0); list_for_each_entry_safe(cn, tmp, &rs_list, rs_list) { - struct us_conntrack *u; - - u = cache_get_conntrack(STATE_SYNC(internal), cn); size = sprintf(buf, "seq:%u\n", cn->seq); send(fd, buf, size, 0); } @@ -305,9 +301,9 @@ static void rs_list_to_tx(struct cache *c, unsigned int from, unsigned int to) struct cache_ftfw *cn, *tmp; list_for_each_entry_safe(cn, tmp, &rs_list, rs_list) { - struct us_conntrack *u; + struct cache_object *obj;; - u = cache_get_conntrack(STATE_SYNC(internal), cn); + obj = cache_data_get_object(STATE_SYNC(internal), cn); if (before(cn->seq, from)) continue; else if (after(cn->seq, to)) @@ -330,9 +326,9 @@ static void rs_list_empty(struct cache *c, unsigned int from, unsigned int to) struct cache_ftfw *cn, *tmp; list_for_each_entry_safe(cn, tmp, &rs_list, rs_list) { - struct us_conntrack *u; + struct cache_object *obj; - u = cache_get_conntrack(STATE_SYNC(internal), cn); + obj = cache_data_get_object(STATE_SYNC(internal), cn); if (before(cn->seq, from)) continue; else if (after(cn->seq, to)) @@ -473,7 +469,7 @@ out: return ret; } -static void ftfw_send(struct nethdr *net, struct us_conntrack *u) +static void ftfw_send(struct nethdr *net, struct cache_object *obj) { struct cache_ftfw *cn; @@ -482,7 +478,7 @@ static void ftfw_send(struct nethdr *net, struct us_conntrack *u) case NET_T_STATE_UPD: case NET_T_STATE_DEL: cn = (struct cache_ftfw *) - cache_get_extra(STATE_SYNC(internal), u); + cache_get_extra(STATE_SYNC(internal), obj); if (!list_empty(&cn->rs_list)) { list_del_init(&cn->rs_list); @@ -538,10 +534,10 @@ static int tx_queue_xmit(void *data1, const void *data2) return 0; } -static int tx_list_xmit(struct list_head *i, struct us_conntrack *u, int type) +static int tx_list_xmit(struct list_head *i, struct cache_object *obj, int type) { int ret; - struct nethdr *net = BUILD_NETMSG(u->ct, type); + struct nethdr *net = BUILD_NETMSG(obj->ct, type); dp("tx_list sq: %u fl:%u len:%u\n", ntohl(net->seq), net->flags, ntohs(net->len)); @@ -550,7 +546,7 @@ static int tx_list_xmit(struct list_head *i, struct us_conntrack *u, int type) tx_list_len--; ret = mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net); - ftfw_send(net, u); + ftfw_send(net, obj); return ret; } @@ -564,13 +560,13 @@ static void ftfw_run(void) /* send conntracks in the tx_list */ list_for_each_entry_safe(cn, tmp, &tx_list, tx_list) { - struct us_conntrack *u; + struct cache_object *obj; - u = cache_get_conntrack(STATE_SYNC(internal), cn); - if (alarm_pending(&u->alarm)) - tx_list_xmit(&cn->tx_list, u, NET_T_STATE_DEL); + obj = cache_data_get_object(STATE_SYNC(internal), cn); + if (alarm_pending(&obj->alarm)) + tx_list_xmit(&cn->tx_list, obj, NET_T_STATE_DEL); else - tx_list_xmit(&cn->tx_list, u, NET_T_STATE_UPD); + tx_list_xmit(&cn->tx_list, obj, NET_T_STATE_UPD); } /* reset alive alarm */ diff --git a/src/sync-mode.c b/src/sync-mode.c index ad2e2ff..368984f 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -22,7 +22,6 @@ #include "log.h" #include "cache.h" #include "conntrackd.h" -#include "us-conntrack.h" #include "network.h" #include "fds.h" #include "event.h" @@ -38,7 +37,8 @@ static void do_mcast_handler_step(struct nethdr *net, size_t remain) { char __ct[nfct_maxsize()]; struct nf_conntrack *ct = (struct nf_conntrack *)(void*) __ct; - struct us_conntrack *u; + struct cache_object *obj; + int id; if (net->version != CONNTRACKD_PROTOCOL_VERSION) { STATE_SYNC(error).msg_rcv_malformed++; @@ -75,33 +75,32 @@ static void do_mcast_handler_step(struct nethdr *net, size_t remain) switch(net->type) { case NET_T_STATE_NEW: -retry: - if ((u = cache_add(STATE_SYNC(external), ct))) { - debug_ct(u->ct, "external new"); - } else { - /* - * One certain connection A arrives to the cache but - * another existing connection B in the cache has - * the same configuration, therefore B clashes with A. - */ - if (errno == EEXIST) { - cache_del(STATE_SYNC(external), ct); - goto retry; + obj = cache_find(STATE_SYNC(external), ct, &id); + if (obj == NULL) { +retry: + obj = cache_object_new(STATE_SYNC(external), ct); + if (obj == NULL) + return; + + if (cache_add(STATE_SYNC(external), obj, id) == -1) { + cache_object_free(obj); + return; } - debug_ct(ct, "can't add"); + } else { + cache_del(STATE_SYNC(external), obj); + cache_object_free(obj); + goto retry; } break; case NET_T_STATE_UPD: - if ((u = cache_update_force(STATE_SYNC(external), ct))) { - debug_ct(u->ct, "external update"); - } else - debug_ct(ct, "can't update"); + cache_update_force(STATE_SYNC(external), ct); break; case NET_T_STATE_DEL: - if (cache_del(STATE_SYNC(external), ct)) - debug_ct(ct, "external destroy"); - else - debug_ct(ct, "can't destroy"); + obj = cache_find(STATE_SYNC(external), ct, &id); + if (obj) { + cache_del(STATE_SYNC(external), obj); + cache_object_free(obj); + } break; default: STATE_SYNC(error).msg_rcv_malformed++; @@ -441,14 +440,14 @@ static void dump_sync(struct nf_conntrack *ct) debug_ct(ct, "resync"); } -static void mcast_send_sync(struct us_conntrack *u, int query) +static void mcast_send_sync(struct cache_object *obj, int query) { struct nethdr *net; - net = BUILD_NETMSG(u->ct, query); + net = BUILD_NETMSG(obj->ct, query); if (STATE_SYNC(sync)->send) - STATE_SYNC(sync)->send(net, u); + STATE_SYNC(sync)->send(net, obj); mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net); } @@ -457,13 +456,13 @@ static int purge_step(void *data1, void *data2) { int ret; struct nfct_handle *h = STATE(dump); - struct us_conntrack *u = data2; + struct cache_object *obj = data2; - ret = nfct_query(h, NFCT_Q_GET, u->ct); + ret = nfct_query(h, NFCT_Q_GET, obj->ct); if (ret == -1 && errno == ENOENT) { - debug_ct(u->ct, "overrun purge resync"); - mcast_send_sync(u, NET_T_STATE_DEL); - __cache_del_timer(STATE_SYNC(internal), u, CONFIG(del_timeout)); + debug_ct(obj->ct, "overrun purge resync"); + mcast_send_sync(obj, NET_T_STATE_DEL); + cache_del_timer(STATE_SYNC(internal), obj, CONFIG(del_timeout)); } return 0; @@ -480,7 +479,7 @@ static int overrun_sync(enum nf_conntrack_msg_type type, struct nf_conntrack *ct, void *data) { - struct us_conntrack *u; + struct cache_object *obj; if (ct_filter_conntrack(ct, 1)) return NFCT_CB_CONTINUE; @@ -492,11 +491,9 @@ static int overrun_sync(enum nf_conntrack_msg_type type, nfct_attr_unset(ct, ATTR_REPL_COUNTER_PACKETS); nfct_attr_unset(ct, ATTR_USE); - if (!cache_test(STATE_SYNC(internal), ct)) { - if ((u = cache_update_force(STATE_SYNC(internal), ct))) { - debug_ct(u->ct, "overrun resync"); - mcast_send_sync(u, NET_T_STATE_UPD); - } + if ((obj = cache_update_force(STATE_SYNC(internal), ct))) { + debug_ct(obj->ct, "overrun resync"); + mcast_send_sync(obj, NET_T_STATE_UPD); } return NFCT_CB_CONTINUE; @@ -504,50 +501,59 @@ static int overrun_sync(enum nf_conntrack_msg_type type, static void event_new_sync(struct nf_conntrack *ct) { - struct us_conntrack *u; + struct cache_object *obj; + int id; /* required by linux kernel <= 2.6.20 */ nfct_attr_unset(ct, ATTR_ORIG_COUNTER_BYTES); nfct_attr_unset(ct, ATTR_ORIG_COUNTER_PACKETS); nfct_attr_unset(ct, ATTR_REPL_COUNTER_BYTES); nfct_attr_unset(ct, ATTR_REPL_COUNTER_PACKETS); + + obj = cache_find(STATE_SYNC(internal), ct, &id); + if (obj == NULL) { retry: - if ((u = cache_add(STATE_SYNC(internal), ct))) { - mcast_send_sync(u, NET_T_STATE_NEW); - debug_ct(u->ct, "internal new"); - } else { - if (errno == EEXIST) { - cache_del(STATE_SYNC(internal), ct); - goto retry; + obj = cache_object_new(STATE_SYNC(internal), ct); + if (obj == NULL) + return; + if (cache_add(STATE_SYNC(internal), obj, id) == -1) { + cache_object_free(obj); + return; } + mcast_send_sync(obj, NET_T_STATE_NEW); + debug_ct(obj->ct, "internal new"); + } else { + cache_del(STATE_SYNC(internal), obj); + cache_object_free(obj); debug_ct(ct, "can't add"); + goto retry; } } static void event_update_sync(struct nf_conntrack *ct) { - struct us_conntrack *u; + struct cache_object *obj; - if ((u = cache_update_force(STATE_SYNC(internal), ct)) == NULL) { + if ((obj = cache_update_force(STATE_SYNC(internal), ct)) == NULL) { debug_ct(ct, "can't update"); return; } - debug_ct(u->ct, "internal update"); - mcast_send_sync(u, NET_T_STATE_UPD); + debug_ct(obj->ct, "internal update"); + mcast_send_sync(obj, NET_T_STATE_UPD); } static int event_destroy_sync(struct nf_conntrack *ct) { - struct us_conntrack *u; + struct cache_object *obj; + int id; - u = cache_find(STATE_SYNC(internal), ct); - if (u == NULL) { + obj = cache_find(STATE_SYNC(internal), ct, &id); + if (obj == NULL) { debug_ct(ct, "can't destroy"); return 0; } - - mcast_send_sync(u, NET_T_STATE_DEL); - __cache_del_timer(STATE_SYNC(internal), u, CONFIG(del_timeout)); + mcast_send_sync(obj, NET_T_STATE_DEL); + cache_del_timer(STATE_SYNC(internal), obj, CONFIG(del_timeout)); debug_ct(ct, "internal destroy"); return 1; } diff --git a/src/sync-notrack.c b/src/sync-notrack.c index 700e272..2d3783e 100644 --- a/src/sync-notrack.c +++ b/src/sync-notrack.c @@ -18,7 +18,6 @@ #include "conntrackd.h" #include "sync.h" -#include "us-conntrack.h" #include "queue.h" #include "debug.h" #include "network.h" @@ -36,13 +35,13 @@ struct cache_notrack { struct list_head tx_list; }; -static void cache_notrack_add(struct us_conntrack *u, void *data) +static void cache_notrack_add(struct cache_object *obj, void *data) { struct cache_notrack *cn = data; INIT_LIST_HEAD(&cn->tx_list); } -static void cache_notrack_del(struct us_conntrack *u, void *data) +static void cache_notrack_del(struct cache_object *obj, void *data) { struct cache_notrack *cn = data; @@ -89,8 +88,8 @@ static void notrack_kill(void) static int do_cache_to_tx(void *data1, void *data2) { - struct us_conntrack *u = data2; - struct cache_notrack *cn = cache_get_extra(STATE_SYNC(internal), u); + struct cache_object *obj = data2; + struct cache_notrack *cn = cache_get_extra(STATE_SYNC(internal), obj); if (!list_empty(&cn->tx_list)) return 0; @@ -164,10 +163,10 @@ static int tx_queue_xmit(void *data1, const void *data2) return 0; } -static int tx_list_xmit(struct list_head *i, struct us_conntrack *u, int type) +static int tx_list_xmit(struct list_head *i, struct cache_object *obj, int type) { int ret; - struct nethdr *net = BUILD_NETMSG(u->ct, type); + struct nethdr *net = BUILD_NETMSG(obj->ct, type); list_del_init(i); tx_list_len--; @@ -186,10 +185,10 @@ static void notrack_run(void) /* send conntracks in the tx_list */ list_for_each_entry_safe(cn, tmp, &tx_list, tx_list) { - struct us_conntrack *u; + struct cache_object *obj; - u = cache_get_conntrack(STATE_SYNC(internal), cn); - tx_list_xmit(&cn->tx_list, u, NET_T_STATE_UPD); + obj = cache_data_get_object(STATE_SYNC(internal), cn); + tx_list_xmit(&cn->tx_list, obj, NET_T_STATE_UPD); } } -- cgit v1.2.3 From b1d00262f999a597fa24af3298195db9cf52b790 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sat, 17 Jan 2009 18:03:50 +0100 Subject: sync: enqueue state updates to tx_queue With this patch, all the states updates are enqueued in the tx_queue. Thus, there's a single output path. This patch adds a simple refcounting mechanism to note when an object is sitting in the txqueue. This patch also removes the alarm that is required by the ftfw approach. Signed-off-by: Pablo Neira Ayuso --- include/cache.h | 7 ++--- include/sync.h | 2 +- src/cache.c | 59 ++++++++++++++++++------------------------ src/sync-alarm.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++-------- src/sync-ftfw.c | 70 +++++++++++++++++++++++++------------------------- src/sync-mode.c | 23 ++++++++--------- src/sync-notrack.c | 12 ++++++++- 7 files changed, 152 insertions(+), 96 deletions(-) (limited to 'src/sync-alarm.c') diff --git a/include/cache.h b/include/cache.h index fd8e05f..03b6822 100644 --- a/include/cache.h +++ b/include/cache.h @@ -4,7 +4,6 @@ #include #include #include "hash.h" -#include "alarm.h" /* cache features */ enum { @@ -36,7 +35,7 @@ struct cache_object { struct nf_conntrack *ct; struct cache *cache; int status; - struct alarm_block alarm; + int refcnt; char data[0]; }; @@ -106,12 +105,14 @@ void cache_destroy(struct cache *e); struct cache_object *cache_object_new(struct cache *c, struct nf_conntrack *ct); void cache_object_free(struct cache_object *obj); +void cache_object_get(struct cache_object *obj); +int cache_object_put(struct cache_object *obj); +void cache_object_set_status(struct cache_object *obj, int status); int cache_add(struct cache *c, struct cache_object *obj, int id); void cache_update(struct cache *c, struct cache_object *obj, int id, struct nf_conntrack *ct); struct cache_object *cache_update_force(struct cache *c, struct nf_conntrack *ct); void cache_del(struct cache *c, struct cache_object *obj); -int cache_del_timer(struct cache *c, struct cache_object *obj, int timeout); struct cache_object *cache_find(struct cache *c, struct nf_conntrack *ct, int *pos); void cache_stats(const struct cache *c, int fd); void cache_stats_extended(const struct cache *c, int fd); diff --git a/include/sync.h b/include/sync.h index bced1cc..51f8f5b 100644 --- a/include/sync.h +++ b/include/sync.h @@ -17,7 +17,7 @@ struct sync_mode { void (*kill)(void); int (*local)(int fd, int type, void *data); int (*recv)(const struct nethdr *net); - void (*send)(struct nethdr *net, struct cache_object *obj); + void (*enqueue)(struct cache_object *obj, int type); void (*xmit)(void); }; diff --git a/src/cache.c b/src/cache.c index c46498b..1e08a33 100644 --- a/src/cache.c +++ b/src/cache.c @@ -174,8 +174,6 @@ void cache_destroy(struct cache *c) free(c); } -static void __del_timeout(struct alarm_block *a, void *data); - struct cache_object *cache_object_new(struct cache *c, struct nf_conntrack *ct) { struct cache_object *obj; @@ -187,7 +185,6 @@ struct cache_object *cache_object_new(struct cache *c, struct nf_conntrack *ct) return NULL; } obj->cache = c; - init_alarm(&obj->alarm, obj, __del_timeout); if ((obj->ct = nfct_new()) == NULL) { free(obj); @@ -207,6 +204,30 @@ void cache_object_free(struct cache_object *obj) free(obj); } +int cache_object_put(struct cache_object *obj) +{ + if (--obj->refcnt == 0) { + cache_del(obj->cache, obj); + cache_object_free(obj); + return 1; + } + return 0; +} + +void cache_object_get(struct cache_object *obj) +{ + obj->refcnt++; +} + +void cache_object_set_status(struct cache_object *obj, int status) +{ + if (status == C_OBJ_DEAD) { + obj->cache->stats.del_ok++; + obj->cache->stats.active--; + } + obj->status = status; +} + static int __add(struct cache *c, struct cache_object *obj, int id) { int ret; @@ -227,6 +248,7 @@ static int __add(struct cache *c, struct cache_object *obj, int id) c->stats.active++; obj->status = C_OBJ_NEW; + obj->refcnt++; return 0; } @@ -292,7 +314,6 @@ void cache_del(struct cache *c, struct cache_object *obj) c->stats.del_ok++; c->stats.active--; } - del_alarm(&obj->alarm); __del(c, obj); } @@ -322,36 +343,6 @@ cache_update_force(struct cache *c, struct nf_conntrack *ct) return obj; } -static void __del_timeout(struct alarm_block *a, void *data) -{ - struct cache_object *obj = (struct cache_object *) data; - __del(obj->cache, obj); - cache_object_free(obj); -} - -int cache_del_timer(struct cache *c, struct cache_object *obj, int timeout) -{ - if (timeout <= 0) { - cache_del(c, obj); - cache_object_free(obj); - return 1; - } - if (obj->status != C_OBJ_DEAD) { - obj->status = C_OBJ_DEAD; - add_alarm(&obj->alarm, timeout, 0); - /* - * increase stats even if this entry was not really - * removed yet. We do not want to make people think - * that the replication protocol does not work - * properly. - */ - c->stats.del_ok++; - c->stats.active--; - return 1; - } - return 0; -} - struct cache_object * cache_find(struct cache *c, struct nf_conntrack *ct, int *id) { diff --git a/src/sync-alarm.c b/src/sync-alarm.c index 34937fe..a2f17ac 100644 --- a/src/sync-alarm.c +++ b/src/sync-alarm.c @@ -21,14 +21,21 @@ #include "network.h" #include "alarm.h" #include "cache.h" +#include "queue.h" #include "debug.h" #include #include +struct cache_alarm { + struct queue_node qnode; + struct alarm_block alarm; +}; + +static void alarm_enqueue(struct cache_object *obj, int query); + static void refresher(struct alarm_block *a, void *data) { - struct nethdr *net; struct cache_object *obj = data; debug_ct(obj->ct, "persistence update"); @@ -37,36 +44,37 @@ static void refresher(struct alarm_block *a, void *data) random() % CONFIG(refresh) + 1, ((random() % 5 + 1) * 200000) - 1); - net = BUILD_NETMSG(obj->ct, NET_T_STATE_UPD); - mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net); + alarm_enqueue(obj, NET_T_STATE_UPD); } static void cache_alarm_add(struct cache_object *obj, void *data) { - struct alarm_block *a = data; + struct cache_alarm *ca = data; - init_alarm(a, obj, refresher); - add_alarm(a, + queue_node_init(&ca->qnode, Q_ELEM_OBJ); + init_alarm(&ca->alarm, obj, refresher); + add_alarm(&ca->alarm, random() % CONFIG(refresh) + 1, ((random() % 5 + 1) * 200000) - 1); } static void cache_alarm_update(struct cache_object *obj, void *data) { - struct alarm_block *a = data; - add_alarm(a, + struct cache_alarm *ca = data; + add_alarm(&ca->alarm, random() % CONFIG(refresh) + 1, ((random() % 5 + 1) * 200000) - 1); } static void cache_alarm_destroy(struct cache_object *obj, void *data) { - struct alarm_block *a = data; - del_alarm(a); + struct cache_alarm *ca = data; + queue_del(&ca->qnode); + del_alarm(&ca->alarm); } static struct cache_extra cache_alarm_extra = { - .size = sizeof(struct alarm_block), + .size = sizeof(struct cache_alarm), .add = cache_alarm_add, .update = cache_alarm_update, .destroy = cache_alarm_destroy @@ -102,9 +110,54 @@ static int alarm_recv(const struct nethdr *net) return 0; } +static void alarm_enqueue(struct cache_object *obj, int query) +{ + struct cache_alarm *ca = cache_get_extra(STATE_SYNC(internal), obj); + if (queue_add(STATE_SYNC(tx_queue), &ca->qnode)) + cache_object_get(obj); +} + +static int tx_queue_xmit(struct queue_node *n, const void *data) +{ + struct nethdr *net; + + queue_del(n); + + switch(n->type) { + case Q_ELEM_CTL: + net = queue_node_data(n); + nethdr_set_ctl(net); + HDR_HOST2NETWORK(net); + mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net); + queue_object_free((struct queue_object *)n); + break; + case Q_ELEM_OBJ: { + struct cache_alarm *ca; + struct cache_object *obj; + int type; + + ca = (struct cache_alarm *)n; + obj = cache_data_get_object(STATE_SYNC(internal), ca); + type = object_status_to_network_type(obj->status); + net = BUILD_NETMSG(obj->ct, type); + mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net); + cache_object_put(obj); + break; + } + } + return 0; +} + +static void alarm_xmit(void) +{ + queue_iterate(STATE_SYNC(tx_queue), NULL, tx_queue_xmit); +} + struct sync_mode sync_alarm = { .internal_cache_flags = LIFETIME, .external_cache_flags = TIMER | LIFETIME, .internal_cache_extra = &cache_alarm_extra, .recv = alarm_recv, + .enqueue = alarm_enqueue, + .xmit = alarm_xmit, }; diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c index d544a7b..a287ecd 100644 --- a/src/sync-ftfw.c +++ b/src/sync-ftfw.c @@ -168,11 +168,13 @@ static int do_cache_to_tx(void *data1, void *data2) struct cache_object *obj = data2; struct cache_ftfw *cn = cache_get_extra(STATE_SYNC(internal), obj); - if (queue_in(rs_queue, &cn->qnode)) + if (queue_in(rs_queue, &cn->qnode)) { queue_del(&cn->qnode); - - queue_add(STATE_SYNC(tx_queue), &cn->qnode); - + queue_add(STATE_SYNC(tx_queue), &cn->qnode); + } else { + if (queue_add(STATE_SYNC(tx_queue), &cn->qnode)) + cache_object_get(obj); + } return 0; } @@ -278,16 +280,15 @@ static int rs_queue_empty(struct queue_node *n, const void *data) { const struct nethdr_ack *h = data; - if (h == NULL) { - dp("inconditional remove from queue (seq=%u)\n", net->seq); - queue_del(n); - return 0; - } - switch(n->type) { case Q_ELEM_CTL: { struct nethdr_ack *net = queue_node_data(n); + if (h == NULL) { + queue_del(n); + queue_object_free((struct queue_object *)n); + return 0; + } if (before(net->seq, h->from)) return 0; /* continue */ else if (after(net->seq, h->to)) @@ -300,8 +301,15 @@ static int rs_queue_empty(struct queue_node *n, const void *data) } case Q_ELEM_OBJ: { struct cache_ftfw *cn; + struct cache_object *obj; cn = (struct cache_ftfw *) n; + if (h == NULL) { + queue_del(n); + obj = cache_data_get_object(STATE_SYNC(internal), cn); + cache_object_put(obj); + return 0; + } if (before(cn->seq, h->from)) return 0; else if (after(cn->seq, h->to)) @@ -309,6 +317,8 @@ static int rs_queue_empty(struct queue_node *n, const void *data) dp("queue: deleting from queue (seq=%u)\n", cn->seq); queue_del(n); + obj = cache_data_get_object(STATE_SYNC(internal), cn); + cache_object_put(obj); break; } } @@ -441,28 +451,6 @@ out: return ret; } -static void ftfw_send(struct nethdr *net, struct cache_object *obj) -{ - struct cache_ftfw *cn; - - switch(net->type) { - case NET_T_STATE_NEW: - case NET_T_STATE_UPD: - case NET_T_STATE_DEL: - cn = (struct cache_ftfw *) - cache_get_extra(STATE_SYNC(internal), obj); - - if (queue_in(rs_queue, &cn->qnode)) - queue_del(&cn->qnode); - - nethdr_set_hello(net); - - cn->seq = ntohl(net->seq); - queue_add(rs_queue, &cn->qnode); - break; - } -} - static int tx_queue_xmit(struct queue_node *n, const void *data) { queue_del(n); @@ -511,7 +499,9 @@ static int tx_queue_xmit(struct queue_node *n, const void *data) ntohl(net->seq), net->flags, ntohs(net->len)); mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net); - ftfw_send(net, obj); + cn->seq = ntohl(net->seq); + queue_add(rs_queue, &cn->qnode); + /* we release the object once we get the acknowlegment */ break; } } @@ -527,6 +517,18 @@ static void ftfw_xmit(void) queue_len(tx_queue), queue_len(rs_queue)); } +static void ftfw_enqueue(struct cache_object *obj, int type) +{ + struct cache_ftfw *cn = cache_get_extra(STATE_SYNC(internal), obj); + if (queue_in(rs_queue, &cn->qnode)) { + queue_del(&cn->qnode); + queue_add(STATE_SYNC(tx_queue), &cn->qnode); + } else { + if (queue_add(STATE_SYNC(tx_queue), &cn->qnode)) + cache_object_get(obj); + } +} + struct sync_mode sync_ftfw = { .internal_cache_flags = LIFETIME, .external_cache_flags = LIFETIME, @@ -535,6 +537,6 @@ struct sync_mode sync_ftfw = { .kill = ftfw_kill, .local = ftfw_local, .recv = ftfw_recv, - .send = ftfw_send, + .enqueue = ftfw_enqueue, .xmit = ftfw_xmit, }; diff --git a/src/sync-mode.c b/src/sync-mode.c index 5ae9062..00e2f7b 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -442,14 +442,7 @@ static void dump_sync(struct nf_conntrack *ct) static void mcast_send_sync(struct cache_object *obj, int query) { - struct nethdr *net; - - net = BUILD_NETMSG(obj->ct, query); - - if (STATE_SYNC(sync)->send) - STATE_SYNC(sync)->send(net, obj); - - mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net); + STATE_SYNC(sync)->enqueue(obj, query); } static int purge_step(void *data1, void *data2) @@ -461,8 +454,11 @@ static int purge_step(void *data1, void *data2) ret = nfct_query(h, NFCT_Q_GET, obj->ct); if (ret == -1 && errno == ENOENT) { debug_ct(obj->ct, "overrun purge resync"); - mcast_send_sync(obj, NET_T_STATE_DEL); - cache_del_timer(STATE_SYNC(internal), obj, CONFIG(del_timeout)); + if (obj->status != C_OBJ_DEAD) { + cache_object_set_status(obj, C_OBJ_DEAD); + mcast_send_sync(obj, NET_T_STATE_DEL); + cache_object_put(obj); + } } return 0; @@ -552,8 +548,11 @@ static int event_destroy_sync(struct nf_conntrack *ct) debug_ct(ct, "can't destroy"); return 0; } - mcast_send_sync(obj, NET_T_STATE_DEL); - cache_del_timer(STATE_SYNC(internal), obj, CONFIG(del_timeout)); + if (obj->status != C_OBJ_DEAD) { + cache_object_set_status(obj, C_OBJ_DEAD); + mcast_send_sync(obj, NET_T_STATE_DEL); + cache_object_put(obj); + } debug_ct(ct, "internal destroy"); return 1; } diff --git a/src/sync-notrack.c b/src/sync-notrack.c index 4ded298..3b547ee 100644 --- a/src/sync-notrack.c +++ b/src/sync-notrack.c @@ -71,7 +71,8 @@ static int do_cache_to_tx(void *data1, void *data2) { struct cache_object *obj = data2; struct cache_notrack *cn = cache_get_extra(STATE_SYNC(internal), obj); - queue_add(STATE_SYNC(tx_queue), &cn->qnode); + if (queue_add(STATE_SYNC(tx_queue), &cn->qnode)) + cache_object_get(obj); return 0; } @@ -152,6 +153,7 @@ static int tx_queue_xmit(struct queue_node *n, const void *data2) mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net); queue_del(n); + cache_object_put(obj); break; } } @@ -163,11 +165,19 @@ static void notrack_xmit(void) queue_iterate(STATE_SYNC(tx_queue), NULL, tx_queue_xmit); } +static void notrack_enqueue(struct cache_object *obj, int query) +{ + struct cache_notrack *cn = cache_get_extra(STATE_SYNC(internal), obj); + if (queue_add(STATE_SYNC(tx_queue), &cn->qnode)) + cache_object_get(obj); +} + struct sync_mode sync_notrack = { .internal_cache_flags = LIFETIME, .external_cache_flags = LIFETIME, .internal_cache_extra = &cache_notrack_extra, .local = notrack_local, .recv = notrack_recv, + .enqueue = notrack_enqueue, .xmit = notrack_xmit, }; -- cgit v1.2.3 From 1c9faf8c218bc7ff4617557383e4116f1adb11e5 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 25 Jan 2009 17:53:02 +0100 Subject: cache: move lifetime feature to main cache code The lifetime feature is used by all working modes, it is useful to know how long it has been an entry living in the cache. This patch moves the lifetime feature to the main caching code. Signed-off-by: Pablo Neira Ayuso --- include/cache.h | 6 ++--- src/Makefile.am | 2 +- src/cache.c | 3 ++- src/cache_iterators.c | 6 +++++ src/cache_lifetime.c | 65 --------------------------------------------------- src/stats-mode.c | 4 +--- src/sync-alarm.c | 4 ++-- src/sync-ftfw.c | 4 ++-- src/sync-notrack.c | 4 ++-- 9 files changed, 18 insertions(+), 80 deletions(-) delete mode 100644 src/cache_lifetime.c (limited to 'src/sync-alarm.c') diff --git a/include/cache.h b/include/cache.h index 5e96dd3..1fd3881 100644 --- a/include/cache.h +++ b/include/cache.h @@ -12,10 +12,7 @@ enum { TIMER_FEATURE = 0, TIMER = (1 << TIMER_FEATURE), - LIFETIME_FEATURE = 2, - LIFETIME = (1 << LIFETIME_FEATURE), - - WRITE_THROUGH_FEATURE = 3, + WRITE_THROUGH_FEATURE = 1, WRITE_THROUGH = (1 << WRITE_THROUGH_FEATURE), __CACHE_MAX_FEATURE @@ -36,6 +33,7 @@ struct cache_object { struct cache *cache; int status; int refcnt; + long lifetime; char data[0]; }; diff --git a/src/Makefile.am b/src/Makefile.am index 64ed2b5..8ba09e1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -14,7 +14,7 @@ conntrackd_SOURCES = alarm.c main.c run.c hash.c queue.c rbtree.c \ local.c log.c mcast.c netlink.c vector.c \ filter.c fds.c event.c \ cache.c cache_iterators.c \ - cache_lifetime.c cache_timer.c cache_wt.c \ + cache_timer.c cache_wt.c \ sync-mode.c sync-alarm.c sync-ftfw.c sync-notrack.c \ traffic_stats.c stats-mode.c \ network.c cidr.c \ diff --git a/src/cache.c b/src/cache.c index a5f37dd..71825e1 100644 --- a/src/cache.c +++ b/src/cache.c @@ -26,6 +26,7 @@ #include #include #include +#include static uint32_t __hash4(const struct nf_conntrack *ct, const struct hashtable *table) @@ -94,7 +95,6 @@ static int compare(const void *data1, const void *data2) struct cache_feature *cache_feature[CACHE_MAX_FEATURE] = { [TIMER_FEATURE] = &timer_feature, - [LIFETIME_FEATURE] = &lifetime_feature, [WRITE_THROUGH_FEATURE] = &writethrough_feature, }; @@ -249,6 +249,7 @@ static int __add(struct cache *c, struct cache_object *obj, int id) c->extra->add(obj, ((char *) obj) + c->extra_offset); c->stats.active++; + obj->lifetime = time(NULL); obj->status = C_OBJ_NEW; obj->refcnt++; return 0; diff --git a/src/cache_iterators.c b/src/cache_iterators.c index 4bf518a..3a1ec72 100644 --- a/src/cache_iterators.c +++ b/src/cache_iterators.c @@ -26,6 +26,7 @@ #include #include #include +#include struct __dump_container { int fd; @@ -75,6 +76,11 @@ static int do_dump(void *data1, struct hashtable_node *n) data += obj->cache->features[i]->size; } } + if (container->type != NFCT_O_XML) { + long tm = time(NULL); + size += sprintf(buf+size, " [active since %lds]", + tm - obj->lifetime); + } size += sprintf(buf+size, "\n"); if (send(container->fd, buf, size, 0) == -1) { if (errno != EPIPE) diff --git a/src/cache_lifetime.c b/src/cache_lifetime.c deleted file mode 100644 index 639d8c1..0000000 --- a/src/cache_lifetime.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * (C) 2006 by Pablo Neira Ayuso - * - * 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 -#include "cache.h" -#include -#include -#include - -static void lifetime_add(struct cache_object *obj, void *data) -{ - long *lifetime = data; - struct timeval tv; - - gettimeofday(&tv, NULL); - - *lifetime = tv.tv_sec; -} - -static void lifetime_update(struct cache_object *obj, void *data) -{ -} - -static void lifetime_destroy(struct cache_object *obj, void *data) -{ -} - -static int lifetime_dump(struct cache_object *obj, - void *data, - char *buf, - int type) -{ - long *lifetime = data; - struct timeval tv; - - if (type == NFCT_O_XML) - return 0; - - gettimeofday(&tv, NULL); - - return sprintf(buf, " [active since %lds]", tv.tv_sec - *lifetime); -} - -struct cache_feature lifetime_feature = { - .size = sizeof(long), - .add = lifetime_add, - .update = lifetime_update, - .destroy = lifetime_destroy, - .dump = lifetime_dump -}; diff --git a/src/stats-mode.c b/src/stats-mode.c index b742c0c..226a6b8 100644 --- a/src/stats-mode.c +++ b/src/stats-mode.c @@ -37,9 +37,7 @@ static int init_stats(void) } memset(state.stats, 0, sizeof(struct ct_stats_state)); - STATE_STATS(cache) = cache_create("stats", - LIFETIME, - NULL); + STATE_STATS(cache) = cache_create("stats", NO_FEATURES, NULL); if (!STATE_STATS(cache)) { dlog(LOG_ERR, "can't allocate memory for the " "external cache"); diff --git a/src/sync-alarm.c b/src/sync-alarm.c index a2f17ac..1815447 100644 --- a/src/sync-alarm.c +++ b/src/sync-alarm.c @@ -154,8 +154,8 @@ static void alarm_xmit(void) } struct sync_mode sync_alarm = { - .internal_cache_flags = LIFETIME, - .external_cache_flags = TIMER | LIFETIME, + .internal_cache_flags = NO_FEATURES, + .external_cache_flags = TIMER, .internal_cache_extra = &cache_alarm_extra, .recv = alarm_recv, .enqueue = alarm_enqueue, diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c index fd6c350..91ce25d 100644 --- a/src/sync-ftfw.c +++ b/src/sync-ftfw.c @@ -561,8 +561,8 @@ static void ftfw_enqueue(struct cache_object *obj, int type) } struct sync_mode sync_ftfw = { - .internal_cache_flags = LIFETIME, - .external_cache_flags = LIFETIME, + .internal_cache_flags = NO_FEATURES, + .external_cache_flags = NO_FEATURES, .internal_cache_extra = &cache_ftfw_extra, .init = ftfw_init, .kill = ftfw_kill, diff --git a/src/sync-notrack.c b/src/sync-notrack.c index 3b547ee..7bd4351 100644 --- a/src/sync-notrack.c +++ b/src/sync-notrack.c @@ -173,8 +173,8 @@ static void notrack_enqueue(struct cache_object *obj, int query) } struct sync_mode sync_notrack = { - .internal_cache_flags = LIFETIME, - .external_cache_flags = LIFETIME, + .internal_cache_flags = NO_FEATURES, + .external_cache_flags = NO_FEATURES, .internal_cache_extra = &cache_notrack_extra, .local = notrack_local, .recv = notrack_recv, -- cgit v1.2.3 From e83250c0381bbff232011b67c87a5b9f3a0de09a Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Fri, 20 Feb 2009 20:42:22 +0100 Subject: src: remove obsolete debug() and debug_ct() calls This patch removes debug() and debug_ct(), I haven't use the debugging information that these functions provide in years. Signed-off-by: Pablo Neira Ayuso --- src/cache_timer.c | 2 -- src/mcast.c | 17 ----------------- src/netlink.c | 1 - src/network.c | 1 - src/stats-mode.c | 8 ++------ src/sync-alarm.c | 3 --- src/sync-ftfw.c | 1 - src/sync-mode.c | 26 ++++++-------------------- src/sync-notrack.c | 1 - 9 files changed, 8 insertions(+), 52 deletions(-) (limited to 'src/sync-alarm.c') diff --git a/src/cache_timer.c b/src/cache_timer.c index a9e3e3d..5881236 100644 --- a/src/cache_timer.c +++ b/src/cache_timer.c @@ -19,7 +19,6 @@ #include "cache.h" #include "conntrackd.h" #include "alarm.h" -#include "debug.h" #include @@ -27,7 +26,6 @@ static void timeout(struct alarm_block *a, void *data) { struct cache_object *obj = data; - debug_ct(obj->ct, "expired timeout"); cache_del(obj->cache, obj); cache_object_free(obj); } diff --git a/src/mcast.c b/src/mcast.c index 70205d8..bc530d3 100644 --- a/src/mcast.c +++ b/src/mcast.c @@ -19,7 +19,6 @@ */ #include "mcast.h" -#include "debug.h" #include #include @@ -73,7 +72,6 @@ struct mcast_sock *mcast_server_create(struct mcast_conf *conf) } if ((m->fd = socket(conf->ipproto, SOCK_DGRAM, 0)) == -1) { - debug("mcast_sock_server_create:socket"); free(m); return NULL; } @@ -84,7 +82,6 @@ struct mcast_sock *mcast_server_create(struct mcast_conf *conf) strncpy(ifr.ifr_name, conf->iface, sizeof(ifr.ifr_name)); if (ioctl(m->fd, SIOCGIFMTU, &ifr) == -1) { - debug("ioctl"); close(m->fd); free(m); return NULL; @@ -94,7 +91,6 @@ struct mcast_sock *mcast_server_create(struct mcast_conf *conf) if (setsockopt(m->fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { - debug("mcast_sock_server_create:setsockopt1"); close(m->fd); free(m); return NULL; @@ -109,7 +105,6 @@ struct mcast_sock *mcast_server_create(struct mcast_conf *conf) sizeof(int)) == -1) { /* not supported in linux kernel < 2.6.14 */ if (errno != ENOPROTOOPT) { - debug("mcast_sock_server_create:setsockopt2"); close(m->fd); free(m); return NULL; @@ -119,7 +114,6 @@ struct mcast_sock *mcast_server_create(struct mcast_conf *conf) getsockopt(m->fd, SOL_SOCKET, SO_RCVBUF, &conf->rcvbuf, &socklen); if (bind(m->fd, (struct sockaddr *) &m->addr, m->sockaddr_len) == -1) { - debug("mcast_sock_server_create:bind"); close(m->fd); free(m); return NULL; @@ -129,7 +123,6 @@ struct mcast_sock *mcast_server_create(struct mcast_conf *conf) case AF_INET: if (setsockopt(m->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq.ipv4, sizeof(mreq.ipv4)) < 0) { - debug("mcast_sock_server_create:setsockopt2"); close(m->fd); free(m); return NULL; @@ -138,7 +131,6 @@ struct mcast_sock *mcast_server_create(struct mcast_conf *conf) case AF_INET6: if (setsockopt(m->fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq.ipv6, sizeof(mreq.ipv6)) < 0) { - debug("mcast_sock_server_create:setsockopt2"); close(m->fd); free(m); return NULL; @@ -207,7 +199,6 @@ __mcast_client_create_ipv4(struct mcast_sock *m, struct mcast_conf *conf) if (setsockopt(m->fd, IPPROTO_IP, IP_MULTICAST_LOOP, &no, sizeof(int)) < 0) { - debug("mcast_sock_client_create:setsockopt2"); close(m->fd); return -1; } @@ -215,7 +206,6 @@ __mcast_client_create_ipv4(struct mcast_sock *m, struct mcast_conf *conf) if (setsockopt(m->fd, IPPROTO_IP, IP_MULTICAST_IF, &conf->ifa.interface_addr, sizeof(struct in_addr)) == -1) { - debug("mcast_sock_client_create:setsockopt3"); close(m->fd); return -1; } @@ -237,7 +227,6 @@ __mcast_client_create_ipv6(struct mcast_sock *m, struct mcast_conf *conf) if (setsockopt(m->fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &no, sizeof(int)) < 0) { - debug("mcast_sock_client_create:setsockopt2"); close(m->fd); return -1; } @@ -245,7 +234,6 @@ __mcast_client_create_ipv6(struct mcast_sock *m, struct mcast_conf *conf) if (setsockopt(m->fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &conf->ifa.interface_index6, sizeof(unsigned int)) == -1) { - debug("mcast_sock_client_create:setsockopt3"); close(m->fd); return -1; } @@ -267,14 +255,12 @@ struct mcast_sock *mcast_client_create(struct mcast_conf *conf) m->interface_idx = conf->interface_idx; if ((m->fd = socket(conf->ipproto, SOCK_DGRAM, 0)) == -1) { - debug("mcast_sock_client_create:socket"); free(m); return NULL; } if (setsockopt(m->fd, SOL_SOCKET, SO_NO_CHECK, &conf->checksum, sizeof(int)) == -1) { - debug("mcast_sock_client_create:setsockopt1"); close(m->fd); free(m); return NULL; @@ -289,7 +275,6 @@ struct mcast_sock *mcast_client_create(struct mcast_conf *conf) sizeof(int)) == -1) { /* not supported in linux kernel < 2.6.14 */ if (errno != ENOPROTOOPT) { - debug("mcast_sock_server_create:setsockopt2"); close(m->fd); free(m); return NULL; @@ -376,7 +361,6 @@ ssize_t mcast_send(struct mcast_sock *m, void *data, int size) (struct sockaddr *) &m->addr, m->sockaddr_len); if (ret == -1) { - debug("mcast_sock_send"); m->stats.error++; return ret; } @@ -399,7 +383,6 @@ ssize_t mcast_recv(struct mcast_sock *m, void *data, int size) (struct sockaddr *)&m->addr, &sin_size); if (ret == -1) { - debug("mcast_sock_recv"); m->stats.error++; return ret; } diff --git a/src/netlink.c b/src/netlink.c index 78cc466..ef729c1 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -20,7 +20,6 @@ #include "conntrackd.h" #include "filter.h" #include "log.h" -#include "debug.h" #include #include diff --git a/src/network.c b/src/network.c index f71aef0..690b28e 100644 --- a/src/network.c +++ b/src/network.c @@ -19,7 +19,6 @@ #include "conntrackd.h" #include "network.h" #include "log.h" -#include "debug.h" #include #include diff --git a/src/stats-mode.c b/src/stats-mode.c index 94fc45b..af1c136 100644 --- a/src/stats-mode.c +++ b/src/stats-mode.c @@ -18,7 +18,6 @@ #include "netlink.h" #include "traffic_stats.h" -#include "debug.h" #include "cache.h" #include "log.h" #include "conntrackd.h" @@ -97,8 +96,7 @@ static void dump_stats(struct nf_conntrack *ct) nfct_attr_unset(ct, ATTR_TIMEOUT); nfct_attr_unset(ct, ATTR_USE); - if (cache_update_force(STATE_STATS(cache), ct)) - debug_ct(ct, "resync entry"); + cache_update_force(STATE_STATS(cache), ct); } static int resync_stats(enum nf_conntrack_msg_type type, @@ -116,8 +114,7 @@ static int resync_stats(enum nf_conntrack_msg_type type, nfct_attr_unset(ct, ATTR_REPL_COUNTER_PACKETS); nfct_attr_unset(ct, ATTR_USE); - if (!cache_update_force(STATE_STATS(cache), ct)) - debug_ct(ct, "stats resync"); + cache_update_force(STATE_STATS(cache), ct); return NFCT_CB_CONTINUE; } @@ -129,7 +126,6 @@ static int purge_step(void *data1, void *data2) STATE(get_retval) = 0; nl_get_conntrack(STATE(get), obj->ct); /* modifies STATE(get_retval) */ if (!STATE(get_retval)) { - debug_ct(obj->ct, "purge stats"); cache_del(STATE_STATS(cache), obj); dlog_ct(STATE(stats_log), obj->ct, NFCT_O_PLAIN); cache_object_free(obj); diff --git a/src/sync-alarm.c b/src/sync-alarm.c index 1815447..a59ae11 100644 --- a/src/sync-alarm.c +++ b/src/sync-alarm.c @@ -22,7 +22,6 @@ #include "alarm.h" #include "cache.h" #include "queue.h" -#include "debug.h" #include #include @@ -38,8 +37,6 @@ static void refresher(struct alarm_block *a, void *data) { struct cache_object *obj = data; - debug_ct(obj->ct, "persistence update"); - add_alarm(a, random() % CONFIG(refresh) + 1, ((random() % 5 + 1) * 200000) - 1); diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c index 91ce25d..d608e5b 100644 --- a/src/sync-ftfw.c +++ b/src/sync-ftfw.c @@ -19,7 +19,6 @@ #include "conntrackd.h" #include "sync.h" #include "queue.h" -#include "debug.h" #include "network.h" #include "alarm.h" #include "log.h" diff --git a/src/sync-mode.c b/src/sync-mode.c index 02a5a46..d1a941b 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -25,7 +25,6 @@ #include "network.h" #include "fds.h" #include "event.h" -#include "debug.h" #include "queue.h" #include @@ -166,10 +165,6 @@ static void mcast_handler(struct mcast_sock *m, int if_idx) } } - debug("recv sq: %u fl:%u len:%u (rem:%d)\n", - ntohl(net->seq), net->flags, - ntohs(net->len), remain); - HDR_NETWORK2HOST(net); do_mcast_handler_step(if_idx, net, remain); @@ -531,8 +526,7 @@ static void dump_sync(struct nf_conntrack *ct) nfct_attr_unset(ct, ATTR_REPL_COUNTER_PACKETS); nfct_attr_unset(ct, ATTR_USE); - if (cache_update_force(STATE_SYNC(internal), ct)) - debug_ct(ct, "dump"); + cache_update_force(STATE_SYNC(internal), ct); } static int purge_step(void *data1, void *data2) @@ -542,7 +536,6 @@ static int purge_step(void *data1, void *data2) STATE(get_retval) = 0; nl_get_conntrack(STATE(get), obj->ct); /* modifies STATE(get_reval) */ if (!STATE(get_retval)) { - debug_ct(obj->ct, "purge resync"); if (obj->status != C_OBJ_DEAD) { cache_object_set_status(obj, C_OBJ_DEAD); mcast_send_sync(obj, NET_T_STATE_DEL); @@ -582,11 +575,9 @@ static int resync_sync(enum nf_conntrack_msg_type type, switch (obj->status) { case C_OBJ_NEW: - debug_ct(ct, "resync"); mcast_send_sync(obj, NET_T_STATE_NEW); break; case C_OBJ_ALIVE: - debug_ct(ct, "resync"); mcast_send_sync(obj, NET_T_STATE_UPD); break; } @@ -615,11 +606,9 @@ retry: return; } mcast_send_sync(obj, NET_T_STATE_NEW); - debug_ct(obj->ct, "internal new"); } else { cache_del(STATE_SYNC(internal), obj); cache_object_free(obj); - debug_ct(ct, "can't add"); goto retry; } } @@ -628,11 +617,10 @@ static void event_update_sync(struct nf_conntrack *ct) { struct cache_object *obj; - if ((obj = cache_update_force(STATE_SYNC(internal), ct)) == NULL) { - debug_ct(ct, "can't update"); + obj = cache_update_force(STATE_SYNC(internal), ct); + if (obj == NULL) return; - } - debug_ct(obj->ct, "internal update"); + mcast_send_sync(obj, NET_T_STATE_UPD); } @@ -642,16 +630,14 @@ static int event_destroy_sync(struct nf_conntrack *ct) int id; obj = cache_find(STATE_SYNC(internal), ct, &id); - if (obj == NULL) { - debug_ct(ct, "can't destroy"); + if (obj == NULL) return 0; - } + if (obj->status != C_OBJ_DEAD) { cache_object_set_status(obj, C_OBJ_DEAD); mcast_send_sync(obj, NET_T_STATE_DEL); cache_object_put(obj); } - debug_ct(ct, "internal destroy"); return 1; } diff --git a/src/sync-notrack.c b/src/sync-notrack.c index 7bd4351..57c3368 100644 --- a/src/sync-notrack.c +++ b/src/sync-notrack.c @@ -19,7 +19,6 @@ #include "conntrackd.h" #include "sync.h" #include "queue.h" -#include "debug.h" #include "network.h" #include "log.h" #include "cache.h" -- cgit v1.2.3 From 656d5ad7c69a5a7d356c6251743890f1eec0bb71 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Thu, 12 Mar 2009 21:09:27 +0100 Subject: sync-mode: add abstract layer to make daemon independent of multicast This patch reworks conntrackd to make it independent of the protocol used to propagate state-changes. This patch adds the channel layer abstraction, this layer allows you to add support for different protocols like unicast UDP or TIPC. Signed-off-by: Pablo Neira Ayuso --- include/Makefile.am | 2 +- include/channel.h | 95 +++++++++++++++++++++++++++ include/conntrackd.h | 10 +-- include/mcast.h | 26 ++------ include/network.h | 5 -- src/Makefile.am | 1 + src/channel.c | 180 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/channel_mcast.c | 123 +++++++++++++++++++++++++++++++++++ src/mcast.c | 169 +---------------------------------------------- src/multichannel.c | 110 +++++++++++++++++++++++++++++++ src/network.c | 61 ----------------- src/read_config_yy.y | 69 +++++++++++--------- src/sync-alarm.c | 4 +- src/sync-ftfw.c | 4 +- src/sync-mode.c | 82 +++++++++-------------- src/sync-notrack.c | 4 +- 16 files changed, 596 insertions(+), 349 deletions(-) create mode 100644 include/channel.h create mode 100644 src/channel.c create mode 100644 src/channel_mcast.c create mode 100644 src/multichannel.c (limited to 'src/sync-alarm.c') diff --git a/include/Makefile.am b/include/Makefile.am index c3f8904..0265620 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -3,5 +3,5 @@ noinst_HEADERS = alarm.h jhash.h cache.h linux_list.h linux_rbtree.h \ sync.h conntrackd.h local.h \ debug.h log.h hash.h mcast.h conntrack.h \ network.h filter.h queue.h vector.h cidr.h \ - traffic_stats.h netlink.h fds.h event.h bitops.h + traffic_stats.h netlink.h fds.h event.h bitops.h channel.h diff --git a/include/channel.h b/include/channel.h new file mode 100644 index 0000000..ac1a93c --- /dev/null +++ b/include/channel.h @@ -0,0 +1,95 @@ +#ifndef _CHANNEL_H_ +#define _CHANNEL_H_ + +#include "mcast.h" + +struct channel; +struct nethdr; + +enum { + CHANNEL_MCAST, + CHANNEL_MAX, +}; + +struct mcast_channel { + struct mcast_sock *client; + struct mcast_sock *server; +}; + +#define CHANNEL_F_DEFAULT (1 << 0) +#define CHANNEL_F_BUFFERED (1 << 1) +#define CHANNEL_F_MAX (1 << 2) + +union channel_type_conf { + struct mcast_conf mcast; +}; + +struct channel_conf { + int channel_type; + char channel_ifname[IFNAMSIZ]; + unsigned int channel_flags; + union channel_type_conf u; +}; + +struct nlif_handle; + +struct channel_ops { + void * (*open)(void *conf); + void (*close)(void *channel); + int (*send)(void *channel, const void *data, int len); + int (*recv)(void *channel, char *buf, int len); + int (*get_fd)(void *channel); + void (*stats)(struct channel *c, int fd); + void (*stats_extended)(struct channel *c, int active, + struct nlif_handle *h, int fd); +}; + +struct channel_buffer; + +struct channel { + int channel_type; + int channel_ifindex; + int channel_ifmtu; + unsigned int channel_flags; + struct channel_buffer *buffer; + struct channel_ops *ops; + void *data; +}; + +void channel_init(void); +struct channel *channel_open(struct channel_conf *conf); +void channel_close(struct channel *c); + +int channel_send(struct channel *c, const struct nethdr *net); +int channel_send_flush(struct channel *c); +int channel_recv(struct channel *c, char *buf, int size); + +int channel_get_fd(struct channel *c); +void channel_stats(struct channel *c, int fd); +void channel_stats_extended(struct channel *c, int active, + struct nlif_handle *h, int fd); + +#define MULTICHANNEL_MAX 4 + +struct multichannel { + int channel_num; + struct channel *channel[MULTICHANNEL_MAX]; + struct channel *current; +}; + +struct multichannel *multichannel_open(struct channel_conf *conf, int len); +void multichannel_close(struct multichannel *m); + +int multichannel_send(struct multichannel *c, const struct nethdr *net); +int multichannel_send_flush(struct multichannel *c); +int multichannel_recv(struct multichannel *c, char *buf, int size); + +void multichannel_stats(struct multichannel *m, int fd); +void multichannel_stats_extended(struct multichannel *m, + struct nlif_handle *h, int fd); + +int multichannel_get_ifindex(struct multichannel *m, int i); +int multichannel_get_current_ifindex(struct multichannel *m); +void multichannel_set_current_channel(struct multichannel *m, int i); + +#endif /* _CHANNEL_H_ */ diff --git a/include/conntrackd.h b/include/conntrackd.h index 536abc9..cfb1ac5 100644 --- a/include/conntrackd.h +++ b/include/conntrackd.h @@ -5,6 +5,7 @@ #include "local.h" #include "alarm.h" #include "filter.h" +#include "channel.h" #include #include @@ -71,9 +72,9 @@ struct ct_conf { int syslog_facility; char lockfile[FILENAME_MAXLEN]; int hashsize; /* hashtable size */ - int mcast_links; - int mcast_default_link; - struct mcast_conf mcast[MCAST_LINKS_MAX]; + int channel_num; + int channel_default; + struct channel_conf channel[MULTICHANNEL_MAX]; struct local_conf local; /* unix socket facilities */ int nice; int limit; @@ -163,8 +164,7 @@ struct ct_sync_state { struct cache *internal; /* internal events cache (netlink) */ struct cache *external; /* external events cache (mcast) */ - struct mcast_sock_multi *mcast_server; /* multicast incoming */ - struct mcast_sock_multi *mcast_client; /* multicast outgoing */ + struct multichannel *channel; struct nlif_handle *interface; struct queue *tx_queue; diff --git a/include/mcast.h b/include/mcast.h index 623f390..68d18e8 100644 --- a/include/mcast.h +++ b/include/mcast.h @@ -42,38 +42,22 @@ struct mcast_sock { struct mcast_stats stats; }; -#define MCAST_LINKS_MAX 4 - -struct mcast_sock_multi { - int num_links; - int max_mtu; - struct mcast_sock *current_link; - struct mcast_sock *multi[MCAST_LINKS_MAX]; -}; - struct mcast_sock *mcast_server_create(struct mcast_conf *conf); void mcast_server_destroy(struct mcast_sock *m); -struct mcast_sock_multi *mcast_server_create_multi(struct mcast_conf *conf, int conf_len); -void mcast_server_destroy_multi(struct mcast_sock_multi *m); struct mcast_sock *mcast_client_create(struct mcast_conf *conf); void mcast_client_destroy(struct mcast_sock *m); -struct mcast_sock_multi *mcast_client_create_multi(struct mcast_conf *conf, int conf_len); -void mcast_client_destroy_multi(struct mcast_sock_multi*m); ssize_t mcast_send(struct mcast_sock *m, void *data, int size); ssize_t mcast_recv(struct mcast_sock *m, void *data, int size); int mcast_get_fd(struct mcast_sock *m); -int mcast_get_ifidx(struct mcast_sock_multi *m, int i); -int mcast_get_current_ifidx(struct mcast_sock_multi *m); - -struct mcast_sock *mcast_get_current_link(struct mcast_sock_multi *m); -void mcast_set_current_link(struct mcast_sock_multi *m, int i); -void mcast_dump_stats(int fd, const struct mcast_sock_multi *s, const struct mcast_sock_multi *r); +int mcast_snprintf_stats(char *buf, size_t buflen, char *ifname, + struct mcast_stats *s, struct mcast_stats *r); -struct nlif_handle; +int mcast_snprintf_stats2(char *buf, size_t buflen, const char *ifname, + const char *status, int active, + struct mcast_stats *s, struct mcast_stats *r); -void mcast_dump_stats_extended(int fd, const struct mcast_sock_multi *s, const struct mcast_sock_multi *r, const struct nlif_handle *h); #endif diff --git a/include/network.h b/include/network.h index 29a6113..7019d7d 100644 --- a/include/network.h +++ b/include/network.h @@ -106,11 +106,6 @@ int mcast_track_is_seq_set(void); struct mcast_conf; -int mcast_buffered_init(int mtu); -void mcast_buffered_destroy(void); -int mcast_buffered_send_netmsg(struct mcast_sock_multi *m, const struct nethdr *net); -ssize_t mcast_buffered_pending_netmsg(struct mcast_sock_multi *m); - #define IS_DATA(x) (x->type <= NET_T_STATE_MAX && \ (x->flags & ~(NET_F_HELLO | NET_F_HELLO_BACK)) == 0) #define IS_ACK(x) (x->type == NET_T_CTL && x->flags & NET_F_ACK) diff --git a/src/Makefile.am b/src/Makefile.am index 8ba09e1..54cfda4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,6 +19,7 @@ conntrackd_SOURCES = alarm.c main.c run.c hash.c queue.c rbtree.c \ traffic_stats.c stats-mode.c \ network.c cidr.c \ build.c parse.c \ + channel.c multichannel.c channel_mcast.c \ read_config_yy.y read_config_lex.l # yacc and lex generate dirty code diff --git a/src/channel.c b/src/channel.c new file mode 100644 index 0000000..733fd03 --- /dev/null +++ b/src/channel.c @@ -0,0 +1,180 @@ +/* + * (C) 2009 by Pablo Neira Ayuso + * + * 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. + */ + +#include +#include +#include +#include +#include +#include + +#include "channel.h" +#include "network.h" + +static struct channel_ops *ops[CHANNEL_MAX]; +extern struct channel_ops channel_mcast; + +void channel_init(void) +{ + ops[CHANNEL_MCAST] = &channel_mcast; +} + +#define HEADERSIZ 28 /* IP header (20 bytes) + UDP header 8 (bytes) */ + +struct channel_buffer { + char *data; + int size; + int len; +}; + +static struct channel_buffer * +channel_buffer_open(int mtu) +{ + struct channel_buffer *b; + + b = calloc(sizeof(struct channel_buffer), 1); + if (b == NULL) + return NULL; + + b->size = mtu - HEADERSIZ; + + b->data = malloc(b->size); + if (b->data == NULL) { + free(b); + return NULL; + } + return b; +} + +static void +channel_buffer_close(struct channel_buffer *b) +{ + free(b->data); + free(b); +} + +struct channel * +channel_open(struct channel_conf *conf) +{ + struct channel *c; + struct ifreq ifr; + int fd; + + if (conf->channel_type >= CHANNEL_MAX) + return NULL; + if (!conf->channel_ifname[0]) + return NULL; + if (conf->channel_flags >= CHANNEL_F_MAX) + return NULL; + + c = calloc(sizeof(struct channel), 1); + if (c == NULL) + return NULL; + + c->channel_type = conf->channel_type; + + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd == -1) { + free(c); + return NULL; + } + strncpy(ifr.ifr_name, conf->channel_ifname, sizeof(ifr.ifr_name)); + + if (ioctl(fd, SIOCGIFMTU, &ifr) == -1) { + free(c); + return NULL; + } + close(fd); + c->channel_ifmtu = ifr.ifr_mtu; + + c->channel_ifindex = if_nametoindex(conf->channel_ifname); + if (c->channel_ifindex == 0) { + free(c); + return NULL; + } + c->ops = ops[conf->channel_type]; + + if (conf->channel_flags & CHANNEL_F_BUFFERED) { + c->buffer = channel_buffer_open(c->channel_ifmtu); + if (c->buffer == NULL) { + free(c); + return NULL; + } + } + c->channel_flags = conf->channel_flags; + + c->data = c->ops->open(&conf->u); + if (c->data == NULL) { + channel_buffer_close(c->buffer); + free(c); + return NULL; + } + return c; +} + +void +channel_close(struct channel *c) +{ + c->ops->close(c->data); + if (c->channel_flags & CHANNEL_F_BUFFERED) + channel_buffer_close(c->buffer); + free(c); +} + +int channel_send(struct channel *c, const struct nethdr *net) +{ + int ret = 0, len = ntohs(net->len); + + if (!(c->channel_flags & CHANNEL_F_BUFFERED)) { + c->ops->send(c->data, net, len); + return 1; + } +retry: + if (c->buffer->len + len < c->buffer->size) { + memcpy(c->buffer->data + c->buffer->len, net, len); + c->buffer->len += len; + } else { + c->ops->send(c->data, c->buffer->data, c->buffer->len); + ret = 1; + c->buffer->len = 0; + goto retry; + } + return ret; +} + +int channel_send_flush(struct channel *c) +{ + if (!(c->channel_flags & CHANNEL_F_BUFFERED) || c->buffer->len == 0) + return 0; + + c->ops->send(c->data, c->buffer->data, c->buffer->len); + c->buffer->len = 0; + return 1; +} + +int channel_recv(struct channel *c, char *buf, int size) +{ + return c->ops->recv(c->data, buf, size); +} + +int channel_get_fd(struct channel *c) +{ + return c->ops->get_fd(c->data); +} + +void channel_stats(struct channel *c, int fd) +{ + return c->ops->stats(c, fd); +} + +void channel_stats_extended(struct channel *c, int active, + struct nlif_handle *h, int fd) +{ + return c->ops->stats_extended(c, active, h, fd); +} diff --git a/src/channel_mcast.c b/src/channel_mcast.c new file mode 100644 index 0000000..898b194 --- /dev/null +++ b/src/channel_mcast.c @@ -0,0 +1,123 @@ +/* + * (C) 2009 by Pablo Neira Ayuso + * + * 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. + */ + +#include +#include + +#include "channel.h" +#include "mcast.h" + +static void +*channel_mcast_open(void *conf) +{ + struct mcast_channel *m; + struct mcast_conf *c = conf; + + m = calloc(sizeof(struct mcast_channel), 1); + if (m == NULL) + return NULL; + + m->client = mcast_client_create(c); + if (m->client == NULL) { + free(m); + return NULL; + } + + m->server = mcast_server_create(c); + if (m->server == NULL) { + mcast_client_destroy(m->client); + free(m); + return NULL; + } + return m; +} + +static int +channel_mcast_send(void *channel, const void *data, int len) +{ + struct mcast_channel *m = channel; + return mcast_send(m->client, data, len); +} + +static int +channel_mcast_recv(void *channel, char *buf, int size) +{ + struct mcast_channel *m = channel; + return mcast_recv(m->server, buf, size); +} + +static void +channel_mcast_close(void *channel) +{ + struct mcast_channel *m = channel; + mcast_client_destroy(m->client); + mcast_server_destroy(m->server); + free(m); +} + +static int +channel_mcast_get_fd(void *channel) +{ + struct mcast_channel *m = channel; + return mcast_get_fd(m->server); +} + +static void +channel_mcast_stats(struct channel *c, int fd) +{ + struct mcast_channel *m = c->data; + char ifname[IFNAMSIZ], buf[512]; + int size; + + if_indextoname(c->channel_ifindex, ifname); + size = mcast_snprintf_stats(buf, sizeof(buf), ifname, + &m->client->stats, &m->server->stats); + send(fd, buf, size, 0); +} + +static void +channel_mcast_stats_extended(struct channel *c, int active, + struct nlif_handle *h, int fd) +{ + struct mcast_channel *m = c->data; + char ifname[IFNAMSIZ], buf[512]; + const char *status; + unsigned int flags; + int size; + + if_indextoname(c->channel_ifindex, ifname); + nlif_get_ifflags(h, c->channel_ifindex, &flags); + /* + * IFF_UP shows administrative status + * IFF_RUNNING shows carrier status + */ + if (flags & IFF_UP) { + if (!(flags & IFF_RUNNING)) + status = "NO-CARRIER"; + else + status = "RUNNING"; + } else { + status = "DOWN"; + } + size = mcast_snprintf_stats2(buf, sizeof(buf), + ifname, status, active, + &m->client->stats, + &m->server->stats); + send(fd, buf, size, 0); +} + +struct channel_ops channel_mcast = { + .open = channel_mcast_open, + .close = channel_mcast_close, + .send = channel_mcast_send, + .recv = channel_mcast_recv, + .get_fd = channel_mcast_get_fd, + .stats = channel_mcast_stats, + .stats_extended = channel_mcast_stats_extended, +}; diff --git a/src/mcast.c b/src/mcast.c index 8f11762..8eedd07 100644 --- a/src/mcast.c +++ b/src/mcast.c @@ -143,52 +143,12 @@ struct mcast_sock *mcast_server_create(struct mcast_conf *conf) return m; } -struct mcast_sock_multi * -mcast_server_create_multi(struct mcast_conf *conf, int conf_len) -{ - struct mcast_sock_multi *m; - int i, j; - - if (conf_len <= 0 || conf_len > MCAST_LINKS_MAX) - return NULL; - - m = calloc(sizeof(struct mcast_sock_multi), 1); - if (m == NULL) - return NULL; - - m->max_mtu = INT_MAX; - for (i=0; imulti[i] = mcast_server_create(&conf[i]); - if (m->multi[i] == NULL) { - for (j=0; jmulti[j]); - } - free(m); - return NULL; - } - if (m->max_mtu > conf[i].mtu) - m->max_mtu = conf[i].mtu; - } - m->num_links = conf_len; - - return m; -} - void mcast_server_destroy(struct mcast_sock *m) { close(m->fd); free(m); } -void mcast_server_destroy_multi(struct mcast_sock_multi *m) -{ - int i; - - for (i=0; inum_links; i++) - mcast_server_destroy(m->multi[i]); - free(m); -} - static int __mcast_client_create_ipv4(struct mcast_sock *m, struct mcast_conf *conf) { @@ -306,52 +266,12 @@ struct mcast_sock *mcast_client_create(struct mcast_conf *conf) return m; } -struct mcast_sock_multi * -mcast_client_create_multi(struct mcast_conf *conf, int conf_len) -{ - struct mcast_sock_multi *m; - int i, j; - - if (conf_len <= 0 || conf_len > MCAST_LINKS_MAX) - return NULL; - - m = calloc(sizeof(struct mcast_sock_multi), 1); - if (m == NULL) - return NULL; - - m->max_mtu = INT_MAX; - for (i=0; imulti[i] = mcast_client_create(&conf[i]); - if (m->multi[i] == NULL) { - for (j=0; jmulti[j]); - } - free(m); - return NULL; - } - if (m->max_mtu > conf[i].mtu) - m->max_mtu = conf[i].mtu; - } - m->num_links = conf_len; - - return m; -} - void mcast_client_destroy(struct mcast_sock *m) { close(m->fd); free(m); } -void mcast_client_destroy_multi(struct mcast_sock_multi *m) -{ - int i; - - for (i=0; inum_links; i++) - mcast_client_destroy(m->multi[i]); - free(m); -} - ssize_t mcast_send(struct mcast_sock *m, void *data, int size) { ssize_t ret; @@ -395,32 +315,12 @@ ssize_t mcast_recv(struct mcast_sock *m, void *data, int size) return ret; } -void mcast_set_current_link(struct mcast_sock_multi *m, int i) -{ - m->current_link = m->multi[i]; -} - -struct mcast_sock *mcast_get_current_link(struct mcast_sock_multi *m) -{ - return m->current_link; -} - int mcast_get_fd(struct mcast_sock *m) { return m->fd; } -int mcast_get_current_ifidx(struct mcast_sock_multi *m) -{ - return m->current_link->interface_idx; -} - -int mcast_get_ifidx(struct mcast_sock_multi *m, int i) -{ - return m->multi[i]->interface_idx; -} - -static int +int mcast_snprintf_stats(char *buf, size_t buflen, char *ifname, struct mcast_stats *s, struct mcast_stats *r) { @@ -443,7 +343,7 @@ mcast_snprintf_stats(char *buf, size_t buflen, char *ifname, return size; } -static int +int mcast_snprintf_stats2(char *buf, size_t buflen, const char *ifname, const char *status, int active, struct mcast_stats *s, struct mcast_stats *r) @@ -467,68 +367,3 @@ mcast_snprintf_stats2(char *buf, size_t buflen, const char *ifname, (unsigned long long)r->error); return size; } - -void -mcast_dump_stats(int fd, - const struct mcast_sock_multi *s, - const struct mcast_sock_multi *r) -{ - int i; - struct mcast_stats snd = { 0, 0, 0}; - struct mcast_stats rcv = { 0, 0, 0}; - char ifname[IFNAMSIZ], buf[512]; - int size; - - /* it is the same for the receiver, no need to do it twice */ - if_indextoname(s->current_link->interface_idx, ifname); - - for (i=0; inum_links && inum_links; i++) { - snd.bytes += s->multi[i]->stats.bytes; - snd.messages += s->multi[i]->stats.messages; - snd.error += s->multi[i]->stats.error; - rcv.bytes += r->multi[i]->stats.bytes; - rcv.messages += r->multi[i]->stats.messages; - rcv.error += r->multi[i]->stats.error; - } - size = mcast_snprintf_stats(buf, sizeof(buf), ifname, &snd, &rcv); - send(fd, buf, size, 0); -} - -void -mcast_dump_stats_extended(int fd, - const struct mcast_sock_multi *s, - const struct mcast_sock_multi *r, - const struct nlif_handle *h) -{ - int i; - char buf[4096]; - int size = 0; - - for (i=0; inum_links && inum_links; i++) { - int idx = s->multi[i]->interface_idx, active; - unsigned int flags; - char ifname[IFNAMSIZ]; - const char *status; - - if_indextoname(idx, ifname); - nlif_get_ifflags(h, idx, &flags); - active = (s->multi[i] == s->current_link); - /* - * IFF_UP shows administrative status - * IFF_RUNNING shows carrier status - */ - if (flags & IFF_UP) { - if (!(flags & IFF_RUNNING)) - status = "NO-CARRIER"; - else - status = "RUNNING"; - } else { - status = "DOWN"; - } - size += mcast_snprintf_stats2(buf+size, sizeof(buf), - ifname, status, active, - &s->multi[i]->stats, - &r->multi[i]->stats); - } - send(fd, buf, size, 0); -} diff --git a/src/multichannel.c b/src/multichannel.c new file mode 100644 index 0000000..ab0f04c --- /dev/null +++ b/src/multichannel.c @@ -0,0 +1,110 @@ +/* + * (C) 2009 by Pablo Neira Ayuso + * + * 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. + */ + +#include + +#include "channel.h" +#include "network.h" + +struct multichannel * +multichannel_open(struct channel_conf *conf, int len) +{ + struct multichannel *m; + int i, set_default_channel = 0; + + if (len <= 0 || len > MULTICHANNEL_MAX) + return NULL; + + m = calloc(sizeof(struct multichannel), 1); + if (m == NULL) + return NULL; + + m->channel_num = len; + for (i = 0; i < len; i++) { + m->channel[i] = channel_open(&conf[i]); + if (m->channel[i] == NULL) { + int j; + + for (j=0; jchannel[j]); + } + free(m); + return NULL; + } + if (conf[i].channel_flags & CHANNEL_F_DEFAULT) { + m->current = m->channel[i]; + set_default_channel = 1; + } + } + if (!set_default_channel) + m->current = m->channel[0]; + + return m; +} + +int multichannel_send(struct multichannel *c, const struct nethdr *net) +{ + return channel_send(c->current, net); +} + +int multichannel_send_flush(struct multichannel *c) +{ + return channel_send_flush(c->current); +} + +int multichannel_recv(struct multichannel *c, char *buf, int size) +{ + return channel_recv(c->current, buf, size); +} + +void multichannel_close(struct multichannel *m) +{ + int i; + + for (i = 0; i < m->channel_num; i++) { + channel_close(m->channel[i]); + } + free(m); +} + +void multichannel_stats(struct multichannel *m, int fd) +{ + channel_stats(m->current, fd); +} + +void +multichannel_stats_extended(struct multichannel *m, + struct nlif_handle *h, int fd) +{ + int i, active; + + for (i = 0; i < m->channel_num; i++) { + if (m->current == m->channel[i]) { + active = 1; + } else { + active = 0; + } + channel_stats_extended(m->channel[i], active, h, fd); + } +} + +int multichannel_get_ifindex(struct multichannel *m, int i) +{ + return m->channel[i]->channel_ifindex; +} + +int multichannel_get_current_ifindex(struct multichannel *m) +{ + return m->current->channel_ifindex; +} + +void multichannel_set_current_channel(struct multichannel *m, int i) +{ + m->current = m->channel[i]; +} diff --git a/src/network.c b/src/network.c index 690b28e..bdfa10c 100644 --- a/src/network.c +++ b/src/network.c @@ -65,67 +65,6 @@ void nethdr_set_ctl(struct nethdr *net) __nethdr_set(net, NETHDR_SIZ); } -static size_t tx_buflenmax; -static size_t tx_buflen = 0; -static char *tx_buf; - -#define HEADERSIZ 28 /* IP header (20 bytes) + UDP header 8 (bytes) */ - -int mcast_buffered_init(int if_mtu) -{ - int mtu = if_mtu - HEADERSIZ; - - /* default to Ethernet MTU 1500 bytes */ - if (if_mtu == 0) - mtu = 1500 - HEADERSIZ; - - tx_buf = malloc(mtu); - if (tx_buf == NULL) - return -1; - - tx_buflenmax = mtu; - - return 0; -} - -void mcast_buffered_destroy(void) -{ - free(tx_buf); -} - -/* return 0 if it is not sent, otherwise return 1 */ -int -mcast_buffered_send_netmsg(struct mcast_sock_multi *m, const struct nethdr *net) -{ - int ret = 0, len = ntohs(net->len); - -retry: - if (tx_buflen + len < tx_buflenmax) { - memcpy(tx_buf + tx_buflen, net, len); - tx_buflen += len; - } else { - mcast_send(mcast_get_current_link(m), tx_buf, tx_buflen); - ret = 1; - tx_buflen = 0; - goto retry; - } - - return ret; -} - -ssize_t mcast_buffered_pending_netmsg(struct mcast_sock_multi *m) -{ - ssize_t ret; - - if (tx_buflen == 0) - return 0; - - ret = mcast_send(mcast_get_current_link(m), tx_buf, tx_buflen); - tx_buflen = 0; - - return ret; -} - static int local_seq_set = 0; /* this function only tracks, it does not update the last sequence received */ diff --git a/src/read_config_yy.y b/src/read_config_yy.y index b9a37f7..b3a2640 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -181,18 +181,18 @@ checksum: T_CHECKSUM T_ON * XXX: The use of Checksum outside of the Multicast clause is broken * if we have more than one dedicated links. */ - conf.mcast[0].checksum = 0; + conf.channel[0].u.mcast.checksum = 0; }; checksum: T_CHECKSUM T_OFF { fprintf(stderr, "WARNING: The use of `Checksum' outside the " "`Multicast' clause is ambiguous.\n"); - /* + /* * XXX: The use of Checksum outside of the Multicast clause is broken * if we have more than one dedicated links. */ - conf.mcast[0].checksum = 1; + conf.channel[0].u.mcast.checksum = 1; }; ignore_traffic : T_IGNORE_TRAFFIC '{' ignore_traffic_options '}' @@ -256,13 +256,18 @@ ignore_traffic_option : T_IPV6_ADDR T_IP multicast_line : T_MULTICAST '{' multicast_options '}' { - conf.mcast_links++; + conf.channel[conf.channel_num].channel_type = CHANNEL_MCAST; + conf.channel[conf.channel_num].channel_flags = CHANNEL_F_BUFFERED; + conf.channel_num++; }; multicast_line : T_MULTICAST T_DEFAULT '{' multicast_options '}' { - conf.mcast_default_link = conf.mcast_links; - conf.mcast_links++; + conf.channel[conf.channel_num].channel_type = CHANNEL_MCAST; + conf.channel[conf.channel_num].channel_flags = CHANNEL_F_DEFAULT | + CHANNEL_F_BUFFERED; + conf.channel_default = conf.channel_num; + conf.channel_num++; }; multicast_options : @@ -272,19 +277,19 @@ multicast_option : T_IPV4_ADDR T_IP { __max_mcast_dedicated_links_reached(); - if (!inet_aton($2, &conf.mcast[conf.mcast_links].in)) { + if (!inet_aton($2, &conf.channel[conf.channel_num].u.mcast.in)) { fprintf(stderr, "%s is not a valid IPv4 address\n", $2); break; } - if (conf.mcast[conf.mcast_links].ipproto == AF_INET6) { + if (conf.channel[conf.channel_num].u.mcast.ipproto == AF_INET6) { fprintf(stderr, "Your multicast address is IPv4 but " "is binded to an IPv6 interface? Surely " "this is not what you want\n"); break; } - conf.mcast[conf.mcast_links].ipproto = AF_INET; + conf.channel[conf.channel_num].u.mcast.ipproto = AF_INET; }; multicast_option : T_IPV6_ADDR T_IP @@ -292,7 +297,8 @@ multicast_option : T_IPV6_ADDR T_IP __max_mcast_dedicated_links_reached(); #ifdef HAVE_INET_PTON_IPV6 - if (inet_pton(AF_INET6, $2, &conf.mcast[conf.mcast_links].in) <= 0) { + if (inet_pton(AF_INET6, $2, + &conf.channel[conf.channel_num].u.mcast.in) <= 0) { fprintf(stderr, "%s is not a valid IPv6 address\n", $2); break; } @@ -301,17 +307,17 @@ multicast_option : T_IPV6_ADDR T_IP break; #endif - if (conf.mcast[conf.mcast_links].ipproto == AF_INET) { + if (conf.channel[conf.channel_num].u.mcast.ipproto == AF_INET) { fprintf(stderr, "Your multicast address is IPv6 but " "is binded to an IPv4 interface? Surely " "this is not what you want\n"); break; } - conf.mcast[conf.mcast_links].ipproto = AF_INET6; + conf.channel[conf.channel_num].u.mcast.ipproto = AF_INET6; - if (conf.mcast[conf.mcast_links].iface[0] && - !conf.mcast[conf.mcast_links].ifa.interface_index6) { + if (conf.channel[conf.channel_num].u.mcast.iface[0] && + !conf.channel[conf.channel_num].u.mcast.ifa.interface_index6) { unsigned int idx; idx = if_nametoindex($2); @@ -320,8 +326,8 @@ multicast_option : T_IPV6_ADDR T_IP break; } - conf.mcast[conf.mcast_links].ifa.interface_index6 = idx; - conf.mcast[conf.mcast_links].ipproto = AF_INET6; + conf.channel[conf.channel_num].u.mcast.ifa.interface_index6 = idx; + conf.channel[conf.channel_num].u.mcast.ipproto = AF_INET6; } }; @@ -329,19 +335,19 @@ multicast_option : T_IPV4_IFACE T_IP { __max_mcast_dedicated_links_reached(); - if (!inet_aton($2, &conf.mcast[conf.mcast_links].ifa)) { + if (!inet_aton($2, &conf.channel[conf.channel_num].u.mcast.ifa)) { fprintf(stderr, "%s is not a valid IPv4 address\n", $2); break; } - if (conf.mcast[conf.mcast_links].ipproto == AF_INET6) { + if (conf.channel[conf.channel_num].u.mcast.ipproto == AF_INET6) { fprintf(stderr, "Your multicast interface is IPv4 but " "is binded to an IPv6 interface? Surely " "this is not what you want\n"); break; } - conf.mcast[conf.mcast_links].ipproto = AF_INET; + conf.channel[conf.channel_num].u.mcast.ipproto = AF_INET; }; multicast_option : T_IPV6_IFACE T_IP @@ -355,18 +361,19 @@ multicast_option : T_IFACE T_STRING __max_mcast_dedicated_links_reached(); - strncpy(conf.mcast[conf.mcast_links].iface, $2, IFNAMSIZ); + strncpy(conf.channel[conf.channel_num].channel_ifname, $2, IFNAMSIZ); + strncpy(conf.channel[conf.channel_num].u.mcast.iface, $2, IFNAMSIZ); idx = if_nametoindex($2); if (!idx) { fprintf(stderr, "%s is an invalid interface.\n", $2); break; } - conf.mcast[conf.mcast_links].interface_idx = idx; + conf.channel[conf.channel_num].u.mcast.interface_idx = idx; - if (conf.mcast[conf.mcast_links].ipproto == AF_INET6) { - conf.mcast[conf.mcast_links].ifa.interface_index6 = idx; - conf.mcast[conf.mcast_links].ipproto = AF_INET6; + if (conf.channel[conf.channel_num].u.mcast.ipproto == AF_INET6) { + conf.channel[conf.channel_num].u.mcast.ifa.interface_index6 = idx; + conf.channel[conf.channel_num].u.mcast.ipproto = AF_INET6; } }; @@ -379,31 +386,31 @@ multicast_option : T_BACKLOG T_NUMBER multicast_option : T_GROUP T_NUMBER { __max_mcast_dedicated_links_reached(); - conf.mcast[conf.mcast_links].port = $2; + conf.channel[conf.channel_num].u.mcast.port = $2; }; multicast_option: T_MCAST_SNDBUFF T_NUMBER { __max_mcast_dedicated_links_reached(); - conf.mcast[conf.mcast_links].sndbuf = $2; + conf.channel[conf.channel_num].u.mcast.sndbuf = $2; }; multicast_option: T_MCAST_RCVBUFF T_NUMBER { __max_mcast_dedicated_links_reached(); - conf.mcast[conf.mcast_links].rcvbuf = $2; + conf.channel[conf.channel_num].u.mcast.rcvbuf = $2; }; multicast_option: T_CHECKSUM T_ON { __max_mcast_dedicated_links_reached(); - conf.mcast[conf.mcast_links].checksum = 0; + conf.channel[conf.channel_num].u.mcast.checksum = 0; }; multicast_option: T_CHECKSUM T_OFF { __max_mcast_dedicated_links_reached(); - conf.mcast[conf.mcast_links].checksum = 1; + conf.channel[conf.channel_num].u.mcast.checksum = 1; }; hashsize : T_HASHSIZE T_NUMBER @@ -1128,10 +1135,10 @@ static void __kernel_filter_add_state(int value) static void __max_mcast_dedicated_links_reached(void) { - if (conf.mcast_links >= MCAST_LINKS_MAX) { + if (conf.channel_num >= MULTICHANNEL_MAX) { fprintf(stderr, "ERROR: too many dedicated links in " "the configuration file (Maximum: %d).\n", - MCAST_LINKS_MAX); + MULTICHANNEL_MAX); exit(EXIT_FAILURE); } } diff --git a/src/sync-alarm.c b/src/sync-alarm.c index a59ae11..caa6bb2 100644 --- a/src/sync-alarm.c +++ b/src/sync-alarm.c @@ -125,7 +125,7 @@ static int tx_queue_xmit(struct queue_node *n, const void *data) net = queue_node_data(n); nethdr_set_ctl(net); HDR_HOST2NETWORK(net); - mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net); + multichannel_send(STATE_SYNC(channel), net); queue_object_free((struct queue_object *)n); break; case Q_ELEM_OBJ: { @@ -137,7 +137,7 @@ static int tx_queue_xmit(struct queue_node *n, const void *data) obj = cache_data_get_object(STATE_SYNC(internal), ca); type = object_status_to_network_type(obj->status); net = BUILD_NETMSG(obj->ct, type); - mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net); + multichannel_send(STATE_SYNC(channel), net); cache_object_put(obj); break; } diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c index d608e5b..cacbb13 100644 --- a/src/sync-ftfw.c +++ b/src/sync-ftfw.c @@ -494,7 +494,7 @@ static int tx_queue_xmit(struct queue_node *n, const void *data) dp("tx_queue sq: %u fl:%u len:%u\n", ntohl(net->seq), net->flags, ntohs(net->len)); - mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net); + multichannel_send(STATE_SYNC(channel), net); HDR_NETWORK2HOST(net); if (IS_ACK(net) || IS_NACK(net) || IS_RESYNC(net)) { @@ -523,7 +523,7 @@ static int tx_queue_xmit(struct queue_node *n, const void *data) dp("tx_list sq: %u fl:%u len:%u\n", ntohl(net->seq), net->flags, ntohs(net->len)); - mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net); + multichannel_send(STATE_SYNC(channel), net); cn->seq = ntohl(net->seq); if (queue_add(rs_queue, &cn->qnode) < 0) { if (errno == ENOSPC) { diff --git a/src/sync-mode.c b/src/sync-mode.c index b452cba..22609df 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -38,12 +38,12 @@ static void mcast_change_current_link(int if_idx) { - if (if_idx != mcast_get_current_ifidx(STATE_SYNC(mcast_client))) - mcast_set_current_link(STATE_SYNC(mcast_client), if_idx); + if (if_idx != multichannel_get_current_ifindex(STATE_SYNC(channel))) + multichannel_set_current_channel(STATE_SYNC(channel), if_idx); } static void -do_mcast_handler_step(int if_idx, struct nethdr *net, size_t remain) +do_channel_handler_step(int if_idx, struct nethdr *net, size_t remain) { char __ct[nfct_maxsize()]; struct nf_conntrack *ct = (struct nf_conntrack *)(void*) __ct; @@ -122,14 +122,14 @@ retry: } } -/* handler for multicast messages received */ -static void mcast_handler(struct mcast_sock *m, int if_idx) +/* handler for messages received */ +static void channel_handler(struct channel *m, int if_idx) { ssize_t numbytes; ssize_t remain; char __net[65536], *ptr = __net; /* XXX: maximum MTU for IPv4 */ - numbytes = mcast_recv(m, __net, sizeof(__net)); + numbytes = channel_recv(m, __net, sizeof(__net)); if (numbytes <= 0) return; @@ -168,7 +168,7 @@ static void mcast_handler(struct mcast_sock *m, int if_idx) HDR_NETWORK2HOST(net); - do_mcast_handler_step(if_idx, net, remain); + do_channel_handler_step(if_idx, net, remain); ptr += net->len; remain -= net->len; } @@ -181,13 +181,13 @@ static void interface_candidate(void) unsigned int flags; char buf[IFNAMSIZ]; - for (i=0; inum_links; i++) { - idx = mcast_get_ifidx(STATE_SYNC(mcast_client), i); - if (idx == mcast_get_current_ifidx(STATE_SYNC(mcast_client))) + for (i=0; ichannel_num; i++) { + idx = multichannel_get_ifindex(STATE_SYNC(channel), i); + if (idx == multichannel_get_current_ifindex(STATE_SYNC(channel))) continue; nlif_get_ifflags(STATE_SYNC(interface), idx, &flags); if (flags & (IFF_RUNNING | IFF_UP)) { - mcast_set_current_link(STATE_SYNC(mcast_client), i); + multichannel_set_current_channel(STATE_SYNC(channel), i); dlog(LOG_NOTICE, "device `%s' becomes multicast " "dedicated link", if_indextoname(idx, buf)); @@ -199,7 +199,7 @@ static void interface_candidate(void) static void interface_handler(void) { - int idx = mcast_get_current_ifidx(STATE_SYNC(mcast_client)); + int idx = multichannel_get_current_ifindex(STATE_SYNC(channel)); unsigned int flags; nlif_catch(STATE_SYNC(interface)); @@ -267,38 +267,21 @@ static int init_sync(void) return -1; } - /* multicast server to receive events from the wire */ - STATE_SYNC(mcast_server) = - mcast_server_create_multi(CONFIG(mcast), CONFIG(mcast_links)); - if (STATE_SYNC(mcast_server) == NULL) { - dlog(LOG_ERR, "can't open multicast server!"); + channel_init(); + + /* channel to send events on the wire */ + STATE_SYNC(channel) = + multichannel_open(CONFIG(channel), CONFIG(channel_num)); + if (STATE_SYNC(channel) == NULL) { + dlog(LOG_ERR, "can't open channel socket"); return -1; } - for (i=0; inum_links; i++) { - int fd = mcast_get_fd(STATE_SYNC(mcast_server)->multi[i]); + for (i=0; ichannel_num; i++) { + int fd = channel_get_fd(STATE_SYNC(channel)->channel[i]); if (register_fd(fd, STATE(fds)) == -1) return -1; } - /* multicast client to send events on the wire */ - STATE_SYNC(mcast_client) = - mcast_client_create_multi(CONFIG(mcast), CONFIG(mcast_links)); - if (STATE_SYNC(mcast_client) == NULL) { - dlog(LOG_ERR, "can't open client multicast socket"); - mcast_server_destroy_multi(STATE_SYNC(mcast_server)); - return -1; - } - /* we only use one link to send events, but all to receive them */ - mcast_set_current_link(STATE_SYNC(mcast_client), - CONFIG(mcast_default_link)); - - if (mcast_buffered_init(STATE_SYNC(mcast_client)->max_mtu) == -1) { - dlog(LOG_ERR, "can't init tx buffer!"); - mcast_server_destroy_multi(STATE_SYNC(mcast_server)); - mcast_client_destroy_multi(STATE_SYNC(mcast_client)); - return -1; - } - STATE_SYNC(interface) = nl_init_interface_handler(); if (!STATE_SYNC(interface)) { dlog(LOG_ERR, "can't open interface watcher"); @@ -328,10 +311,10 @@ static void run_sync(fd_set *readfds) { int i; - for (i=0; inum_links; i++) { - int fd = mcast_get_fd(STATE_SYNC(mcast_server)->multi[i]); + for (i=0; ichannel_num; i++) { + int fd = channel_get_fd(STATE_SYNC(channel)->channel[i]); if (FD_ISSET(fd, readfds)) - mcast_handler(STATE_SYNC(mcast_server)->multi[i], i); + channel_handler(STATE_SYNC(channel)->channel[i], i); } if (FD_ISSET(queue_get_eventfd(STATE_SYNC(tx_queue)), readfds)) @@ -341,7 +324,7 @@ static void run_sync(fd_set *readfds) interface_handler(); /* flush pending messages */ - mcast_buffered_pending_netmsg(STATE_SYNC(mcast_client)); + multichannel_send_flush(STATE_SYNC(channel)); } static void kill_sync(void) @@ -349,12 +332,10 @@ static void kill_sync(void) cache_destroy(STATE_SYNC(internal)); cache_destroy(STATE_SYNC(external)); - mcast_server_destroy_multi(STATE_SYNC(mcast_server)); - mcast_client_destroy_multi(STATE_SYNC(mcast_client)); + multichannel_close(STATE_SYNC(channel)); nlif_close(STATE_SYNC(interface)); - mcast_buffered_destroy(); queue_destroy(STATE_SYNC(tx_queue)); if (STATE_SYNC(sync)->kill) @@ -486,23 +467,20 @@ static int local_handler_sync(int fd, int type, void *data) cache_stats(STATE_SYNC(internal), fd); cache_stats(STATE_SYNC(external), fd); dump_traffic_stats(fd); - mcast_dump_stats(fd, STATE_SYNC(mcast_client), - STATE_SYNC(mcast_server)); + multichannel_stats(STATE_SYNC(channel), fd); dump_stats_sync(fd); break; case STATS_NETWORK: dump_stats_sync_extended(fd); - mcast_dump_stats(fd, STATE_SYNC(mcast_client), - STATE_SYNC(mcast_server)); + multichannel_stats(STATE_SYNC(channel), fd); break; case STATS_CACHE: cache_stats_extended(STATE_SYNC(internal), fd); cache_stats_extended(STATE_SYNC(external), fd); break; case STATS_MULTICAST: - mcast_dump_stats_extended(fd, STATE_SYNC(mcast_client), - STATE_SYNC(mcast_server), - STATE_SYNC(interface)); + multichannel_stats_extended(STATE_SYNC(channel), + STATE_SYNC(interface), fd); break; default: if (STATE_SYNC(sync)->local) diff --git a/src/sync-notrack.c b/src/sync-notrack.c index 57c3368..737ee52 100644 --- a/src/sync-notrack.c +++ b/src/sync-notrack.c @@ -134,7 +134,7 @@ static int tx_queue_xmit(struct queue_node *n, const void *data2) else nethdr_set_ctl(net); HDR_HOST2NETWORK(net); - mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net); + multichannel_send(STATE_SYNC(channel), net); queue_del(n); queue_object_free((struct queue_object *)n); break; @@ -150,7 +150,7 @@ static int tx_queue_xmit(struct queue_node *n, const void *data2) type = object_status_to_network_type(obj->status);; net = BUILD_NETMSG(obj->ct, type); - mcast_buffered_send_netmsg(STATE_SYNC(mcast_client), net); + multichannel_send(STATE_SYNC(channel), net); queue_del(n); cache_object_put(obj); break; -- cgit v1.2.3 From 338d8fc2da19f5d6a75c339d9e6ecac43b68a1e4 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Thu, 12 Mar 2009 21:19:19 +0100 Subject: sync-mode: rename mcast_track_*() by nethdr_track_*() This patch is a cleanup. It renames the mcast_track_*() functions by nethdr_track_*() because this functions are related to message sequence tracking. They are not stick to multicast at all. Signed-off-by: Pablo Neira Ayuso --- include/network.h | 6 +++--- src/network.c | 6 +++--- src/sync-alarm.c | 2 +- src/sync-ftfw.c | 6 +++--- src/sync-notrack.c | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) (limited to 'src/sync-alarm.c') diff --git a/include/network.h b/include/network.h index 7019d7d..b182339 100644 --- a/include/network.h +++ b/include/network.h @@ -100,9 +100,9 @@ enum { SEQ_BEFORE, }; -int mcast_track_seq(uint32_t seq, uint32_t *exp_seq); -void mcast_track_update_seq(uint32_t seq); -int mcast_track_is_seq_set(void); +int nethdr_track_seq(uint32_t seq, uint32_t *exp_seq); +void nethdr_track_update_seq(uint32_t seq); +int nethdr_track_is_seq_set(void); struct mcast_conf; diff --git a/src/network.c b/src/network.c index bdfa10c..6a66a2b 100644 --- a/src/network.c +++ b/src/network.c @@ -68,7 +68,7 @@ void nethdr_set_ctl(struct nethdr *net) static int local_seq_set = 0; /* this function only tracks, it does not update the last sequence received */ -int mcast_track_seq(uint32_t seq, uint32_t *exp_seq) +int nethdr_track_seq(uint32_t seq, uint32_t *exp_seq) { int ret = SEQ_UNKNOWN; @@ -104,7 +104,7 @@ out: return ret; } -void mcast_track_update_seq(uint32_t seq) +void nethdr_track_update_seq(uint32_t seq) { if (!local_seq_set) local_seq_set = 1; @@ -112,7 +112,7 @@ void mcast_track_update_seq(uint32_t seq) STATE_SYNC(last_seq_recv) = seq; } -int mcast_track_is_seq_set() +int nethdr_track_is_seq_set() { return local_seq_set; } diff --git a/src/sync-alarm.c b/src/sync-alarm.c index caa6bb2..4757026 100644 --- a/src/sync-alarm.c +++ b/src/sync-alarm.c @@ -102,7 +102,7 @@ static int alarm_recv(const struct nethdr *net) * just joined the cluster, instead they just get resynchronized in * RefreshTime seconds at worst case. */ - mcast_track_seq(net->seq, &exp_seq); + nethdr_track_seq(net->seq, &exp_seq); return 0; } diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c index cacbb13..e026b1c 100644 --- a/src/sync-ftfw.c +++ b/src/sync-ftfw.c @@ -129,7 +129,7 @@ static void tx_queue_add_ctlmsg2(uint32_t flags) /* this function is called from the alarm framework */ static void do_alive_alarm(struct alarm_block *a, void *data) { - if (ack_from_set && mcast_track_is_seq_set()) { + if (ack_from_set && nethdr_track_is_seq_set()) { /* exp_seq contains the last update received */ tx_queue_add_ctlmsg(NET_F_ACK, ack_from, @@ -396,7 +396,7 @@ static int ftfw_recv(const struct nethdr *net) goto bypass; } - switch (mcast_track_seq(net->seq, &exp_seq)) { + switch (nethdr_track_seq(net->seq, &exp_seq)) { case SEQ_AFTER: ret = digest_msg(net); if (ret == MSG_BAD) { @@ -446,7 +446,7 @@ bypass: out: if ((ret == MSG_DATA || ret == MSG_CTL)) - mcast_track_update_seq(net->seq); + nethdr_track_update_seq(net->seq); return ret; } diff --git a/src/sync-notrack.c b/src/sync-notrack.c index 737ee52..6502bcd 100644 --- a/src/sync-notrack.c +++ b/src/sync-notrack.c @@ -114,12 +114,12 @@ static int notrack_recv(const struct nethdr *net) int ret; unsigned int exp_seq; - mcast_track_seq(net->seq, &exp_seq); + nethdr_track_seq(net->seq, &exp_seq); ret = digest_msg(net); if (ret != MSG_BAD) - mcast_track_update_seq(net->seq); + nethdr_track_update_seq(net->seq); return ret; } -- cgit v1.2.3 From 8ad5df6121c46753a6d12fafa5ab9da309ddb721 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 21 Oct 2009 01:43:07 +0200 Subject: conntrackd: add `DisableInternalCache' clause This patch adds the clause `DisableInternalCache' that allows you to bypass the internal cache. This clause can only be used with the notrack synchronization mode. Signed-off-by: Pablo Neira Ayuso --- include/Makefile.am | 2 +- include/conntrackd.h | 12 +-- include/internal.h | 39 +++++++++ src/Makefile.am | 1 + src/internal_bypass.c | 165 +++++++++++++++++++++++++++++++++++++ src/internal_cache.c | 220 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/read_config_lex.l | 1 + src/read_config_yy.y | 13 ++- src/run.c | 62 ++++++++------ src/stats-mode.c | 24 +++--- src/sync-alarm.c | 5 +- src/sync-ftfw.c | 19 +++-- src/sync-mode.c | 190 ++++--------------------------------------- src/sync-notrack.c | 53 ++++++++++-- 14 files changed, 572 insertions(+), 234 deletions(-) create mode 100644 include/internal.h create mode 100644 src/internal_bypass.c create mode 100644 src/internal_cache.c (limited to 'src/sync-alarm.c') diff --git a/include/Makefile.am b/include/Makefile.am index a89490e..cbbca6b 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -4,5 +4,5 @@ noinst_HEADERS = alarm.h jhash.h cache.h linux_list.h linux_rbtree.h \ debug.h log.h hash.h mcast.h conntrack.h \ network.h filter.h queue.h vector.h cidr.h \ traffic_stats.h netlink.h fds.h event.h bitops.h channel.h \ - process.h origin.h external.h date.h + process.h origin.h internal.h external.h date.h diff --git a/include/conntrackd.h b/include/conntrackd.h index 7737532..c7f33f0 100644 --- a/include/conntrackd.h +++ b/include/conntrackd.h @@ -6,6 +6,7 @@ #include "alarm.h" #include "filter.h" #include "channel.h" +#include "internal.h" #include #include @@ -99,6 +100,7 @@ struct ct_conf { int error_queue_length; } channelc; struct { + int internal_cache_disable; int external_cache_disable; } sync; struct { @@ -177,7 +179,6 @@ struct ct_general_state { #define STATE_SYNC(x) state.sync->x struct ct_sync_state { - struct cache *internal; /* internal events cache (netlink) */ struct external_handler *external; struct multichannel *channel; @@ -239,18 +240,11 @@ extern union ct_state state; extern struct ct_general_state st; struct ct_mode { + struct internal_handler *internal; int (*init)(void); void (*run)(fd_set *readfds); int (*local)(int fd, int type, void *data); void (*kill)(void); - void (*dump)(struct nf_conntrack *ct); - int (*resync)(enum nf_conntrack_msg_type type, - struct nf_conntrack *ct, - void *data); - int (*purge)(void); - void (*event_new)(struct nf_conntrack *ct, int origin); - void (*event_upd)(struct nf_conntrack *ct, int origin); - int (*event_dst)(struct nf_conntrack *ct, int origin); }; /* conntrackd modes */ diff --git a/include/internal.h b/include/internal.h new file mode 100644 index 0000000..1f11340 --- /dev/null +++ b/include/internal.h @@ -0,0 +1,39 @@ +#ifndef _INTERNAL_H_ +#define _INTERNAL_H_ + +#include + +struct nf_conntrack; + +enum { + INTERNAL_F_POPULATE = (1 << 0), + INTERNAL_F_RESYNC = (1 << 1), + INTERNAL_F_MAX = (1 << 2) +}; + +struct internal_handler { + void *data; + unsigned int flags; + + int (*init)(void); + void (*close)(void); + + void (*new)(struct nf_conntrack *ct, int origin_type); + void (*update)(struct nf_conntrack *ct, int origin_type); + int (*destroy)(struct nf_conntrack *ct, int origin_type); + + void (*dump)(int fd, int type); + void (*populate)(struct nf_conntrack *ct); + void (*purge)(void); + int (*resync)(enum nf_conntrack_msg_type type, + struct nf_conntrack *ct, void *data); + void (*flush)(void); + + void (*stats)(int fd); + void (*stats_ext)(int fd); +}; + +extern struct internal_handler internal_cache; +extern struct internal_handler internal_bypass; + +#endif diff --git a/src/Makefile.am b/src/Makefile.am index 8b36642..76f0e73 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -22,6 +22,7 @@ conntrackd_SOURCES = alarm.c main.c run.c hash.c queue.c rbtree.c \ channel.c multichannel.c channel_mcast.c channel_udp.c \ tcp.c channel_tcp.c \ external_cache.c external_inject.c \ + internal_cache.c internal_bypass.c \ read_config_yy.y read_config_lex.l # yacc and lex generate dirty code diff --git a/src/internal_bypass.c b/src/internal_bypass.c new file mode 100644 index 0000000..4caaf4f --- /dev/null +++ b/src/internal_bypass.c @@ -0,0 +1,165 @@ +/* + * (C) 2009 by Pablo Neira Ayuso + * + * 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 feature has been sponsored by 6WIND . + */ +#include "conntrackd.h" +#include "sync.h" +#include "log.h" +#include "cache.h" +#include "netlink.h" +#include "network.h" +#include "origin.h" + +static int _init(void) +{ + return 0; +} + +static void _close(void) +{ +} + +static int dump_cb(enum nf_conntrack_msg_type type, + struct nf_conntrack *ct, void *data) +{ + char buf[1024]; + int size, *fd = data; + + size = nfct_snprintf(buf, 1024, ct, NFCT_T_UNKNOWN, NFCT_O_DEFAULT, 0); + if (size < 1024) { + buf[size] = '\n'; + size++; + } + send(*fd, buf, size, 0); + + return NFCT_CB_CONTINUE; +} + +static void dump(int fd, int type) +{ + struct nfct_handle *h; + u_int32_t family = AF_UNSPEC; + int ret; + + h = nfct_open(CONNTRACK, 0); + if (h == NULL) { + dlog(LOG_ERR, "can't allocate memory for the internal cache"); + return; + } + nfct_callback_register(h, NFCT_T_ALL, dump_cb, &fd); + ret = nfct_query(h, NFCT_Q_DUMP, &family); + if (ret == -1) { + dlog(LOG_ERR, "can't dump kernel table"); + } + nfct_close(h); +} + +static void flush(void) +{ + nl_flush_conntrack_table(STATE(flush)); +} + +struct { + uint32_t new; + uint32_t upd; + uint32_t del; +} internal_bypass_stats; + +static void stats(int fd) +{ + char buf[512]; + int size; + + size = sprintf(buf, "internal bypass:\n" + "connections new:\t\t%12u\n" + "connections updated:\t\t%12u\n" + "connections destroyed:\t\t%12u\n\n", + internal_bypass_stats.new, + internal_bypass_stats.upd, + internal_bypass_stats.del); + + send(fd, buf, size, 0); +} + +/* unused, INTERNAL_F_POPULATE is unset. No cache, nothing to populate. */ +static void populate(struct nf_conntrack *ct) +{ +} + +/* unused, INTERNAL_F_RESYNC is unset. */ +static void purge(void) +{ +} + +/* unused, INTERNAL_F_RESYNC is unset. Nothing to resync, we have no cache. */ +static int resync(enum nf_conntrack_msg_type type, + struct nf_conntrack *ct, + void *data) +{ + return NFCT_CB_CONTINUE; +} + +static void +event_new_sync(struct nf_conntrack *ct, int origin) +{ + struct nethdr *net; + + /* this event has been triggered by me, skip */ + if (origin != CTD_ORIGIN_NOT_ME) + return; + + net = BUILD_NETMSG(ct, NET_T_STATE_NEW); + multichannel_send(STATE_SYNC(channel), net); + internal_bypass_stats.new++; +} + +static void +event_update_sync(struct nf_conntrack *ct, int origin) +{ + struct nethdr *net; + + /* this event has been triggered by me, skip */ + if (origin != CTD_ORIGIN_NOT_ME) + return; + + net = BUILD_NETMSG(ct, NET_T_STATE_UPD); + multichannel_send(STATE_SYNC(channel), net); + internal_bypass_stats.upd++; +} + +static int +event_destroy_sync(struct nf_conntrack *ct, int origin) +{ + struct nethdr *net; + + /* this event has been triggered by me, skip */ + if (origin != CTD_ORIGIN_NOT_ME) + return 1; + + net = BUILD_NETMSG(ct, NET_T_STATE_DEL); + multichannel_send(STATE_SYNC(channel), net); + internal_bypass_stats.del++; + + return 1; +} + +struct internal_handler internal_bypass = { + .init = _init, + .close = _close, + .dump = dump, + .flush = flush, + .stats = stats, + .stats_ext = stats, + .populate = populate, + .purge = purge, + .resync = resync, + .new = event_new_sync, + .update = event_update_sync, + .destroy = event_destroy_sync, +}; diff --git a/src/internal_cache.c b/src/internal_cache.c new file mode 100644 index 0000000..daadfd6 --- /dev/null +++ b/src/internal_cache.c @@ -0,0 +1,220 @@ +/* + * (C) 2009 by Pablo Neira Ayuso + * + * 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. + */ +#include "conntrackd.h" +#include "sync.h" +#include "log.h" +#include "cache.h" +#include "netlink.h" +#include "network.h" +#include "origin.h" + +static inline void sync_send(struct cache_object *obj, int query) +{ + STATE_SYNC(sync)->enqueue(obj, query); +} + +static int _init(void) +{ + STATE(mode)->internal->data = + cache_create("internal", + STATE_SYNC(sync)->internal_cache_flags, + STATE_SYNC(sync)->internal_cache_extra); + + if (!STATE(mode)->internal->data) { + dlog(LOG_ERR, "can't allocate memory for the internal cache"); + return -1; + } + return 0; +} + +static void _close(void) +{ + cache_destroy(STATE(mode)->internal->data); +} + +static void dump(int fd, int type) +{ + cache_dump(STATE(mode)->internal->data, fd, NFCT_O_PLAIN); +} + +static void flush(void) +{ + cache_flush(STATE(mode)->internal->data); +} + +static void stats(int fd) +{ + cache_stats(STATE(mode)->internal->data, fd); +} + +static void stats_ext(int fd) +{ + cache_stats_extended(STATE(mode)->internal->data, fd); +} + +static void populate(struct nf_conntrack *ct) +{ + /* This is required by kernels < 2.6.20 */ + nfct_attr_unset(ct, ATTR_ORIG_COUNTER_BYTES); + nfct_attr_unset(ct, ATTR_ORIG_COUNTER_PACKETS); + nfct_attr_unset(ct, ATTR_REPL_COUNTER_BYTES); + nfct_attr_unset(ct, ATTR_REPL_COUNTER_PACKETS); + nfct_attr_unset(ct, ATTR_USE); + + cache_update_force(STATE(mode)->internal->data, ct); +} + +static int purge_step(void *data1, void *data2) +{ + struct cache_object *obj = data2; + + STATE(get_retval) = 0; + nl_get_conntrack(STATE(get), obj->ct); /* modifies STATE(get_reval) */ + if (!STATE(get_retval)) { + if (obj->status != C_OBJ_DEAD) { + cache_object_set_status(obj, C_OBJ_DEAD); + sync_send(obj, NET_T_STATE_DEL); + cache_object_put(obj); + } + } + + return 0; +} + +static void purge(void) +{ + cache_iterate(STATE(mode)->internal->data, NULL, purge_step); +} + +static int resync(enum nf_conntrack_msg_type type, + struct nf_conntrack *ct, + void *data) +{ + struct cache_object *obj; + + if (ct_filter_conntrack(ct, 1)) + return NFCT_CB_CONTINUE; + + /* This is required by kernels < 2.6.20 */ + nfct_attr_unset(ct, ATTR_ORIG_COUNTER_BYTES); + nfct_attr_unset(ct, ATTR_ORIG_COUNTER_PACKETS); + nfct_attr_unset(ct, ATTR_REPL_COUNTER_BYTES); + nfct_attr_unset(ct, ATTR_REPL_COUNTER_PACKETS); + nfct_attr_unset(ct, ATTR_USE); + + obj = cache_update_force(STATE(mode)->internal->data, ct); + if (obj == NULL) + return NFCT_CB_CONTINUE; + + switch (obj->status) { + case C_OBJ_NEW: + sync_send(obj, NET_T_STATE_NEW); + break; + case C_OBJ_ALIVE: + sync_send(obj, NET_T_STATE_UPD); + break; + } + return NFCT_CB_CONTINUE; +} + +static void +event_new_sync(struct nf_conntrack *ct, int origin) +{ + struct cache_object *obj; + int id; + + /* this event has been triggered by a direct inject, skip */ + if (origin == CTD_ORIGIN_INJECT) + return; + + /* required by linux kernel <= 2.6.20 */ + nfct_attr_unset(ct, ATTR_ORIG_COUNTER_BYTES); + nfct_attr_unset(ct, ATTR_ORIG_COUNTER_PACKETS); + nfct_attr_unset(ct, ATTR_REPL_COUNTER_BYTES); + nfct_attr_unset(ct, ATTR_REPL_COUNTER_PACKETS); + + obj = cache_find(STATE(mode)->internal->data, ct, &id); + if (obj == NULL) { +retry: + obj = cache_object_new(STATE(mode)->internal->data, ct); + if (obj == NULL) + return; + if (cache_add(STATE(mode)->internal->data, obj, id) == -1) { + cache_object_free(obj); + return; + } + /* only synchronize events that have been triggered by other + * processes or the kernel, but don't propagate events that + * have been triggered by conntrackd itself, eg. commits. */ + if (origin == CTD_ORIGIN_NOT_ME) + sync_send(obj, NET_T_STATE_NEW); + } else { + cache_del(STATE(mode)->internal->data, obj); + cache_object_free(obj); + goto retry; + } +} + +static void +event_update_sync(struct nf_conntrack *ct, int origin) +{ + struct cache_object *obj; + + /* this event has been triggered by a direct inject, skip */ + if (origin == CTD_ORIGIN_INJECT) + return; + + obj = cache_update_force(STATE(mode)->internal->data, ct); + if (obj == NULL) + return; + + if (origin == CTD_ORIGIN_NOT_ME) + sync_send(obj, NET_T_STATE_UPD); +} + +static int +event_destroy_sync(struct nf_conntrack *ct, int origin) +{ + struct cache_object *obj; + int id; + + /* this event has been triggered by a direct inject, skip */ + if (origin == CTD_ORIGIN_INJECT) + return 0; + + /* we don't synchronize events for objects that are not in the cache */ + obj = cache_find(STATE(mode)->internal->data, ct, &id); + if (obj == NULL) + return 0; + + if (obj->status != C_OBJ_DEAD) { + cache_object_set_status(obj, C_OBJ_DEAD); + if (origin == CTD_ORIGIN_NOT_ME) { + sync_send(obj, NET_T_STATE_DEL); + } + cache_object_put(obj); + } + return 1; +} + +struct internal_handler internal_cache = { + .flags = INTERNAL_F_POPULATE | INTERNAL_F_RESYNC, + .init = _init, + .close = _close, + .dump = dump, + .flush = flush, + .stats = stats, + .stats_ext = stats_ext, + .populate = populate, + .purge = purge, + .resync = resync, + .new = event_new_sync, + .update = event_update_sync, + .destroy = event_destroy_sync, +}; diff --git a/src/read_config_lex.l b/src/read_config_lex.l index b4be6f0..b2d4bdb 100644 --- a/src/read_config_lex.l +++ b/src/read_config_lex.l @@ -136,6 +136,7 @@ notrack [N|n][O|o][T|t][R|r][A|a][C|c][K|k] "Type" { return T_TYPE; } "Priority" { return T_PRIO; } "NetlinkEventsReliable" { return T_NETLINK_EVENTS_RELIABLE; } +"DisableInternalCache" { return T_DISABLE_INTERNAL_CACHE; } "DisableExternalCache" { return T_DISABLE_EXTERNAL_CACHE; } "ErrorQueueLength" { return T_ERROR_QUEUE_LENGTH; } diff --git a/src/read_config_yy.y b/src/read_config_yy.y index 5075cf0..157e945 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -72,7 +72,7 @@ static void __max_dedicated_links_reached(void); %token T_FROM T_USERSPACE T_KERNELSPACE T_EVENT_ITER_LIMIT T_DEFAULT %token T_NETLINK_OVERRUN_RESYNC T_NICE T_IPV4_DEST_ADDR T_IPV6_DEST_ADDR %token T_SCHEDULER T_TYPE T_PRIO T_NETLINK_EVENTS_RELIABLE -%token T_DISABLE_EXTERNAL_CACHE T_ERROR_QUEUE_LENGTH +%token T_DISABLE_INTERNAL_CACHE T_DISABLE_EXTERNAL_CACHE T_ERROR_QUEUE_LENGTH %token T_IP T_PATH_VAL %token T_NUMBER @@ -852,9 +852,20 @@ sync_mode_notrack_list: sync_mode_notrack_line: timeout | purge + | disable_internal_cache | disable_external_cache ; +disable_internal_cache: T_DISABLE_INTERNAL_CACHE T_ON +{ + conf.sync.internal_cache_disable = 1; +}; + +disable_internal_cache: T_DISABLE_INTERNAL_CACHE T_OFF +{ + conf.sync.internal_cache_disable = 0; +}; + disable_external_cache: T_DISABLE_EXTERNAL_CACHE T_ON { conf.sync.external_cache_disable = 1; diff --git a/src/run.c b/src/run.c index 54ab1a5..803bbcc 100644 --- a/src/run.c +++ b/src/run.c @@ -28,6 +28,7 @@ #include "process.h" #include "origin.h" #include "date.h" +#include "internal.h" #include #include @@ -56,7 +57,9 @@ void killer(int foo) local_server_destroy(&STATE(local)); STATE(mode)->kill(); - nfct_close(STATE(dump)); /* cache_wt needs this here */ + if (STATE(mode)->internal->flags & INTERNAL_F_POPULATE) { + nfct_close(STATE(dump)); + } destroy_fds(STATE(fds)); unlink(CONFIG(lockfile)); @@ -210,9 +213,13 @@ static int local_handler(int fd, void *data) } break; case RESYNC_MASTER: - STATE(stats).nl_kernel_table_resync++; - dlog(LOG_NOTICE, "resync with master table"); - nl_dump_conntrack_table(STATE(dump)); + if (STATE(mode)->internal->flags & INTERNAL_F_POPULATE) { + STATE(stats).nl_kernel_table_resync++; + dlog(LOG_NOTICE, "resync with master table"); + nl_dump_conntrack_table(STATE(dump)); + } else { + dlog(LOG_NOTICE, "resync is unsupported in this mode"); + } break; case STATS_RUNTIME: dump_stats_runtime(fd); @@ -238,8 +245,8 @@ static void do_overrun_resync_alarm(struct alarm_block *a, void *data) static void do_polling_alarm(struct alarm_block *a, void *data) { - if (STATE(mode)->purge) - STATE(mode)->purge(); + if (STATE(mode)->internal->purge) + STATE(mode)->internal->purge(); nl_send_resync(STATE(resync)); add_alarm(&STATE(polling_alarm), CONFIG(poll_kernel_secs), 0); @@ -264,13 +271,13 @@ static int event_handler(const struct nlmsghdr *nlh, switch(type) { case NFCT_T_NEW: - STATE(mode)->event_new(ct, origin_type); + STATE(mode)->internal->new(ct, origin_type); break; case NFCT_T_UPDATE: - STATE(mode)->event_upd(ct, origin_type); + STATE(mode)->internal->update(ct, origin_type); break; case NFCT_T_DESTROY: - if (STATE(mode)->event_dst(ct, origin_type)) + if (STATE(mode)->internal->destroy(ct, origin_type)) update_traffic_stats(ct); break; default: @@ -295,7 +302,7 @@ static int dump_handler(enum nf_conntrack_msg_type type, switch(type) { case NFCT_T_UPDATE: - STATE(mode)->dump(ct); + STATE(mode)->internal->populate(ct); break; default: STATE(stats).nl_dump_unknown_type++; @@ -371,23 +378,26 @@ init(void) } nfct_callback_register(STATE(resync), NFCT_T_ALL, - STATE(mode)->resync, + STATE(mode)->internal->resync, NULL); register_fd(nfct_fd(STATE(resync)), STATE(fds)); fcntl(nfct_fd(STATE(resync)), F_SETFL, O_NONBLOCK); - STATE(dump) = nfct_open(CONNTRACK, 0); - if (STATE(dump) == 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(dump), NFCT_T_ALL, dump_handler, NULL); + if (STATE(mode)->internal->flags & INTERNAL_F_POPULATE) { + STATE(dump) = nfct_open(CONNTRACK, 0); + if (STATE(dump) == 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(dump), NFCT_T_ALL, + dump_handler, NULL); - if (nl_dump_conntrack_table(STATE(dump)) == -1) { - dlog(LOG_ERR, "can't get kernel conntrack table"); - return -1; + if (nl_dump_conntrack_table(STATE(dump)) == -1) { + dlog(LOG_ERR, "can't get kernel conntrack table"); + return -1; + } } STATE(get) = nfct_open(CONNTRACK, 0); @@ -499,7 +509,9 @@ static void __run(struct timeval *next_alarm) * we resync ourselves. */ nl_resize_socket_buffer(STATE(event)); - if (CONFIG(nl_overrun_resync) > 0) { + if (CONFIG(nl_overrun_resync) > 0 && + STATE(mode)->internal->flags & + INTERNAL_F_RESYNC) { add_alarm(&STATE(resync_alarm), CONFIG(nl_overrun_resync),0); } @@ -523,8 +535,8 @@ static void __run(struct timeval *next_alarm) } if (FD_ISSET(nfct_fd(STATE(resync)), &readfds)) { nfct_catch(STATE(resync)); - if (STATE(mode)->purge) - STATE(mode)->purge(); + if (STATE(mode)->internal->purge) + STATE(mode)->internal->purge(); } } else { /* using polling mode */ diff --git a/src/stats-mode.c b/src/stats-mode.c index 5cfb638..0403ce2 100644 --- a/src/stats-mode.c +++ b/src/stats-mode.c @@ -21,6 +21,7 @@ #include "cache.h" #include "log.h" #include "conntrackd.h" +#include "internal.h" #include #include @@ -87,7 +88,7 @@ static int local_handler_stats(int fd, int type, void *data) return ret; } -static void dump_stats(struct nf_conntrack *ct) +static void populate_stats(struct nf_conntrack *ct) { nfct_attr_unset(ct, ATTR_ORIG_COUNTER_BYTES); nfct_attr_unset(ct, ATTR_ORIG_COUNTER_PACKETS); @@ -134,11 +135,9 @@ static int purge_step(void *data1, void *data2) return 0; } -static int purge_stats(void) +static void purge_stats(void) { cache_iterate(STATE_STATS(cache), NULL, purge_step); - - return 0; } static void @@ -188,15 +187,20 @@ event_destroy_stats(struct nf_conntrack *ct, int origin) return 0; } +static struct internal_handler internal_cache_stats = { + .flags = INTERNAL_F_POPULATE | INTERNAL_F_RESYNC, + .populate = populate_stats, + .resync = resync_stats, + .purge = purge_stats, + .new = event_new_stats, + .update = event_update_stats, + .destroy = event_destroy_stats +}; + struct ct_mode stats_mode = { .init = init_stats, .run = NULL, .local = local_handler_stats, .kill = kill_stats, - .dump = dump_stats, - .resync = resync_stats, - .purge = purge_stats, - .event_new = event_new_stats, - .event_upd = event_update_stats, - .event_dst = event_destroy_stats + .internal = &internal_cache_stats, }; diff --git a/src/sync-alarm.c b/src/sync-alarm.c index 4757026..0fc7943 100644 --- a/src/sync-alarm.c +++ b/src/sync-alarm.c @@ -109,7 +109,8 @@ static int alarm_recv(const struct nethdr *net) static void alarm_enqueue(struct cache_object *obj, int query) { - struct cache_alarm *ca = cache_get_extra(STATE_SYNC(internal), obj); + struct cache_alarm *ca = + cache_get_extra(STATE(mode)->internal->data, obj); if (queue_add(STATE_SYNC(tx_queue), &ca->qnode)) cache_object_get(obj); } @@ -134,7 +135,7 @@ static int tx_queue_xmit(struct queue_node *n, const void *data) int type; ca = (struct cache_alarm *)n; - obj = cache_data_get_object(STATE_SYNC(internal), ca); + obj = cache_data_get_object(STATE(mode)->internal->data, ca); type = object_status_to_network_type(obj->status); net = BUILD_NETMSG(obj->ct, type); multichannel_send(STATE_SYNC(channel), net); diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c index 0d31e17..86edeab 100644 --- a/src/sync-ftfw.c +++ b/src/sync-ftfw.c @@ -166,7 +166,8 @@ static void ftfw_kill(void) static int do_cache_to_tx(void *data1, void *data2) { struct cache_object *obj = data2; - struct cache_ftfw *cn = cache_get_extra(STATE_SYNC(internal), obj); + struct cache_ftfw *cn = + cache_get_extra(STATE(mode)->internal->data, obj); if (queue_in(rs_queue, &cn->qnode)) { queue_del(&cn->qnode); @@ -224,7 +225,8 @@ static int ftfw_local(int fd, int type, void *data) break; case SEND_BULK: dlog(LOG_NOTICE, "sending bulk update"); - cache_iterate(STATE_SYNC(internal), NULL, do_cache_to_tx); + cache_iterate(STATE(mode)->internal->data, + NULL, do_cache_to_tx); break; case STATS_RSQUEUE: ftfw_local_queue(fd); @@ -303,7 +305,7 @@ static int rs_queue_empty(struct queue_node *n, const void *data) cn = (struct cache_ftfw *) n; if (h == NULL) { queue_del(n); - obj = cache_data_get_object(STATE_SYNC(internal), cn); + obj = cache_data_get_object(STATE(mode)->internal->data, cn); cache_object_put(obj); return 0; } @@ -314,7 +316,7 @@ static int rs_queue_empty(struct queue_node *n, const void *data) dp("queue: deleting from queue (seq=%u)\n", cn->seq); queue_del(n); - obj = cache_data_get_object(STATE_SYNC(internal), cn); + obj = cache_data_get_object(STATE(mode)->internal->data, cn); cache_object_put(obj); break; } @@ -347,7 +349,7 @@ static int digest_msg(const struct nethdr *net) } else if (IS_RESYNC(net)) { dp("RESYNC ALL\n"); - cache_iterate(STATE_SYNC(internal), NULL, do_cache_to_tx); + cache_iterate(STATE(mode)->internal->data, NULL, do_cache_to_tx); return MSG_CTL; } else if (IS_ALIVE(net)) @@ -464,7 +466,7 @@ static void rs_queue_purge_full(void) struct cache_object *obj; cn = (struct cache_ftfw *)n; - obj = cache_data_get_object(STATE_SYNC(internal), cn); + obj = cache_data_get_object(STATE(mode)->internal->data, cn); cache_object_put(obj); break; } @@ -512,7 +514,7 @@ static int tx_queue_xmit(struct queue_node *n, const void *data) struct nethdr *net; cn = (struct cache_ftfw *)n; - obj = cache_data_get_object(STATE_SYNC(internal), cn); + obj = cache_data_get_object(STATE(mode)->internal->data, cn); type = object_status_to_network_type(obj->status); net = BUILD_NETMSG(obj->ct, type); nethdr_set_hello(net); @@ -546,7 +548,8 @@ static void ftfw_xmit(void) static void ftfw_enqueue(struct cache_object *obj, int type) { - struct cache_ftfw *cn = cache_get_extra(STATE_SYNC(internal), obj); + struct cache_ftfw *cn = + cache_get_extra(STATE(mode)->internal->data, obj); if (queue_in(rs_queue, &cn->qnode)) { queue_del(&cn->qnode); queue_add(STATE_SYNC(tx_queue), &cn->qnode); diff --git a/src/sync-mode.c b/src/sync-mode.c index 63fae68..ecc2f0d 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -28,6 +28,7 @@ #include "queue.h" #include "process.h" #include "origin.h" +#include "internal.h" #include "external.h" #include @@ -246,7 +247,7 @@ static void do_reset_cache_alarm(struct alarm_block *a, void *data) exit(EXIT_SUCCESS); } /* this is not required if events don't get lost */ - cache_flush(STATE_SYNC(internal)); + STATE(mode)->internal->flush(); } static int init_sync(void) @@ -276,15 +277,15 @@ static int init_sync(void) if (STATE_SYNC(sync)->init) STATE_SYNC(sync)->init(); - STATE_SYNC(internal) = - cache_create("internal", - STATE_SYNC(sync)->internal_cache_flags, - STATE_SYNC(sync)->internal_cache_extra); + if (CONFIG(sync).internal_cache_disable == 0) { + STATE(mode)->internal = &internal_cache; + } else { + STATE(mode)->internal = &internal_bypass; + dlog(LOG_NOTICE, "disabling internal cache"); - if (!STATE_SYNC(internal)) { - dlog(LOG_ERR, "can't allocate memory for the internal cache"); - return -1; } + if (STATE(mode)->internal->init() == -1) + return -1; if (CONFIG(sync).external_cache_disable == 0) { STATE_SYNC(external) = &external_cache; @@ -389,7 +390,7 @@ static void run_sync(fd_set *readfds) static void kill_sync(void) { - cache_destroy(STATE_SYNC(internal)); + STATE(mode)->internal->close(); STATE_SYNC(external)->close(); multichannel_close(STATE_SYNC(channel)); @@ -466,7 +467,7 @@ static int local_handler_sync(int fd, int type, void *data) case DUMP_INTERNAL: ret = fork_process_new(CTD_PROC_ANY, 0, NULL, NULL); if (ret == 0) { - cache_dump(STATE_SYNC(internal), fd, NFCT_O_PLAIN); + STATE(mode)->internal->dump(fd, NFCT_O_PLAIN); exit(EXIT_SUCCESS); } break; @@ -480,7 +481,7 @@ static int local_handler_sync(int fd, int type, void *data) case DUMP_INT_XML: ret = fork_process_new(CTD_PROC_ANY, 0, NULL, NULL); if (ret == 0) { - cache_dump(STATE_SYNC(internal), fd, NFCT_O_XML); + STATE(mode)->internal->dump(fd, NFCT_O_XML); exit(EXIT_SUCCESS); } break; @@ -512,14 +513,14 @@ static int local_handler_sync(int fd, int type, void *data) /* 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)); + STATE(mode)->internal->flush(); STATE_SYNC(external)->flush(); break; case FLUSH_INT_CACHE: /* inmediate flush, remove pending flush scheduled if any */ del_alarm(&STATE_SYNC(reset_cache_alarm)); dlog(LOG_NOTICE, "flushing internal cache"); - cache_flush(STATE_SYNC(internal)); + STATE(mode)->internal->flush(); break; case FLUSH_EXT_CACHE: dlog(LOG_NOTICE, "flushing external cache"); @@ -529,7 +530,7 @@ static int local_handler_sync(int fd, int type, void *data) killer(0); break; case STATS: - cache_stats(STATE_SYNC(internal), fd); + STATE(mode)->internal->stats(fd); STATE_SYNC(external)->stats(fd); dump_traffic_stats(fd); multichannel_stats(STATE_SYNC(channel), fd); @@ -540,7 +541,7 @@ static int local_handler_sync(int fd, int type, void *data) multichannel_stats(STATE_SYNC(channel), fd); break; case STATS_CACHE: - cache_stats_extended(STATE_SYNC(internal), fd); + STATE(mode)->internal->stats_ext(fd); STATE_SYNC(external)->stats_ext(fd); break; case STATS_LINK: @@ -559,167 +560,10 @@ static int local_handler_sync(int fd, int type, void *data) return ret; } -static void sync_send(struct cache_object *obj, int query) -{ - STATE_SYNC(sync)->enqueue(obj, query); -} - -static void dump_sync(struct nf_conntrack *ct) -{ - /* This is required by kernels < 2.6.20 */ - nfct_attr_unset(ct, ATTR_ORIG_COUNTER_BYTES); - nfct_attr_unset(ct, ATTR_ORIG_COUNTER_PACKETS); - nfct_attr_unset(ct, ATTR_REPL_COUNTER_BYTES); - nfct_attr_unset(ct, ATTR_REPL_COUNTER_PACKETS); - nfct_attr_unset(ct, ATTR_USE); - - cache_update_force(STATE_SYNC(internal), ct); -} - -static int purge_step(void *data1, void *data2) -{ - struct cache_object *obj = data2; - - STATE(get_retval) = 0; - nl_get_conntrack(STATE(get), obj->ct); /* modifies STATE(get_reval) */ - if (!STATE(get_retval)) { - if (obj->status != C_OBJ_DEAD) { - cache_object_set_status(obj, C_OBJ_DEAD); - sync_send(obj, NET_T_STATE_DEL); - cache_object_put(obj); - } - } - - return 0; -} - -static int purge_sync(void) -{ - cache_iterate(STATE_SYNC(internal), NULL, purge_step); - - return 0; -} - -static int resync_sync(enum nf_conntrack_msg_type type, - struct nf_conntrack *ct, - void *data) -{ - struct cache_object *obj; - - if (ct_filter_conntrack(ct, 1)) - return NFCT_CB_CONTINUE; - - /* This is required by kernels < 2.6.20 */ - nfct_attr_unset(ct, ATTR_ORIG_COUNTER_BYTES); - nfct_attr_unset(ct, ATTR_ORIG_COUNTER_PACKETS); - nfct_attr_unset(ct, ATTR_REPL_COUNTER_BYTES); - nfct_attr_unset(ct, ATTR_REPL_COUNTER_PACKETS); - nfct_attr_unset(ct, ATTR_USE); - - obj = cache_update_force(STATE_SYNC(internal), ct); - if (obj == NULL) - return NFCT_CB_CONTINUE; - - switch (obj->status) { - case C_OBJ_NEW: - sync_send(obj, NET_T_STATE_NEW); - break; - case C_OBJ_ALIVE: - sync_send(obj, NET_T_STATE_UPD); - break; - } - return NFCT_CB_CONTINUE; -} - -static void -event_new_sync(struct nf_conntrack *ct, int origin) -{ - struct cache_object *obj; - int id; - - /* this event has been triggered by a direct inject, skip */ - if (origin == CTD_ORIGIN_INJECT) - return; - - /* required by linux kernel <= 2.6.20 */ - nfct_attr_unset(ct, ATTR_ORIG_COUNTER_BYTES); - nfct_attr_unset(ct, ATTR_ORIG_COUNTER_PACKETS); - nfct_attr_unset(ct, ATTR_REPL_COUNTER_BYTES); - nfct_attr_unset(ct, ATTR_REPL_COUNTER_PACKETS); - - obj = cache_find(STATE_SYNC(internal), ct, &id); - if (obj == NULL) { -retry: - obj = cache_object_new(STATE_SYNC(internal), ct); - if (obj == NULL) - return; - if (cache_add(STATE_SYNC(internal), obj, id) == -1) { - cache_object_free(obj); - return; - } - /* only synchronize events that have been triggered by other - * processes or the kernel, but don't propagate events that - * have been triggered by conntrackd itself, eg. commits. */ - if (origin == CTD_ORIGIN_NOT_ME) - sync_send(obj, NET_T_STATE_NEW); - } else { - cache_del(STATE_SYNC(internal), obj); - cache_object_free(obj); - goto retry; - } -} - -static void -event_update_sync(struct nf_conntrack *ct, int origin) -{ - struct cache_object *obj; - - /* this event has been triggered by a direct inject, skip */ - if (origin == CTD_ORIGIN_INJECT) - return; - - obj = cache_update_force(STATE_SYNC(internal), ct); - if (obj == NULL) - return; - - if (origin == CTD_ORIGIN_NOT_ME) - sync_send(obj, NET_T_STATE_UPD); -} - -static int -event_destroy_sync(struct nf_conntrack *ct, int origin) -{ - struct cache_object *obj; - int id; - - /* this event has been triggered by a direct inject, skip */ - if (origin == CTD_ORIGIN_INJECT) - return 0; - - /* we don't synchronize events for objects that are not in the cache */ - obj = cache_find(STATE_SYNC(internal), ct, &id); - if (obj == NULL) - return 0; - - if (obj->status != C_OBJ_DEAD) { - cache_object_set_status(obj, C_OBJ_DEAD); - if (origin == CTD_ORIGIN_NOT_ME) { - sync_send(obj, NET_T_STATE_DEL); - } - cache_object_put(obj); - } - return 1; -} - struct ct_mode sync_mode = { .init = init_sync, .run = run_sync, .local = local_handler_sync, .kill = kill_sync, - .dump = dump_sync, - .resync = resync_sync, - .purge = purge_sync, - .event_new = event_new_sync, - .event_upd = event_update_sync, - .event_dst = event_destroy_sync + /* the internal handler is set in run-time. */ }; diff --git a/src/sync-notrack.c b/src/sync-notrack.c index d9f273e..c4ad941 100644 --- a/src/sync-notrack.c +++ b/src/sync-notrack.c @@ -74,12 +74,44 @@ static void tx_queue_add_ctlmsg(uint32_t flags, uint32_t from, uint32_t to) static int do_cache_to_tx(void *data1, void *data2) { struct cache_object *obj = data2; - struct cache_notrack *cn = cache_get_extra(STATE_SYNC(internal), obj); + struct cache_notrack *cn = + cache_get_extra(STATE(mode)->internal->data, obj); if (queue_add(STATE_SYNC(tx_queue), &cn->qnode)) cache_object_get(obj); return 0; } +static int kernel_resync_cb(enum nf_conntrack_msg_type type, + struct nf_conntrack *ct, void *data) +{ + struct nethdr *net; + + net = BUILD_NETMSG(ct, NET_T_STATE_NEW); + multichannel_send(STATE_SYNC(channel), net); + + return NFCT_CB_CONTINUE; +} + +/* Only used if the internal cache is disabled. */ +static void kernel_resync(void) +{ + struct nfct_handle *h; + u_int32_t family = AF_UNSPEC; + int ret; + + h = nfct_open(CONNTRACK, 0); + if (h == NULL) { + dlog(LOG_ERR, "can't allocate memory for the internal cache"); + return; + } + nfct_callback_register(h, NFCT_T_ALL, kernel_resync_cb, NULL); + ret = nfct_query(h, NFCT_Q_DUMP, &family); + if (ret == -1) { + dlog(LOG_ERR, "can't dump kernel table"); + } + nfct_close(h); +} + static int notrack_local(int fd, int type, void *data) { int ret = LOCAL_RET_OK; @@ -91,7 +123,12 @@ static int notrack_local(int fd, int type, void *data) break; case SEND_BULK: dlog(LOG_NOTICE, "sending bulk update"); - cache_iterate(STATE_SYNC(internal), NULL, do_cache_to_tx); + if (CONFIG(sync).internal_cache_disable) { + kernel_resync(); + } else { + cache_iterate(STATE(mode)->internal->data, + NULL, do_cache_to_tx); + } break; default: ret = 0; @@ -107,7 +144,12 @@ static int digest_msg(const struct nethdr *net) return MSG_DATA; if (IS_RESYNC(net)) { - cache_iterate(STATE_SYNC(internal), NULL, do_cache_to_tx); + if (CONFIG(sync).internal_cache_disable) { + kernel_resync(); + } else { + cache_iterate(STATE(mode)->internal->data, + NULL, do_cache_to_tx); + } return MSG_CTL; } @@ -154,7 +196,7 @@ static int tx_queue_xmit(struct queue_node *n, const void *data2) struct nethdr *net; cn = (struct cache_ftfw *)n; - obj = cache_data_get_object(STATE_SYNC(internal), cn); + obj = cache_data_get_object(STATE(mode)->internal->data, cn); type = object_status_to_network_type(obj->status);; net = BUILD_NETMSG(obj->ct, type); @@ -175,7 +217,8 @@ static void notrack_xmit(void) static void notrack_enqueue(struct cache_object *obj, int query) { - struct cache_notrack *cn = cache_get_extra(STATE_SYNC(internal), obj); + struct cache_notrack *cn = + cache_get_extra(STATE(mode)->internal->data, obj); if (queue_add(STATE_SYNC(tx_queue), &cn->qnode)) cache_object_get(obj); } -- cgit v1.2.3 From 8da00687d65f06160827e4cd469c330d3a73a9d9 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 4 Jan 2012 14:16:57 +0100 Subject: conntrackd: fix checking of return value of queue_add() Most callers of queue_add() assume that it returns != 0 in case of success. However, it may return -1 in case that the queue gets full. In that case, most callers have to: - release the object that they want to enqueue. - decrement the refcount, in case they have bumped it. However, most of these callers are using the tx_queue which currently has no limit in size at all. This fix is necessary in case that I decide to limit the size of the transmission queue in the future (which makes a lot of sense indeed). Signed-off-by: Pablo Neira Ayuso --- src/sync-alarm.c | 2 +- src/sync-ftfw.c | 10 ++++++---- src/sync-notrack.c | 10 ++++++---- 3 files changed, 13 insertions(+), 9 deletions(-) (limited to 'src/sync-alarm.c') diff --git a/src/sync-alarm.c b/src/sync-alarm.c index 0fc7943..b555dd5 100644 --- a/src/sync-alarm.c +++ b/src/sync-alarm.c @@ -111,7 +111,7 @@ static void alarm_enqueue(struct cache_object *obj, int query) { struct cache_alarm *ca = cache_get_extra(STATE(mode)->internal->data, obj); - if (queue_add(STATE_SYNC(tx_queue), &ca->qnode)) + if (queue_add(STATE_SYNC(tx_queue), &ca->qnode) > 0) cache_object_get(obj); } diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c index 86edeab..581b5ca 100644 --- a/src/sync-ftfw.c +++ b/src/sync-ftfw.c @@ -107,7 +107,8 @@ static void tx_queue_add_ctlmsg(uint32_t flags, uint32_t from, uint32_t to) ack->from = from; ack->to = to; - queue_add(STATE_SYNC(tx_queue), &qobj->qnode); + if (queue_add(STATE_SYNC(tx_queue), &qobj->qnode) < 0) + queue_object_free(qobj); } static void tx_queue_add_ctlmsg2(uint32_t flags) @@ -123,7 +124,8 @@ static void tx_queue_add_ctlmsg2(uint32_t flags) ctl->type = NET_T_CTL; ctl->flags = flags; - queue_add(STATE_SYNC(tx_queue), &qobj->qnode); + if (queue_add(STATE_SYNC(tx_queue), &qobj->qnode) < 0) + queue_object_free(qobj); } /* this function is called from the alarm framework */ @@ -173,7 +175,7 @@ static int do_cache_to_tx(void *data1, void *data2) queue_del(&cn->qnode); queue_add(STATE_SYNC(tx_queue), &cn->qnode); } else { - if (queue_add(STATE_SYNC(tx_queue), &cn->qnode)) + if (queue_add(STATE_SYNC(tx_queue), &cn->qnode) > 0) cache_object_get(obj); } return 0; @@ -554,7 +556,7 @@ static void ftfw_enqueue(struct cache_object *obj, int type) queue_del(&cn->qnode); queue_add(STATE_SYNC(tx_queue), &cn->qnode); } else { - if (queue_add(STATE_SYNC(tx_queue), &cn->qnode)) + if (queue_add(STATE_SYNC(tx_queue), &cn->qnode) > 0) cache_object_get(obj); } } diff --git a/src/sync-notrack.c b/src/sync-notrack.c index c4ad941..06af58b 100644 --- a/src/sync-notrack.c +++ b/src/sync-notrack.c @@ -68,7 +68,8 @@ static void tx_queue_add_ctlmsg(uint32_t flags, uint32_t from, uint32_t to) ack->from = from; ack->to = to; - queue_add(STATE_SYNC(tx_queue), &qobj->qnode); + if (queue_add(STATE_SYNC(tx_queue), &qobj->qnode) < 0) + queue_object_free(qobj); } static int do_cache_to_tx(void *data1, void *data2) @@ -76,7 +77,7 @@ static int do_cache_to_tx(void *data1, void *data2) struct cache_object *obj = data2; struct cache_notrack *cn = cache_get_extra(STATE(mode)->internal->data, obj); - if (queue_add(STATE_SYNC(tx_queue), &cn->qnode)) + if (queue_add(STATE_SYNC(tx_queue), &cn->qnode) > 0) cache_object_get(obj); return 0; } @@ -219,7 +220,7 @@ static void notrack_enqueue(struct cache_object *obj, int query) { struct cache_notrack *cn = cache_get_extra(STATE(mode)->internal->data, obj); - if (queue_add(STATE_SYNC(tx_queue), &cn->qnode)) + if (queue_add(STATE_SYNC(tx_queue), &cn->qnode) > 0) cache_object_get(obj); } @@ -236,7 +237,8 @@ static void tx_queue_add_ctlmsg2(uint32_t flags) ctl->type = NET_T_CTL; ctl->flags = flags; - queue_add(STATE_SYNC(tx_queue), &qobj->qnode); + if (queue_add(STATE_SYNC(tx_queue), &qobj->qnode) < 0) + queue_object_free(qobj); } static void do_alive_alarm(struct alarm_block *a, void *data) -- cgit v1.2.3 From 65be3d49b0f4350a227dedd70ac17c7c9cf6274e Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 4 Jan 2012 14:28:50 +0100 Subject: conntrackd: generalize caching infrastructure This patch generalizes the caching infrastructure to store different object types. This patch is the first in the series to prepare support for the synchronization of expectations. Signed-off-by: Pablo Neira Ayuso --- include/cache.h | 57 +++++++- include/internal.h | 27 ++-- src/Makefile.am | 2 +- src/cache-ct.c | 358 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/cache.c | 154 +++++++++------------- src/cache_iterators.c | 268 ------------------------------------- src/external_cache.c | 4 +- src/internal_bypass.c | 67 +++++----- src/internal_cache.c | 104 ++++++++------- src/run.c | 23 ++-- src/stats-mode.c | 42 +++--- src/sync-alarm.c | 11 +- src/sync-ftfw.c | 23 ++-- src/sync-mode.c | 19 +-- src/sync-notrack.c | 12 +- 15 files changed, 647 insertions(+), 524 deletions(-) create mode 100644 src/cache-ct.c delete mode 100644 src/cache_iterators.c (limited to 'src/sync-alarm.c') diff --git a/include/cache.h b/include/cache.h index ddf2049..a42e395 100644 --- a/include/cache.h +++ b/include/cache.h @@ -27,7 +27,7 @@ enum { struct cache; struct cache_object { struct hashtable_node hashnode; - struct nf_conntrack *ct; + void *ptr; struct cache *cache; int status; int refcnt; @@ -48,14 +48,22 @@ extern struct cache_feature timer_feature; #define CACHE_MAX_NAMELEN 32 +enum cache_type { + CACHE_T_NONE = 0, + CACHE_T_CT, + CACHE_T_MAX +}; + struct cache { char name[CACHE_MAX_NAMELEN]; + enum cache_type type; struct hashtable *h; unsigned int num_features; struct cache_feature **features; unsigned int feature_type[CACHE_MAX_FEATURE]; unsigned int *feature_offset; + struct cache_ops *ops; struct cache_extra *extra; unsigned int extra_offset; size_t object_size; @@ -94,22 +102,48 @@ struct cache_extra { void (*destroy)(struct cache_object *obj, void *data); }; +struct nfct_handle; + +/* cache options depends on the object type: conntrack or expectation. */ +struct cache_ops { + /* hashing and comparison of objects. */ + uint32_t (*hash)(const void *data, const struct hashtable *table); + int (*cmp)(const void *data1, const void *data2); + + /* object allocation, copy and release. */ + void *(*alloc)(void); + void (*copy)(void *dst, void *src, unsigned int flags); + void (*free)(void *ptr); + + /* dump and commit. */ + int (*dump_step)(void *data1, void *n); + int (*commit)(struct cache *c, struct nfct_handle *h, int clientfd); + + /* build network message from object. */ + struct nethdr *(*build_msg)(const struct cache_object *obj, int type); +}; + +/* templates to configure conntrack caching. */ +extern struct cache_ops cache_sync_internal_ct_ops; +extern struct cache_ops cache_sync_external_ct_ops; +extern struct cache_ops cache_stats_ct_ops; + struct nf_conntrack; -struct cache *cache_create(const char *name, unsigned int features, struct cache_extra *extra); +struct cache *cache_create(const char *name, enum cache_type type, unsigned int features, struct cache_extra *extra, struct cache_ops *ops); void cache_destroy(struct cache *e); -struct cache_object *cache_object_new(struct cache *c, struct nf_conntrack *ct); +struct cache_object *cache_object_new(struct cache *c, void *ptr); void cache_object_free(struct cache_object *obj); void cache_object_get(struct cache_object *obj); int cache_object_put(struct cache_object *obj); void cache_object_set_status(struct cache_object *obj, int status); int cache_add(struct cache *c, struct cache_object *obj, int id); -void cache_update(struct cache *c, struct cache_object *obj, int id, struct nf_conntrack *ct); -struct cache_object *cache_update_force(struct cache *c, struct nf_conntrack *ct); +void cache_update(struct cache *c, struct cache_object *obj, int id, void *ptr); +struct cache_object *cache_update_force(struct cache *c, void *ptr); void cache_del(struct cache *c, struct cache_object *obj); -struct cache_object *cache_find(struct cache *c, struct nf_conntrack *ct, int *pos); +struct cache_object *cache_find(struct cache *c, void *ptr, int *pos); void cache_stats(const struct cache *c, int fd); void cache_stats_extended(const struct cache *c, int fd); struct cache_object *cache_data_get_object(struct cache *c, void *data); @@ -120,7 +154,18 @@ void cache_iterate_limit(struct cache *c, void *data, uint32_t from, uint32_t st /* iterators */ struct nfct_handle; +struct __dump_container { + int fd; + int type; +}; + void cache_dump(struct cache *c, int fd, int type); + +struct __commit_container { + struct nfct_handle *h; + struct cache *c; +}; + int cache_commit(struct cache *c, struct nfct_handle *h, int clientfd); void cache_flush(struct cache *c); void cache_bulk(struct cache *c); diff --git a/include/internal.h b/include/internal.h index 1f11340..f50eb79 100644 --- a/include/internal.h +++ b/include/internal.h @@ -12,25 +12,28 @@ enum { }; struct internal_handler { - void *data; unsigned int flags; int (*init)(void); void (*close)(void); - void (*new)(struct nf_conntrack *ct, int origin_type); - void (*update)(struct nf_conntrack *ct, int origin_type); - int (*destroy)(struct nf_conntrack *ct, int origin_type); + struct { + void *data; - void (*dump)(int fd, int type); - void (*populate)(struct nf_conntrack *ct); - void (*purge)(void); - int (*resync)(enum nf_conntrack_msg_type type, - struct nf_conntrack *ct, void *data); - void (*flush)(void); + void (*new)(struct nf_conntrack *ct, int origin_type); + void (*upd)(struct nf_conntrack *ct, int origin_type); + int (*del)(struct nf_conntrack *ct, int origin_type); - void (*stats)(int fd); - void (*stats_ext)(int fd); + void (*dump)(int fd, int type); + void (*populate)(struct nf_conntrack *ct); + void (*purge)(void); + int (*resync)(enum nf_conntrack_msg_type type, + struct nf_conntrack *ct, void *data); + void (*flush)(void); + + void (*stats)(int fd); + void (*stats_ext)(int fd); + } ct; }; extern struct internal_handler internal_cache; diff --git a/src/Makefile.am b/src/Makefile.am index 70e496d..a0abeee 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -12,7 +12,7 @@ conntrack_LDADD = ../extensions/libct_proto_tcp.la ../extensions/libct_proto_udp conntrackd_SOURCES = alarm.c main.c run.c hash.c queue.c rbtree.c \ local.c log.c mcast.c udp.c netlink.c vector.c \ filter.c fds.c event.c process.c origin.c date.c \ - cache.c cache_iterators.c \ + cache.c cache-ct.c \ cache_timer.c \ sync-mode.c sync-alarm.c sync-ftfw.c sync-notrack.c \ traffic_stats.c stats-mode.c \ diff --git a/src/cache-ct.c b/src/cache-ct.c new file mode 100644 index 0000000..2c6fd4e --- /dev/null +++ b/src/cache-ct.c @@ -0,0 +1,358 @@ +/* + * (C) 2006-2011 by Pablo Neira Ayuso + * (C) 2011 by Vyatta Inc. + * + * 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 "cache.h" +#include "hash.h" +#include "log.h" +#include "conntrackd.h" +#include "netlink.h" +#include "event.h" +#include "jhash.h" +#include "network.h" + +#include +#include +#include +#include + +static uint32_t +cache_hash4_ct(const struct nf_conntrack *ct, const struct hashtable *table) +{ + uint32_t a[4] = { + [0] = nfct_get_attr_u32(ct, ATTR_IPV4_SRC), + [1] = nfct_get_attr_u32(ct, ATTR_IPV4_DST), + [2] = nfct_get_attr_u8(ct, ATTR_L3PROTO) << 16 | + nfct_get_attr_u8(ct, ATTR_L4PROTO), + [3] = nfct_get_attr_u16(ct, ATTR_PORT_SRC) << 16 | + nfct_get_attr_u16(ct, ATTR_PORT_DST), + }; + + /* + * Instead of returning hash % table->hashsize (implying a divide) + * we return the high 32 bits of the (hash * table->hashsize) that will + * give results between [0 and hashsize-1] and same hash distribution, + * but using a multiply, less expensive than a divide. See: + * http://www.mail-archive.com/netdev@vger.kernel.org/msg56623.html + */ + return ((uint64_t)jhash2(a, 4, 0) * table->hashsize) >> 32; +} + +static uint32_t +cache_hash6_ct(const struct nf_conntrack *ct, const struct hashtable *table) +{ + uint32_t a[10]; + + memcpy(&a[0], nfct_get_attr(ct, ATTR_IPV6_SRC), sizeof(uint32_t)*4); + memcpy(&a[4], nfct_get_attr(ct, ATTR_IPV6_SRC), sizeof(uint32_t)*4); + a[8] = nfct_get_attr_u8(ct, ATTR_ORIG_L3PROTO) << 16 | + nfct_get_attr_u8(ct, ATTR_ORIG_L4PROTO); + a[9] = nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC) << 16 | + nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST); + + return ((uint64_t)jhash2(a, 10, 0) * table->hashsize) >> 32; +} + +static uint32_t +cache_ct_hash(const void *data, const struct hashtable *table) +{ + int ret = 0; + const struct nf_conntrack *ct = data; + + switch(nfct_get_attr_u8(ct, ATTR_L3PROTO)) { + case AF_INET: + ret = cache_hash4_ct(ct, table); + break; + case AF_INET6: + ret = cache_hash6_ct(ct, table); + break; + default: + dlog(LOG_ERR, "unknown layer 3 proto in hash"); + break; + } + return ret; +} + +static int cache_ct_cmp(const void *data1, const void *data2) +{ + const struct cache_object *obj = data1; + const struct nf_conntrack *ct = data2; + + return nfct_cmp(obj->ptr, ct, NFCT_CMP_ORIG) && + nfct_get_attr_u32(obj->ptr, ATTR_ID) == + nfct_get_attr_u32(ct, ATTR_ID); +} + +static void *cache_ct_alloc(void) +{ + return nfct_new(); +} + +static void cache_ct_free(void *ptr) +{ + nfct_destroy(ptr); +} + +static void cache_ct_copy(void *dst, void *src, unsigned int flags) +{ + nfct_copy(dst, src, flags); +} + +static int cache_ct_dump_step(void *data1, void *n) +{ + char buf[1024]; + int size; + struct __dump_container *container = data1; + struct cache_object *obj = n; + char *data = obj->data; + unsigned i; + + /* + * XXX: Do not dump the entries that are scheduled to expire. + * These entries talk about already destroyed connections + * that we keep for some time just in case that we have to + * resent some lost messages. We do not show them to the + * user as he may think that the firewall replicas are not + * in sync. The branch below is a hack as it is quite + * specific and it breaks conntrackd modularity. Probably + * there's a nicer way to do this but until I come up with it... + */ + if (CONFIG(flags) & CTD_SYNC_FTFW && obj->status == C_OBJ_DEAD) + return 0; + + /* do not show cached timeout, this may confuse users */ + if (nfct_attr_is_set(obj->ptr, ATTR_TIMEOUT)) + nfct_attr_unset(obj->ptr, ATTR_TIMEOUT); + + memset(buf, 0, sizeof(buf)); + size = nfct_snprintf(buf, + sizeof(buf), + obj->ptr, + NFCT_T_UNKNOWN, + container->type, + 0); + + for (i = 0; i < obj->cache->num_features; i++) { + if (obj->cache->features[i]->dump) { + size += obj->cache->features[i]->dump(obj, + data, + buf+size, + container->type); + data += obj->cache->features[i]->size; + } + } + if (container->type != NFCT_O_XML) { + long tm = time(NULL); + size += sprintf(buf+size, " [active since %lds]", + tm - obj->lifetime); + } + size += sprintf(buf+size, "\n"); + if (send(container->fd, buf, size, 0) == -1) { + if (errno != EPIPE) + return -1; + } + + return 0; +} + +static void +cache_ct_commit_step(struct __commit_container *tmp, struct cache_object *obj) +{ + int ret, retry = 1, timeout; + struct nf_conntrack *ct = obj->ptr; + + if (CONFIG(commit_timeout)) { + timeout = CONFIG(commit_timeout); + } else { + timeout = time(NULL) - obj->lastupdate; + if (timeout < 0) { + /* XXX: Arbitrarily set the timer to one minute, how + * can this happen? For example, an adjustment due to + * daylight-saving. Probably other situations can + * trigger this. */ + timeout = 60; + } + /* calculate an estimation of the current timeout */ + timeout = nfct_get_attr_u32(ct, ATTR_TIMEOUT) - timeout; + if (timeout < 0) { + timeout = 60; + } + } + +retry: + if (nl_create_conntrack(tmp->h, ct, timeout) == -1) { + if (errno == EEXIST && retry == 1) { + ret = nl_destroy_conntrack(tmp->h, ct); + if (ret == 0 || (ret == -1 && errno == ENOENT)) { + if (retry) { + retry = 0; + goto retry; + } + } + dlog(LOG_ERR, "commit-destroy: %s", strerror(errno)); + dlog_ct(STATE(log), ct, NFCT_O_PLAIN); + tmp->c->stats.commit_fail++; + } else { + dlog(LOG_ERR, "commit-create: %s", strerror(errno)); + dlog_ct(STATE(log), ct, NFCT_O_PLAIN); + tmp->c->stats.commit_fail++; + } + } else { + tmp->c->stats.commit_ok++; + } +} + +static int cache_ct_commit_related(void *data, void *n) +{ + struct cache_object *obj = n; + + if (ct_is_related(obj->ptr)) + cache_ct_commit_step(data, obj); + + /* keep iterating even if we have found errors */ + return 0; +} + +static int cache_ct_commit_master(void *data, void *n) +{ + struct cache_object *obj = n; + + if (ct_is_related(obj->ptr)) + return 0; + + cache_ct_commit_step(data, obj); + return 0; +} + +static int cache_ct_commit(struct cache *c, struct nfct_handle *h, int clientfd) +{ + unsigned int commit_ok, commit_fail; + struct __commit_container tmp = { + .h = h, + .c = c, + }; + struct timeval commit_stop, res; + + /* we already have one commit in progress, skip this. The clientfd + * descriptor has to be closed by the caller. */ + if (clientfd && STATE_SYNC(commit).clientfd != -1) + return 0; + + switch(STATE_SYNC(commit).state) { + case COMMIT_STATE_INACTIVE: + gettimeofday(&STATE_SYNC(commit).stats.start, NULL); + STATE_SYNC(commit).stats.ok = c->stats.commit_ok; + STATE_SYNC(commit).stats.fail = c->stats.commit_fail; + STATE_SYNC(commit).clientfd = clientfd; + case COMMIT_STATE_MASTER: + STATE_SYNC(commit).current = + hashtable_iterate_limit(c->h, &tmp, + STATE_SYNC(commit).current, + CONFIG(general).commit_steps, + cache_ct_commit_master); + if (STATE_SYNC(commit).current < CONFIG(hashsize)) { + STATE_SYNC(commit).state = COMMIT_STATE_MASTER; + /* give it another step as soon as possible */ + write_evfd(STATE_SYNC(commit).evfd); + return 1; + } + STATE_SYNC(commit).current = 0; + STATE_SYNC(commit).state = COMMIT_STATE_RELATED; + case COMMIT_STATE_RELATED: + STATE_SYNC(commit).current = + hashtable_iterate_limit(c->h, &tmp, + STATE_SYNC(commit).current, + CONFIG(general).commit_steps, + cache_ct_commit_related); + if (STATE_SYNC(commit).current < CONFIG(hashsize)) { + STATE_SYNC(commit).state = COMMIT_STATE_RELATED; + /* give it another step as soon as possible */ + write_evfd(STATE_SYNC(commit).evfd); + return 1; + } + /* calculate the time that commit has taken */ + gettimeofday(&commit_stop, NULL); + timersub(&commit_stop, &STATE_SYNC(commit).stats.start, &res); + + /* calculate new entries committed */ + commit_ok = c->stats.commit_ok - STATE_SYNC(commit).stats.ok; + commit_fail = + c->stats.commit_fail - STATE_SYNC(commit).stats.fail; + + /* log results */ + dlog(LOG_NOTICE, "Committed %u new entries", commit_ok); + + if (commit_fail) + dlog(LOG_NOTICE, "%u entries can't be " + "committed", commit_fail); + + dlog(LOG_NOTICE, "commit has taken %lu.%06lu seconds", + res.tv_sec, res.tv_usec); + + /* prepare the state machine for new commits */ + STATE_SYNC(commit).current = 0; + STATE_SYNC(commit).state = COMMIT_STATE_INACTIVE; + + /* Close the client socket now that we're done. */ + close(STATE_SYNC(commit).clientfd); + STATE_SYNC(commit).clientfd = -1; + } + return 1; +} + +static struct nethdr * +cache_ct_build_msg(const struct cache_object *obj, int type) +{ + return BUILD_NETMSG_FROM_CT(obj->ptr, type); +} + +/* template to cache conntracks coming from the kernel. */ +struct cache_ops cache_sync_internal_ct_ops = { + .hash = cache_ct_hash, + .cmp = cache_ct_cmp, + .alloc = cache_ct_alloc, + .free = cache_ct_free, + .copy = cache_ct_copy, + .dump_step = cache_ct_dump_step, + .commit = NULL, + .build_msg = cache_ct_build_msg, +}; + +/* template to cache conntracks coming from the network. */ +struct cache_ops cache_sync_external_ct_ops = { + .hash = cache_ct_hash, + .cmp = cache_ct_cmp, + .alloc = cache_ct_alloc, + .free = cache_ct_free, + .copy = cache_ct_copy, + .dump_step = cache_ct_dump_step, + .commit = cache_ct_commit, + .build_msg = NULL, +}; + +/* template to cache conntracks for the statistics mode. */ +struct cache_ops cache_stats_ct_ops = { + .hash = cache_ct_hash, + .cmp = cache_ct_cmp, + .alloc = cache_ct_alloc, + .free = cache_ct_free, + .copy = cache_ct_copy, + .dump_step = cache_ct_dump_step, + .commit = NULL, + .build_msg = NULL, +}; diff --git a/src/cache.c b/src/cache.c index f411121..efdab0e 100644 --- a/src/cache.c +++ b/src/cache.c @@ -1,5 +1,6 @@ /* - * (C) 2006-2009 by Pablo Neira Ayuso + * (C) 2006-2011 by Pablo Neira Ayuso + * (C) 2011 by Vyatta Inc. * * 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 @@ -28,80 +29,14 @@ #include #include -static uint32_t -__hash4(const struct nf_conntrack *ct, const struct hashtable *table) -{ - uint32_t a[4] = { - [0] = nfct_get_attr_u32(ct, ATTR_IPV4_SRC), - [1] = nfct_get_attr_u32(ct, ATTR_IPV4_DST), - [2] = nfct_get_attr_u8(ct, ATTR_L3PROTO) << 16 | - nfct_get_attr_u8(ct, ATTR_L4PROTO), - [3] = nfct_get_attr_u16(ct, ATTR_PORT_SRC) << 16 | - nfct_get_attr_u16(ct, ATTR_PORT_DST), - }; - - /* - * Instead of returning hash % table->hashsize (implying a divide) - * we return the high 32 bits of the (hash * table->hashsize) that will - * give results between [0 and hashsize-1] and same hash distribution, - * but using a multiply, less expensive than a divide. See: - * http://www.mail-archive.com/netdev@vger.kernel.org/msg56623.html - */ - return ((uint64_t)jhash2(a, 4, 0) * table->hashsize) >> 32; -} - -static uint32_t -__hash6(const struct nf_conntrack *ct, const struct hashtable *table) -{ - uint32_t a[10]; - - memcpy(&a[0], nfct_get_attr(ct, ATTR_IPV6_SRC), sizeof(uint32_t)*4); - memcpy(&a[4], nfct_get_attr(ct, ATTR_IPV6_SRC), sizeof(uint32_t)*4); - a[8] = nfct_get_attr_u8(ct, ATTR_ORIG_L3PROTO) << 16 | - nfct_get_attr_u8(ct, ATTR_ORIG_L4PROTO); - a[9] = nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC) << 16 | - nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST); - - return ((uint64_t)jhash2(a, 10, 0) * table->hashsize) >> 32; -} - -static uint32_t hash(const void *data, const struct hashtable *table) -{ - int ret = 0; - const struct nf_conntrack *ct = data; - - switch(nfct_get_attr_u8(ct, ATTR_L3PROTO)) { - case AF_INET: - ret = __hash4(ct, table); - break; - case AF_INET6: - ret = __hash6(ct, table); - break; - default: - dlog(LOG_ERR, "unknown layer 3 proto in hash"); - break; - } - - return ret; -} - -static int compare(const void *data1, const void *data2) -{ - const struct cache_object *obj = data1; - const struct nf_conntrack *ct = data2; - - return nfct_cmp(obj->ct, ct, NFCT_CMP_ORIG) && - nfct_get_attr_u32(obj->ct, ATTR_ID) == - nfct_get_attr_u32(ct, ATTR_ID); -} - struct cache_feature *cache_feature[CACHE_MAX_FEATURE] = { [TIMER_FEATURE] = &timer_feature, }; -struct cache *cache_create(const char *name, +struct cache *cache_create(const char *name, enum cache_type type, unsigned int features, - struct cache_extra *extra) + struct cache_extra *extra, + struct cache_ops *ops) { size_t size = sizeof(struct cache_object); int i, j = 0; @@ -110,12 +45,16 @@ struct cache *cache_create(const char *name, unsigned int feature_offset[CACHE_MAX_FEATURE] = {}; unsigned int feature_type[CACHE_MAX_FEATURE] = {}; + if (type == CACHE_T_NONE || type >= CACHE_T_MAX) + return NULL; + c = malloc(sizeof(struct cache)); if (!c) return NULL; memset(c, 0, sizeof(struct cache)); strcpy(c->name, name); + c->type = type; for (i = 0; i < CACHE_MAX_FEATURE; i++) { if ((1 << i) & features) { @@ -150,11 +89,19 @@ struct cache *cache_create(const char *name, } memcpy(c->feature_offset, feature_offset, sizeof(unsigned int) * j); + if (!ops || !ops->hash || !ops->cmp || + !ops->alloc || !ops->copy || !ops->free) { + free(c->feature_offset); + free(c->features); + free(c); + return NULL; + } + c->ops = ops; + c->h = hashtable_create(CONFIG(hashsize), CONFIG(limit), - hash, - compare); - + c->ops->hash, + c->ops->cmp); if (!c->h) { free(c->features); free(c->feature_offset); @@ -175,7 +122,7 @@ void cache_destroy(struct cache *c) free(c); } -struct cache_object *cache_object_new(struct cache *c, struct nf_conntrack *ct) +struct cache_object *cache_object_new(struct cache *c, void *ptr) { struct cache_object *obj; @@ -187,13 +134,14 @@ struct cache_object *cache_object_new(struct cache *c, struct nf_conntrack *ct) } obj->cache = c; - if ((obj->ct = nfct_new()) == NULL) { + obj->ptr = c->ops->alloc(); + if (obj->ptr == NULL) { free(obj); errno = ENOMEM; c->stats.add_fail_enomem++; return NULL; } - nfct_copy(obj->ct, ct, NFCT_CP_OVERRIDE); + c->ops->copy(obj->ptr, ptr, NFCT_CP_OVERRIDE); obj->status = C_OBJ_NONE; c->stats.objects++; @@ -203,7 +151,8 @@ struct cache_object *cache_object_new(struct cache *c, struct nf_conntrack *ct) void cache_object_free(struct cache_object *obj) { obj->cache->stats.objects--; - nfct_destroy(obj->ct); + obj->cache->ops->free(obj->ptr); + free(obj); } @@ -271,13 +220,12 @@ int cache_add(struct cache *c, struct cache_object *obj, int id) return 0; } -void cache_update(struct cache *c, struct cache_object *obj, int id, - struct nf_conntrack *ct) +void cache_update(struct cache *c, struct cache_object *obj, int id, void *ptr) { char *data = obj->data; unsigned int i; - nfct_copy(obj->ct, ct, NFCT_CP_META); + c->ops->copy(obj->ptr, ptr, NFCT_CP_META); for (i = 0; i < c->num_features; i++) { c->features[i]->update(obj, data); @@ -322,23 +270,22 @@ void cache_del(struct cache *c, struct cache_object *obj) __del(c, obj); } -struct cache_object * -cache_update_force(struct cache *c, struct nf_conntrack *ct) +struct cache_object *cache_update_force(struct cache *c, void *ptr) { struct cache_object *obj; int id; - obj = cache_find(c, ct, &id); + obj = cache_find(c, ptr, &id); if (obj) { if (obj->status != C_OBJ_DEAD) { - cache_update(c, obj, id, ct); + cache_update(c, obj, id, ptr); return obj; } else { cache_del(c, obj); cache_object_free(obj); } } - obj = cache_object_new(c, ct); + obj = cache_object_new(c, ptr); if (obj == NULL) return NULL; @@ -350,11 +297,10 @@ cache_update_force(struct cache *c, struct nf_conntrack *ct) return obj; } -struct cache_object * -cache_find(struct cache *c, struct nf_conntrack *ct, int *id) +struct cache_object *cache_find(struct cache *c, void *ptr, int *id) { - *id = hashtable_hash(c->h, ct); - return ((struct cache_object *) hashtable_find(c->h, ct, *id)); + *id = hashtable_hash(c->h, ptr); + return ((struct cache_object *) hashtable_find(c->h, ptr, *id)); } struct cache_object *cache_data_get_object(struct cache *c, void *data) @@ -432,3 +378,33 @@ void cache_iterate_limit(struct cache *c, void *data, { hashtable_iterate_limit(c->h, data, from, steps, iterate); } + +void cache_dump(struct cache *c, int fd, int type) +{ + struct __dump_container tmp = { + .fd = fd, + .type = type + }; + hashtable_iterate(c->h, (void *) &tmp, c->ops->dump_step); +} + +int cache_commit(struct cache *c, struct nfct_handle *h, int clientfd) +{ + return c->ops->commit(c, h, clientfd); +} + +static int do_flush(void *data, void *n) +{ + struct cache *c = data; + struct cache_object *obj = n; + + cache_del(c, obj); + cache_object_free(obj); + return 0; +} + +void cache_flush(struct cache *c) +{ + hashtable_iterate(c->h, c, do_flush); + c->stats.flush++; +} diff --git a/src/cache_iterators.c b/src/cache_iterators.c deleted file mode 100644 index 3248c70..0000000 --- a/src/cache_iterators.c +++ /dev/null @@ -1,268 +0,0 @@ -/* - * (C) 2006-2007 by Pablo Neira Ayuso - * - * 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 "cache.h" -#include "hash.h" -#include "log.h" -#include "conntrackd.h" -#include "netlink.h" -#include "event.h" - -#include -#include -#include -#include -#include - -struct __dump_container { - int fd; - int type; -}; - -static int do_dump(void *data1, void *n) -{ - char buf[1024]; - int size; - struct __dump_container *container = data1; - struct cache_object *obj = n; - char *data = obj->data; - unsigned i; - - /* - * XXX: Do not dump the entries that are scheduled to expire. - * These entries talk about already destroyed connections - * that we keep for some time just in case that we have to - * resent some lost messages. We do not show them to the - * user as he may think that the firewall replicas are not - * in sync. The branch below is a hack as it is quite - * specific and it breaks conntrackd modularity. Probably - * there's a nicer way to do this but until I come up with it... - */ - if (CONFIG(flags) & CTD_SYNC_FTFW && obj->status == C_OBJ_DEAD) - return 0; - - /* do not show cached timeout, this may confuse users */ - if (nfct_attr_is_set(obj->ct, ATTR_TIMEOUT)) - nfct_attr_unset(obj->ct, ATTR_TIMEOUT); - - memset(buf, 0, sizeof(buf)); - size = nfct_snprintf(buf, - sizeof(buf), - obj->ct, - NFCT_T_UNKNOWN, - container->type, - 0); - - for (i = 0; i < obj->cache->num_features; i++) { - if (obj->cache->features[i]->dump) { - size += obj->cache->features[i]->dump(obj, - data, - buf+size, - container->type); - data += obj->cache->features[i]->size; - } - } - if (container->type != NFCT_O_XML) { - long tm = time(NULL); - size += sprintf(buf+size, " [active since %lds]", - tm - obj->lifetime); - } - size += sprintf(buf+size, "\n"); - if (send(container->fd, buf, size, 0) == -1) { - if (errno != EPIPE) - return -1; - } - - return 0; -} - -void cache_dump(struct cache *c, int fd, int type) -{ - struct __dump_container tmp = { - .fd = fd, - .type = type - }; - - hashtable_iterate(c->h, (void *) &tmp, do_dump); -} - -struct __commit_container { - struct nfct_handle *h; - struct cache *c; -}; - -static void -__do_commit_step(struct __commit_container *tmp, struct cache_object *obj) -{ - int ret, retry = 1, timeout; - struct nf_conntrack *ct = obj->ct; - - if (CONFIG(commit_timeout)) { - timeout = CONFIG(commit_timeout); - } else { - timeout = time(NULL) - obj->lastupdate; - if (timeout < 0) { - /* XXX: Arbitrarily set the timer to one minute, how - * can this happen? For example, an adjustment due to - * daylight-saving. Probably other situations can - * trigger this. */ - timeout = 60; - } - /* calculate an estimation of the current timeout */ - timeout = nfct_get_attr_u32(ct, ATTR_TIMEOUT) - timeout; - if (timeout < 0) { - timeout = 60; - } - } - -retry: - if (nl_create_conntrack(tmp->h, ct, timeout) == -1) { - if (errno == EEXIST && retry == 1) { - ret = nl_destroy_conntrack(tmp->h, ct); - if (ret == 0 || (ret == -1 && errno == ENOENT)) { - if (retry) { - retry = 0; - goto retry; - } - } - dlog(LOG_ERR, "commit-destroy: %s", strerror(errno)); - dlog_ct(STATE(log), ct, NFCT_O_PLAIN); - tmp->c->stats.commit_fail++; - } else { - dlog(LOG_ERR, "commit-create: %s", strerror(errno)); - dlog_ct(STATE(log), ct, NFCT_O_PLAIN); - tmp->c->stats.commit_fail++; - } - } else { - tmp->c->stats.commit_ok++; - } -} - -static int do_commit_related(void *data, void *n) -{ - struct cache_object *obj = n; - - if (ct_is_related(obj->ct)) - __do_commit_step(data, obj); - - /* keep iterating even if we have found errors */ - return 0; -} - -static int do_commit_master(void *data, void *n) -{ - struct cache_object *obj = n; - - if (ct_is_related(obj->ct)) - return 0; - - __do_commit_step(data, obj); - return 0; -} - -int cache_commit(struct cache *c, struct nfct_handle *h, int clientfd) -{ - unsigned int commit_ok, commit_fail; - struct __commit_container tmp = { - .h = h, - .c = c, - }; - struct timeval commit_stop, res; - - /* we already have one commit in progress, skip this. The clientfd - * descriptor has to be closed by the caller. */ - if (clientfd && STATE_SYNC(commit).clientfd != -1) - return 0; - - switch(STATE_SYNC(commit).state) { - case COMMIT_STATE_INACTIVE: - gettimeofday(&STATE_SYNC(commit).stats.start, NULL); - STATE_SYNC(commit).stats.ok = c->stats.commit_ok; - STATE_SYNC(commit).stats.fail = c->stats.commit_fail; - STATE_SYNC(commit).clientfd = clientfd; - case COMMIT_STATE_MASTER: - STATE_SYNC(commit).current = - hashtable_iterate_limit(c->h, &tmp, - STATE_SYNC(commit).current, - CONFIG(general).commit_steps, - do_commit_master); - if (STATE_SYNC(commit).current < CONFIG(hashsize)) { - STATE_SYNC(commit).state = COMMIT_STATE_MASTER; - /* give it another step as soon as possible */ - write_evfd(STATE_SYNC(commit).evfd); - return 1; - } - STATE_SYNC(commit).current = 0; - STATE_SYNC(commit).state = COMMIT_STATE_RELATED; - case COMMIT_STATE_RELATED: - STATE_SYNC(commit).current = - hashtable_iterate_limit(c->h, &tmp, - STATE_SYNC(commit).current, - CONFIG(general).commit_steps, - do_commit_related); - if (STATE_SYNC(commit).current < CONFIG(hashsize)) { - STATE_SYNC(commit).state = COMMIT_STATE_RELATED; - /* give it another step as soon as possible */ - write_evfd(STATE_SYNC(commit).evfd); - return 1; - } - /* calculate the time that commit has taken */ - gettimeofday(&commit_stop, NULL); - timersub(&commit_stop, &STATE_SYNC(commit).stats.start, &res); - - /* calculate new entries committed */ - commit_ok = c->stats.commit_ok - STATE_SYNC(commit).stats.ok; - commit_fail = - c->stats.commit_fail - STATE_SYNC(commit).stats.fail; - - /* log results */ - dlog(LOG_NOTICE, "Committed %u new entries", commit_ok); - - if (commit_fail) - dlog(LOG_NOTICE, "%u entries can't be " - "committed", commit_fail); - - dlog(LOG_NOTICE, "commit has taken %lu.%06lu seconds", - res.tv_sec, res.tv_usec); - - /* prepare the state machine for new commits */ - STATE_SYNC(commit).current = 0; - STATE_SYNC(commit).state = COMMIT_STATE_INACTIVE; - - /* Close the client socket now that we're done. */ - close(STATE_SYNC(commit).clientfd); - STATE_SYNC(commit).clientfd = -1; - } - return 1; -} - -static int do_flush(void *data, void *n) -{ - struct cache *c = data; - struct cache_object *obj = n; - - cache_del(c, obj); - cache_object_free(obj); - return 0; -} - -void cache_flush(struct cache *c) -{ - hashtable_iterate(c->h, c, do_flush); - c->stats.flush++; -} diff --git a/src/external_cache.c b/src/external_cache.c index 59c706a..073f309 100644 --- a/src/external_cache.c +++ b/src/external_cache.c @@ -28,9 +28,9 @@ static struct cache *external; static int external_cache_init(void) { - external = cache_create("external", + external = cache_create("external", CACHE_T_CT, STATE_SYNC(sync)->external_cache_flags, - NULL); + NULL, &cache_sync_external_ct_ops); if (external == NULL) { dlog(LOG_ERR, "can't allocate memory for the external cache"); return -1; diff --git a/src/internal_bypass.c b/src/internal_bypass.c index 1e1478f..8ecec34 100644 --- a/src/internal_bypass.c +++ b/src/internal_bypass.c @@ -1,6 +1,7 @@ /* - * (C) 2009 by Pablo Neira Ayuso - * + * (C) 2006-2011 by Pablo Neira Ayuso + * (C) 2011 by Vyatta Inc. + * * 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 @@ -16,17 +17,18 @@ #include "network.h" #include "origin.h" -static int _init(void) +static int internal_bypass_init(void) { return 0; } -static void _close(void) +static void internal_bypass_close(void) { } -static int dump_cb(enum nf_conntrack_msg_type type, - struct nf_conntrack *ct, void *data) +static int +internal_bypass_ct_dump_cb(enum nf_conntrack_msg_type type, + struct nf_conntrack *ct, void *data) { char buf[1024]; int size, *fd = data; @@ -44,7 +46,7 @@ static int dump_cb(enum nf_conntrack_msg_type type, return NFCT_CB_CONTINUE; } -static void dump(int fd, int type) +static void internal_bypass_ct_dump(int fd, int type) { struct nfct_handle *h; u_int32_t family = AF_UNSPEC; @@ -55,7 +57,7 @@ static void dump(int fd, int type) dlog(LOG_ERR, "can't allocate memory for the internal cache"); return; } - nfct_callback_register(h, NFCT_T_ALL, dump_cb, &fd); + nfct_callback_register(h, NFCT_T_ALL, internal_bypass_ct_dump_cb, &fd); ret = nfct_query(h, NFCT_Q_DUMP, &family); if (ret == -1) { dlog(LOG_ERR, "can't dump kernel table"); @@ -63,7 +65,7 @@ static void dump(int fd, int type) nfct_close(h); } -static void flush(void) +static void internal_bypass_ct_flush(void) { nl_flush_conntrack_table(STATE(flush)); } @@ -74,7 +76,7 @@ struct { uint32_t del; } internal_bypass_stats; -static void stats(int fd) +static void internal_bypass_ct_stats(int fd) { char buf[512]; int size; @@ -91,25 +93,24 @@ static void stats(int fd) } /* unused, INTERNAL_F_POPULATE is unset. No cache, nothing to populate. */ -static void populate(struct nf_conntrack *ct) +static void internal_bypass_ct_populate(struct nf_conntrack *ct) { } /* unused, INTERNAL_F_RESYNC is unset. */ -static void purge(void) +static void internal_bypass_ct_purge(void) { } /* unused, INTERNAL_F_RESYNC is unset. Nothing to resync, we have no cache. */ -static int resync(enum nf_conntrack_msg_type type, - struct nf_conntrack *ct, - void *data) +static int +internal_bypass_ct_resync(enum nf_conntrack_msg_type type, + struct nf_conntrack *ct, void *data) { return NFCT_CB_CONTINUE; } -static void -event_new_sync(struct nf_conntrack *ct, int origin) +static void internal_bypass_ct_event_new(struct nf_conntrack *ct, int origin) { struct nethdr *net; @@ -122,8 +123,7 @@ event_new_sync(struct nf_conntrack *ct, int origin) internal_bypass_stats.new++; } -static void -event_update_sync(struct nf_conntrack *ct, int origin) +static void internal_bypass_ct_event_upd(struct nf_conntrack *ct, int origin) { struct nethdr *net; @@ -136,8 +136,7 @@ event_update_sync(struct nf_conntrack *ct, int origin) internal_bypass_stats.upd++; } -static int -event_destroy_sync(struct nf_conntrack *ct, int origin) +static int internal_bypass_ct_event_del(struct nf_conntrack *ct, int origin) { struct nethdr *net; @@ -153,16 +152,18 @@ event_destroy_sync(struct nf_conntrack *ct, int origin) } struct internal_handler internal_bypass = { - .init = _init, - .close = _close, - .dump = dump, - .flush = flush, - .stats = stats, - .stats_ext = stats, - .populate = populate, - .purge = purge, - .resync = resync, - .new = event_new_sync, - .update = event_update_sync, - .destroy = event_destroy_sync, + .init = internal_bypass_init, + .close = internal_bypass_close, + .ct = { + .dump = internal_bypass_ct_dump, + .flush = internal_bypass_ct_flush, + .stats = internal_bypass_ct_stats, + .stats_ext = internal_bypass_ct_stats, + .populate = internal_bypass_ct_populate, + .purge = internal_bypass_ct_purge, + .resync = internal_bypass_ct_resync, + .new = internal_bypass_ct_event_new, + .upd = internal_bypass_ct_event_upd, + .del = internal_bypass_ct_event_del, + }, }; diff --git a/src/internal_cache.c b/src/internal_cache.c index e50e1db..7a698e6 100644 --- a/src/internal_cache.c +++ b/src/internal_cache.c @@ -1,6 +1,7 @@ /* - * (C) 2009 by Pablo Neira Ayuso - * + * (C) 2006-2011 by Pablo Neira Ayuso + * (C) 2011 by Vyatta Inc. + * * 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 @@ -19,46 +20,47 @@ static inline void sync_send(struct cache_object *obj, int query) STATE_SYNC(sync)->enqueue(obj, query); } -static int _init(void) +static int internal_cache_init(void) { - STATE(mode)->internal->data = - cache_create("internal", + STATE(mode)->internal->ct.data = + cache_create("internal", CACHE_T_CT, STATE_SYNC(sync)->internal_cache_flags, - STATE_SYNC(sync)->internal_cache_extra); + STATE_SYNC(sync)->internal_cache_extra, + &cache_sync_internal_ct_ops); - if (!STATE(mode)->internal->data) { + if (!STATE(mode)->internal->ct.data) { dlog(LOG_ERR, "can't allocate memory for the internal cache"); return -1; } return 0; } -static void _close(void) +static void internal_cache_close(void) { - cache_destroy(STATE(mode)->internal->data); + cache_destroy(STATE(mode)->internal->ct.data); } -static void dump(int fd, int type) +static void internal_cache_ct_dump(int fd, int type) { - cache_dump(STATE(mode)->internal->data, fd, type); + cache_dump(STATE(mode)->internal->ct.data, fd, type); } -static void flush(void) +static void internal_cache_ct_flush(void) { - cache_flush(STATE(mode)->internal->data); + cache_flush(STATE(mode)->internal->ct.data); } -static void stats(int fd) +static void internal_cache_ct_stats(int fd) { - cache_stats(STATE(mode)->internal->data, fd); + cache_stats(STATE(mode)->internal->ct.data, fd); } -static void stats_ext(int fd) +static void internal_cache_ct_stats_ext(int fd) { - cache_stats_extended(STATE(mode)->internal->data, fd); + cache_stats_extended(STATE(mode)->internal->ct.data, fd); } -static void populate(struct nf_conntrack *ct) +static void internal_cache_ct_populate(struct nf_conntrack *ct) { /* This is required by kernels < 2.6.20 */ nfct_attr_unset(ct, ATTR_ORIG_COUNTER_BYTES); @@ -67,15 +69,15 @@ static void populate(struct nf_conntrack *ct) nfct_attr_unset(ct, ATTR_REPL_COUNTER_PACKETS); nfct_attr_unset(ct, ATTR_USE); - cache_update_force(STATE(mode)->internal->data, ct); + cache_update_force(STATE(mode)->internal->ct.data, ct); } -static int purge_step(void *data1, void *data2) +static int internal_cache_ct_purge_step(void *data1, void *data2) { struct cache_object *obj = data2; STATE(get_retval) = 0; - nl_get_conntrack(STATE(get), obj->ct); /* modifies STATE(get_reval) */ + nl_get_conntrack(STATE(get), obj->ptr); /* modifies STATE(get_reval) */ if (!STATE(get_retval)) { if (obj->status != C_OBJ_DEAD) { cache_object_set_status(obj, C_OBJ_DEAD); @@ -87,14 +89,15 @@ static int purge_step(void *data1, void *data2) return 0; } -static void purge(void) +static void internal_cache_ct_purge(void) { - cache_iterate(STATE(mode)->internal->data, NULL, purge_step); + cache_iterate(STATE(mode)->internal->ct.data, NULL, + internal_cache_ct_purge_step); } -static int resync(enum nf_conntrack_msg_type type, - struct nf_conntrack *ct, - void *data) +static int +internal_cache_ct_resync(enum nf_conntrack_msg_type type, + struct nf_conntrack *ct, void *data) { struct cache_object *obj; @@ -108,7 +111,7 @@ static int resync(enum nf_conntrack_msg_type type, nfct_attr_unset(ct, ATTR_REPL_COUNTER_PACKETS); nfct_attr_unset(ct, ATTR_USE); - obj = cache_update_force(STATE(mode)->internal->data, ct); + obj = cache_update_force(STATE(mode)->internal->ct.data, ct); if (obj == NULL) return NFCT_CB_CONTINUE; @@ -123,8 +126,7 @@ static int resync(enum nf_conntrack_msg_type type, return NFCT_CB_CONTINUE; } -static void -event_new_sync(struct nf_conntrack *ct, int origin) +static void internal_cache_ct_event_new(struct nf_conntrack *ct, int origin) { struct cache_object *obj; int id; @@ -139,13 +141,13 @@ event_new_sync(struct nf_conntrack *ct, int origin) nfct_attr_unset(ct, ATTR_REPL_COUNTER_BYTES); nfct_attr_unset(ct, ATTR_REPL_COUNTER_PACKETS); - obj = cache_find(STATE(mode)->internal->data, ct, &id); + obj = cache_find(STATE(mode)->internal->ct.data, ct, &id); if (obj == NULL) { retry: - obj = cache_object_new(STATE(mode)->internal->data, ct); + obj = cache_object_new(STATE(mode)->internal->ct.data, ct); if (obj == NULL) return; - if (cache_add(STATE(mode)->internal->data, obj, id) == -1) { + if (cache_add(STATE(mode)->internal->ct.data, obj, id) == -1) { cache_object_free(obj); return; } @@ -155,14 +157,13 @@ retry: if (origin == CTD_ORIGIN_NOT_ME) sync_send(obj, NET_T_STATE_NEW); } else { - cache_del(STATE(mode)->internal->data, obj); + cache_del(STATE(mode)->internal->ct.data, obj); cache_object_free(obj); goto retry; } } -static void -event_update_sync(struct nf_conntrack *ct, int origin) +static void internal_cache_ct_event_upd(struct nf_conntrack *ct, int origin) { struct cache_object *obj; @@ -170,7 +171,7 @@ event_update_sync(struct nf_conntrack *ct, int origin) if (origin == CTD_ORIGIN_INJECT) return; - obj = cache_update_force(STATE(mode)->internal->data, ct); + obj = cache_update_force(STATE(mode)->internal->ct.data, ct); if (obj == NULL) return; @@ -178,8 +179,7 @@ event_update_sync(struct nf_conntrack *ct, int origin) sync_send(obj, NET_T_STATE_UPD); } -static int -event_destroy_sync(struct nf_conntrack *ct, int origin) +static int internal_cache_ct_event_del(struct nf_conntrack *ct, int origin) { struct cache_object *obj; int id; @@ -189,7 +189,7 @@ event_destroy_sync(struct nf_conntrack *ct, int origin) return 0; /* we don't synchronize events for objects that are not in the cache */ - obj = cache_find(STATE(mode)->internal->data, ct, &id); + obj = cache_find(STATE(mode)->internal->ct.data, ct, &id); if (obj == NULL) return 0; @@ -205,16 +205,18 @@ event_destroy_sync(struct nf_conntrack *ct, int origin) struct internal_handler internal_cache = { .flags = INTERNAL_F_POPULATE | INTERNAL_F_RESYNC, - .init = _init, - .close = _close, - .dump = dump, - .flush = flush, - .stats = stats, - .stats_ext = stats_ext, - .populate = populate, - .purge = purge, - .resync = resync, - .new = event_new_sync, - .update = event_update_sync, - .destroy = event_destroy_sync, + .init = internal_cache_init, + .close = internal_cache_close, + .ct = { + .dump = internal_cache_ct_dump, + .flush = internal_cache_ct_flush, + .stats = internal_cache_ct_stats, + .stats_ext = internal_cache_ct_stats_ext, + .populate = internal_cache_ct_populate, + .purge = internal_cache_ct_purge, + .resync = internal_cache_ct_resync, + .new = internal_cache_ct_event_new, + .upd = internal_cache_ct_event_upd, + .del = internal_cache_ct_event_del, + }, }; diff --git a/src/run.c b/src/run.c index 265a949..f8d3fad 100644 --- a/src/run.c +++ b/src/run.c @@ -1,6 +1,7 @@ /* - * (C) 2006-2009 by Pablo Neira Ayuso - * + * (C) 2006-2011 by Pablo Neira Ayuso + * (C) 2011 by Vyatta Inc. + * * 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 @@ -241,8 +242,8 @@ static void do_overrun_resync_alarm(struct alarm_block *a, void *data) static void do_polling_alarm(struct alarm_block *a, void *data) { - if (STATE(mode)->internal->purge) - STATE(mode)->internal->purge(); + if (STATE(mode)->internal->ct.purge) + STATE(mode)->internal->ct.purge(); nl_send_resync(STATE(resync)); add_alarm(&STATE(polling_alarm), CONFIG(poll_kernel_secs), 0); @@ -267,13 +268,13 @@ static int event_handler(const struct nlmsghdr *nlh, switch(type) { case NFCT_T_NEW: - STATE(mode)->internal->new(ct, origin_type); + STATE(mode)->internal->ct.new(ct, origin_type); break; case NFCT_T_UPDATE: - STATE(mode)->internal->update(ct, origin_type); + STATE(mode)->internal->ct.upd(ct, origin_type); break; case NFCT_T_DESTROY: - if (STATE(mode)->internal->destroy(ct, origin_type)) + if (STATE(mode)->internal->ct.del(ct, origin_type)) update_traffic_stats(ct); break; default: @@ -298,7 +299,7 @@ static int dump_handler(enum nf_conntrack_msg_type type, switch(type) { case NFCT_T_UPDATE: - STATE(mode)->internal->populate(ct); + STATE(mode)->internal->ct.populate(ct); break; default: STATE(stats).nl_dump_unknown_type++; @@ -363,7 +364,7 @@ init(void) } nfct_callback_register(STATE(resync), NFCT_T_ALL, - STATE(mode)->internal->resync, + STATE(mode)->internal->ct.resync, NULL); register_fd(nfct_fd(STATE(resync)), STATE(fds)); fcntl(nfct_fd(STATE(resync)), F_SETFL, O_NONBLOCK); @@ -537,8 +538,8 @@ static void run_events(struct timeval *next_alarm) /* we previously requested a resync due to buffer overrun. */ if (FD_ISSET(nfct_fd(STATE(resync)), &readfds)) { nfct_catch(STATE(resync)); - if (STATE(mode)->internal->purge) - STATE(mode)->internal->purge(); + if (STATE(mode)->internal->ct.purge) + STATE(mode)->internal->ct.purge(); } if (STATE(mode)->run) diff --git a/src/stats-mode.c b/src/stats-mode.c index 0403ce2..c7a81e3 100644 --- a/src/stats-mode.c +++ b/src/stats-mode.c @@ -1,6 +1,7 @@ /* - * (C) 2006-2007 by Pablo Neira Ayuso - * + * (C) 2006-2011 by Pablo Neira Ayuso + * (C) 2011 by Vyatta Inc. + * * 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 @@ -37,7 +38,9 @@ static int init_stats(void) } memset(state.stats, 0, sizeof(struct ct_stats_state)); - STATE_STATS(cache) = cache_create("stats", NO_FEATURES, NULL); + STATE_STATS(cache) = cache_create("stats", CACHE_T_CT, + NO_FEATURES, NULL, + &cache_stats_ct_ops); if (!STATE_STATS(cache)) { dlog(LOG_ERR, "can't allocate memory for the " "external cache"); @@ -88,7 +91,7 @@ static int local_handler_stats(int fd, int type, void *data) return ret; } -static void populate_stats(struct nf_conntrack *ct) +static void stats_populate(struct nf_conntrack *ct) { nfct_attr_unset(ct, ATTR_ORIG_COUNTER_BYTES); nfct_attr_unset(ct, ATTR_ORIG_COUNTER_PACKETS); @@ -100,7 +103,7 @@ static void populate_stats(struct nf_conntrack *ct) cache_update_force(STATE_STATS(cache), ct); } -static int resync_stats(enum nf_conntrack_msg_type type, +static int stats_resync(enum nf_conntrack_msg_type type, struct nf_conntrack *ct, void *data) { @@ -125,23 +128,22 @@ static int purge_step(void *data1, void *data2) struct cache_object *obj = data2; STATE(get_retval) = 0; - nl_get_conntrack(STATE(get), obj->ct); /* modifies STATE(get_retval) */ + nl_get_conntrack(STATE(get), obj->ptr); /* modifies STATE(get_retval) */ if (!STATE(get_retval)) { cache_del(STATE_STATS(cache), obj); - dlog_ct(STATE(stats_log), obj->ct, NFCT_O_PLAIN); + dlog_ct(STATE(stats_log), obj->ptr, NFCT_O_PLAIN); cache_object_free(obj); } return 0; } -static void purge_stats(void) +static void stats_purge(void) { cache_iterate(STATE_STATS(cache), NULL, purge_step); } -static void -event_new_stats(struct nf_conntrack *ct, int origin) +static void stats_event_new(struct nf_conntrack *ct, int origin) { int id; struct cache_object *obj; @@ -162,15 +164,13 @@ event_new_stats(struct nf_conntrack *ct, int origin) return; } -static void -event_update_stats(struct nf_conntrack *ct, int origin) +static void stats_event_upd(struct nf_conntrack *ct, int origin) { nfct_attr_unset(ct, ATTR_TIMEOUT); cache_update_force(STATE_STATS(cache), ct); } -static int -event_destroy_stats(struct nf_conntrack *ct, int origin) +static int stats_event_del(struct nf_conntrack *ct, int origin) { int id; struct cache_object *obj; @@ -189,12 +189,14 @@ event_destroy_stats(struct nf_conntrack *ct, int origin) static struct internal_handler internal_cache_stats = { .flags = INTERNAL_F_POPULATE | INTERNAL_F_RESYNC, - .populate = populate_stats, - .resync = resync_stats, - .purge = purge_stats, - .new = event_new_stats, - .update = event_update_stats, - .destroy = event_destroy_stats + .ct = { + .populate = stats_populate, + .resync = stats_resync, + .purge = stats_purge, + .new = stats_event_new, + .upd = stats_event_upd, + .del = stats_event_del, + }, }; struct ct_mode stats_mode = { diff --git a/src/sync-alarm.c b/src/sync-alarm.c index b555dd5..8d6b34d 100644 --- a/src/sync-alarm.c +++ b/src/sync-alarm.c @@ -1,6 +1,7 @@ /* - * (C) 2006-2007 by Pablo Neira Ayuso - * + * (C) 2006-2011 by Pablo Neira Ayuso + * (C) 2011 by Vyatta Inc. + * * 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 @@ -110,7 +111,7 @@ static int alarm_recv(const struct nethdr *net) static void alarm_enqueue(struct cache_object *obj, int query) { struct cache_alarm *ca = - cache_get_extra(STATE(mode)->internal->data, obj); + cache_get_extra(STATE(mode)->internal->ct.data, obj); if (queue_add(STATE_SYNC(tx_queue), &ca->qnode) > 0) cache_object_get(obj); } @@ -135,9 +136,9 @@ static int tx_queue_xmit(struct queue_node *n, const void *data) int type; ca = (struct cache_alarm *)n; - obj = cache_data_get_object(STATE(mode)->internal->data, ca); + obj = cache_data_get_object(STATE(mode)->internal->ct.data, ca); type = object_status_to_network_type(obj->status); - net = BUILD_NETMSG(obj->ct, type); + net = obj->cache->ops->build_msg(obj, type); multichannel_send(STATE_SYNC(channel), net); cache_object_put(obj); break; diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c index 581b5ca..55eda0b 100644 --- a/src/sync-ftfw.c +++ b/src/sync-ftfw.c @@ -1,6 +1,7 @@ /* - * (C) 2006-2008 by Pablo Neira Ayuso - * + * (C) 2006-2011 by Pablo Neira Ayuso + * (C) 2011 by Vyatta Inc. + * * 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 @@ -169,7 +170,7 @@ static int do_cache_to_tx(void *data1, void *data2) { struct cache_object *obj = data2; struct cache_ftfw *cn = - cache_get_extra(STATE(mode)->internal->data, obj); + cache_get_extra(STATE(mode)->internal->ct.data, obj); if (queue_in(rs_queue, &cn->qnode)) { queue_del(&cn->qnode); @@ -227,7 +228,7 @@ static int ftfw_local(int fd, int type, void *data) break; case SEND_BULK: dlog(LOG_NOTICE, "sending bulk update"); - cache_iterate(STATE(mode)->internal->data, + cache_iterate(STATE(mode)->internal->ct.data, NULL, do_cache_to_tx); break; case STATS_RSQUEUE: @@ -307,7 +308,7 @@ static int rs_queue_empty(struct queue_node *n, const void *data) cn = (struct cache_ftfw *) n; if (h == NULL) { queue_del(n); - obj = cache_data_get_object(STATE(mode)->internal->data, cn); + obj = cache_data_get_object(STATE(mode)->internal->ct.data, cn); cache_object_put(obj); return 0; } @@ -318,7 +319,7 @@ static int rs_queue_empty(struct queue_node *n, const void *data) dp("queue: deleting from queue (seq=%u)\n", cn->seq); queue_del(n); - obj = cache_data_get_object(STATE(mode)->internal->data, cn); + obj = cache_data_get_object(STATE(mode)->internal->ct.data, cn); cache_object_put(obj); break; } @@ -351,7 +352,7 @@ static int digest_msg(const struct nethdr *net) } else if (IS_RESYNC(net)) { dp("RESYNC ALL\n"); - cache_iterate(STATE(mode)->internal->data, NULL, do_cache_to_tx); + cache_iterate(STATE(mode)->internal->ct.data, NULL, do_cache_to_tx); return MSG_CTL; } else if (IS_ALIVE(net)) @@ -468,7 +469,7 @@ static void rs_queue_purge_full(void) struct cache_object *obj; cn = (struct cache_ftfw *)n; - obj = cache_data_get_object(STATE(mode)->internal->data, cn); + obj = cache_data_get_object(STATE(mode)->internal->ct.data, cn); cache_object_put(obj); break; } @@ -516,9 +517,9 @@ static int tx_queue_xmit(struct queue_node *n, const void *data) struct nethdr *net; cn = (struct cache_ftfw *)n; - obj = cache_data_get_object(STATE(mode)->internal->data, cn); + obj = cache_data_get_object(STATE(mode)->internal->ct.data, cn); type = object_status_to_network_type(obj->status); - net = BUILD_NETMSG(obj->ct, type); + net = obj->cache->ops->build_msg(obj, type); nethdr_set_hello(net); dp("tx_list sq: %u fl:%u len:%u\n", @@ -551,7 +552,7 @@ static void ftfw_xmit(void) static void ftfw_enqueue(struct cache_object *obj, int type) { struct cache_ftfw *cn = - cache_get_extra(STATE(mode)->internal->data, obj); + cache_get_extra(STATE(mode)->internal->ct.data, obj); if (queue_in(rs_queue, &cn->qnode)) { queue_del(&cn->qnode); queue_add(STATE_SYNC(tx_queue), &cn->qnode); diff --git a/src/sync-mode.c b/src/sync-mode.c index 5351110..34d9706 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -1,6 +1,7 @@ /* - * (C) 2006-2007 by Pablo Neira Ayuso - * + * (C) 2006-2011 by Pablo Neira Ayuso + * (C) 2011 by Vyatta Inc. + * * 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 @@ -251,7 +252,7 @@ static void do_reset_cache_alarm(struct alarm_block *a, void *data) exit(EXIT_SUCCESS); } /* this is not required if events don't get lost */ - STATE(mode)->internal->flush(); + STATE(mode)->internal->ct.flush(); } static int init_sync(void) @@ -471,7 +472,7 @@ static int local_handler_sync(int fd, int type, void *data) switch(type) { case DUMP_INTERNAL: if (fork_process_new(CTD_PROC_ANY, 0, NULL, NULL) == 0) { - STATE(mode)->internal->dump(fd, NFCT_O_PLAIN); + STATE(mode)->internal->ct.dump(fd, NFCT_O_PLAIN); exit(EXIT_SUCCESS); } break; @@ -483,7 +484,7 @@ static int local_handler_sync(int fd, int type, void *data) break; case DUMP_INT_XML: if (fork_process_new(CTD_PROC_ANY, 0, NULL, NULL) == 0) { - STATE(mode)->internal->dump(fd, NFCT_O_XML); + STATE(mode)->internal->ct.dump(fd, NFCT_O_XML); exit(EXIT_SUCCESS); } break; @@ -512,14 +513,14 @@ static int local_handler_sync(int fd, int type, void *data) /* inmediate flush, remove pending flush scheduled if any */ del_alarm(&STATE_SYNC(reset_cache_alarm)); dlog(LOG_NOTICE, "flushing caches"); - STATE(mode)->internal->flush(); + STATE(mode)->internal->ct.flush(); STATE_SYNC(external)->flush(); break; case FLUSH_INT_CACHE: /* inmediate flush, remove pending flush scheduled if any */ del_alarm(&STATE_SYNC(reset_cache_alarm)); dlog(LOG_NOTICE, "flushing internal cache"); - STATE(mode)->internal->flush(); + STATE(mode)->internal->ct.flush(); break; case FLUSH_EXT_CACHE: dlog(LOG_NOTICE, "flushing external cache"); @@ -529,7 +530,7 @@ static int local_handler_sync(int fd, int type, void *data) killer(0); break; case STATS: - STATE(mode)->internal->stats(fd); + STATE(mode)->internal->ct.stats(fd); STATE_SYNC(external)->stats(fd); dump_traffic_stats(fd); multichannel_stats(STATE_SYNC(channel), fd); @@ -540,7 +541,7 @@ static int local_handler_sync(int fd, int type, void *data) multichannel_stats(STATE_SYNC(channel), fd); break; case STATS_CACHE: - STATE(mode)->internal->stats_ext(fd); + STATE(mode)->internal->ct.stats_ext(fd); STATE_SYNC(external)->stats_ext(fd); break; case STATS_LINK: diff --git a/src/sync-notrack.c b/src/sync-notrack.c index 06af58b..e25cfd8 100644 --- a/src/sync-notrack.c +++ b/src/sync-notrack.c @@ -76,7 +76,7 @@ static int do_cache_to_tx(void *data1, void *data2) { struct cache_object *obj = data2; struct cache_notrack *cn = - cache_get_extra(STATE(mode)->internal->data, obj); + cache_get_extra(STATE(mode)->internal->ct.data, obj); if (queue_add(STATE_SYNC(tx_queue), &cn->qnode) > 0) cache_object_get(obj); return 0; @@ -127,7 +127,7 @@ static int notrack_local(int fd, int type, void *data) if (CONFIG(sync).internal_cache_disable) { kernel_resync(); } else { - cache_iterate(STATE(mode)->internal->data, + cache_iterate(STATE(mode)->internal->ct.data, NULL, do_cache_to_tx); } break; @@ -148,7 +148,7 @@ static int digest_msg(const struct nethdr *net) if (CONFIG(sync).internal_cache_disable) { kernel_resync(); } else { - cache_iterate(STATE(mode)->internal->data, + cache_iterate(STATE(mode)->internal->ct.data, NULL, do_cache_to_tx); } return MSG_CTL; @@ -197,9 +197,9 @@ static int tx_queue_xmit(struct queue_node *n, const void *data2) struct nethdr *net; cn = (struct cache_ftfw *)n; - obj = cache_data_get_object(STATE(mode)->internal->data, cn); + obj = cache_data_get_object(STATE(mode)->internal->ct.data, cn); type = object_status_to_network_type(obj->status);; - net = BUILD_NETMSG(obj->ct, type); + net = obj->cache->ops->build_msg(obj, type); multichannel_send(STATE_SYNC(channel), net); queue_del(n); @@ -219,7 +219,7 @@ static void notrack_xmit(void) static void notrack_enqueue(struct cache_object *obj, int query) { struct cache_notrack *cn = - cache_get_extra(STATE(mode)->internal->data, obj); + cache_get_extra(STATE(mode)->internal->ct.data, obj); if (queue_add(STATE_SYNC(tx_queue), &cn->qnode) > 0) cache_object_get(obj); } -- cgit v1.2.3 From 931c0eff309d8c7277ebe6d670fd72d8fbe3c674 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 4 Jan 2012 14:30:02 +0100 Subject: conntrackd: generalize/cleanup network message building/parsing This patch generalizes the network message building and parsing to prepare the upcoming expectation support. Basically, it renames: - NET_T_STATE_* by NET_T_STATE_CT_*, as I plan to add NET_T_STATE_EXP_* - BUILD_NETMSG by BUILD_NETMSG_FROM_CT, and build_payload by ct2msg. I plan to add exp2msg. - parse_payload by msg2ct, since I plan to add msg2exp. - modify object_status_to_network_type to prepare the support of expectations. - add prefix ct_ to all parsing functions in parse.c, as we will have similar functions to convert messages to expectation objects. Signed-off-by: Pablo Neira Ayuso --- include/cache.h | 3 +- include/network.h | 21 +++++++------ src/build.c | 81 ++++++++++++++++++++++++------------------------ src/internal_bypass.c | 6 ++-- src/internal_cache.c | 12 ++++---- src/network.c | 19 +++++++----- src/parse.c | 85 ++++++++++++++++++++++++++------------------------- src/sync-alarm.c | 4 +-- src/sync-ftfw.c | 2 +- src/sync-mode.c | 44 +++++++++++++++++--------- src/sync-notrack.c | 9 +++--- 11 files changed, 155 insertions(+), 131 deletions(-) (limited to 'src/sync-alarm.c') diff --git a/include/cache.h b/include/cache.h index a42e395..02bb386 100644 --- a/include/cache.h +++ b/include/cache.h @@ -21,7 +21,8 @@ enum { C_OBJ_NONE = 0, /* not in the cache */ C_OBJ_NEW, /* just added to the cache */ C_OBJ_ALIVE, /* in the cache, alive */ - C_OBJ_DEAD /* still in the cache, but dead */ + C_OBJ_DEAD, /* still in the cache, but dead */ + C_OBJ_MAX }; struct cache; diff --git a/include/network.h b/include/network.h index 567317b..d0531b9 100644 --- a/include/network.h +++ b/include/network.h @@ -25,10 +25,10 @@ struct nethdr { #define NETHDR_SIZ nethdr_align(sizeof(struct nethdr)) enum nethdr_type { - NET_T_STATE_NEW = 0, - NET_T_STATE_UPD, - NET_T_STATE_DEL, - NET_T_STATE_MAX = NET_T_STATE_DEL, + NET_T_STATE_CT_NEW = 0, + NET_T_STATE_CT_UPD, + NET_T_STATE_CT_DEL, + NET_T_STATE_MAX = NET_T_STATE_CT_DEL, NET_T_CTL = 10, }; @@ -37,7 +37,9 @@ int nethdr_size(int len); void nethdr_set(struct nethdr *net, int type); void nethdr_set_ack(struct nethdr *net); void nethdr_set_ctl(struct nethdr *net); -int object_status_to_network_type(int status); + +struct cache_object; +int object_status_to_network_type(struct cache_object *obj); #define NETHDR_DATA(x) \ (struct netattr *)(((char *)x) + NETHDR_SIZ) @@ -79,13 +81,13 @@ enum { MSG_BAD, }; -#define BUILD_NETMSG(ct, query) \ +#define BUILD_NETMSG_FROM_CT(ct, query) \ ({ \ static char __net[4096]; \ struct nethdr *__hdr = (struct nethdr *) __net; \ memset(__hdr, 0, NETHDR_SIZ); \ nethdr_set(__hdr, query); \ - build_payload(ct, __hdr); \ + ct2msg(ct, __hdr); \ HDR_HOST2NETWORK(__hdr); \ __hdr; \ }) @@ -234,8 +236,7 @@ struct nta_attr_natseqadj { uint32_t repl_seq_offset_after; }; -void build_payload(const struct nf_conntrack *ct, struct nethdr *n); - -int parse_payload(struct nf_conntrack *ct, struct nethdr *n, size_t remain); +void ct2msg(const struct nf_conntrack *ct, struct nethdr *n); +int msg2ct(struct nf_conntrack *ct, struct nethdr *n, size_t remain); #endif diff --git a/src/build.c b/src/build.c index a495872..9c3687c 100644 --- a/src/build.c +++ b/src/build.c @@ -1,6 +1,7 @@ /* - * (C) 2006-2008 by Pablo Neira Ayuso - * + * (C) 2006-2011 by Pablo Neira Ayuso + * (C) 2011 by Vyatta Inc. + * * 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 @@ -42,14 +43,14 @@ addattr(struct nethdr *n, int attr, const void *data, size_t len) } static inline void -__build_u8(const struct nf_conntrack *ct, int a, struct nethdr *n, int b) +ct_build_u8(const struct nf_conntrack *ct, int a, struct nethdr *n, int b) { void *ptr = put_header(n, b, sizeof(uint8_t)); memcpy(ptr, nfct_get_attr(ct, a), sizeof(uint8_t)); } static inline void -__build_u16(const struct nf_conntrack *ct, int a, struct nethdr *n, int b) +ct_build_u16(const struct nf_conntrack *ct, int a, struct nethdr *n, int b) { uint16_t data = nfct_get_attr_u16(ct, a); data = htons(data); @@ -57,7 +58,7 @@ __build_u16(const struct nf_conntrack *ct, int a, struct nethdr *n, int b) } static inline void -__build_u32(const struct nf_conntrack *ct, int a, struct nethdr *n, int b) +ct_build_u32(const struct nf_conntrack *ct, int a, struct nethdr *n, int b) { uint32_t data = nfct_get_attr_u32(ct, a); data = htonl(data); @@ -65,7 +66,7 @@ __build_u32(const struct nf_conntrack *ct, int a, struct nethdr *n, int b) } static inline void -__build_group(const struct nf_conntrack *ct, int a, struct nethdr *n, +ct_build_group(const struct nf_conntrack *ct, int a, struct nethdr *n, int b, int size) { void *ptr = put_header(n, b, size); @@ -73,7 +74,7 @@ __build_group(const struct nf_conntrack *ct, int a, struct nethdr *n, } static inline void -__build_natseqadj(const struct nf_conntrack *ct, struct nethdr *n) +ct_build_natseqadj(const struct nf_conntrack *ct, struct nethdr *n) { struct nta_attr_natseqadj data = { .orig_seq_correction_pos = @@ -99,54 +100,54 @@ static enum nf_conntrack_attr nat_type[] = static void build_l4proto_tcp(const struct nf_conntrack *ct, struct nethdr *n) { - __build_group(ct, ATTR_GRP_ORIG_PORT, n, NTA_PORT, + ct_build_group(ct, ATTR_GRP_ORIG_PORT, n, NTA_PORT, sizeof(struct nfct_attr_grp_port)); if (!nfct_attr_is_set(ct, ATTR_TCP_STATE)) return; - __build_u8(ct, ATTR_TCP_STATE, n, NTA_TCP_STATE); + ct_build_u8(ct, ATTR_TCP_STATE, n, NTA_TCP_STATE); if (CONFIG(sync).tcp_window_tracking) { - __build_u8(ct, ATTR_TCP_WSCALE_ORIG, n, NTA_TCP_WSCALE_ORIG); - __build_u8(ct, ATTR_TCP_WSCALE_REPL, n, NTA_TCP_WSCALE_REPL); + ct_build_u8(ct, ATTR_TCP_WSCALE_ORIG, n, NTA_TCP_WSCALE_ORIG); + ct_build_u8(ct, ATTR_TCP_WSCALE_REPL, n, NTA_TCP_WSCALE_REPL); } } static void build_l4proto_sctp(const struct nf_conntrack *ct, struct nethdr *n) { - __build_group(ct, ATTR_GRP_ORIG_PORT, n, NTA_PORT, + ct_build_group(ct, ATTR_GRP_ORIG_PORT, n, NTA_PORT, sizeof(struct nfct_attr_grp_port)); if (!nfct_attr_is_set(ct, ATTR_SCTP_STATE)) return; - __build_u8(ct, ATTR_SCTP_STATE, n, NTA_SCTP_STATE); - __build_u32(ct, ATTR_SCTP_VTAG_ORIG, n, NTA_SCTP_VTAG_ORIG); - __build_u32(ct, ATTR_SCTP_VTAG_REPL, n, NTA_SCTP_VTAG_REPL); + ct_build_u8(ct, ATTR_SCTP_STATE, n, NTA_SCTP_STATE); + ct_build_u32(ct, ATTR_SCTP_VTAG_ORIG, n, NTA_SCTP_VTAG_ORIG); + ct_build_u32(ct, ATTR_SCTP_VTAG_REPL, n, NTA_SCTP_VTAG_REPL); } static void build_l4proto_dccp(const struct nf_conntrack *ct, struct nethdr *n) { - __build_group(ct, ATTR_GRP_ORIG_PORT, n, NTA_PORT, + ct_build_group(ct, ATTR_GRP_ORIG_PORT, n, NTA_PORT, sizeof(struct nfct_attr_grp_port)); if (!nfct_attr_is_set(ct, ATTR_DCCP_STATE)) return; - __build_u8(ct, ATTR_DCCP_STATE, n, NTA_DCCP_STATE); - __build_u8(ct, ATTR_DCCP_ROLE, n, NTA_DCCP_ROLE); + ct_build_u8(ct, ATTR_DCCP_STATE, n, NTA_DCCP_STATE); + ct_build_u8(ct, ATTR_DCCP_ROLE, n, NTA_DCCP_ROLE); } static void build_l4proto_icmp(const struct nf_conntrack *ct, struct nethdr *n) { - __build_u8(ct, ATTR_ICMP_TYPE, n, NTA_ICMP_TYPE); - __build_u8(ct, ATTR_ICMP_CODE, n, NTA_ICMP_CODE); - __build_u16(ct, ATTR_ICMP_ID, n, NTA_ICMP_ID); + ct_build_u8(ct, ATTR_ICMP_TYPE, n, NTA_ICMP_TYPE); + ct_build_u8(ct, ATTR_ICMP_CODE, n, NTA_ICMP_CODE); + ct_build_u16(ct, ATTR_ICMP_ID, n, NTA_ICMP_ID); } static void build_l4proto_udp(const struct nf_conntrack *ct, struct nethdr *n) { - __build_group(ct, ATTR_GRP_ORIG_PORT, n, NTA_PORT, + ct_build_group(ct, ATTR_GRP_ORIG_PORT, n, NTA_PORT, sizeof(struct nfct_attr_grp_port)); } @@ -165,45 +166,45 @@ static struct build_l4proto { [IPPROTO_UDP] = { .build = build_l4proto_udp }, }; -void build_payload(const struct nf_conntrack *ct, struct nethdr *n) +void ct2msg(const struct nf_conntrack *ct, struct nethdr *n) { uint8_t l4proto = nfct_get_attr_u8(ct, ATTR_L4PROTO); if (nfct_attr_grp_is_set(ct, ATTR_GRP_ORIG_IPV4)) { - __build_group(ct, ATTR_GRP_ORIG_IPV4, n, NTA_IPV4, + ct_build_group(ct, ATTR_GRP_ORIG_IPV4, n, NTA_IPV4, sizeof(struct nfct_attr_grp_ipv4)); } else if (nfct_attr_grp_is_set(ct, ATTR_GRP_ORIG_IPV6)) { - __build_group(ct, ATTR_GRP_ORIG_IPV6, n, NTA_IPV6, + ct_build_group(ct, ATTR_GRP_ORIG_IPV6, n, NTA_IPV6, sizeof(struct nfct_attr_grp_ipv6)); } - __build_u32(ct, ATTR_STATUS, n, NTA_STATUS); - __build_u8(ct, ATTR_L4PROTO, n, NTA_L4PROTO); + ct_build_u32(ct, ATTR_STATUS, n, NTA_STATUS); + ct_build_u8(ct, ATTR_L4PROTO, n, NTA_L4PROTO); if (l4proto_fcn[l4proto].build) l4proto_fcn[l4proto].build(ct, n); if (!CONFIG(commit_timeout) && nfct_attr_is_set(ct, ATTR_TIMEOUT)) - __build_u32(ct, ATTR_TIMEOUT, n, NTA_TIMEOUT); + ct_build_u32(ct, ATTR_TIMEOUT, n, NTA_TIMEOUT); if (nfct_attr_is_set(ct, ATTR_MARK)) - __build_u32(ct, ATTR_MARK, n, NTA_MARK); + ct_build_u32(ct, ATTR_MARK, n, NTA_MARK); /* setup the master conntrack */ if (nfct_attr_grp_is_set(ct, ATTR_GRP_MASTER_IPV4)) { - __build_group(ct, ATTR_GRP_MASTER_IPV4, n, NTA_MASTER_IPV4, + ct_build_group(ct, ATTR_GRP_MASTER_IPV4, n, NTA_MASTER_IPV4, sizeof(struct nfct_attr_grp_ipv4)); - __build_u8(ct, ATTR_MASTER_L4PROTO, n, NTA_MASTER_L4PROTO); + ct_build_u8(ct, ATTR_MASTER_L4PROTO, n, NTA_MASTER_L4PROTO); if (nfct_attr_grp_is_set(ct, ATTR_GRP_MASTER_PORT)) { - __build_group(ct, ATTR_GRP_MASTER_PORT, + ct_build_group(ct, ATTR_GRP_MASTER_PORT, n, NTA_MASTER_PORT, sizeof(struct nfct_attr_grp_port)); } } else if (nfct_attr_grp_is_set(ct, ATTR_GRP_MASTER_IPV6)) { - __build_group(ct, ATTR_GRP_MASTER_IPV6, n, NTA_MASTER_IPV6, + ct_build_group(ct, ATTR_GRP_MASTER_IPV6, n, NTA_MASTER_IPV6, sizeof(struct nfct_attr_grp_ipv6)); - __build_u8(ct, ATTR_MASTER_L4PROTO, n, NTA_MASTER_L4PROTO); + ct_build_u8(ct, ATTR_MASTER_L4PROTO, n, NTA_MASTER_L4PROTO); if (nfct_attr_grp_is_set(ct, ATTR_GRP_MASTER_PORT)) { - __build_group(ct, ATTR_GRP_MASTER_PORT, + ct_build_group(ct, ATTR_GRP_MASTER_PORT, n, NTA_MASTER_PORT, sizeof(struct nfct_attr_grp_port)); } @@ -211,15 +212,15 @@ void build_payload(const struct nf_conntrack *ct, struct nethdr *n) /* NAT */ if (nfct_getobjopt(ct, NFCT_GOPT_IS_SNAT)) - __build_u32(ct, ATTR_REPL_IPV4_DST, n, NTA_SNAT_IPV4); + ct_build_u32(ct, ATTR_REPL_IPV4_DST, n, NTA_SNAT_IPV4); if (nfct_getobjopt(ct, NFCT_GOPT_IS_DNAT)) - __build_u32(ct, ATTR_REPL_IPV4_SRC, n, NTA_DNAT_IPV4); + ct_build_u32(ct, ATTR_REPL_IPV4_SRC, n, NTA_DNAT_IPV4); if (nfct_getobjopt(ct, NFCT_GOPT_IS_SPAT)) - __build_u16(ct, ATTR_REPL_PORT_DST, n, NTA_SPAT_PORT); + ct_build_u16(ct, ATTR_REPL_PORT_DST, n, NTA_SPAT_PORT); if (nfct_getobjopt(ct, NFCT_GOPT_IS_DPAT)) - __build_u16(ct, ATTR_REPL_PORT_SRC, n, NTA_DPAT_PORT); + ct_build_u16(ct, ATTR_REPL_PORT_SRC, n, NTA_DPAT_PORT); /* NAT sequence adjustment */ if (nfct_attr_is_set_array(ct, nat_type, 6)) - __build_natseqadj(ct, n); + ct_build_natseqadj(ct, n); } diff --git a/src/internal_bypass.c b/src/internal_bypass.c index 8ecec34..98717f3 100644 --- a/src/internal_bypass.c +++ b/src/internal_bypass.c @@ -118,7 +118,7 @@ static void internal_bypass_ct_event_new(struct nf_conntrack *ct, int origin) if (origin != CTD_ORIGIN_NOT_ME) return; - net = BUILD_NETMSG(ct, NET_T_STATE_NEW); + net = BUILD_NETMSG_FROM_CT(ct, NET_T_STATE_CT_NEW); multichannel_send(STATE_SYNC(channel), net); internal_bypass_stats.new++; } @@ -131,7 +131,7 @@ static void internal_bypass_ct_event_upd(struct nf_conntrack *ct, int origin) if (origin != CTD_ORIGIN_NOT_ME) return; - net = BUILD_NETMSG(ct, NET_T_STATE_UPD); + net = BUILD_NETMSG_FROM_CT(ct, NET_T_STATE_CT_UPD); multichannel_send(STATE_SYNC(channel), net); internal_bypass_stats.upd++; } @@ -144,7 +144,7 @@ static int internal_bypass_ct_event_del(struct nf_conntrack *ct, int origin) if (origin != CTD_ORIGIN_NOT_ME) return 1; - net = BUILD_NETMSG(ct, NET_T_STATE_DEL); + net = BUILD_NETMSG_FROM_CT(ct, NET_T_STATE_CT_DEL); multichannel_send(STATE_SYNC(channel), net); internal_bypass_stats.del++; diff --git a/src/internal_cache.c b/src/internal_cache.c index 7a698e6..952327d 100644 --- a/src/internal_cache.c +++ b/src/internal_cache.c @@ -81,7 +81,7 @@ static int internal_cache_ct_purge_step(void *data1, void *data2) if (!STATE(get_retval)) { if (obj->status != C_OBJ_DEAD) { cache_object_set_status(obj, C_OBJ_DEAD); - sync_send(obj, NET_T_STATE_DEL); + sync_send(obj, NET_T_STATE_CT_DEL); cache_object_put(obj); } } @@ -117,10 +117,10 @@ internal_cache_ct_resync(enum nf_conntrack_msg_type type, switch (obj->status) { case C_OBJ_NEW: - sync_send(obj, NET_T_STATE_NEW); + sync_send(obj, NET_T_STATE_CT_NEW); break; case C_OBJ_ALIVE: - sync_send(obj, NET_T_STATE_UPD); + sync_send(obj, NET_T_STATE_CT_UPD); break; } return NFCT_CB_CONTINUE; @@ -155,7 +155,7 @@ retry: * processes or the kernel, but don't propagate events that * have been triggered by conntrackd itself, eg. commits. */ if (origin == CTD_ORIGIN_NOT_ME) - sync_send(obj, NET_T_STATE_NEW); + sync_send(obj, NET_T_STATE_CT_NEW); } else { cache_del(STATE(mode)->internal->ct.data, obj); cache_object_free(obj); @@ -176,7 +176,7 @@ static void internal_cache_ct_event_upd(struct nf_conntrack *ct, int origin) return; if (origin == CTD_ORIGIN_NOT_ME) - sync_send(obj, NET_T_STATE_UPD); + sync_send(obj, NET_T_STATE_CT_UPD); } static int internal_cache_ct_event_del(struct nf_conntrack *ct, int origin) @@ -196,7 +196,7 @@ static int internal_cache_ct_event_del(struct nf_conntrack *ct, int origin) if (obj->status != C_OBJ_DEAD) { cache_object_set_status(obj, C_OBJ_DEAD); if (origin == CTD_ORIGIN_NOT_ME) { - sync_send(obj, NET_T_STATE_DEL); + sync_send(obj, NET_T_STATE_CT_DEL); } cache_object_put(obj); } diff --git a/src/network.c b/src/network.c index 6a66a2b..cadc466 100644 --- a/src/network.c +++ b/src/network.c @@ -1,6 +1,7 @@ /* - * (C) 2006-2007 by Pablo Neira Ayuso - * + * (C) 2006-2011 by Pablo Neira Ayuso + * (C) 2011 by Vyatta Inc. + * * 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 @@ -119,13 +120,15 @@ int nethdr_track_is_seq_set() #include "cache.h" -static int status2type[] = { - [C_OBJ_NEW] = NET_T_STATE_NEW, - [C_OBJ_ALIVE] = NET_T_STATE_UPD, - [C_OBJ_DEAD] = NET_T_STATE_DEL, +static int status2type[CACHE_T_MAX][C_OBJ_MAX] = { + [CACHE_T_CT] = { + [C_OBJ_NEW] = NET_T_STATE_CT_NEW, + [C_OBJ_ALIVE] = NET_T_STATE_CT_UPD, + [C_OBJ_DEAD] = NET_T_STATE_CT_DEL, + }, }; -int object_status_to_network_type(int status) +int object_status_to_network_type(struct cache_object *obj) { - return status2type[status]; + return status2type[obj->cache->type][obj->status]; } diff --git a/src/parse.c b/src/parse.c index 7e60597..0718128 100644 --- a/src/parse.c +++ b/src/parse.c @@ -1,6 +1,7 @@ /* - * (C) 2006-2007 by Pablo Neira Ayuso - * + * (C) 2006-2011 by Pablo Neira Ayuso + * (C) 2011 by Vyatta Inc. + * * 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 @@ -24,184 +25,184 @@ #define ssizeof(x) (int)sizeof(x) #endif -static void parse_u8(struct nf_conntrack *ct, int attr, void *data); -static void parse_u16(struct nf_conntrack *ct, int attr, void *data); -static void parse_u32(struct nf_conntrack *ct, int attr, void *data); -static void parse_group(struct nf_conntrack *ct, int attr, void *data); -static void parse_nat_seq_adj(struct nf_conntrack *ct, int attr, void *data); +static void ct_parse_u8(struct nf_conntrack *ct, int attr, void *data); +static void ct_parse_u16(struct nf_conntrack *ct, int attr, void *data); +static void ct_parse_u32(struct nf_conntrack *ct, int attr, void *data); +static void ct_parse_group(struct nf_conntrack *ct, int attr, void *data); +static void ct_parse_nat_seq_adj(struct nf_conntrack *ct, int attr, void *data); -struct parser { +struct ct_parser { void (*parse)(struct nf_conntrack *ct, int attr, void *data); int attr; int size; }; -static struct parser h[NTA_MAX] = { +static struct ct_parser h[NTA_MAX] = { [NTA_IPV4] = { - .parse = parse_group, + .parse = ct_parse_group, .attr = ATTR_GRP_ORIG_IPV4, .size = NTA_SIZE(sizeof(struct nfct_attr_grp_ipv4)), }, [NTA_IPV6] = { - .parse = parse_group, + .parse = ct_parse_group, .attr = ATTR_GRP_ORIG_IPV6, .size = NTA_SIZE(sizeof(struct nfct_attr_grp_ipv6)), }, [NTA_PORT] = { - .parse = parse_group, + .parse = ct_parse_group, .attr = ATTR_GRP_ORIG_PORT, .size = NTA_SIZE(sizeof(struct nfct_attr_grp_port)), }, [NTA_L4PROTO] = { - .parse = parse_u8, + .parse = ct_parse_u8, .attr = ATTR_L4PROTO, .size = NTA_SIZE(sizeof(uint8_t)), }, [NTA_TCP_STATE] = { - .parse = parse_u8, + .parse = ct_parse_u8, .attr = ATTR_TCP_STATE, .size = NTA_SIZE(sizeof(uint8_t)), }, [NTA_STATUS] = { - .parse = parse_u32, + .parse = ct_parse_u32, .attr = ATTR_STATUS, .size = NTA_SIZE(sizeof(uint32_t)), }, [NTA_MARK] = { - .parse = parse_u32, + .parse = ct_parse_u32, .attr = ATTR_MARK, .size = NTA_SIZE(sizeof(uint32_t)), }, [NTA_TIMEOUT] = { - .parse = parse_u32, + .parse = ct_parse_u32, .attr = ATTR_TIMEOUT, .size = NTA_SIZE(sizeof(uint32_t)), }, [NTA_MASTER_IPV4] = { - .parse = parse_group, + .parse = ct_parse_group, .attr = ATTR_GRP_MASTER_IPV4, .size = NTA_SIZE(sizeof(struct nfct_attr_grp_ipv4)), }, [NTA_MASTER_IPV6] = { - .parse = parse_group, + .parse = ct_parse_group, .attr = ATTR_GRP_MASTER_IPV6, .size = NTA_SIZE(sizeof(struct nfct_attr_grp_ipv6)), }, [NTA_MASTER_L4PROTO] = { - .parse = parse_u8, + .parse = ct_parse_u8, .attr = ATTR_MASTER_L4PROTO, .size = NTA_SIZE(sizeof(uint8_t)), }, [NTA_MASTER_PORT] = { - .parse = parse_group, + .parse = ct_parse_group, .attr = ATTR_GRP_MASTER_PORT, .size = NTA_SIZE(sizeof(struct nfct_attr_grp_port)), }, [NTA_SNAT_IPV4] = { - .parse = parse_u32, + .parse = ct_parse_u32, .attr = ATTR_SNAT_IPV4, .size = NTA_SIZE(sizeof(uint32_t)), }, [NTA_DNAT_IPV4] = { - .parse = parse_u32, + .parse = ct_parse_u32, .attr = ATTR_DNAT_IPV4, .size = NTA_SIZE(sizeof(uint32_t)), }, [NTA_SPAT_PORT] = { - .parse = parse_u16, + .parse = ct_parse_u16, .attr = ATTR_SNAT_PORT, .size = NTA_SIZE(sizeof(uint16_t)), }, [NTA_DPAT_PORT] = { - .parse = parse_u16, + .parse = ct_parse_u16, .attr = ATTR_DNAT_PORT, .size = NTA_SIZE(sizeof(uint16_t)), }, [NTA_NAT_SEQ_ADJ] = { - .parse = parse_nat_seq_adj, + .parse = ct_parse_nat_seq_adj, .size = NTA_SIZE(sizeof(struct nta_attr_natseqadj)), }, [NTA_SCTP_STATE] = { - .parse = parse_u8, + .parse = ct_parse_u8, .attr = ATTR_SCTP_STATE, .size = NTA_SIZE(sizeof(uint8_t)), }, [NTA_SCTP_VTAG_ORIG] = { - .parse = parse_u32, + .parse = ct_parse_u32, .attr = ATTR_SCTP_VTAG_ORIG, .size = NTA_SIZE(sizeof(uint32_t)), }, [NTA_SCTP_VTAG_REPL] = { - .parse = parse_u32, + .parse = ct_parse_u32, .attr = ATTR_SCTP_VTAG_REPL, .size = NTA_SIZE(sizeof(uint32_t)), }, [NTA_DCCP_STATE] = { - .parse = parse_u8, + .parse = ct_parse_u8, .attr = ATTR_DCCP_STATE, .size = NTA_SIZE(sizeof(uint8_t)), }, [NTA_DCCP_ROLE] = { - .parse = parse_u8, + .parse = ct_parse_u8, .attr = ATTR_DCCP_ROLE, .size = NTA_SIZE(sizeof(uint8_t)), }, [NTA_ICMP_TYPE] = { - .parse = parse_u8, + .parse = ct_parse_u8, .attr = ATTR_ICMP_TYPE, .size = NTA_SIZE(sizeof(uint8_t)), }, [NTA_ICMP_CODE] = { - .parse = parse_u8, + .parse = ct_parse_u8, .attr = ATTR_ICMP_CODE, .size = NTA_SIZE(sizeof(uint8_t)), }, [NTA_ICMP_ID] = { - .parse = parse_u16, + .parse = ct_parse_u16, .attr = ATTR_ICMP_ID, .size = NTA_SIZE(sizeof(uint16_t)), }, [NTA_TCP_WSCALE_ORIG] = { - .parse = parse_u8, + .parse = ct_parse_u8, .attr = ATTR_TCP_WSCALE_ORIG, .size = NTA_SIZE(sizeof(uint8_t)), }, [NTA_TCP_WSCALE_REPL] = { - .parse = parse_u8, + .parse = ct_parse_u8, .attr = ATTR_TCP_WSCALE_REPL, .size = NTA_SIZE(sizeof(uint8_t)), }, }; static void -parse_u8(struct nf_conntrack *ct, int attr, void *data) +ct_parse_u8(struct nf_conntrack *ct, int attr, void *data) { uint8_t *value = (uint8_t *) data; nfct_set_attr_u8(ct, h[attr].attr, *value); } static void -parse_u16(struct nf_conntrack *ct, int attr, void *data) +ct_parse_u16(struct nf_conntrack *ct, int attr, void *data) { uint16_t *value = (uint16_t *) data; nfct_set_attr_u16(ct, h[attr].attr, ntohs(*value)); } static void -parse_u32(struct nf_conntrack *ct, int attr, void *data) +ct_parse_u32(struct nf_conntrack *ct, int attr, void *data) { uint32_t *value = (uint32_t *) data; nfct_set_attr_u32(ct, h[attr].attr, ntohl(*value)); } static void -parse_group(struct nf_conntrack *ct, int attr, void *data) +ct_parse_group(struct nf_conntrack *ct, int attr, void *data) { nfct_set_attr_grp(ct, h[attr].attr, data); } static void -parse_nat_seq_adj(struct nf_conntrack *ct, int attr, void *data) +ct_parse_nat_seq_adj(struct nf_conntrack *ct, int attr, void *data) { struct nta_attr_natseqadj *this = data; nfct_set_attr_u32(ct, ATTR_ORIG_NAT_SEQ_CORRECTION_POS, @@ -218,7 +219,7 @@ parse_nat_seq_adj(struct nf_conntrack *ct, int attr, void *data) ntohl(this->repl_seq_offset_after)); } -int parse_payload(struct nf_conntrack *ct, struct nethdr *net, size_t remain) +int msg2ct(struct nf_conntrack *ct, struct nethdr *net, size_t remain) { int len; struct netattr *attr; diff --git a/src/sync-alarm.c b/src/sync-alarm.c index 8d6b34d..65154a1 100644 --- a/src/sync-alarm.c +++ b/src/sync-alarm.c @@ -42,7 +42,7 @@ static void refresher(struct alarm_block *a, void *data) random() % CONFIG(refresh) + 1, ((random() % 5 + 1) * 200000) - 1); - alarm_enqueue(obj, NET_T_STATE_UPD); + alarm_enqueue(obj, NET_T_STATE_CT_UPD); } static void cache_alarm_add(struct cache_object *obj, void *data) @@ -137,7 +137,7 @@ static int tx_queue_xmit(struct queue_node *n, const void *data) ca = (struct cache_alarm *)n; obj = cache_data_get_object(STATE(mode)->internal->ct.data, ca); - type = object_status_to_network_type(obj->status); + type = object_status_to_network_type(obj); net = obj->cache->ops->build_msg(obj, type); multichannel_send(STATE_SYNC(channel), net); cache_object_put(obj); diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c index 55eda0b..cff4d25 100644 --- a/src/sync-ftfw.c +++ b/src/sync-ftfw.c @@ -518,7 +518,7 @@ static int tx_queue_xmit(struct queue_node *n, const void *data) cn = (struct cache_ftfw *)n; obj = cache_data_get_object(STATE(mode)->internal->ct.data, cn); - type = object_status_to_network_type(obj->status); + type = object_status_to_network_type(obj); net = obj->cache->ops->build_msg(obj, type); nethdr_set_hello(net); diff --git a/src/sync-mode.c b/src/sync-mode.c index 7f019f7..17533f8 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -41,6 +41,24 @@ #include #include +static struct nf_conntrack *msg2ct_alloc(struct nethdr *net, size_t remain) +{ + struct nf_conntrack *ct; + + /* TODO: add stats on ENOMEM errors in the future. */ + ct = nfct_new(); + if (ct == NULL) + return NULL; + + if (msg2ct(ct, net, remain) == -1) { + STATE_SYNC(error).msg_rcv_malformed++; + STATE_SYNC(error).msg_rcv_bad_payload++; + nfct_destroy(ct); + return NULL; + } + return ct; +} + static void do_channel_handler_step(int i, struct nethdr *net, size_t remain) { @@ -74,26 +92,24 @@ do_channel_handler_step(int i, struct nethdr *net, size_t remain) STATE_SYNC(error).msg_rcv_bad_type++; return; } - /* TODO: add stats on ENOMEM errors in the future. */ - ct = nfct_new(); - if (ct == NULL) - return; - - if (parse_payload(ct, net, remain) == -1) { - STATE_SYNC(error).msg_rcv_malformed++; - STATE_SYNC(error).msg_rcv_bad_payload++; - nfct_destroy(ct); - return; - } switch(net->type) { - case NET_T_STATE_NEW: + case NET_T_STATE_CT_NEW: + ct = msg2ct_alloc(net, remain); + if (ct == NULL) + return; STATE_SYNC(external)->ct.new(ct); break; - case NET_T_STATE_UPD: + case NET_T_STATE_CT_UPD: + ct = msg2ct_alloc(net, remain); + if (ct == NULL) + return; STATE_SYNC(external)->ct.upd(ct); break; - case NET_T_STATE_DEL: + case NET_T_STATE_CT_DEL: + ct = msg2ct_alloc(net, remain); + if (ct == NULL) + return; STATE_SYNC(external)->ct.del(ct); break; default: diff --git a/src/sync-notrack.c b/src/sync-notrack.c index e25cfd8..6c798ac 100644 --- a/src/sync-notrack.c +++ b/src/sync-notrack.c @@ -1,6 +1,7 @@ /* - * (C) 2008 by Pablo Neira Ayuso - * + * (C) 2006-2011 by Pablo Neira Ayuso + * (C) 2011 by Vyatta Inc. + * * 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 @@ -87,7 +88,7 @@ static int kernel_resync_cb(enum nf_conntrack_msg_type type, { struct nethdr *net; - net = BUILD_NETMSG(ct, NET_T_STATE_NEW); + net = BUILD_NETMSG_FROM_CT(ct, NET_T_STATE_CT_NEW); multichannel_send(STATE_SYNC(channel), net); return NFCT_CB_CONTINUE; @@ -198,7 +199,7 @@ static int tx_queue_xmit(struct queue_node *n, const void *data2) cn = (struct cache_ftfw *)n; obj = cache_data_get_object(STATE(mode)->internal->ct.data, cn); - type = object_status_to_network_type(obj->status);; + type = object_status_to_network_type(obj);; net = obj->cache->ops->build_msg(obj, type); multichannel_send(STATE_SYNC(channel), net); -- cgit v1.2.3 From 79ab299bfb20b7fc1982ca90d77d8b908b824fea Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 4 Jan 2012 14:31:41 +0100 Subject: conntrackd: simplify cache_get_extra function This patch simplifies cache_get_extra which now takes only one parameter that is the cache_object. With it, the extra area can be calculated. Signed-off-by: Pablo Neira Ayuso --- include/cache.h | 2 +- src/cache.c | 4 ++-- src/sync-alarm.c | 3 +-- src/sync-ftfw.c | 6 ++---- src/sync-notrack.c | 6 ++---- 5 files changed, 8 insertions(+), 13 deletions(-) (limited to 'src/sync-alarm.c') diff --git a/include/cache.h b/include/cache.h index 02bb386..65f7e3a 100644 --- a/include/cache.h +++ b/include/cache.h @@ -148,7 +148,7 @@ struct cache_object *cache_find(struct cache *c, void *ptr, int *pos); void cache_stats(const struct cache *c, int fd); void cache_stats_extended(const struct cache *c, int fd); struct cache_object *cache_data_get_object(struct cache *c, void *data); -void *cache_get_extra(struct cache *, void *); +void *cache_get_extra(struct cache_object *); void cache_iterate(struct cache *c, void *data, int (*iterate)(void *data1, void *data2)); void cache_iterate_limit(struct cache *c, void *data, uint32_t from, uint32_t steps, int (*iterate)(void *data1, void *data2)); diff --git a/src/cache.c b/src/cache.c index efdab0e..f515ba0 100644 --- a/src/cache.c +++ b/src/cache.c @@ -308,9 +308,9 @@ struct cache_object *cache_data_get_object(struct cache *c, void *data) return (struct cache_object *)((char*)data - c->extra_offset); } -void *cache_get_extra(struct cache *c, void *data) +void *cache_get_extra(struct cache_object *obj) { - return (char*)data + c->extra_offset; + return (char*)obj + obj->cache->extra_offset; } void cache_stats(const struct cache *c, int fd) diff --git a/src/sync-alarm.c b/src/sync-alarm.c index 65154a1..03481fd 100644 --- a/src/sync-alarm.c +++ b/src/sync-alarm.c @@ -110,8 +110,7 @@ static int alarm_recv(const struct nethdr *net) static void alarm_enqueue(struct cache_object *obj, int query) { - struct cache_alarm *ca = - cache_get_extra(STATE(mode)->internal->ct.data, obj); + struct cache_alarm *ca = cache_get_extra(obj); if (queue_add(STATE_SYNC(tx_queue), &ca->qnode) > 0) cache_object_get(obj); } diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c index cff4d25..c7cc4aa 100644 --- a/src/sync-ftfw.c +++ b/src/sync-ftfw.c @@ -169,8 +169,7 @@ static void ftfw_kill(void) static int do_cache_to_tx(void *data1, void *data2) { struct cache_object *obj = data2; - struct cache_ftfw *cn = - cache_get_extra(STATE(mode)->internal->ct.data, obj); + struct cache_ftfw *cn = cache_get_extra(obj); if (queue_in(rs_queue, &cn->qnode)) { queue_del(&cn->qnode); @@ -551,8 +550,7 @@ static void ftfw_xmit(void) static void ftfw_enqueue(struct cache_object *obj, int type) { - struct cache_ftfw *cn = - cache_get_extra(STATE(mode)->internal->ct.data, obj); + struct cache_ftfw *cn = cache_get_extra(obj); if (queue_in(rs_queue, &cn->qnode)) { queue_del(&cn->qnode); queue_add(STATE_SYNC(tx_queue), &cn->qnode); diff --git a/src/sync-notrack.c b/src/sync-notrack.c index 6c798ac..a8cc6bf 100644 --- a/src/sync-notrack.c +++ b/src/sync-notrack.c @@ -76,8 +76,7 @@ static void tx_queue_add_ctlmsg(uint32_t flags, uint32_t from, uint32_t to) static int do_cache_to_tx(void *data1, void *data2) { struct cache_object *obj = data2; - struct cache_notrack *cn = - cache_get_extra(STATE(mode)->internal->ct.data, obj); + struct cache_notrack *cn = cache_get_extra(obj); if (queue_add(STATE_SYNC(tx_queue), &cn->qnode) > 0) cache_object_get(obj); return 0; @@ -219,8 +218,7 @@ static void notrack_xmit(void) static void notrack_enqueue(struct cache_object *obj, int query) { - struct cache_notrack *cn = - cache_get_extra(STATE(mode)->internal->ct.data, obj); + struct cache_notrack *cn = cache_get_extra(obj); if (queue_add(STATE_SYNC(tx_queue), &cn->qnode) > 0) cache_object_get(obj); } -- cgit v1.2.3 From 75a7cd3c722e1abca14fc375bec8ab30c34ab284 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 16 Nov 2011 02:10:31 +0100 Subject: conntrackd: remove cache_data_get_object and replace by direct pointer We now include one pointer to the object in the extra section. This is required to generalize this code for the expectation support. We consume 4-8 bytes extra, but we will not need more changes to support expectations which is a good idea. --- include/cache.h | 1 - src/cache.c | 5 ----- src/sync-alarm.c | 10 +++++----- src/sync-ftfw.c | 19 +++++++------------ src/sync-notrack.c | 14 +++++++------- 5 files changed, 19 insertions(+), 30 deletions(-) (limited to 'src/sync-alarm.c') diff --git a/include/cache.h b/include/cache.h index 65f7e3a..abebb97 100644 --- a/include/cache.h +++ b/include/cache.h @@ -147,7 +147,6 @@ void cache_del(struct cache *c, struct cache_object *obj); struct cache_object *cache_find(struct cache *c, void *ptr, int *pos); void cache_stats(const struct cache *c, int fd); void cache_stats_extended(const struct cache *c, int fd); -struct cache_object *cache_data_get_object(struct cache *c, void *data); void *cache_get_extra(struct cache_object *); void cache_iterate(struct cache *c, void *data, int (*iterate)(void *data1, void *data2)); void cache_iterate_limit(struct cache *c, void *data, uint32_t from, uint32_t steps, int (*iterate)(void *data1, void *data2)); diff --git a/src/cache.c b/src/cache.c index f515ba0..7c41e54 100644 --- a/src/cache.c +++ b/src/cache.c @@ -303,11 +303,6 @@ struct cache_object *cache_find(struct cache *c, void *ptr, int *id) return ((struct cache_object *) hashtable_find(c->h, ptr, *id)); } -struct cache_object *cache_data_get_object(struct cache *c, void *data) -{ - return (struct cache_object *)((char*)data - c->extra_offset); -} - void *cache_get_extra(struct cache_object *obj) { return (char*)obj + obj->cache->extra_offset; diff --git a/src/sync-alarm.c b/src/sync-alarm.c index 03481fd..acaf5e6 100644 --- a/src/sync-alarm.c +++ b/src/sync-alarm.c @@ -29,6 +29,7 @@ struct cache_alarm { struct queue_node qnode; + struct cache_object *obj; struct alarm_block alarm; }; @@ -50,6 +51,7 @@ static void cache_alarm_add(struct cache_object *obj, void *data) struct cache_alarm *ca = data; queue_node_init(&ca->qnode, Q_ELEM_OBJ); + ca->obj = obj; init_alarm(&ca->alarm, obj, refresher); add_alarm(&ca->alarm, random() % CONFIG(refresh) + 1, @@ -131,15 +133,13 @@ static int tx_queue_xmit(struct queue_node *n, const void *data) break; case Q_ELEM_OBJ: { struct cache_alarm *ca; - struct cache_object *obj; int type; ca = (struct cache_alarm *)n; - obj = cache_data_get_object(STATE(mode)->internal->ct.data, ca); - type = object_status_to_network_type(obj); - net = obj->cache->ops->build_msg(obj, type); + type = object_status_to_network_type(ca->obj); + net = ca->obj->cache->ops->build_msg(ca->obj, type); multichannel_send(STATE_SYNC(channel), net); - cache_object_put(obj); + cache_object_put(ca->obj); break; } } diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c index c7cc4aa..fa76c0c 100644 --- a/src/sync-ftfw.c +++ b/src/sync-ftfw.c @@ -55,12 +55,14 @@ static int say_hello_back; struct cache_ftfw { struct queue_node qnode; + struct cache_object *obj; uint32_t seq; }; static void cache_ftfw_add(struct cache_object *obj, void *data) { struct cache_ftfw *cn = data; + cn->obj = obj; /* These nodes are not inserted in the list */ queue_node_init(&cn->qnode, Q_ELEM_OBJ); } @@ -302,13 +304,11 @@ static int rs_queue_empty(struct queue_node *n, const void *data) } case Q_ELEM_OBJ: { struct cache_ftfw *cn; - struct cache_object *obj; cn = (struct cache_ftfw *) n; if (h == NULL) { queue_del(n); - obj = cache_data_get_object(STATE(mode)->internal->ct.data, cn); - cache_object_put(obj); + cache_object_put(cn->obj); return 0; } if (before(cn->seq, h->from)) @@ -318,8 +318,7 @@ static int rs_queue_empty(struct queue_node *n, const void *data) dp("queue: deleting from queue (seq=%u)\n", cn->seq); queue_del(n); - obj = cache_data_get_object(STATE(mode)->internal->ct.data, cn); - cache_object_put(obj); + cache_object_put(cn->obj); break; } } @@ -465,11 +464,9 @@ static void rs_queue_purge_full(void) } case Q_ELEM_OBJ: { struct cache_ftfw *cn; - struct cache_object *obj; cn = (struct cache_ftfw *)n; - obj = cache_data_get_object(STATE(mode)->internal->ct.data, cn); - cache_object_put(obj); + cache_object_put(cn->obj); break; } } @@ -511,14 +508,12 @@ static int tx_queue_xmit(struct queue_node *n, const void *data) } case Q_ELEM_OBJ: { struct cache_ftfw *cn; - struct cache_object *obj; int type; struct nethdr *net; cn = (struct cache_ftfw *)n; - obj = cache_data_get_object(STATE(mode)->internal->ct.data, cn); - type = object_status_to_network_type(obj); - net = obj->cache->ops->build_msg(obj, type); + type = object_status_to_network_type(cn->obj); + net = cn->obj->cache->ops->build_msg(cn->obj, type); nethdr_set_hello(net); dp("tx_list sq: %u fl:%u len:%u\n", diff --git a/src/sync-notrack.c b/src/sync-notrack.c index a8cc6bf..06ad1f0 100644 --- a/src/sync-notrack.c +++ b/src/sync-notrack.c @@ -34,12 +34,14 @@ static struct alarm_block alive_alarm; struct cache_notrack { struct queue_node qnode; + struct cache_object *obj; }; static void cache_notrack_add(struct cache_object *obj, void *data) { struct cache_notrack *cn = data; queue_node_init(&cn->qnode, Q_ELEM_OBJ); + cn->obj = obj; } static void cache_notrack_del(struct cache_object *obj, void *data) @@ -191,19 +193,17 @@ static int tx_queue_xmit(struct queue_node *n, const void *data2) break; } case Q_ELEM_OBJ: { - struct cache_ftfw *cn; - struct cache_object *obj; + struct cache_notrack *cn; int type; struct nethdr *net; - cn = (struct cache_ftfw *)n; - obj = cache_data_get_object(STATE(mode)->internal->ct.data, cn); - type = object_status_to_network_type(obj);; - net = obj->cache->ops->build_msg(obj, type); + cn = (struct cache_notrack *)n; + type = object_status_to_network_type(cn->obj); + net = cn->obj->cache->ops->build_msg(cn->obj, type); multichannel_send(STATE_SYNC(channel), net); queue_del(n); - cache_object_put(obj); + cache_object_put(cn->obj); break; } } -- cgit v1.2.3