summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/cache.h1
-rw-r--r--include/network.h2
-rw-r--r--src/build.c3
-rw-r--r--src/cache.c3
-rw-r--r--src/cache_iterators.c22
-rw-r--r--src/read_config_yy.y4
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;