diff --git a/include/types/pattern.h b/include/types/pattern.h index 01fb69ca8d..d9346d9964 100644 --- a/include/types/pattern.h +++ b/include/types/pattern.h @@ -28,10 +28,10 @@ /* pattern in and out types */ enum { - PATTERN_TYPE_IP = 0, /* ipv4 type */ - PATTERN_TYPE_INTEGER = 1, /* unsigned 32bits integer type */ - PATTERN_TYPE_STRING = 2, /* char string type */ - PATTERN_TYPES + PATTERN_TYPE_IP = 0, /* ipv4 type */ + PATTERN_TYPE_INTEGER, /* unsigned 32bits integer type */ + PATTERN_TYPE_STRING, /* char string type */ + PATTERN_TYPES /* number of types, must always be last */ }; /* pattern fetch direction */ @@ -40,9 +40,9 @@ enum { /* pattern result data */ union pattern_data { - struct in_addr ip; /* used for ipv4 type */ - uint32_t integer; /* used for unsigned 32bits integer type */ - struct chunk str; /* used for char string type */ + struct in_addr ip; /* used for ipv4 type */ + uint32_t integer; /* used for unsigned 32bits integer type */ + struct chunk str; /* used for char string type */ }; /* pattern result */ diff --git a/include/types/stick_table.h b/include/types/stick_table.h index fd0c806072..b63b790e7a 100644 --- a/include/types/stick_table.h +++ b/include/types/stick_table.h @@ -31,46 +31,49 @@ #include /* stick table key types */ -#define STKTABLE_TYPE_IP 0 /* table key is ipv4 */ -#define STKTABLE_TYPE_INTEGER 1 /* table key is unsigned 32bit integer */ -#define STKTABLE_TYPE_STRING 2 /* table key is a null terminated string */ +enum { + STKTABLE_TYPE_IP = 0, /* table key is ipv4 */ + STKTABLE_TYPE_INTEGER, /* table key is unsigned 32bit integer */ + STKTABLE_TYPE_STRING, /* table key is a null terminated string */ + STKTABLE_TYPES /* Number of types, must always be last */ +}; -#define STKTABLE_TYPES 3 /* Increase this value if you add a type */ - -/* stick table type flags */ -#define STKTABLE_TYPEFLAG_CUSTOMKEYSIZE 0x00000001 /* this table type maxsize is configurable */ +/* stick table key type flags */ +#define STK_F_CUSTOM_KEYSIZE 0x00000001 /* this table's key size is configurable */ /* stick table keyword type */ struct stktable_type { - const char *kw; /* keyword string */ - int flags; /* type flags */ - size_t default_size; /* default key size */ + const char *kw; /* keyword string */ + int flags; /* type flags */ + size_t default_size; /* default key size */ }; -/* stuck session */ +/* sticky session */ struct stksess { - int sid; /* id of server to use for session */ + int sid; /* id of server to use for this session */ unsigned int expire; /* session expiration date */ struct eb32_node exps; /* ebtree node used to hold the session in expiration tree */ struct ebmb_node keys; /* ebtree node used to hold the session in table */ + /* WARNING! do not put anything after , it's used by the key */ }; - /* stick table */ struct stktable { - struct eb_root keys; /* head of stuck session tree */ - struct eb_root exps; /* head of stuck session expiration tree */ - struct pool_head *pool; /* pool used to allocate stuck sessions */ + struct eb_root keys; /* head of sticky session tree */ + struct eb_root exps; /* head of sticky session expiration tree */ + struct pool_head *pool; /* pool used to allocate sticky sessions */ struct task *exp_task; /* expiration task */ - unsigned long type; /* type of table (determine key format) */ + unsigned long type; /* type of table (determines key format) */ size_t key_size; /* size of a key, maximum size in case of string */ - unsigned int size; /* maximum stuck session in table */ - unsigned int current; /* number of stuck session in table */ - int nopurge; /* 1 never purge stuck sessions */ - int exp_next; /* next epiration date */ - int expire; /* duration before expiration of stuck session */ + unsigned int size; /* maximum number of sticky sessions in table */ + unsigned int current; /* number of sticky sessions currently in table */ + int nopurge; /* if non-zero, don't purge sticky sessions when full */ + int exp_next; /* next expiration date (ticks) */ + int expire; /* time to live for sticky sessions (milliseconds) */ }; +/*** The definitions below should probably be better placed in pattern.h ***/ + /* stick table key data */ union stktable_key_data { struct in_addr ip; /* used to store an ip key */ diff --git a/src/stick_table.c b/src/stick_table.c index 0d70e32a75..bc75f67f8a 100644 --- a/src/stick_table.c +++ b/src/stick_table.c @@ -29,22 +29,23 @@ /* - * Free an allocate sticked session . - * Decrease table sticked session counter . + * Free an allocated sticky session , and decrease sticky sessions counter + * in table . */ void stksess_free(struct stktable *t, struct stksess *ts) { t->current--; - pool_free2(t->pool,ts); + pool_free2(t->pool, ts); } /* - * Init or modify of th sticked session present in table . + * Initialize or update the key in the sticky session present in table + * from the value present in . */ void stksess_key(struct stktable *t, struct stksess *ts, struct stktable_key *key) { if (t->type != STKTABLE_TYPE_STRING) - memcpy(ts->keys.key, key->key , t->key_size); + memcpy(ts->keys.key, key->key, t->key_size); else { memcpy(ts->keys.key, key->key, MIN(t->key_size - 1, key->key_len)); ts->keys.key[MIN(t->key_size - 1, key->key_len)] = 0; @@ -53,7 +54,7 @@ void stksess_key(struct stktable *t, struct stksess *ts, struct stktable_key *ke /* - * Init sticked session using . + * Init sticky session of table using . */ struct stksess *stksess_init(struct stktable *t, struct stksess * ts, struct stktable_key *key) { @@ -66,8 +67,8 @@ struct stksess *stksess_init(struct stktable *t, struct stksess * ts, struct stk } /* - * Trash oldest sticked sessions from table - * Returns number of trashed sticked session. + * Trash oldest sticky sessions from table + * Returns number of trashed sticky sessions. */ static int stktable_trash_oldest(struct stktable *t, int to_batch) { @@ -109,8 +110,8 @@ static int stktable_trash_oldest(struct stktable *t, int to_batch) continue; } - /* session expired, trash it */ + /* session expired, trash it */ ebmb_delete(&ts->keys); stksess_free(t, ts); batched++; @@ -120,11 +121,10 @@ static int stktable_trash_oldest(struct stktable *t, int to_batch) } /* - * Allocate and initialise a new sticked session. - * The new sticked session is returned or NULL in case of lack of memory. - * Sticked sessions should only be allocated this way, and must be - * freed using stksess_free(). - * Increase table sticked session counter. + * Allocate and initialise a new sticky session. + * The new sticky session is returned or NULL in case of lack of memory. + * Sticky sessions should only be allocated this way, and must be freed using + * stksess_free(). Increase table sticky session counter. */ struct stksess *stksess_new(struct stktable *t, struct stktable_key *key) { @@ -148,14 +148,13 @@ struct stksess *stksess_new(struct stktable *t, struct stktable_key *key) } /* - * Lookup in table for a sticked session identified by . - * Returns pointer on requested sticked session or NULL if no one found. + * Looks in table for a sticky session matching . + * Returns pointer on requested sticky session or NULL if none was found. */ struct stksess *stktable_lookup(struct stktable *t, struct stktable_key *key) { struct ebmb_node *eb; - /* lookup on track session */ if (t->type == STKTABLE_TYPE_STRING) eb = ebst_lookup_len(&t->keys, key->key, key->key_len); else @@ -166,39 +165,40 @@ struct stksess *stktable_lookup(struct stktable *t, struct stktable_key *key) return NULL; } - /* Existing session, returns server id */ return ebmb_entry(eb, struct stksess, keys); } -/* - * Store sticked session if not present in table. - * Il already present, update the existing session. +/* 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. */ -int stktable_store(struct stktable *t, struct stksess *tsess, int sid) +int stktable_store(struct stktable *t, struct stksess *ts, int sid) { - struct stksess *ts; struct ebmb_node *eb; if (t->type == STKTABLE_TYPE_STRING) - eb = ebst_lookup(&(t->keys), (char *)tsess->keys.key); + eb = ebst_lookup(&(t->keys), (char *)ts->keys.key); else - eb = ebmb_lookup(&(t->keys), tsess->keys.key, t->key_size); + eb = ebmb_lookup(&(t->keys), ts->keys.key, t->key_size); if (unlikely(!eb)) { - tsess->sid = sid; - ebmb_insert(&t->keys, &tsess->keys, t->key_size); + /* no existing session, insert ours */ + ts->sid = sid; + ebmb_insert(&t->keys, &ts->keys, t->key_size); - tsess->exps.key = tsess->expire = tick_add(now_ms, MS_TO_TICKS(t->expire)); - eb32_insert(&t->exps, &tsess->exps); + ts->exps.key = ts->expire = tick_add(now_ms, MS_TO_TICKS(t->expire)); + eb32_insert(&t->exps, &ts->exps); if (t->expire) { - t->exp_task->expire = t->exp_next = tick_first(tsess->expire, t->exp_next); + t->exp_task->expire = t->exp_next = tick_first(ts->expire, t->exp_next); task_queue(t->exp_task); } return 0; } - /* Existing track session */ ts = ebmb_entry(eb, struct stksess, keys); if ( ts->sid != sid ) @@ -207,7 +207,8 @@ int stktable_store(struct stktable *t, struct stksess *tsess, int sid) } /* - * Trash expired sticked sessions from table . + * Trash expired sticky sessions from table . The next expiration date is + * returned. */ static int stktable_trash_expired(struct stktable *t) { @@ -262,9 +263,10 @@ static int stktable_trash_expired(struct stktable *t) } /* - * Task processing function to trash expired sticked sessions. + * Task processing function to trash expired sticky sessions. A pointer to the + * task itself is returned since it never dies. */ -static struct task *process_table_expire(struct task * task) +static struct task *process_table_expire(struct task *task) { struct stktable *t = (struct stktable *)task->context; @@ -272,7 +274,7 @@ static struct task *process_table_expire(struct task * task) return task; } -/* Perform minimal intializations, report 0 in case of error, 1 if OK. */ +/* Perform minimal stick table intializations, report 0 in case of error, 1 if OK. */ int stktable_init(struct stktable *t) { if (t->size) { @@ -298,7 +300,7 @@ int stktable_init(struct stktable *t) */ struct stktable_type stktable_types[STKTABLE_TYPES] = { { "ip", 0, 4 } , { "integer", 0, 4 }, - { "string", STKTABLE_TYPEFLAG_CUSTOMKEYSIZE, 32 } }; + { "string", STK_F_CUSTOM_KEYSIZE, 32 } }; /* @@ -315,7 +317,7 @@ int stktable_parse_type(char **args, int *myidx, unsigned long *type, size_t *ke *key_size = stktable_types[*type].default_size; (*myidx)++; - if (stktable_types[*type].flags & STKTABLE_TYPEFLAG_CUSTOMKEYSIZE) { + if (stktable_types[*type].flags & STK_F_CUSTOM_KEYSIZE) { if (strcmp("len", args[*myidx]) == 0) { (*myidx)++; *key_size = atol(args[*myidx]);