]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MEDIUM] stick-tables: add support for arguments to data_types
authorWilly Tarreau <w@1wt.eu>
Sun, 20 Jun 2010 07:11:39 +0000 (09:11 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 10 Aug 2010 16:04:13 +0000 (18:04 +0200)
Some data types will require arguments (eg: period for a rate counter).
This patch adds support for such arguments between parenthesis in the
"store" directive of the stick-table statement. Right now only integers
are supported.

include/proto/stick_table.h
include/types/stick_table.h
src/cfgparse.c

index 38ec9ae8f24d2f8f42d92ed6de75680cedd5811c..7381737c0a5d0d9aa779404c35ead006a0e74036 100644 (file)
@@ -23,6 +23,7 @@
 #ifndef _PROTO_STICK_TABLE_H
 #define _PROTO_STICK_TABLE_H
 
+#include <common/errors.h>
 #include <types/stick_table.h>
 
 #define stktable_data_size(type) (sizeof(((union stktable_data*)0)->type))
@@ -48,21 +49,27 @@ int stktable_compatible_pattern(struct pattern_expr *expr, unsigned long table_t
 int stktable_get_data_type(char *name);
 struct proxy *find_stktable(const char *name);
 
-/* reserve some space for data type <type>. Return non-0 if OK, or 0 if already
- * allocated (or impossible type).
+/* reserve some space for data type <type>, and associate argument at <sa> if
+ * not NULL. Returns PE_NONE (0) if OK or an error code among :
+ *   - PE_ENUM_OOR if <type> does not exist
+ *   - PE_EXIST if <type> is already registered
  */
-static inline int stktable_alloc_data_type(struct stktable *t, int type)
+static inline int stktable_alloc_data_type(struct stktable *t, int type, const char *sa)
 {
        if (type >= STKTABLE_DATA_TYPES)
-               return 0;
+               return PE_ENUM_OOR;
 
        if (t->data_ofs[type])
                /* already allocated */
-               return 0;
+               return PE_EXIST;
 
        t->data_size      += stktable_data_types[type].data_length;
        t->data_ofs[type]  = -t->data_size;
-       return 1;
+       /* right now only int type is supported, but we may later support type-
+        * specific arg type.
+        */
+       t->data_arg[type].i = sa ? atoi(sa) : 0;
+       return PE_NONE;
 }
 
 /* return pointer for data type <type> in sticky session <ts> of table <t>, or
index 4cd18d3f7b05ee0a1db8842dcd3b513ba1ba56bb..caca0bea0c1ec3c3650725629722026efae77f7d 100644 (file)
@@ -50,6 +50,13 @@ enum {
        STKTABLE_DATA_TYPES       /* Number of data types, must always be last */
 };
 
+/* The types of optional arguments to stored data */
+enum {
+       ARG_T_NONE = 0,           /* data type takes no argument (default) */
+       ARG_T_INT,                /* signed integer */
+       ARG_T_DELAY,              /* a delay which supports time units */
+};
+
 /* stick_table extra data. This is mainly used for casting or size computation */
 union stktable_data {
        int server_id;
@@ -64,6 +71,7 @@ union stktable_data {
 struct stktable_data_type {
        const char *name; /* name of the data type */
        int data_length;  /* length of this type, or 0 if variable (eg: string) */
+       int arg_type;     /* type of optional argument, ARG_T_* */
 };
 
 /* stick table key type flags */
@@ -104,6 +112,11 @@ struct stktable {
        int expire;               /* time to live for sticky sessions (milliseconds) */
        int data_size;            /* the size of the data that is prepended *before* stksess */
        int data_ofs[STKTABLE_DATA_TYPES]; /* negative offsets of present data types, or 0 if absent */
+       union {
+               int i;
+               unsigned int u;
+               void *p;
+       } data_arg[STKTABLE_DATA_TYPES]; /* optional argument of each data type */
 };
 
 struct stktable_data_type stktable_data_types[STKTABLE_DATA_TYPES];
index 69ab56606539020b0b6c3688a6814d9f86581cb9..3fa6c7eb1b5fe9c2cea4a6146ea8981b328c78b4 100644 (file)
@@ -2276,15 +2276,31 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
                        }
                        else if (strcmp(args[myidx], "store") == 0) {
                                int type;
-                               char *cw, *nw;
+                               char *cw, *nw, *sa;
 
                                myidx++;
                                nw = args[myidx];
                                while (*nw) {
                                        /* the "store" keyword supports a comma-separated list */
                                        cw = nw;
-                                       while (*nw && *nw != ',')
+                                       sa = NULL; /* store arg */
+                                       while (*nw && *nw != ',') {
+                                               if (*nw == '(') {
+                                                       *nw = 0;
+                                                       sa = ++nw;
+                                                       while (*nw != ')') {
+                                                               if (!*nw) {
+                                                                       Alert("parsing [%s:%d] : %s: missing closing parenthesis after store option '%s'.\n",
+                                                                             file, linenum, args[0], cw);
+                                                                       err_code |= ERR_ALERT | ERR_FATAL;
+                                                                       goto out;
+                                                               }
+                                                               nw++;
+                                                       }
+                                                       *nw = '\0';
+                                               }
                                                nw++;
+                                       }
                                        if (*nw)
                                                *nw++ = '\0';
                                        type = stktable_get_data_type(cw);
@@ -2294,7 +2310,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
                                                err_code |= ERR_ALERT | ERR_FATAL;
                                                goto out;
                                        }
-                                       if (!stktable_alloc_data_type(&curproxy->table, type)) {
+                                       if (stktable_alloc_data_type(&curproxy->table, type, sa)) {
                                                Warning("parsing [%s:%d]: %s: store option '%s' already enabled, ignored.\n",
                                                        file, linenum, args[0], cw);
                                                err_code |= ERR_WARN;
@@ -4910,7 +4926,7 @@ int check_config_validity()
                        else {
                                free((void *)mrule->table.name);
                                mrule->table.t = &(target->table);
-                               stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID);
+                               stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID, NULL);
                        }
                }
 
@@ -4943,7 +4959,7 @@ int check_config_validity()
                        else {
                                free((void *)mrule->table.name);
                                mrule->table.t = &(target->table);
-                               stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID);
+                               stktable_alloc_data_type(&target->table, STKTABLE_DT_SERVER_ID, NULL);
                        }
                }