diff options
author | /C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org </C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org> | 2007-05-20 21:13:06 +0000 |
---|---|---|
committer | /C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org </C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org> | 2007-05-20 21:13:06 +0000 |
commit | 9f1b4b2d028129966f7e6f23cec6ac0712c2b1b6 (patch) | |
tree | d635d4e4ad7dac6918470676bf222f27d21f192e /src/sync-mode.c | |
parent | 2932c6b8e6952ae84b221b854b43810c61e5c8fa (diff) | |
download | conntrack-tools-9f1b4b2d028129966f7e6f23cec6ac0712c2b1b6.tar.gz conntrack-tools-9f1b4b2d028129966f7e6f23cec6ac0712c2b1b6.zip |
- introduce cache_iterate
- empty debug_ct function if DEBUG_CT is not set
- revisit overrun handler: this is a hard battle, just try to do our best here, call Patrick :)
- explicit warning message when netlink_buffer_max_growth is reached
- fix silly bug in stats-mode when dumping in XML format
- fix UDP handler for conntrack
Diffstat (limited to 'src/sync-mode.c')
-rw-r--r-- | src/sync-mode.c | 85 |
1 files changed, 82 insertions, 3 deletions
diff --git a/src/sync-mode.c b/src/sync-mode.c index 0a195d7..65a3c5b 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -1,5 +1,5 @@ /* - * (C) 2006 by Pablo Neira Ayuso <pablo@netfilter.org> + * (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 @@ -293,7 +293,9 @@ static void mcast_send_sync(struct nlmsghdr *nlh, STATE_SYNC(mcast_sync)->post_send(type, net, u); } -static void overrun_sync(struct nf_conntrack *ct, struct nlmsghdr *nlh) +static int overrun_cb(enum nf_conntrack_msg_type type, + struct nf_conntrack *ct, + void *data) { struct us_conntrack *u; @@ -307,10 +309,87 @@ static void overrun_sync(struct nf_conntrack *ct, struct nlmsghdr *nlh) if (!cache_test(STATE_SYNC(internal), ct)) { if ((u = cache_update_force(STATE_SYNC(internal), ct))) { - debug_ct(ct, "overrun resync"); + int ret; + char buf[4096]; + struct nlnetwork *net = (struct nlnetwork *) buf; + unsigned int size = sizeof(struct nlnetwork); + struct nlmsghdr *nlh = (struct nlmsghdr *) (buf + size); + + debug_ct(u->ct, "overrun resync"); + + ret = build_network_msg(NFCT_Q_UPDATE, + STATE(subsys_dump), + u->ct, + buf, + sizeof(buf)); + + if (ret == -1) { + dlog(STATE(log), "can't build overrun"); + return NFCT_CB_CONTINUE; + } + mcast_send_sync(nlh, u, ct, NFCT_T_UPDATE); } } + + return NFCT_CB_CONTINUE; +} + +static int overrun_purge_step(void *data1, void *data2) +{ + int ret; + struct nfct_handle *h = data1; + struct us_conntrack *u = data2; + + ret = nfct_query(h, NFCT_Q_GET, u->ct); + if (ret == -1 && errno == ENOENT) { + char buf[4096]; + struct nlnetwork *net = (struct nlnetwork *) buf; + unsigned int size = sizeof(struct nlnetwork); + struct nlmsghdr *nlh = (struct nlmsghdr *) (buf + size); + + debug_ct(u->ct, "overrun purge resync"); + + ret = build_network_msg(NFCT_Q_DESTROY, + STATE(subsys_dump), + u->ct, + buf, + sizeof(buf)); + + if (ret == -1) + dlog(STATE(log), "failed to build network message"); + + mcast_send_sync(nlh, NULL, u->ct, NFCT_T_DESTROY); + __cache_del(STATE_SYNC(internal), u->ct); + } + + return 0; +} + +/* it's likely that we're losing events, just try to do our best here */ +static void overrun_sync() +{ + int ret; + struct nfct_handle *h; + int family = CONFIG(family); + + h = nfct_open(CONNTRACK, 0); + if (!h) { + dlog(STATE(log), "can't open overrun handler"); + return; + } + + nfct_callback_register(h, NFCT_T_ALL, overrun_cb, NULL); + + ret = nfct_query(h, NFCT_Q_DUMP, &family); + if (ret == -1) + dlog(STATE(log), "overrun query error %s", strerror(errno)); + + nfct_callback_unregister(h); + + cache_iterate(STATE_SYNC(internal), h, overrun_purge_step); + + nfct_close(h); } static void event_new_sync(struct nf_conntrack *ct, struct nlmsghdr *nlh) |