From a5c2a83f907a6a82912165bf2ef67ded13e84bc1 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Thu, 31 Dec 2009 19:10:41 +0100 Subject: conntrackd: open event handler once cache has been populated With this patch, we open the event handler once the internal cache (if any) is populated. This reduces the chances of a possible premature overrun if we lauch conntrackd in a busy firewall. However, we may still start with an internal cache that may differ a bit from the once in the kernel. This patch has no impact in setups where conntrackd is started in a spare firewall. Signed-off-by: Pablo Neira Ayuso --- src/run.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/run.c b/src/run.c index f68dd91..5781939 100644 --- a/src/run.c +++ b/src/run.c @@ -355,19 +355,6 @@ init(void) } register_fd(STATE(local).fd, STATE(fds)); - if (!(CONFIG(flags) & CTD_POLL)) { - STATE(event) = nl_init_event_handler(); - if (STATE(event) == NULL) { - dlog(LOG_ERR, "can't open netlink handler: %s", - strerror(errno)); - dlog(LOG_ERR, "no ctnetlink kernel support?"); - return -1; - } - nfct_callback_register2(STATE(event), NFCT_T_ALL, - event_handler, NULL); - register_fd(nfct_fd(STATE(event)), STATE(fds)); - } - /* resynchronize (like 'dump' socket) but it also purges old entries */ STATE(resync) = nfct_open(CONNTRACK, 0); if (STATE(resync)== NULL) { @@ -423,6 +410,24 @@ init(void) dlog(LOG_NOTICE, "running in polling mode"); } else { init_alarm(&STATE(resync_alarm), NULL, do_overrun_resync_alarm); + /* + * The last nfct handler that we register is the event handler. + * The reason to do this is that we may receive events while + * populating the internal cache. Thus, we hit ENOBUFS + * prematurely. However, if we open the event handler before + * populating the internal cache, we may still lose events + * that have occured during the population. + */ + STATE(event) = nl_init_event_handler(); + if (STATE(event) == NULL) { + dlog(LOG_ERR, "can't open netlink handler: %s", + strerror(errno)); + dlog(LOG_ERR, "no ctnetlink kernel support?"); + return -1; + } + nfct_callback_register2(STATE(event), NFCT_T_ALL, + event_handler, NULL); + register_fd(nfct_fd(STATE(event)), STATE(fds)); } /* Signals handling */ -- cgit v1.2.3