diff --git a/include/common/cfgparse.h b/include/common/cfgparse.h index c3355ca44..c003bd3b0 100644 --- a/include/common/cfgparse.h +++ b/include/common/cfgparse.h @@ -66,6 +66,8 @@ extern char *cfg_scope; 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); +int cfg_parse_track_sc_num(unsigned int *track_sc_num, + const char *arg, const char *end, char **err); int readcfgfile(const char *file); void cfg_register_keywords(struct cfg_kw_list *kwl); void cfg_unregister_keywords(struct cfg_kw_list *kwl); diff --git a/src/cfgparse.c b/src/cfgparse.c index eea820aa5..2e10e3537 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -7120,6 +7120,31 @@ cfg_parse_scope(const char *file, int linenum, char *line) return err_code; } +int +cfg_parse_track_sc_num(unsigned int *track_sc_num, + const char *arg, const char *end, char **errmsg) +{ + const char *p; + unsigned int num; + + p = arg; + num = read_uint64(&arg, end); + + if (arg != end) { + memprintf(errmsg, "Wrong track-sc number '%s'", p); + return -1; + } + + if (num >= MAX_SESS_STKCTR) { + memprintf(errmsg, "%u track-sc number exceeding " + "%d (MAX_SESS_STKCTR-1) value", num, MAX_SESS_STKCTR - 1); + return -1; + } + + *track_sc_num = num; + return 0; +} + /* * This function reads and parses the configuration file given in the argument. * Returns the error code, 0 if OK, or any combination of : diff --git a/src/proto_http.c b/src/proto_http.c index 64bd4109f..699017619 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -8543,16 +8544,24 @@ struct act_rule *parse_http_req_cond(const char **args, const char *file, int li proxy->conf.lfs_file = strdup(proxy->conf.args.file); proxy->conf.lfs_line = proxy->conf.args.line; cur_arg += 1; - } else if (strncmp(args[0], "track-sc", 8) == 0 && - args[0][9] == '\0' && args[0][8] >= '0' && - args[0][8] < '0' + MAX_SESS_STKCTR) { /* track-sc 0..9 */ + } else if (strncmp(args[0], "track-sc", 8) == 0) { struct sample_expr *expr; unsigned int where; char *err = NULL; + unsigned int tsc_num; + const char *tsc_num_str; cur_arg = 1; proxy->conf.args.ctx = ARGC_TRK; + tsc_num_str = &args[0][8]; + if (cfg_parse_track_sc_num(&tsc_num, tsc_num_str, tsc_num_str + strlen(tsc_num_str), &err) == -1) { + ha_alert("parsing [%s:%d] : error detected in %s '%s' while parsing 'http-request %s' rule : %s.\n", + file, linenum, proxy_type_str(proxy), proxy->id, args[0], err); + free(err); + goto out_err; + } + expr = sample_parse_expr((char **)args, &cur_arg, file, linenum, &err, &proxy->conf.args); if (!expr) { ha_alert("parsing [%s:%d] : error detected in %s '%s' while parsing 'http-request %s' rule : %s.\n", @@ -8589,7 +8598,7 @@ struct act_rule *parse_http_req_cond(const char **args, const char *file, int li cur_arg++; } rule->arg.trk_ctr.expr = expr; - rule->action = ACT_ACTION_TRK_SC0 + args[0][8] - '0'; + rule->action = ACT_ACTION_TRK_SC0 + tsc_num; rule->check_ptr = check_trk_action; } else if (strcmp(args[0], "redirect") == 0) { struct redirect_rule *redir; @@ -9148,16 +9157,24 @@ struct act_rule *parse_http_res_cond(const char **args, const char *file, int li redir->cond = NULL; cur_arg = 2; return rule; - } else if (strncmp(args[0], "track-sc", 8) == 0 && - args[0][9] == '\0' && args[0][8] >= '0' && - args[0][8] < '0' + MAX_SESS_STKCTR) { /* track-sc 0..9 */ + } else if (strncmp(args[0], "track-sc", 8) == 0) { struct sample_expr *expr; unsigned int where; char *err = NULL; + unsigned int tsc_num; + const char *tsc_num_str; cur_arg = 1; proxy->conf.args.ctx = ARGC_TRK; + tsc_num_str = &args[0][8]; + if (cfg_parse_track_sc_num(&tsc_num, tsc_num_str, tsc_num_str + strlen(tsc_num_str), &err) == -1) { + ha_alert("parsing [%s:%d] : error detected in %s '%s' while parsing 'http-response %s' rule : %s.\n", + file, linenum, proxy_type_str(proxy), proxy->id, args[0], err); + free(err); + goto out_err; + } + expr = sample_parse_expr((char **)args, &cur_arg, file, linenum, &err, &proxy->conf.args); if (!expr) { ha_alert("parsing [%s:%d] : error detected in %s '%s' while parsing 'http-response %s' rule : %s.\n", @@ -9194,7 +9211,7 @@ struct act_rule *parse_http_res_cond(const char **args, const char *file, int li cur_arg++; } rule->arg.trk_ctr.expr = expr; - rule->action = ACT_ACTION_TRK_SC0 + args[0][8] - '0'; + rule->action = ACT_ACTION_TRK_SC0 + tsc_num; rule->check_ptr = check_trk_action; } else if (((custom = action_http_res_custom(args[0])) != NULL)) { char *errmsg = NULL; diff --git a/src/tcp_rules.c b/src/tcp_rules.c index feee44163..deb34acf8 100644 --- a/src/tcp_rules.c +++ b/src/tcp_rules.c @@ -730,14 +730,20 @@ static int tcp_parse_request_rule(char **args, int arg, int section_type, rule->arg.cap.hdr = hdr; rule->action = ACT_TCP_CAPTURE; } - else if (strncmp(args[arg], "track-sc", 8) == 0 && - args[arg][9] == '\0' && args[arg][8] >= '0' && - args[arg][8] < '0' + MAX_SESS_STKCTR) { /* track-sc 0..9 */ + else if (strncmp(args[arg], "track-sc", 8) == 0) { struct sample_expr *expr; int kw = arg; + unsigned int tsc_num; + const char *tsc_num_str; arg++; + tsc_num_str = &args[kw][8]; + if (cfg_parse_track_sc_num(&tsc_num, tsc_num_str, tsc_num_str + strlen(tsc_num_str), err) == -1) { + memprintf(err, "'%s %s %s' : %s", args[0], args[1], args[kw], *err); + return -1; + } + curpx->conf.args.ctx = ARGC_TRK; expr = sample_parse_expr(args, &arg, file, line, err, &curpx->conf.args); if (!expr) { @@ -772,7 +778,7 @@ static int tcp_parse_request_rule(char **args, int arg, int section_type, arg++; } rule->arg.trk_ctr.expr = expr; - rule->action = ACT_ACTION_TRK_SC0 + args[kw][8] - '0'; + rule->action = ACT_ACTION_TRK_SC0 + tsc_num; rule->check_ptr = check_trk_action; } else if (strcmp(args[arg], "expect-proxy") == 0) {