diff --git a/include/haproxy/proxy.h b/include/haproxy/proxy.h index 177e71783..783154af6 100644 --- a/include/haproxy/proxy.h +++ b/include/haproxy/proxy.h @@ -84,6 +84,7 @@ void proxy_capture_error(struct proxy *proxy, int is_back, void proxy_adjust_all_maxconn(void); struct proxy *cli_find_frontend(struct appctx *appctx, const char *arg); struct proxy *cli_find_frontend(struct appctx *appctx, const char *arg); +int resolve_stick_rule(struct proxy *curproxy, struct sticking_rule *mrule); /* * This function returns a string containing the type of the proxy in a format diff --git a/src/cfgparse.c b/src/cfgparse.c index fc04fc479..9a28fae55 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -3243,71 +3243,22 @@ int check_config_validity() /* find the target table for 'stick' rules */ list_for_each_entry(mrule, &curproxy->sticking_rules, list) { - struct stktable *target; - curproxy->be_req_ana |= AN_REQ_STICKING_RULES; if (mrule->flags & STK_IS_STORE) curproxy->be_rsp_ana |= AN_RES_STORE_RULES; - if (mrule->table.name) - target = stktable_find_by_name(mrule->table.name); - else - target = curproxy->table; + if (!resolve_stick_rule(curproxy, mrule)) + cfgerr++; - if (!target) { - ha_alert("Proxy '%s': unable to find stick-table '%s'.\n", - curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id); - cfgerr++; - } - else if (!stktable_compatible_sample(mrule->expr, target->type)) { - ha_alert("Proxy '%s': type of fetch not usable with type of stick-table '%s'.\n", - curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id); - cfgerr++; - } - else { - ha_free(&mrule->table.name); - mrule->table.t = target; - stktable_alloc_data_type(target, STKTABLE_DT_SERVER_ID, NULL, NULL); - stktable_alloc_data_type(target, STKTABLE_DT_SERVER_KEY, NULL, NULL); - if (!in_proxies_list(target->proxies_list, curproxy)) { - curproxy->next_stkt_ref = target->proxies_list; - target->proxies_list = curproxy; - } - } err_code |= warnif_tcp_http_cond(curproxy, mrule->cond); } /* find the target table for 'store response' rules */ list_for_each_entry(mrule, &curproxy->storersp_rules, list) { - struct stktable *target; - curproxy->be_rsp_ana |= AN_RES_STORE_RULES; - if (mrule->table.name) - target = stktable_find_by_name(mrule->table.name); - else - target = curproxy->table; - - if (!target) { - ha_alert("Proxy '%s': unable to find store table '%s'.\n", - curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id); + if (!resolve_stick_rule(curproxy, mrule)) cfgerr++; - } - else if (!stktable_compatible_sample(mrule->expr, target->type)) { - ha_alert("Proxy '%s': type of fetch not usable with type of stick-table '%s'.\n", - curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id); - cfgerr++; - } - else { - ha_free(&mrule->table.name); - mrule->table.t = target; - stktable_alloc_data_type(target, STKTABLE_DT_SERVER_ID, NULL, NULL); - stktable_alloc_data_type(target, STKTABLE_DT_SERVER_KEY, NULL, NULL); - if (!in_proxies_list(target->proxies_list, curproxy)) { - curproxy->next_stkt_ref = target->proxies_list; - target->proxies_list = curproxy; - } - } } /* check validity for 'tcp-request' layer 4/5/6/7 rules */ diff --git a/src/proxy.c b/src/proxy.c index f8233fc78..7ff087190 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -130,6 +130,41 @@ const struct cfg_opt cfg_opts2[] = { NULL, 0, 0, 0 } }; +/* Helper function to resolve a single sticking rule after config parsing. + * Returns 1 for success and 0 for failure + */ +int resolve_stick_rule(struct proxy *curproxy, struct sticking_rule *mrule) +{ + struct stktable *target; + + if (mrule->table.name) + target = stktable_find_by_name(mrule->table.name); + else + target = curproxy->table; + + if (!target) { + ha_alert("Proxy '%s': unable to find stick-table '%s'.\n", + curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id); + return 0; + } + else if (!stktable_compatible_sample(mrule->expr, target->type)) { + ha_alert("Proxy '%s': type of fetch not usable with type of stick-table '%s'.\n", + curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id); + return 0; + } + + /* success */ + ha_free(&mrule->table.name); + mrule->table.t = target; + stktable_alloc_data_type(target, STKTABLE_DT_SERVER_ID, NULL, NULL); + stktable_alloc_data_type(target, STKTABLE_DT_SERVER_KEY, NULL, NULL); + if (!in_proxies_list(target->proxies_list, curproxy)) { + curproxy->next_stkt_ref = target->proxies_list; + target->proxies_list = curproxy; + } + return 1; +} + static void free_stick_rules(struct list *rules) { struct sticking_rule *rule, *ruleb;