haproxy/include/types/arg.h
Willy Tarreau a4312fa28e MAJOR: sample: maintain a per-proxy list of the fetch args to resolve
While ACL args were resolved after all the config was parsed, it was not the
case with sample fetch args because they're almost everywhere now.

The issue is that ACLs now solely rely on sample fetches, so their args
resolving doesn't work anymore. And many fetches involving a server, a
proxy or a userlist don't work at all.

The real issue is that at the bottom layers we have no information about
proxies, line numbers, even ACLs in order to report understandable errors,
and that at the top layers we have no visibility over the locations where
fetches are referenced (think log node).

After failing multiple unsatisfying solutions attempts, we now have a new
concept of args list. The principle is that every proxy has a list head
which contains a number of indications such as the config keyword, the
context where it's used, the file and line number, etc... and a list of
arguments. This list head is of the same type as the elements, so it
serves as a template for adding new elements. This way, it is filled from
top to bottom by the callers with the information they have (eg: line
numbers, ACL name, ...) and the lower layers just have to duplicate it and
add an element when they face an argument they cannot resolve yet.

Then at the end of the configuration parsing, a loop passes over each
proxy's list and resolves all the args in sequence. And this way there is
all necessary information to report verbose errors.

The first immediate benefit is that for the first time we got very precise
location of issues (arg number in a keyword in its context, ...). Second,
in order to do this we had to parse log-format and unique-id-format a bit
earlier, so that was a great opportunity for doing so when the directives
are encountered (unless it's a default section). This way, the recorded
line numbers for these args are the ones of the place where the log format
is declared, not the end of the file.

Userlists report slightly more information now. They're the only remaining
ones in the ACL resolving function.
2013-04-03 02:13:02 +02:00

106 lines
3.7 KiB
C

/*
* include/types/arg.h
* This file contains structure declarations for generaic argument parsing.
*
* Copyright 2012 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
* License as published by the Free Software Foundation, version 2.1
* exclusively.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _TYPES_ARG_H
#define _TYPES_ARG_H
#include <sys/socket.h>
#include <netinet/in.h>
#include <common/chunk.h>
#include <common/mini-clist.h>
enum {
ARGT_STOP = 0, /* end of the arg list */
ARGT_UINT, /* unsigned integer, which is a positive integer without any sign */
ARGT_SINT, /* signed integer, the sign (+/-) was explicit. Falls back to UINT if no sign. */
ARGT_STR, /* string */
ARGT_IPV4, /* an IPv4 address */
ARGT_MSK4, /* an IPv4 address mask (integer or dotted), stored as ARGT_IPV4 */
ARGT_IPV6, /* an IPv6 address */
ARGT_MSK6, /* an IPv6 address mask (integer or dotted), stored as ARGT_IPV4 */
ARGT_TIME, /* a delay in ms by default, stored as ARGT_UINT */
ARGT_SIZE, /* a size in bytes by default, stored as ARGT_UINT */
ARGT_FE, /* a pointer to a frontend only */
ARGT_BE, /* a pointer to a backend only */
ARGT_TAB, /* a pointer to a stick table */
ARGT_SRV, /* a pointer to a server */
ARGT_USR, /* a pointer to a user list */
ARGT_UNASSIGNED15, /* will probably be used for variables later */
ARGT_NBTYPES /* no more values past 15 */
};
/* context where arguments are used, in order to help error reporting */
enum {
ARGC_ACL = 0, /* ACL */
ARGC_STK, /* sticking rule */
ARGC_TRK, /* tracking rule */
ARGC_LOG, /* log-format */
ARGC_HDR, /* add-header */
ARGC_UIF, /* unique-id-format */
};
/* some types that are externally defined */
struct proxy;
struct server;
struct userlist;
union arg_data {
unsigned int uint; /* used for uint, time, size */
int sint;
struct chunk str;
struct in_addr ipv4;
struct in6_addr ipv6;
struct proxy *prx; /* used for fe, be, tables */
struct server *srv;
struct userlist *usr;
};
struct arg {
unsigned char type; /* argument type, ARGT_* */
unsigned char unresolved; /* argument contains a string in <str> that must be resolved and freed */
union arg_data data; /* argument data */
};
/* arg lists are used to store information about arguments that could not be
* resolved when parsing the configuration. The head is an arg_list which
* serves as a template to create new entries. Nothing here is allocated,
* so plain copies are OK.
*/
struct arg_list {
struct list list; /* chaining with other arg_list, or list head */
struct arg *arg; /* pointer to the arg, NULL on list head */
int arg_pos; /* argument position */
int ctx; /* context where the arg is used (ARGC_*) */
const char *kw; /* keyword making use of these args */
const char *conv; /* conv keyword when in conv, otherwise NULL */
const char *file; /* file name where the args are referenced */
int line; /* line number where the args are referenced */
};
#endif /* _TYPES_ARG_H */
/*
* Local variables:
* c-indent-level: 8
* c-basic-offset: 8
* End:
*/