From: Willy Tarreau Date: Sun, 15 Mar 2009 14:23:16 +0000 (+0100) Subject: [CLEANUP] config: catch and report some possibly wrong rule ordering X-Git-Tag: v1.3.16~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5af24efee92713d89c7a8a7e47c864129514294f;p=thirdparty%2Fhaproxy.git [CLEANUP] config: catch and report some possibly wrong rule ordering There are some configurations in which redirect rules are declared after use_backend rules. We can also find "block" rules after any of these ones. The processing sequence is : - block - redirect - use_backend So as of now we try to detect wrong ordering to warn the user about a possibly undesired behaviour. --- diff --git a/include/common/cfgparse.h b/include/common/cfgparse.h index 35e5614e94..5486b7e991 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 c3344738a9..e5d684002d 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 ec9d23a0c9..6d10b464f9 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; }