diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2008-05-25 15:14:31 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2008-05-25 15:14:31 +0200 |
commit | ed49d60424a18635c31dafc77e2cb720f75cc4ff (patch) | |
tree | a03fa967fc353777eb20d5b81dfd46430e38c45e | |
parent | ed50c346126f5385163d03bc9639d28ead6c8536 (diff) | |
download | conntrack-tools-ed49d60424a18635c31dafc77e2cb720f75cc4ff.tar.gz conntrack-tools-ed49d60424a18635c31dafc77e2cb720f75cc4ff.zip |
add eventfd emulation to communicate receiver -> sender
-rw-r--r-- | ChangeLog | 1 | ||||
-rw-r--r-- | include/Makefile.am | 2 | ||||
-rw-r--r-- | include/conntrackd.h | 1 | ||||
-rw-r--r-- | include/event.h | 14 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/event.c | 73 | ||||
-rw-r--r-- | src/sync-ftfw.c | 5 | ||||
-rw-r--r-- | src/sync-mode.c | 28 |
8 files changed, 117 insertions, 9 deletions
@@ -34,6 +34,7 @@ o use generic nfct_cmp() to compare objects o improve network message sanity checkings o add Mcast[Snd|Rcv]SocketBuffer clauses to tune multicast socket buffers o add missing string.h required by strdup in config parsing +o add eventfd emulation to communicate receiver -> sender version 0.9.6 (2008/03/08) ------------------------------ diff --git a/include/Makefile.am b/include/Makefile.am index 92ebbcc..d68f10a 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -3,5 +3,5 @@ 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 \ - traffic_stats.h netlink.h fds.h + traffic_stats.h netlink.h fds.h eventfd.h diff --git a/include/conntrackd.h b/include/conntrackd.h index b266289..c7a65be 100644 --- a/include/conntrackd.h +++ b/include/conntrackd.h @@ -125,6 +125,7 @@ struct ct_sync_state { struct mcast_sock *mcast_server; /* multicast socket: incoming */ struct mcast_sock *mcast_client; /* multicast socket: outgoing */ + struct evfd *evfd; /* event fd */ struct sync_mode *sync; /* sync mode */ diff --git a/include/event.h b/include/event.h new file mode 100644 index 0000000..b6bff5a --- /dev/null +++ b/include/event.h @@ -0,0 +1,14 @@ +#ifndef _EVENT_H_ +#define _EVENT_H_ + +struct evfd *create_evfd(void); + +void destroy_evfd(struct evfd *e); + +int get_read_evfd(struct evfd *evfd); + +int write_evfd(struct evfd *evfd); + +int read_evfd(struct evfd *evfd); + +#endif diff --git a/src/Makefile.am b/src/Makefile.am index d3fc020..554074f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -12,7 +12,7 @@ conntrack_LDFLAGS = $(all_libraries) @LIBNETFILTER_CONNTRACK_LIBS@ 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 fds.c \ + ignore_pool.c fds.c event.c \ cache.c cache_iterators.c \ cache_lifetime.c cache_timer.c cache_wt.c \ sync-mode.c sync-alarm.c sync-ftfw.c \ diff --git a/src/event.c b/src/event.c new file mode 100644 index 0000000..ed78835 --- /dev/null +++ b/src/event.c @@ -0,0 +1,73 @@ +/* + * (C) 2006-2007 by Pablo Neira Ayuso <pablo@netfilter.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include <unistd.h> +#include <stdlib.h> + +#include "event.h" + +struct evfd { + int read; + int fds[2]; +}; + +struct evfd *create_evfd(void) +{ + struct evfd *e; + + e = calloc(1, sizeof(struct evfd)); + if (e == NULL) + return NULL; + + if (pipe(e->fds) == -1) { + free(e); + return NULL; + } + + return e; +} + +void destroy_evfd(struct evfd *e) +{ + close(e->fds[0]); + close(e->fds[1]); + free(e); +} + +int get_read_evfd(struct evfd *evfd) +{ + return evfd->fds[0]; +} + +int write_evfd(struct evfd *evfd) +{ + int data = 0; + + if (evfd->read) + return 0; + + evfd->read = 1; + return write(evfd->fds[1], &data, sizeof(data)); +} + +int read_evfd(struct evfd *evfd) +{ + int data; + + evfd->read = 0; + return read(evfd->fds[0], &data, sizeof(data)); +} diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c index 77f8fd4..adfdda9 100644 --- a/src/sync-ftfw.c +++ b/src/sync-ftfw.c @@ -25,6 +25,7 @@ #include "alarm.h" #include "log.h" #include "cache.h" +#include "event.h" #include <string.h> @@ -97,6 +98,7 @@ static void tx_queue_add_ctlmsg(uint32_t flags, uint32_t from, uint32_t to) }; queue_add(tx_queue, &ack, NETHDR_ACK_SIZ); + write_evfd(STATE_SYNC(evfd)); } static void ftfw_run(void); @@ -191,6 +193,7 @@ static int do_cache_to_tx(void *data1, void *data2) /* add to tx list */ list_add_tail(&cn->tx_list, &tx_list); tx_list_len++; + write_evfd(STATE_SYNC(evfd)); return 0; } @@ -225,6 +228,7 @@ static int rs_queue_to_tx(void *data1, const void *data2) dp("rs_queue_to_tx sq: %u fl:%u len:%u\n", net->seq, net->flags, net->len); queue_add(tx_queue, net, net->len); + write_evfd(STATE_SYNC(evfd)); queue_del(rs_queue, net); } return 0; @@ -256,6 +260,7 @@ static void rs_list_to_tx(struct cache *c, unsigned int from, unsigned int to) rs_list_len--; list_add_tail(&cn->tx_list, &tx_list); tx_list_len++; + write_evfd(STATE_SYNC(evfd)); } } } diff --git a/src/sync-mode.c b/src/sync-mode.c index ad55adc..2fe7406 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -26,6 +26,7 @@ #include "us-conntrack.h" #include "network.h" #include "fds.h" +#include "event.h" #include "debug.h" #include <errno.h> @@ -232,6 +233,12 @@ static int init_sync(void) return -1; } + STATE_SYNC(evfd) = create_evfd(); + if (STATE_SYNC(evfd) == NULL) { + dlog(LOG_ERR, "cannot open evfd"); + return -1; + } + /* initialization of multicast sequence generation */ STATE_SYNC(last_seq_sent) = time(NULL); @@ -240,21 +247,26 @@ static int init_sync(void) static int register_fds_sync(struct fds *fds) { - return register_fd(STATE_SYNC(mcast_server->fd), fds); + if (register_fd(STATE_SYNC(mcast_server->fd), fds) == -1) + return -1; + + return register_fd(get_read_evfd(STATE_SYNC(evfd)), fds); } static void run_sync(fd_set *readfds) { /* multicast packet has been received */ - if (FD_ISSET(STATE_SYNC(mcast_server->fd), readfds)) { + if (FD_ISSET(STATE_SYNC(mcast_server->fd), readfds)) mcast_handler(); - if (STATE_SYNC(sync)->run) - STATE_SYNC(sync)->run(); - - /* flush pending messages */ - mcast_buffered_pending_netmsg(STATE_SYNC(mcast_client)); + if (FD_ISSET(get_read_evfd(STATE_SYNC(evfd)), readfds) && + STATE_SYNC(sync)->run) { + read_evfd(STATE_SYNC(evfd)); + STATE_SYNC(sync)->run(); } + + /* flush pending messages */ + mcast_buffered_pending_netmsg(STATE_SYNC(mcast_client)); } static void kill_sync(void) @@ -265,6 +277,8 @@ static void kill_sync(void) mcast_server_destroy(STATE_SYNC(mcast_server)); mcast_client_destroy(STATE_SYNC(mcast_client)); + destroy_evfd(STATE_SYNC(evfd)); + mcast_buffered_destroy(); if (STATE_SYNC(sync)->kill) |