]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: config: Extract the code of "stick-table" line parsing.
authorFrédéric Lécaille <flecaille@haproxy.com>
Fri, 8 Mar 2019 13:47:00 +0000 (14:47 +0100)
committerWilly Tarreau <w@1wt.eu>
Tue, 7 May 2019 04:54:06 +0000 (06:54 +0200)
With this patch we move the code responsible of parsing "stick-table"
lines to implement parse_stick_table() function in src/stick-tabble.c
so that to be able to parse "stick-table" elsewhere than in proxy sections.
We have have also added a conf struct to stktable struct to store the filename
and the line in the file the stick-table has been parsed to help in
diagnosing and displaying any configuration issue.

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

index 40bb8ca6c2b566bcba8ea28b0e2611d962f98e1b..962c95a1f7220af8d8807c0cf8f257ac138bf737 100644 (file)
@@ -38,6 +38,8 @@ int stksess_kill(struct stktable *t, struct stksess *ts, int decrefcount);
 
 int stktable_init(struct stktable *t);
 int stktable_parse_type(char **args, int *idx, unsigned long *type, size_t *key_size);
+int parse_stick_table(const char *file, int linenum, char **args,
+                      struct stktable *t, char *id, struct peers *peers);
 struct stksess *stktable_get_entry(struct stktable *table, struct stktable_key *key);
 struct stksess *stktable_set_entry(struct stktable *table, struct stksess *nts);
 void stktable_touch_with_exp(struct stktable *t, struct stksess *ts, int decrefcount, int expire);
index 28e255fb83c44c533eaea1d9452b5d7afe80ae09..695a75c9a6a260f22cc0103377a86ec051248dc7 100644 (file)
@@ -144,6 +144,13 @@ struct stksess {
 /* stick table */
 struct stktable {
        char *id;                 /* table id name */
+       struct stktable *next;    /* The stick-table may be linked when belonging to
+                                  * the same configuration section.
+                                  */
+       struct {
+               const char *file;     /* The file where the stick-table is declared. */
+               int line;             /* The line in this <file> the stick-table is declared. */
+       } conf;
        struct eb_root keys;      /* head of sticky session tree */
        struct eb_root exps;      /* head of sticky session expiration tree */
        struct eb_root updates;   /* head of sticky updates sequence tree */
@@ -175,6 +182,7 @@ struct stktable {
                unsigned int u;
                void *p;
        } data_arg[STKTABLE_DATA_TYPES]; /* optional argument of each data type */
+       struct proxy *proxy;      /* The proxy this stick-table is attached to, if any.*/
 };
 
 extern struct stktable_data_type stktable_data_types[STKTABLE_DATA_TYPES];
index e7cd0663eac5edc17a8c7fadc18300e4512de25d..c0f4a4669315221d9d99c04fd439eb9ee8e059fe 100644 (file)
@@ -25,6 +25,7 @@
 #include <proto/protocol.h>
 #include <proto/proxy.h>
 #include <proto/server.h>
+#include <proto/stick_table.h>
 
 /* Report a warning if a rule is placed after a 'tcp-request session' rule.
  * Return 1 if the warning has been emitted, otherwise 0.
@@ -1710,7 +1711,6 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
                LIST_ADDQ(&curproxy->persist_rules, &rule->list);
        }
        else if (!strcmp(args[0], "stick-table")) {
-               int myidx = 1;
                struct proxy *other;
 
                if (curproxy == &defproxy) {
@@ -1728,163 +1728,12 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
                        goto out;
                }
 
-               curproxy->table.id =  curproxy->id;
-               curproxy->table.type = (unsigned int)-1;
-               while (*args[myidx]) {
-                       const char *err;
-
-                       if (strcmp(args[myidx], "size") == 0) {
-                               myidx++;
-                               if (!*(args[myidx])) {
-                                       ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
-                                                file, linenum, args[myidx-1]);
-                                       err_code |= ERR_ALERT | ERR_FATAL;
-                                       goto out;
-                               }
-                               if ((err = parse_size_err(args[myidx], &curproxy->table.size))) {
-                                       ha_alert("parsing [%s:%d] : stick-table: unexpected character '%c' in argument of '%s'.\n",
-                                                file, linenum, *err, args[myidx-1]);
-                                       err_code |= ERR_ALERT | ERR_FATAL;
-                                       goto out;
-                               }
-                               myidx++;
-                       }
-                       else if (strcmp(args[myidx], "peers") == 0) {
-                               myidx++;
-                               if (!*(args[myidx])) {
-                                       ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
-                                                file, linenum, args[myidx-1]);
-                                       err_code |= ERR_ALERT | ERR_FATAL;
-                                       goto out;
-                               }
-                               curproxy->table.peers.name = strdup(args[myidx++]);
-                       }
-                       else if (strcmp(args[myidx], "expire") == 0) {
-                               myidx++;
-                               if (!*(args[myidx])) {
-                                       ha_alert("parsing [%s:%d] : stick-table: missing argument after '%s'.\n",
-                                                file, linenum, args[myidx-1]);
-                                       err_code |= ERR_ALERT | ERR_FATAL;
-                                       goto out;
-                               }
-                               err = parse_time_err(args[myidx], &val, TIME_UNIT_MS);
-                               if (err) {
-                                       ha_alert("parsing [%s:%d] : stick-table: unexpected character '%c' in argument of '%s'.\n",
-                                                file, linenum, *err, args[myidx-1]);
-                                       err_code |= ERR_ALERT | ERR_FATAL;
-                                       goto out;
-                               }
-                               if (val > INT_MAX) {
-                                       ha_alert("parsing [%s:%d] : Expire value [%u]ms exceeds maxmimum value of 24.85 days.\n",
-                                                file, linenum, val);
-                                       err_code |= ERR_ALERT | ERR_FATAL;
-                                       goto out;
-                               }
-                               curproxy->table.expire = val;
-                               myidx++;
-                       }
-                       else if (strcmp(args[myidx], "nopurge") == 0) {
-                               curproxy->table.nopurge = 1;
-                               myidx++;
-                       }
-                       else if (strcmp(args[myidx], "type") == 0) {
-                               myidx++;
-                               if (stktable_parse_type(args, &myidx, &curproxy->table.type, &curproxy->table.key_size) != 0) {
-                                       ha_alert("parsing [%s:%d] : stick-table: unknown type '%s'.\n",
-                                                file, linenum, args[myidx]);
-                                       err_code |= ERR_ALERT | ERR_FATAL;
-                                       goto out;
-                               }
-                               /* myidx already points to next arg */
-                       }
-                       else if (strcmp(args[myidx], "store") == 0) {
-                               int type, err;
-                               char *cw, *nw, *sa;
-
-                               myidx++;
-                               nw = args[myidx];
-                               while (*nw) {
-                                       /* the "store" keyword supports a comma-separated list */
-                                       cw = nw;
-                                       sa = NULL; /* store arg */
-                                       while (*nw && *nw != ',') {
-                                               if (*nw == '(') {
-                                                       *nw = 0;
-                                                       sa = ++nw;
-                                                       while (*nw != ')') {
-                                                               if (!*nw) {
-                                                                       ha_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);
-                                       if (type < 0) {
-                                               ha_alert("parsing [%s:%d] : %s: unknown store option '%s'.\n",
-                                                        file, linenum, args[0], cw);
-                                               err_code |= ERR_ALERT | ERR_FATAL;
-                                               goto out;
-                                       }
-
-                                       err = stktable_alloc_data_type(&curproxy->table, type, sa);
-                                       switch (err) {
-                                       case PE_NONE: break;
-                                       case PE_EXIST:
-                                               ha_warning("parsing [%s:%d]: %s: store option '%s' already enabled, ignored.\n",
-                                                          file, linenum, args[0], cw);
-                                               err_code |= ERR_WARN;
-                                               break;
-
-                                       case PE_ARG_MISSING:
-                                               ha_alert("parsing [%s:%d] : %s: missing argument to store option '%s'.\n",
-                                                        file, linenum, args[0], cw);
-                                               err_code |= ERR_ALERT | ERR_FATAL;
-                                               goto out;
-
-                                       case PE_ARG_NOT_USED:
-                                               ha_alert("parsing [%s:%d] : %s: unexpected argument to store option '%s'.\n",
-                                                        file, linenum, args[0], cw);
-                                               err_code |= ERR_ALERT | ERR_FATAL;
-                                               goto out;
-
-                                       default:
-                                               ha_alert("parsing [%s:%d] : %s: error when processing store option '%s'.\n",
-                                                        file, linenum, args[0], cw);
-                                               err_code |= ERR_ALERT | ERR_FATAL;
-                                               goto out;
-                                       }
-                               }
-                               myidx++;
-                       }
-                       else {
-                               ha_alert("parsing [%s:%d] : stick-table: unknown argument '%s'.\n",
-                                        file, linenum, args[myidx]);
-                               err_code |= ERR_ALERT | ERR_FATAL;
-                               goto out;
-                       }
-               }
-
-               if (!curproxy->table.size) {
-                       ha_alert("parsing [%s:%d] : stick-table: missing size.\n",
-                                file, linenum);
-                       err_code |= ERR_ALERT | ERR_FATAL;
+               err_code |= parse_stick_table(file, linenum, args, &curproxy->table, curproxy->id, NULL);
+               if (err_code & ERR_FATAL)
                        goto out;
-               }
 
-               if (curproxy->table.type == (unsigned int)-1) {
-                       ha_alert("parsing [%s:%d] : stick-table: missing type.\n",
-                                file, linenum);
-                       err_code |= ERR_ALERT | ERR_FATAL;
-                       goto out;
-               }
+               /* Store the proxy in the stick-table. */
+               curproxy->table->proxy = curproxy;
        }
        else if (!strcmp(args[0], "stick")) {
                struct sticking_rule *rule;
index e24ef65b6ffd754f99dc6473e07279ad5c3e547d..d8053dc04f3262edd8b3cd5e790cd46242ec8f54 100644 (file)
@@ -15,6 +15,7 @@
 #include <errno.h>
 
 #include <common/config.h>
+#include <common/cfgparse.h>
 #include <common/initcall.h>
 #include <common/memory.h>
 #include <common/mini-clist.h>
@@ -664,6 +665,197 @@ int stktable_parse_type(char **args, int *myidx, unsigned long *type, size_t *ke
        return 1;
 }
 
+/*
+ * Parse a line with <linenum> as number in <file> configuration file to configure the
+ * stick-table with <t> as address and  <id> as ID.
+ * <peers> provides the "peers" section pointer only if this function is called from a "peers" section.
+ * Return an error status with ERR_* flags set if required, 0 if no error was encountered.
+ */
+int parse_stick_table(const char *file, int linenum, char **args,
+                      struct stktable *t, char *id, struct peers *peers)
+{
+       int err_code = 0;
+       int idx = 1;
+       unsigned int val;
+
+       if (!id || !*id) {
+               ha_alert("parsing [%s:%d] : %s: ID not provided.\n", file, linenum, args[0]);
+               err_code |= ERR_ALERT | ERR_ABORT;
+               goto out;
+       }
+
+       /* Store the "peers" section if this function is called from a "peers" section. */
+       if (peers) {
+               t->peers.p = peers;
+               idx++;
+       }
+
+       t->id =  id;
+       t->type = (unsigned int)-1;
+       t->conf.file = file;
+       t->conf.line = linenum;
+
+       while (*args[idx]) {
+               const char *err;
+
+               if (strcmp(args[idx], "size") == 0) {
+                       idx++;
+                       if (!*(args[idx])) {
+                               ha_alert("parsing [%s:%d] : %s: missing argument after '%s'.\n",
+                                        file, linenum, args[0], args[idx-1]);
+                               err_code |= ERR_ALERT | ERR_FATAL;
+                               goto out;
+                       }
+                       if ((err = parse_size_err(args[idx], &t->size))) {
+                               ha_alert("parsing [%s:%d] : %s: unexpected character '%c' in argument of '%s'.\n",
+                                        file, linenum, args[0], *err, args[idx-1]);
+                               err_code |= ERR_ALERT | ERR_FATAL;
+                               goto out;
+                       }
+                       idx++;
+               }
+               /* This argument does not exit in "peers" section. */
+               else if (!peers && strcmp(args[idx], "peers") == 0) {
+                       idx++;
+                       if (!*(args[idx])) {
+                               ha_alert("parsing [%s:%d] : %s: missing argument after '%s'.\n",
+                                        file, linenum, args[0], args[idx-1]);
+                               err_code |= ERR_ALERT | ERR_FATAL;
+                               goto out;
+                       }
+                       t->peers.name = strdup(args[idx++]);
+               }
+               else if (strcmp(args[idx], "expire") == 0) {
+                       idx++;
+                       if (!*(args[idx])) {
+                               ha_alert("parsing [%s:%d] : %s: missing argument after '%s'.\n",
+                                        file, linenum, args[0], args[idx-1]);
+                               err_code |= ERR_ALERT | ERR_FATAL;
+                               goto out;
+                       }
+                       err = parse_time_err(args[idx], &val, TIME_UNIT_MS);
+                       if (err) {
+                               ha_alert("parsing [%s:%d] : %s: unexpected character '%c' in argument of '%s'.\n",
+                                        file, linenum, args[0], *err, args[idx-1]);
+                               err_code |= ERR_ALERT | ERR_FATAL;
+                               goto out;
+                       }
+                       if (val > INT_MAX) {
+                               ha_alert("parsing [%s:%d] : Expire value [%u]ms exceeds maxmimum value of 24.85 days.\n",
+                                        file, linenum, val);
+                               err_code |= ERR_ALERT | ERR_FATAL;
+                               goto out;
+                       }
+                       t->expire = val;
+                       idx++;
+               }
+               else if (strcmp(args[idx], "nopurge") == 0) {
+                       t->nopurge = 1;
+                       idx++;
+               }
+               else if (strcmp(args[idx], "type") == 0) {
+                       idx++;
+                       if (stktable_parse_type(args, &idx, &t->type, &t->key_size) != 0) {
+                               ha_alert("parsing [%s:%d] : %s: unknown type '%s'.\n",
+                                        file, linenum, args[0], args[idx]);
+                               err_code |= ERR_ALERT | ERR_FATAL;
+                               goto out;
+                       }
+                       /* idx already points to next arg */
+               }
+               else if (strcmp(args[idx], "store") == 0) {
+                       int type, err;
+                       char *cw, *nw, *sa;
+
+                       idx++;
+                       nw = args[idx];
+                       while (*nw) {
+                               /* the "store" keyword supports a comma-separated list */
+                               cw = nw;
+                               sa = NULL; /* store arg */
+                               while (*nw && *nw != ',') {
+                                       if (*nw == '(') {
+                                               *nw = 0;
+                                               sa = ++nw;
+                                               while (*nw != ')') {
+                                                       if (!*nw) {
+                                                               ha_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);
+                               if (type < 0) {
+                                       ha_alert("parsing [%s:%d] : %s: unknown store option '%s'.\n",
+                                                file, linenum, args[0], cw);
+                                       err_code |= ERR_ALERT | ERR_FATAL;
+                                       goto out;
+                               }
+
+                               err = stktable_alloc_data_type(t, type, sa);
+                               switch (err) {
+                               case PE_NONE: break;
+                               case PE_EXIST:
+                                       ha_warning("parsing [%s:%d]: %s: store option '%s' already enabled, ignored.\n",
+                                                  file, linenum, args[0], cw);
+                                       err_code |= ERR_WARN;
+                                       break;
+
+                               case PE_ARG_MISSING:
+                                       ha_alert("parsing [%s:%d] : %s: missing argument to store option '%s'.\n",
+                                                file, linenum, args[0], cw);
+                                       err_code |= ERR_ALERT | ERR_FATAL;
+                                       goto out;
+
+                               case PE_ARG_NOT_USED:
+                                       ha_alert("parsing [%s:%d] : %s: unexpected argument to store option '%s'.\n",
+                                                file, linenum, args[0], cw);
+                                       err_code |= ERR_ALERT | ERR_FATAL;
+                                       goto out;
+
+                               default:
+                                       ha_alert("parsing [%s:%d] : %s: error when processing store option '%s'.\n",
+                                                file, linenum, args[0], cw);
+                                       err_code |= ERR_ALERT | ERR_FATAL;
+                                       goto out;
+                               }
+                       }
+                       idx++;
+               }
+               else {
+                       ha_alert("parsing [%s:%d] : %s: unknown argument '%s'.\n",
+                                file, linenum, args[0], args[idx]);
+                       err_code |= ERR_ALERT | ERR_FATAL;
+                       goto out;
+               }
+       }
+
+       if (!t->size) {
+               ha_alert("parsing [%s:%d] : %s: missing size.\n",
+                        file, linenum, args[0]);
+               err_code |= ERR_ALERT | ERR_FATAL;
+               goto out;
+       }
+
+       if (t->type == (unsigned int)-1) {
+               ha_alert("parsing [%s:%d] : %s: missing type.\n",
+                        file, linenum, args[0]);
+               err_code |= ERR_ALERT | ERR_FATAL;
+               goto out;
+       }
+
+ out:
+       return err_code;
+}
+
 /* Prepares a stktable_key from a sample <smp> to search into table <t>.
  * Note that the sample *is* modified and that the returned key may point
  * to it, so the sample must not be modified afterwards before the lookup.