mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-22 14:21:25 +02: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_init(struct stktable *t);
|
||||||
int stktable_parse_type(char **args, int *idx, unsigned long *type, size_t *key_size);
|
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_get_entry(struct stktable *table, struct stktable_key *key);
|
||||||
struct stksess *stktable_set_entry(struct stktable *table, struct stksess *nts);
|
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);
|
void stktable_touch_with_exp(struct stktable *t, struct stksess *ts, int decrefcount, int expire);
|
||||||
|
@ -144,6 +144,13 @@ struct stksess {
|
|||||||
/* stick table */
|
/* stick table */
|
||||||
struct stktable {
|
struct stktable {
|
||||||
char *id; /* table id name */
|
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 keys; /* head of sticky session tree */
|
||||||
struct eb_root exps; /* head of sticky session expiration tree */
|
struct eb_root exps; /* head of sticky session expiration tree */
|
||||||
struct eb_root updates; /* head of sticky updates sequence tree */
|
struct eb_root updates; /* head of sticky updates sequence tree */
|
||||||
@ -175,6 +182,7 @@ struct stktable {
|
|||||||
unsigned int u;
|
unsigned int u;
|
||||||
void *p;
|
void *p;
|
||||||
} data_arg[STKTABLE_DATA_TYPES]; /* optional argument of each data type */
|
} 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];
|
extern struct stktable_data_type stktable_data_types[STKTABLE_DATA_TYPES];
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include <proto/protocol.h>
|
#include <proto/protocol.h>
|
||||||
#include <proto/proxy.h>
|
#include <proto/proxy.h>
|
||||||
#include <proto/server.h>
|
#include <proto/server.h>
|
||||||
|
#include <proto/stick_table.h>
|
||||||
|
|
||||||
/* Report a warning if a rule is placed after a 'tcp-request session' rule.
|
/* Report a warning if a rule is placed after a 'tcp-request session' rule.
|
||||||
* Return 1 if the warning has been emitted, otherwise 0.
|
* 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);
|
LIST_ADDQ(&curproxy->persist_rules, &rule->list);
|
||||||
}
|
}
|
||||||
else if (!strcmp(args[0], "stick-table")) {
|
else if (!strcmp(args[0], "stick-table")) {
|
||||||
int myidx = 1;
|
|
||||||
struct proxy *other;
|
struct proxy *other;
|
||||||
|
|
||||||
if (curproxy == &defproxy) {
|
if (curproxy == &defproxy) {
|
||||||
@ -1728,163 +1728,12 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
curproxy->table.id = curproxy->id;
|
err_code |= parse_stick_table(file, linenum, args, &curproxy->table, curproxy->id, NULL);
|
||||||
curproxy->table.type = (unsigned int)-1;
|
if (err_code & ERR_FATAL)
|
||||||
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;
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
|
|
||||||
if (curproxy->table.type == (unsigned int)-1) {
|
/* Store the proxy in the stick-table. */
|
||||||
ha_alert("parsing [%s:%d] : stick-table: missing type.\n",
|
curproxy->table->proxy = curproxy;
|
||||||
file, linenum);
|
|
||||||
err_code |= ERR_ALERT | ERR_FATAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (!strcmp(args[0], "stick")) {
|
else if (!strcmp(args[0], "stick")) {
|
||||||
struct sticking_rule *rule;
|
struct sticking_rule *rule;
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include <common/config.h>
|
#include <common/config.h>
|
||||||
|
#include <common/cfgparse.h>
|
||||||
#include <common/initcall.h>
|
#include <common/initcall.h>
|
||||||
#include <common/memory.h>
|
#include <common/memory.h>
|
||||||
#include <common/mini-clist.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;
|
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>.
|
/* 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
|
* 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.
|
* to it, so the sample must not be modified afterwards before the lookup.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user