]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MEDIUM] stick_table: add room for extra data types
authorWilly Tarreau <w@1wt.eu>
Sun, 6 Jun 2010 11:34:54 +0000 (13:34 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 14 Jun 2010 13:10:24 +0000 (15:10 +0200)
The stick_tables will now be able to store extra data for a same key.
A limited set of extra data types will be defined and for each of them
an offset in the sticky session will be assigned at startup time. All
of this information will be stored in the stick table.

The extra data types will have to be specified after the new "store"
keyword of the "stick-table" directive, which will reserve some space
for them.

doc/configuration.txt
include/proto/stick_table.h
include/types/stick_table.h
src/cfgparse.c
src/stick_table.c

index a9a5793b05fba18838f4df673c7a7156675171f5..ad4a3ceb05dd7d9bd7c962353d24a982e5d2b1c3 100644 (file)
@@ -4995,7 +4995,7 @@ stick store-request <pattern> [table <table>] [{if | unless} <condition>]
 
 
 stick-table type {ip | integer | string [len <length>] } size <size>
-            [expire <expire>] [nopurge]
+            [expire <expire>] [nopurge] [store <data_type>]*
   Configure the stickiness table for the current backend
   May be used in sections :   defaults | frontend | listen | backend
                                  no    |    no    |   yes  |   yes
@@ -5049,6 +5049,12 @@ stick-table type {ip | integer | string [len <length>] } size <size>
                be removed once full. Be sure not to use the "nopurge" parameter
                if not expiration delay is specified.
 
+   <data_type> is used to store additional information in the stick-table. This
+               may be used by ACLs in order to control various criteria related
+               to the activity of the client matching the stick-table. For each
+               item specified here, the size of each entry will be inflated so
+               that the additional data can fit.
+
   The is only one stick-table per backend. At the moment of writing this doc,
   it does not seem useful to have multiple tables per backend. If this happens
   to be required, simply create a dummy backend with a stick-table in it and
index f26e002a9000476755de150db8c6e427cb36cce1..01cd391ffabab0486c7d9a48cfde377f2099191f 100644 (file)
@@ -3,6 +3,7 @@
  * Functions for stick tables management.
  *
  * Copyright (C) 2009-2010 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
+ * Copyright (C) 2010 Willy Tarreau <w@1wt.eu>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -36,6 +37,23 @@ struct stktable_key *stktable_fetch_key(struct proxy *px, struct session *l4,
                                        void *l7, int dir, struct pattern_expr *expr,
                                        unsigned long table_type);
 int stktable_compatible_pattern(struct pattern_expr *expr, unsigned long table_type);
+int stktable_get_data_type(char *name);
 
+/* reserve some space for data type <type>. Return non-0 if OK, or 0 if already
+ * allocated (or impossible type).
+ */
+static inline int stktable_alloc_data_type(struct stktable *t, int type)
+{
+       if (type >= STKTABLE_DATA_TYPES)
+               return 0;
+
+       if (t->data_ofs[type])
+               /* already allocated */
+               return 0;
+
+       t->data_size      += stktable_data_types[type].data_length;
+       t->data_ofs[type]  = -t->data_size;
+       return 1;
+}
 
 #endif /* _PROTO_STICK_TABLE_H */
index de23610e7284c6f16f732557080b20e8a5b31d29..dda9edbc011912876d54df06b90d6802434e953c 100644 (file)
@@ -3,6 +3,7 @@
  * Macros, variables and structures for stick tables management.
  *
  * Copyright (C) 2009-2010 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
+ * Copyright (C) 2010 Willy Tarreau <w@1wt.eu>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -38,6 +39,24 @@ enum {
        STKTABLE_TYPES            /* Number of types, must always be last */
 };
 
+/* The types of extra data we can store in a stick table */
+enum {
+       STKTABLE_DATA_TYPES       /* Number of data types, must always be last */
+};
+
+/* stick_table extra data. This is mainly used for casting or size computation */
+union stktable_data {
+};
+
+#define stktable_data_size(type) (sizeof(((union stktable_data*)0)->type))
+#define stktable_data_cast(ptr, type) ((union stktable_data*)(ptr))->type
+
+/* known data types */
+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) */
+};
+
 /* stick table key type flags */
 #define STK_F_CUSTOM_KEYSIZE      0x00000001   /* this table's key size is configurable */
 
@@ -75,9 +94,10 @@ struct stktable {
        int exp_next;             /* next expiration date (ticks) */
        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 */
 };
 
-/*** The definitions below should probably be better placed in pattern.h ***/
+struct stktable_data_type stktable_data_types[STKTABLE_DATA_TYPES];
 
 /* stick table key data */
 union stktable_key_data {
index d2f79f2200c3ea72b92e35717762f7cd6a8015fd..f534270859cc38d554df9523b85e5d5f7f52bdff 100644 (file)
@@ -2274,6 +2274,24 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
                                }
                                /* myidx already points to next arg */
                        }
+                       else if (strcmp(args[myidx], "store") == 0) {
+                               int type;
+
+                               myidx++;
+                               type = stktable_get_data_type(args[myidx]);
+                               if (type < 0) {
+                                       Alert("parsing [%s:%d] : %s: unknown store option '%s'.\n",
+                                             file, linenum, args[0], args[myidx]);
+                                       err_code |= ERR_ALERT | ERR_FATAL;
+                                       goto out;
+                               }
+                               if (!stktable_alloc_data_type(&curproxy->table, type)) {
+                                       Warning("parsing [%s:%d]: %s: store option '%s' already enabled, ignored.\n",
+                                               file, linenum, args[0], args[myidx]);
+                                       err_code |= ERR_WARN;
+                               }
+                               myidx++;
+                       }
                        else {
                                Alert("parsing [%s:%d] : stick-table: unknown argument '%s'.\n",
                                      file, linenum, args[myidx]);
index fa469255529a4a59a8c35dd2e11cbaf4c9934c13..158056e1ccb72b6bfa34ae841f3929e98b93af1b 100644 (file)
@@ -2,6 +2,7 @@
  * Stick tables management functions.
  *
  * Copyright 2009-2010 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
+ * Copyright (C) 2010 Willy Tarreau <w@1wt.eu>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -474,3 +475,22 @@ int stktable_compatible_pattern(struct pattern_expr *expr, unsigned long table_t
        return 1;
 }
 
+/* Extra data types processing */
+struct stktable_data_type stktable_data_types[STKTABLE_DATA_TYPES] = {
+};
+
+/*
+ * Returns the data type number for the stktable_data_type whose name is <name>,
+ * or <0 if not found.
+ */
+int stktable_get_data_type(char *name)
+{
+       int type;
+
+       for (type = 0; type < STKTABLE_DATA_TYPES; type++) {
+               if (strcmp(name, stktable_data_types[type].name) == 0)
+                       return type;
+       }
+       return -1;
+}
+