From: Willy Tarreau Date: Sun, 6 Jun 2010 15:58:34 +0000 (+0200) Subject: [MEDIUM] stick_table: separate storage and update of session entries X-Git-Tag: v1.5-dev8~557 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cb18364ca71715dceb3664486047db83ddff0efc;p=thirdparty%2Fhaproxy.git [MEDIUM] stick_table: separate storage and update of session entries When an entry already exists, we just need to update its expiration timer. Let's have a dedicated function for that instead of spreading open code everywhere. This change also ensures that an update of an existing sticky session really leads to an update of its expiration timer, which was apparently not the case till now. This point needs to be checked in 1.4. --- diff --git a/include/proto/stick_table.h b/include/proto/stick_table.h index 87a550b86b..db45760f25 100644 --- a/include/proto/stick_table.h +++ b/include/proto/stick_table.h @@ -37,6 +37,7 @@ void stksess_free(struct stktable *t, struct stksess *ts); int stktable_init(struct stktable *t); int stktable_parse_type(char **args, int *idx, unsigned long *type, size_t *key_size); struct stksess *stktable_store(struct stktable *t, struct stksess *ts); +struct stksess *stktable_touch(struct stktable *t, struct stksess *ts); struct stksess *stktable_lookup(struct stktable *t, struct stksess *ts); struct stksess *stktable_lookup_key(struct stktable *t, struct stktable_key *key); struct stktable_key *stktable_fetch_key(struct proxy *px, struct session *l4, diff --git a/src/proto_tcp.c b/src/proto_tcp.c index 80c10fdc98..aa78014d05 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -1086,12 +1086,8 @@ acl_fetch_src_update_count(struct proxy *px, struct session *l4, void *l7, int d return 0; stktable_store(&px->table, ts); } - else if (px->table.expire) { - /* if entries can expire, let's update the entry and the table */ - ts->expire = tick_add(now_ms, MS_TO_TICKS(px->table.expire)); - px->table.exp_task->expire = px->table.exp_next = tick_first(ts->expire, px->table.exp_next); - task_queue(px->table.exp_task); - } + else + stktable_touch(&px->table, ts); ptr = stktable_data_ptr(&px->table, ts, STKTABLE_DT_CONN_CUM); if (!ptr) diff --git a/src/session.c b/src/session.c index 2ae6f906cf..1edc725618 100644 --- a/src/session.c +++ b/src/session.c @@ -1057,6 +1057,7 @@ int process_store_rules(struct session *s, struct buffer *rep, int an_bit) ts = stktable_lookup(s->store[i].table, s->store[i].ts); if (ts) { /* the entry already existed, we can free ours */ + stktable_touch(s->store[i].table, s->store[i].ts); stksess_free(s->store[i].table, s->store[i].ts); } else diff --git a/src/stick_table.c b/src/stick_table.c index 9f7feddab2..5723dffd28 100644 --- a/src/stick_table.c +++ b/src/stick_table.c @@ -189,6 +189,19 @@ struct stksess *stktable_lookup(struct stktable *t, struct stksess *ts) return ebmb_entry(eb, struct stksess, key); } +/* Update the expiration timer for but do not touch its expiration node. + * The table's expiration timer is updated if set. + */ +struct stksess *stktable_touch(struct stktable *t, struct stksess *ts) +{ + ts->expire = tick_add(now_ms, MS_TO_TICKS(t->expire)); + if (t->expire) { + t->exp_task->expire = t->exp_next = tick_first(ts->expire, t->exp_next); + task_queue(t->exp_task); + } + return ts; +} + /* Insert new sticky session in the table. It is assumed that it does not * yet exist (the caller must check this). The table's timeout is updated if it * is set. is returned. @@ -196,14 +209,9 @@ struct stksess *stktable_lookup(struct stktable *t, struct stksess *ts) struct stksess *stktable_store(struct stktable *t, struct stksess *ts) { ebmb_insert(&t->keys, &ts->key, t->key_size); - - ts->exp.key = ts->expire = tick_add(now_ms, MS_TO_TICKS(t->expire)); + stktable_touch(t, ts); + ts->exp.key = ts->expire; eb32_insert(&t->exps, &ts->exp); - - if (t->expire) { - t->exp_task->expire = t->exp_next = tick_first(ts->expire, t->exp_next); - task_queue(t->exp_task); - } return ts; }