summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2009-07-19 15:31:25 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2009-07-19 15:31:25 +0200
commit4694ae1e0939f69f4d2696b0caff62ce6a17d92f (patch)
treef0bef91fab2792c0e653ef38293642b812ff51f6
parent651794575c844fe25a717d77bd088c51383067f0 (diff)
conntrackd: improve handling of external messages
With this patch, a) we set the file descriptors for the synchronization channels as non-blocking, b) we perform more than one recv() call per select() signal on the socket and c) we limit the iteration to the value that EventIterationLimit has set. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--src/mcast.c3
-rw-r--r--src/sync-mode.c19
-rw-r--r--src/udp.c3
3 files changed, 21 insertions, 4 deletions
diff --git a/src/mcast.c b/src/mcast.c
index 600fdc2..ec11100 100644
--- a/src/mcast.c
+++ b/src/mcast.c
@@ -288,7 +288,8 @@ ssize_t mcast_recv(struct mcast_sock *m, void *data, int size)
(struct sockaddr *)&m->addr,
&sin_size);
if (ret == -1) {
- m->stats.error++;
+ if (errno != EAGAIN)
+ m->stats.error++;
return ret;
}
diff --git a/src/sync-mode.c b/src/sync-mode.c
index 7853d91..8cf7aa3 100644
--- a/src/sync-mode.c
+++ b/src/sync-mode.c
@@ -36,6 +36,7 @@
#include <stdlib.h>
#include <limits.h>
#include <net/if.h>
+#include <fcntl.h>
static void
do_channel_handler_step(int i, struct nethdr *net, size_t remain)
@@ -118,7 +119,7 @@ retry:
}
/* handler for messages received */
-static void channel_handler(struct channel *m, int i)
+static int channel_handler_routine(struct channel *m, int i)
{
ssize_t numbytes;
ssize_t remain;
@@ -126,7 +127,7 @@ static void channel_handler(struct channel *m, int i)
numbytes = channel_recv(m, __net, sizeof(__net));
if (numbytes <= 0)
- return;
+ return -1;
remain = numbytes;
while (remain > 0) {
@@ -167,6 +168,19 @@ static void channel_handler(struct channel *m, int i)
ptr += net->len;
remain -= net->len;
}
+ return 0;
+}
+
+/* handler for messages received */
+static void channel_handler(struct channel *m, int i)
+{
+ int k;
+
+ for (k=0; k<CONFIG(event_iterations_limit); k++) {
+ if (channel_handler_routine(m, i) == -1) {
+ break;
+ }
+ }
}
/* select a new interface candidate in a round robin basis */
@@ -277,6 +291,7 @@ static int init_sync(void)
}
for (i=0; i<STATE_SYNC(channel)->channel_num; i++) {
int fd = channel_get_fd(STATE_SYNC(channel)->channel[i]);
+ fcntl(fd, F_SETFL, O_NONBLOCK);
if (register_fd(fd, STATE(fds)) == -1)
return -1;
}
diff --git a/src/udp.c b/src/udp.c
index d9943a0..4b9eb80 100644
--- a/src/udp.c
+++ b/src/udp.c
@@ -198,7 +198,8 @@ ssize_t udp_recv(struct udp_sock *m, void *data, int size)
(struct sockaddr *)&m->addr,
&sin_size);
if (ret == -1) {
- m->stats.error++;
+ if (errno != EAGAIN)
+ m->stats.error++;
return ret;
}