diff options
-rw-r--r-- | include/cache.h | 1 | ||||
-rw-r--r-- | include/network.h | 2 | ||||
-rw-r--r-- | src/build.c | 3 | ||||
-rw-r--r-- | src/cache.c | 3 | ||||
-rw-r--r-- | src/cache_iterators.c | 22 | ||||
-rw-r--r-- | 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 <string.h> #include <libnetfilter_conntrack/libnetfilter_conntrack.h> #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; |