diff --git a/include/common/cfgparse.h b/include/common/cfgparse.h index 35e5614e9..5486b7e99 100644 --- a/include/common/cfgparse.h +++ b/include/common/cfgparse.h @@ -33,6 +33,14 @@ #define CFG_GLOBAL 1 #define CFG_LISTEN 2 +/* list of overlapping ACL rules that we can detect */ +enum { + CFG_ACL_TCP = 1, + CFG_ACL_BLOCK = 2, + CFG_ACL_REDIR = 4, + CFG_ACL_BACKEND = 8, +}; + struct cfg_keyword { int section; /* section type for this keyword */ const char *kw; /* the keyword itself */ @@ -58,6 +66,7 @@ struct cfg_kw_list { extern int cfg_maxpconn; extern int cfg_maxconn; +extern unsigned int acl_seen; /* CFG_ACL_* for current proxy being parsed */ int cfg_parse_global(const char *file, int linenum, char **args, int inv); int cfg_parse_listen(const char *file, int linenum, char **args, int inv); diff --git a/src/cfgparse.c b/src/cfgparse.c index c3344738a..e5d684002 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -129,7 +129,8 @@ static const struct cfg_opt cfg_opts2[] = static char *cursection = NULL; static struct proxy defproxy; /* fake proxy used to assign default values on all instances */ int cfg_maxpconn = DEFAULT_MAXCONN; /* # of simultaneous connections per proxy (-N) */ -int cfg_maxconn = 0; /* # of simultaneous connections, (-n) */ +int cfg_maxconn = 0; /* # of simultaneous connections, (-n) */ +unsigned int acl_seen = 0; /* CFG_ACL_* */ /* List head of all known configuration keywords */ static struct cfg_kw_list cfg_keywords = { @@ -636,7 +637,8 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv) Alert("parsing [%s:%d] : out of memory.\n", file, linenum); return -1; } - + + acl_seen = 0; curproxy->next = proxy; proxy = curproxy; LIST_INIT(&curproxy->pendconns); @@ -1204,6 +1206,16 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv) } cond->line = linenum; LIST_ADDQ(&curproxy->block_cond, &cond->list); + + if (!(acl_seen & CFG_ACL_BLOCK)) { + if (acl_seen & CFG_ACL_REDIR) + Warning("parsing [%s:%d] : a '%s' rule placed after a 'redirect' rule will still be processed before.\n", + file, linenum, args[0]); + if (acl_seen & CFG_ACL_BACKEND) + Warning("parsing [%s:%d] : a '%s' rule placed after a 'use_backend' rule will still be processed before.\n", + file, linenum, args[0]); + acl_seen |= CFG_ACL_BLOCK; + } } else if (!strcmp(args[0], "redirect")) { int pol = ACL_COND_NONE; @@ -1340,6 +1352,13 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv) rule->flags = flags; LIST_INIT(&rule->list); LIST_ADDQ(&curproxy->redirect_rules, &rule->list); + + if (!(acl_seen & CFG_ACL_REDIR)) { + if (acl_seen & CFG_ACL_BACKEND) + Warning("parsing [%s:%d] : a '%s' rule placed after a 'use_backend' rule will still be processed before.\n", + file, linenum, args[0]); + acl_seen |= CFG_ACL_REDIR; + } } else if (!strcmp(args[0], "use_backend")) { int pol = ACL_COND_NONE; @@ -1392,6 +1411,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv) rule->be.name = strdup(args[1]); LIST_INIT(&rule->list); LIST_ADDQ(&curproxy->switching_rules, &rule->list); + acl_seen |= CFG_ACL_BACKEND; } else if (!strcmp(args[0], "stats")) { if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL)) diff --git a/src/proto_tcp.c b/src/proto_tcp.c index ec9d23a0c..6d10b464f 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -564,6 +564,7 @@ static int tcp_parse_tcp_req(char **args, int section_type, struct proxy *curpx, rule->action = action; LIST_INIT(&rule->list); LIST_ADDQ(&curpx->tcp_req.inspect_rules, &rule->list); + acl_seen |= CFG_ACL_TCP; return warn; }