From 50c09dec9ad0261d8fcc18d69b2c9ec74052955c Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 25 Jan 2009 17:53:05 +0100 Subject: src: add support for approximate timeout calculation during commit During the commit phase, the entries in the external cache entries are inserted in the kernel conntrack table. Currently, we use a fixed timeout that is specified in the config file. With this patch, if you don't specify the fixed timeout value via CommitTimeout, the daemon calculates the real timeout value during the commit phase. Signed-off-by: Pablo Neira Ayuso --- include/cache.h | 1 + include/network.h | 2 +- src/build.c | 3 +++ src/cache.c | 3 ++- src/cache_iterators.c | 22 ++++++++++++++++++++-- src/read_config_yy.y | 4 ---- 6 files changed, 27 insertions(+), 8 deletions(-) diff --git a/include/cache.h b/include/cache.h index 1fd3881..371170d 100644 --- a/include/cache.h +++ b/include/cache.h @@ -34,6 +34,7 @@ struct cache_object { int status; int refcnt; long lifetime; + long lastupdate; char data[0]; }; diff --git a/include/network.h b/include/network.h index 740e762..7cfaf84 100644 --- a/include/network.h +++ b/include/network.h @@ -192,7 +192,7 @@ enum nta_attr { NTA_PORT, /* struct nfct_attr_grp_port */ NTA_STATE = 4, /* uint8_t */ NTA_STATUS, /* uint32_t */ - NTA_TIMEOUT, /* uint32_t -- unused */ + NTA_TIMEOUT, /* uint32_t */ NTA_MARK, /* uint32_t */ NTA_MASTER_IPV4 = 8, /* struct nfct_attr_grp_ipv4 */ NTA_MASTER_IPV6, /* struct nfct_attr_grp_ipv6 */ diff --git a/src/build.c b/src/build.c index e094aa0..63a85db 100644 --- a/src/build.c +++ b/src/build.c @@ -19,6 +19,7 @@ #include #include #include "network.h" +#include "conntrackd.h" static inline void * put_header(struct nethdr *n, int attr, size_t len) @@ -117,6 +118,8 @@ void build_payload(const struct nf_conntrack *ct, struct nethdr *n) if (nfct_attr_is_set(ct, ATTR_TCP_STATE)) __build_u8(ct, ATTR_TCP_STATE, n, NTA_STATE); + if (!CONFIG(commit_timeout) && nfct_attr_is_set(ct, ATTR_TIMEOUT)) + __build_u32(ct, ATTR_TIMEOUT, n, NTA_TIMEOUT); if (nfct_attr_is_set(ct, ATTR_MARK)) __build_u32(ct, ATTR_MARK, n, NTA_MARK); diff --git a/src/cache.c b/src/cache.c index 71825e1..318b8ec 100644 --- a/src/cache.c +++ b/src/cache.c @@ -249,7 +249,7 @@ static int __add(struct cache *c, struct cache_object *obj, int id) c->extra->add(obj, ((char *) obj) + c->extra_offset); c->stats.active++; - obj->lifetime = time(NULL); + obj->lifetime = obj->lastupdate = time(NULL); obj->status = C_OBJ_NEW; obj->refcnt++; return 0; @@ -287,6 +287,7 @@ void cache_update(struct cache *c, struct cache_object *obj, int id, c->extra->update(obj, ((char *) obj) + c->extra_offset); c->stats.upd_ok++; + obj->lastupdate = time(NULL); obj->status = C_OBJ_ALIVE; } diff --git a/src/cache_iterators.c b/src/cache_iterators.c index 3a1ec72..e16a621 100644 --- a/src/cache_iterators.c +++ b/src/cache_iterators.c @@ -108,11 +108,29 @@ struct __commit_container { static void __do_commit_step(struct __commit_container *tmp, struct cache_object *obj) { - int ret, retry = 1; + int ret, retry = 1, timeout; struct nf_conntrack *ct = obj->ct; + if (CONFIG(commit_timeout)) { + timeout = CONFIG(commit_timeout); + } else { + timeout = time(NULL) - obj->lastupdate; + if (timeout < 0) { + /* XXX: Arbitrarily set the timer to one minute, how + * can this happen? For example, an adjustment due to + * daylight-saving. Probably other situations can + * trigger this. */ + timeout = 60; + } + /* calculate an estimation of the current timeout */ + timeout = nfct_get_attr_u32(ct, ATTR_TIMEOUT) - timeout; + if (timeout < 0) { + timeout = 60; + } + } + retry: - if (nl_create_conntrack(tmp->h, ct, CONFIG(commit_timeout)) == -1) { + if (nl_create_conntrack(tmp->h, ct, timeout) == -1) { if (errno == EEXIST && retry == 1) { ret = nl_destroy_conntrack(tmp->h, ct); if (ret == 0 || (ret == -1 && errno == ENOENT)) { diff --git a/src/read_config_yy.y b/src/read_config_yy.y index d71829f..766d543 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -1141,10 +1141,6 @@ init_config(char *filename) if (CONFIG(cache_timeout) == 0) CONFIG(cache_timeout) = 180; - /* default to 180 seconds: committed entries */ - if (CONFIG(commit_timeout) == 0) - CONFIG(commit_timeout) = 180; - /* default to 15 seconds: purge kernel entries */ if (CONFIG(purge_timeout) == 0) CONFIG(purge_timeout) = 15; -- cgit v1.2.3