mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-03-04 10:28:48 +00:00
[MEDIUM] acl: when possible, report the name and requirements of ACLs in warnings
When an ACL is referenced at a wrong place (eg: response during request, layer7 during layer4), try to indicate precisely the name and requirements of this ACL. Only the first faulty ACL is returned. A small change consisting in iterating that way may improve reports : cap = ACL_USE_any_unexpected while ((acl=cond_find_require(cond, cap))) { warning() cap &= ~acl->requires; } This will report the first ACL of each unsupported type. But doing so will mangle the error reporting a lot, so we need to rework error reports first.
This commit is contained in:
parent
0ceba5af74
commit
dd64f8d394
@ -87,6 +87,11 @@ struct acl_cond *parse_acl_cond(const char **args, struct list *known_acl, int p
|
||||
*/
|
||||
int acl_exec_cond(struct acl_cond *cond, struct proxy *px, struct session *l4, void *l7, int dir);
|
||||
|
||||
/* Reports a pointer to the first ACL used in condition <cond> which requires
|
||||
* at least one of the USE_FLAGS in <require>. Returns NULL if none matches.
|
||||
*/
|
||||
struct acl *cond_find_require(struct acl_cond *cond, unsigned int require);
|
||||
|
||||
/* Return a pointer to the ACL <name> within the list starting at <head>, or
|
||||
* NULL if not found.
|
||||
*/
|
||||
|
24
src/acl.c
24
src/acl.c
@ -1096,6 +1096,30 @@ int acl_exec_cond(struct acl_cond *cond, struct proxy *px, struct session *l4, v
|
||||
}
|
||||
|
||||
|
||||
/* Reports a pointer to the first ACL used in condition <cond> which requires
|
||||
* at least one of the USE_FLAGS in <require>. Returns NULL if none matches.
|
||||
* The construct is almost the same as for acl_exec_cond() since we're walking
|
||||
* down the ACL tree as well. It is important that the tree is really walked
|
||||
* through and never cached, because that way, this function can be used as a
|
||||
* late check.
|
||||
*/
|
||||
struct acl *cond_find_require(struct acl_cond *cond, unsigned int require)
|
||||
{
|
||||
struct acl_term_suite *suite;
|
||||
struct acl_term *term;
|
||||
struct acl *acl;
|
||||
|
||||
list_for_each_entry(suite, &cond->suites, list) {
|
||||
list_for_each_entry(term, &suite->terms, list) {
|
||||
acl = term->acl;
|
||||
if (acl->requires & require)
|
||||
return acl;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* All supported keywords must be declared here. */
|
||||
/************************************************************************/
|
||||
|
@ -1244,8 +1244,13 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv)
|
||||
|
||||
cond->line = linenum;
|
||||
if (cond->requires & ACL_USE_RTR_ANY) {
|
||||
Warning("parsing [%s:%d] : switching rule involves some response-only criteria which will be ignored.\n",
|
||||
file, linenum);
|
||||
struct acl *acl;
|
||||
const char *name;
|
||||
|
||||
acl = cond_find_require(cond, ACL_USE_RTR_ANY);
|
||||
name = acl ? acl->name : "(unknown)";
|
||||
Warning("parsing [%s:%d] : acl '%s' involves some response-only criteria which will be ignored.\n",
|
||||
file, linenum, name);
|
||||
}
|
||||
|
||||
rule = (struct switching_rule *)calloc(1, sizeof(*rule));
|
||||
|
@ -377,6 +377,7 @@ static int tcp_parse_tcp_req(char **args, int section_type, struct proxy *curpx,
|
||||
|
||||
if (!strcmp(args[1], "content")) {
|
||||
int action;
|
||||
int warn = 0;
|
||||
int pol = ACL_COND_NONE;
|
||||
struct acl_cond *cond;
|
||||
struct tcp_rule *rule;
|
||||
@ -410,17 +411,32 @@ static int tcp_parse_tcp_req(char **args, int section_type, struct proxy *curpx,
|
||||
if (pol != ACL_COND_NONE &&
|
||||
(cond = parse_acl_cond((const char **)args+4, &curpx->acl, pol)) == NULL) {
|
||||
retlen = snprintf(err, errlen,
|
||||
"Error detected in %s '%s' while parsing '%s' condition",
|
||||
"error detected in %s '%s' while parsing '%s' condition",
|
||||
proxy_type_str(curpx), curpx->id, args[3]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// FIXME: how to set this ?
|
||||
// cond->line = linenum;
|
||||
if (cond->requires & (ACL_USE_RTR_ANY | ACL_USE_L7_ANY)) {
|
||||
struct acl *acl;
|
||||
const char *name;
|
||||
|
||||
acl = cond_find_require(cond, ACL_USE_RTR_ANY|ACL_USE_L7_ANY);
|
||||
name = acl ? acl->name : "(unknown)";
|
||||
|
||||
retlen = snprintf(err, errlen,
|
||||
"acl '%s' involves some %s criteria which will be ignored.",
|
||||
name,
|
||||
(acl->requires & ACL_USE_RTR_ANY) ? "response-only" : "layer 7");
|
||||
warn++;
|
||||
}
|
||||
rule = (struct tcp_rule *)calloc(1, sizeof(*rule));
|
||||
rule->cond = cond;
|
||||
rule->action = action;
|
||||
LIST_INIT(&rule->list);
|
||||
LIST_ADDQ(&curpx->tcp_req.inspect_rules, &rule->list);
|
||||
return 0;
|
||||
return warn;
|
||||
}
|
||||
|
||||
snprintf(err, errlen, "unknown argument '%s' after '%s' in %s '%s'",
|
||||
|
Loading…
Reference in New Issue
Block a user