diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2008-10-20 14:09:04 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2008-10-20 14:09:04 +0200 |
commit | 8509a878c0df580b7496c7fd0afd961c4c3c771d (patch) | |
tree | c3728c42c21b0460a9c129c13109d15df754fb8f /src | |
parent | b8ed29727d24862523d57066ede86635d8dbacbf (diff) | |
download | conntrack-tools-8509a878c0df580b7496c7fd0afd961c4c3c771d.tar.gz conntrack-tools-8509a878c0df580b7496c7fd0afd961c4c3c771d.zip |
cache: fix update of scheduled-to-timeout entries
This patch fixes a problem that allows the update of entries that
are scheduled to be removed.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/cache.c | 99 |
1 files changed, 55 insertions, 44 deletions
diff --git a/src/cache.c b/src/cache.c index 820a385..63a8cff 100644 --- a/src/cache.c +++ b/src/cache.c @@ -231,6 +231,23 @@ struct us_conntrack *cache_add(struct cache *c, struct nf_conntrack *ct) return NULL; } +static void +__cache_update(struct cache *c, struct us_conntrack *u, struct nf_conntrack *ct) +{ + unsigned i; + char *data = u->data; + + nfct_copy(u->ct, ct, NFCT_CP_META); + + for (i = 0; i < c->num_features; i++) { + c->features[i]->update(u, data); + data += c->features[i]->size; + } + + if (c->extra && c->extra->update) + c->extra->update(u, ((char *) u) + c->extra_offset); +} + static struct us_conntrack *__update(struct cache *c, struct nf_conntrack *ct) { size_t size = c->h->datasize; @@ -241,19 +258,7 @@ static struct us_conntrack *__update(struct cache *c, struct nf_conntrack *ct) u = (struct us_conntrack *) hashtable_test(c->h, u); if (u) { - unsigned i; - char *data = u->data; - - nfct_copy(u->ct, ct, NFCT_CP_META); - - for (i = 0; i < c->num_features; i++) { - c->features[i]->update(u, data); - data += c->features[i]->size; - } - - if (c->extra && c->extra->update) - c->extra->update(u, ((char *) u) + c->extra_offset); - + __cache_update(c, u, ct); return u; } return NULL; @@ -273,37 +278,6 @@ struct us_conntrack *cache_update(struct cache *c, struct nf_conntrack *ct) return NULL; } -struct us_conntrack *cache_update_force(struct cache *c, - struct nf_conntrack *ct) -{ - struct us_conntrack *u; - - if ((u = __update(c, ct)) != NULL) { - c->upd_ok++; - return u; - } - if ((u = __add(c, ct)) != NULL) { - c->add_ok++; - return u; - } - c->add_fail++; - return NULL; -} - -int cache_test(struct cache *c, struct nf_conntrack *ct) -{ - size_t size = c->h->datasize; - char buf[size]; - struct us_conntrack *u = (struct us_conntrack *) buf; - void *ret; - - u->ct = ct; - - ret = hashtable_test(c->h, u); - - return ret != NULL; -} - static void __del2(struct cache *c, struct us_conntrack *u) { unsigned i; @@ -337,6 +311,43 @@ static void __cache_del(struct cache *c, struct us_conntrack *u) __del2(c, u); } +struct us_conntrack *cache_update_force(struct cache *c, + struct nf_conntrack *ct) +{ + struct us_conntrack *u; + + u = cache_find(c, ct); + if (u) { + if (!alarm_pending(&u->alarm)) { + c->upd_ok++; + __cache_update(c, u, ct); + return u; + } else { + __cache_del(c, u); + } + } + if ((u = __add(c, ct)) != NULL) { + c->add_ok++; + return u; + } + c->add_fail++; + return NULL; +} + +int cache_test(struct cache *c, struct nf_conntrack *ct) +{ + size_t size = c->h->datasize; + char buf[size]; + struct us_conntrack *u = (struct us_conntrack *) buf; + void *ret; + + u->ct = ct; + + ret = hashtable_test(c->h, u); + + return ret != NULL; +} + int cache_del(struct cache *c, struct nf_conntrack *ct) { size_t size = c->h->datasize; |