From ed49d60424a18635c31dafc77e2cb720f75cc4ff Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 25 May 2008 15:14:31 +0200 Subject: add eventfd emulation to communicate receiver -> sender --- src/Makefile.am | 2 +- src/event.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/sync-ftfw.c | 5 ++++ src/sync-mode.c | 28 ++++++++++++++++------ 4 files changed, 100 insertions(+), 8 deletions(-) create mode 100644 src/event.c (limited to 'src') 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 + * + * 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 "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 @@ -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 @@ -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) -- cgit v1.2.3