From: Willy Tarreau Date: Fri, 20 May 2022 13:41:45 +0000 (+0200) Subject: MINOR: listener: provide a function to process all of a bind_conf's arguments X-Git-Tag: v2.6-dev11~19 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3882d2a96ca1d37f60ea81f3ee993c39d808ce32;p=thirdparty%2Fhaproxy.git MINOR: listener: provide a function to process all of a bind_conf's arguments The "bind" parsing code was duplicated for the peers section and as a result it wasn't kept updated, resulting in slightly different error behavior (e.g. errors were not freed, warnings were emitted as alerts) Let's first unify it into a new dedicated function that properly reports and frees the error. --- diff --git a/include/haproxy/listener.h b/include/haproxy/listener.h index 5bbbad40e3..1b918b19ac 100644 --- a/include/haproxy/listener.h +++ b/include/haproxy/listener.h @@ -172,6 +172,8 @@ struct bind_kw *bind_find_kw(const char *kw); /* Dumps all registered "bind" keywords to the string pointer. */ void bind_dump_kws(char **out); const char *bind_find_best_kw(const char *word); +int bind_parse_args_list(struct bind_conf *bind_conf, char **args, int cur_arg, + const char *section, const char *file, int linenum); void bind_recount_thread_bits(struct bind_conf *conf); unsigned int bind_map_thread_id(const struct bind_conf *conf, unsigned int r); diff --git a/src/listener.c b/src/listener.c index 2c04049211..3b7b8cfae3 100644 --- a/src/listener.c +++ b/src/listener.c @@ -1565,6 +1565,74 @@ static int bind_parse_id(char **args, int cur_arg, struct proxy *px, struct bind return 0; } +/* Complete a bind_conf by parsing the args after the address. is the + * arguments array, is the first one to be considered.
is + * the section name to report in error messages, and and are + * the file name and line number respectively. Note that args[0..1] are used + * in error messages to provide some context. The return value is an error + * code, zero on success or an OR of ERR_{FATAL,ABORT,ALERT,WARN}. + */ +int bind_parse_args_list(struct bind_conf *bind_conf, char **args, int cur_arg, const char *section, const char *file, int linenum) +{ + int err_code = 0; + + while (*(args[cur_arg])) { + struct bind_kw *kw; + const char *best; + + kw = bind_find_kw(args[cur_arg]); + if (kw) { + char *err = NULL; + int code; + + if (!kw->parse) { + ha_alert("parsing [%s:%d] : '%s %s' in section '%s' : '%s' option is not implemented in this version (check build options).\n", + file, linenum, args[0], args[1], section, args[cur_arg]); + cur_arg += 1 + kw->skip ; + err_code |= ERR_ALERT | ERR_FATAL; + goto out; + } + + code = kw->parse(args, cur_arg, bind_conf->frontend, bind_conf, &err); + err_code |= code; + + if (code) { + if (err && *err) { + indent_msg(&err, 2); + if (((code & (ERR_WARN|ERR_ALERT)) == ERR_WARN)) + ha_warning("parsing [%s:%d] : '%s %s' in section '%s' : %s\n", file, linenum, args[0], args[1], section, err); + else + ha_alert("parsing [%s:%d] : '%s %s' in section '%s' : %s\n", file, linenum, args[0], args[1], section, err); + } + else + ha_alert("parsing [%s:%d] : '%s %s' in section '%s' : error encountered while processing '%s'.\n", + file, linenum, args[0], args[1], section, args[cur_arg]); + if (code & ERR_FATAL) { + free(err); + cur_arg += 1 + kw->skip; + goto out; + } + } + free(err); + cur_arg += 1 + kw->skip; + continue; + } + + best = bind_find_best_kw(args[cur_arg]); + if (best) + ha_alert("parsing [%s:%d] : '%s %s' in section '%s': unknown keyword '%s'; did you mean '%s' maybe ?\n", + file, linenum, args[0], args[1], section, args[cur_arg], best); + else + ha_alert("parsing [%s:%d] : '%s %s' in section '%s': unknown keyword '%s'.\n", + file, linenum, args[0], args[1], section, args[cur_arg]); + + err_code |= ERR_ALERT | ERR_FATAL; + goto out; + } + out: + return err_code; +} + /* parse the "maxconn" bind keyword */ static int bind_parse_maxconn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err) {