From cb18364ca71715dceb3664486047db83ddff0efc Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Sun, 6 Jun 2010 17:58:34 +0200 Subject: [PATCH] [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. --- include/proto/stick_table.h | 1 + src/proto_tcp.c | 8 ++------ src/session.c | 1 + src/stick_table.c | 22 +++++++++++++++------- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/include/proto/stick_table.h b/include/proto/stick_table.h index 87a550b86..db45760f2 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 80c10fdc9..aa78014d0 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 2ae6f906c..1edc72561 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 9f7feddab..5723dffd2 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; }