diff --git a/include/proto/stick_table.h b/include/proto/stick_table.h index 01cd391ff..4200d97fa 100644 --- a/include/proto/stick_table.h +++ b/include/proto/stick_table.h @@ -31,8 +31,9 @@ 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); -int stktable_store(struct stktable *t, struct stksess *ts, int sid); -struct stksess *stktable_lookup(struct stktable *t, struct stktable_key *key); +struct stksess *stktable_store(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, void *l7, int dir, struct pattern_expr *expr, unsigned long table_type); diff --git a/src/session.c b/src/session.c index 63184f389..873201c68 100644 --- a/src/session.c +++ b/src/session.c @@ -942,7 +942,7 @@ int process_sticking_rules(struct session *s, struct buffer *req, int an_bit) if (rule->flags & STK_IS_MATCH) { struct stksess *ts; - if ((ts = stktable_lookup(rule->table.t, key)) != NULL) { + if ((ts = stktable_lookup_key(rule->table.t, key)) != NULL) { if (!(s->flags & SN_ASSIGNED)) { struct eb32_node *node; @@ -1049,10 +1049,18 @@ int process_store_rules(struct session *s, struct buffer *rep, int an_bit) /* process store request and store response */ for (i = 0; i < s->store_count; i++) { - if (stktable_store(s->store[i].table, s->store[i].ts, s->srv->puid) > 0) { + struct stksess *ts; + + ts = stktable_lookup(s->store[i].table, s->store[i].ts); + if (ts) { + /* the entry already existed, we can free ours */ stksess_free(s->store[i].table, s->store[i].ts); - s->store[i].ts = NULL; } + else + ts = stktable_store(s->store[i].table, s->store[i].ts); + + s->store[i].ts = NULL; + ts->sid = s->srv->puid; } rep->analysers &= ~an_bit; diff --git a/src/stick_table.c b/src/stick_table.c index 4cd6c7596..a86f48f41 100644 --- a/src/stick_table.c +++ b/src/stick_table.c @@ -152,10 +152,10 @@ struct stksess *stksess_new(struct stktable *t, struct stktable_key *key) } /* - * Looks in table for a sticky session matching . + * Looks in table for a sticky session matching key . * Returns pointer on requested sticky session or NULL if none was found. */ -struct stksess *stktable_lookup(struct stktable *t, struct stktable_key *key) +struct stksess *stktable_lookup_key(struct stktable *t, struct stktable_key *key) { struct ebmb_node *eb; @@ -172,14 +172,11 @@ struct stksess *stktable_lookup(struct stktable *t, struct stktable_key *key) return ebmb_entry(eb, struct stksess, key); } -/* Try to store sticky session in the table. If another entry already - * exists with the same key, its server ID is updated with and a non - * zero value is returned so that the caller knows it can release its stksess. - * If no similar entry was present, is inserted into the tree and assigned - * server ID . Zero is returned in this case, and the caller must not - * release the stksess. +/* + * Looks in table for a sticky session with same key as . + * Returns pointer on requested sticky session or NULL if none was found. */ -int stktable_store(struct stktable *t, struct stksess *ts, int sid) +struct stksess *stktable_lookup(struct stktable *t, struct stksess *ts) { struct ebmb_node *eb; @@ -188,26 +185,28 @@ int stktable_store(struct stktable *t, struct stksess *ts, int sid) else eb = ebmb_lookup(&(t->keys), ts->key.key, t->key_size); - if (unlikely(!eb)) { - /* no existing session, insert ours */ - ts->sid = sid; - ebmb_insert(&t->keys, &ts->key, t->key_size); + if (unlikely(!eb)) + return NULL; - ts->exp.key = ts->expire = tick_add(now_ms, MS_TO_TICKS(t->expire)); - eb32_insert(&t->exps, &ts->exp); + return ebmb_entry(eb, struct stksess, key); +} - if (t->expire) { - t->exp_task->expire = t->exp_next = tick_first(ts->expire, t->exp_next); - task_queue(t->exp_task); - } - return 0; +/* 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. + */ +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)); + 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); } - - ts = ebmb_entry(eb, struct stksess, key); - - if ( ts->sid != sid ) - ts->sid = sid; - return 1; + return ts; } /*