mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-13 23:14:46 +00:00
MINOR: config: Extract the code of "stick-table" line parsing.
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.
This commit is contained in:
parent
034c88cf03
commit
d456aa4ac2
@ -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);
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user