summaryrefslogtreecommitdiffstats
path: root/src/cfgparse.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-03 05:11:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-03 05:11:10 +0000
commitcff6d757e3ba609c08ef2aaa00f07e53551e5bf6 (patch)
tree08c4fc3255483ad397d712edb4214ded49149fd9 /src/cfgparse.c
parentAdding upstream version 2.9.7. (diff)
downloadhaproxy-upstream/3.0.0.tar.xz
haproxy-upstream/3.0.0.zip
Adding upstream version 3.0.0.upstream/3.0.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--src/cfgparse.c222
1 files changed, 130 insertions, 92 deletions
diff --git a/src/cfgparse.c b/src/cfgparse.c
index bee3040..f5cde50 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -64,6 +64,7 @@
#include <haproxy/lb_fwlc.h>
#include <haproxy/lb_fwrr.h>
#include <haproxy/lb_map.h>
+#include <haproxy/lb_ss.h>
#include <haproxy/listener.h>
#include <haproxy/log.h>
#include <haproxy/sink.h>
@@ -633,8 +634,6 @@ static struct peer *cfg_peers_add_peer(struct peers *peers,
p->conf.file = strdup(file);
p->conf.line = linenum;
p->last_change = ns_to_sec(now_ns);
- p->xprt = xprt_get(XPRT_RAW);
- p->sock_init_arg = NULL;
HA_SPIN_INIT(&p->lock);
if (id)
p->id = strdup(id);
@@ -659,6 +658,7 @@ static struct peer *cfg_peers_add_peer(struct peers *peers,
int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
{
static struct peers *curpeers = NULL;
+ static struct sockaddr_storage *bind_addr = NULL;
static int nb_shards = 0;
struct peer *newpeer = NULL;
const char *err;
@@ -729,12 +729,20 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
* Newly allocated listener is at the end of the list
*/
l = LIST_ELEM(bind_conf->listeners.p, typeof(l), by_bind);
+ bind_addr = &l->rx.addr;
global.maxsock++; /* for the listening socket */
bind_line = 1;
if (cfg_peers->local) {
+ /* Local peer already defined using "server" line has no
+ * address yet, we should update its server's addr:port
+ * settings
+ */
newpeer = cfg_peers->local;
+ BUG_ON(!newpeer->srv);
+ newpeer->srv->addr = *bind_addr;
+ newpeer->srv->svc_port = get_host_port(bind_addr);
}
else {
/* This peer is local.
@@ -747,8 +755,6 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
goto out;
}
}
- newpeer->addr = l->rx.addr;
- newpeer->proto = l->rx.proto;
cur_arg++;
}
@@ -779,6 +785,7 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
else if (strcmp(args[0], "peers") == 0) { /* new peers section */
/* Initialize these static variables when entering a new "peers" section*/
bind_line = peer_line = 0;
+ bind_addr = NULL;
if (!*args[1]) {
ha_alert("parsing [%s:%d] : missing name for peers section.\n", file, linenum);
err_code |= ERR_ALERT | ERR_ABORT;
@@ -889,6 +896,15 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
goto out;
}
+ if (!parse_addr && bind_addr) {
+ /* local peer declared using "server": has name but no
+ * address: we use the known "bind" line addr settings
+ * as implicit server's addr and port.
+ */
+ curpeers->peers_fe->srv->addr = *bind_addr;
+ curpeers->peers_fe->srv->svc_port = get_host_port(bind_addr);
+ }
+
if (nb_shards && curpeers->peers_fe->srv->shard > nb_shards) {
ha_warning("parsing [%s:%d] : '%s %s' : %d peer shard greater value than %d shards value is ignored.\n",
file, linenum, args[0], args[1], curpeers->peers_fe->srv->shard, nb_shards);
@@ -902,16 +918,6 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm)
err_code |= ERR_WARN;
}
- /* If the peer address has just been parsed, let's copy it to <newpeer>
- * and initializes ->proto.
- */
- if (peer || !local_peer) {
- newpeer->addr = curpeers->peers_fe->srv->addr;
- newpeer->proto = protocol_lookup(newpeer->addr.ss_family, PROTO_TYPE_STREAM, 0);
- }
-
- newpeer->xprt = xprt_get(XPRT_RAW);
- newpeer->sock_init_arg = NULL;
HA_SPIN_INIT(&newpeer->lock);
newpeer->srv = curpeers->peers_fe->srv;
@@ -2699,7 +2705,6 @@ static int numa_detect_topology()
int check_config_validity()
{
int cfgerr = 0;
- struct proxy *curproxy = NULL;
struct proxy *init_proxies_list = NULL;
struct stktable *t;
struct server *newsrv = NULL;
@@ -2725,6 +2730,13 @@ int check_config_validity()
if (!global.tune.requri_len)
global.tune.requri_len = REQURI_LEN;
+ if (!global.thread_limit)
+ global.thread_limit = MAX_THREADS;
+
+#if defined(USE_THREAD)
+ if (thread_cpus_enabled_at_boot > global.thread_limit)
+ thread_cpus_enabled_at_boot = global.thread_limit;
+#endif
if (!global.nbthread) {
/* nbthread not set, thus automatic. In this case, and only if
* running on a single process, we enable the same number of
@@ -2748,13 +2760,24 @@ int check_config_validity()
global.nbtgroups = 1;
if (global.nbthread > MAX_THREADS_PER_GROUP * global.nbtgroups) {
- ha_diag_warning("nbthread not set, found %d CPUs, limiting to %d threads (maximum is %d per thread group). Please set nbthreads and/or increase thread-groups in the global section to silence this warning.\n",
- global.nbthread, MAX_THREADS_PER_GROUP * global.nbtgroups, MAX_THREADS_PER_GROUP);
+ if (global.nbthread <= global.thread_limit)
+ ha_diag_warning("nbthread not set, found %d CPUs, limiting to %d threads (maximum is %d per thread group). "
+ "Please set nbthreads and/or increase thread-groups in the global section to silence this warning.\n",
+ global.nbthread, MAX_THREADS_PER_GROUP * global.nbtgroups, MAX_THREADS_PER_GROUP);
global.nbthread = MAX_THREADS_PER_GROUP * global.nbtgroups;
}
+
+ if (global.nbthread > global.thread_limit)
+ global.nbthread = global.thread_limit;
}
#endif
}
+ else if (global.nbthread > global.thread_limit) {
+ ha_warning("nbthread forced to a higher value (%d) than the configured thread-hard-limit (%d), enforcing the limit. "
+ "Please fix either value to remove this warning.\n",
+ global.nbthread, global.thread_limit);
+ global.nbthread = global.thread_limit;
+ }
if (!global.nbtgroups)
global.nbtgroups = 1;
@@ -2879,8 +2902,7 @@ init_proxies_list_stage1:
#ifdef USE_OPENSSL
/* no-alpn ? If so, it's the right moment to remove it */
if (bind_conf->ssl_conf.alpn_str && !bind_conf->ssl_conf.alpn_len) {
- free(bind_conf->ssl_conf.alpn_str);
- bind_conf->ssl_conf.alpn_str = NULL;
+ ha_free(&bind_conf->ssl_conf.alpn_str);
}
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
else if (!bind_conf->ssl_conf.alpn_str && !bind_conf->ssl_conf.npn_str &&
@@ -2934,6 +2956,12 @@ init_proxies_list_stage1:
if (err_code & ERR_FATAL)
goto out;
}
+
+ if (bind_generate_guid(bind_conf)) {
+ cfgerr++;
+ err_code |= ERR_FATAL | ERR_ALERT;
+ goto out;
+ }
}
switch (curproxy->mode) {
@@ -3120,6 +3148,12 @@ init_proxies_list_stage1:
curproxy->id);
err_code |= ERR_WARN;
}
+ if (target->mode == PR_MODE_HTTP) {
+ /* at least one of the used backends will provoke an
+ * HTTP upgrade
+ */
+ curproxy->options |= PR_O_HTTP_UPG;
+ }
}
}
@@ -3135,7 +3169,7 @@ init_proxies_list_stage1:
* parsing is cancelled and be.name is restored to be resolved.
*/
pxname = rule->be.name;
- LIST_INIT(&rule->be.expr);
+ lf_expr_init(&rule->be.expr);
curproxy->conf.args.ctx = ARGC_UBK;
curproxy->conf.args.file = rule->file;
curproxy->conf.args.line = rule->line;
@@ -3147,20 +3181,23 @@ init_proxies_list_stage1:
cfgerr++;
continue;
}
- node = LIST_NEXT(&rule->be.expr, struct logformat_node *, list);
+ node = LIST_NEXT(&rule->be.expr.nodes.list, struct logformat_node *, list);
- if (!LIST_ISEMPTY(&rule->be.expr)) {
- if (node->type != LOG_FMT_TEXT || node->list.n != &rule->be.expr) {
+ if (!lf_expr_isempty(&rule->be.expr)) {
+ if (node->type != LOG_FMT_TEXT || node->list.n != &rule->be.expr.nodes.list) {
rule->dynamic = 1;
free(pxname);
+ /* backend is not yet known so we cannot assume its type,
+ * thus we should consider that at least one of the used
+ * backends may provoke HTTP upgrade
+ */
+ curproxy->options |= PR_O_HTTP_UPG;
continue;
}
/* Only one element in the list, a simple string: free the expression and
* fall back to static rule
*/
- LIST_DELETE(&node->list);
- free(node->arg);
- free(node);
+ lf_expr_deinit(&rule->be.expr);
}
rule->dynamic = 0;
@@ -3187,6 +3224,12 @@ init_proxies_list_stage1:
} else {
ha_free(&rule->be.name);
rule->be.backend = target;
+ if (target->mode == PR_MODE_HTTP) {
+ /* at least one of the used backends will provoke an
+ * HTTP upgrade
+ */
+ curproxy->options |= PR_O_HTTP_UPG;
+ }
}
err_code |= warnif_tcp_http_cond(curproxy, rule->cond);
}
@@ -3202,7 +3245,7 @@ init_proxies_list_stage1:
* to a static rule, thus the parsing is cancelled and we fall back to setting srv.ptr.
*/
server_name = srule->srv.name;
- LIST_INIT(&srule->expr);
+ lf_expr_init(&srule->expr);
curproxy->conf.args.ctx = ARGC_USRV;
err = NULL;
if (!parse_logformat_string(server_name, curproxy, &srule->expr, 0, SMP_VAL_FE_HRQ_HDR, &err)) {
@@ -3212,10 +3255,10 @@ init_proxies_list_stage1:
cfgerr++;
continue;
}
- node = LIST_NEXT(&srule->expr, struct logformat_node *, list);
+ node = LIST_NEXT(&srule->expr.nodes.list, struct logformat_node *, list);
- if (!LIST_ISEMPTY(&srule->expr)) {
- if (node->type != LOG_FMT_TEXT || node->list.n != &srule->expr) {
+ if (!lf_expr_isempty(&srule->expr)) {
+ if (node->type != LOG_FMT_TEXT || node->list.n != &srule->expr.nodes.list) {
srule->dynamic = 1;
free(server_name);
continue;
@@ -3223,9 +3266,7 @@ init_proxies_list_stage1:
/* Only one element in the list, a simple string: free the expression and
* fall back to static rule
*/
- LIST_DELETE(&node->list);
- free(node->arg);
- free(node);
+ lf_expr_deinit(&srule->expr);
}
srule->dynamic = 0;
@@ -3335,7 +3376,7 @@ init_proxies_list_stage1:
}
}
- if (curproxy->uri_auth && !(curproxy->uri_auth->flags & STAT_CONVDONE) &&
+ if (curproxy->uri_auth && !(curproxy->uri_auth->flags & STAT_F_CONVDONE) &&
!LIST_ISEMPTY(&curproxy->uri_auth->http_req_rules) &&
(curproxy->uri_auth->userlist || curproxy->uri_auth->auth_realm )) {
ha_alert("%s '%s': stats 'auth'/'realm' and 'http-request' can't be used at the same time.\n",
@@ -3345,7 +3386,7 @@ init_proxies_list_stage1:
}
if (curproxy->uri_auth && curproxy->uri_auth->userlist &&
- (!(curproxy->uri_auth->flags & STAT_CONVDONE) ||
+ (!(curproxy->uri_auth->flags & STAT_F_CONVDONE) ||
LIST_ISEMPTY(&curproxy->uri_auth->http_req_rules))) {
const char *uri_auth_compat_req[10];
struct act_rule *rule;
@@ -3376,16 +3417,16 @@ init_proxies_list_stage1:
if (curproxy->uri_auth->auth_realm) {
ha_free(&curproxy->uri_auth->auth_realm);
}
- curproxy->uri_auth->flags |= STAT_CONVDONE;
+ curproxy->uri_auth->flags |= STAT_F_CONVDONE;
}
out_uri_auth_compat:
/* check whether we have a logger that uses RFC5424 log format */
list_for_each_entry(tmplogger, &curproxy->loggers, list) {
if (tmplogger->format == LOG_FORMAT_RFC5424) {
- if (!curproxy->conf.logformat_sd_string) {
+ if (!curproxy->logformat_sd.str) {
/* set the default logformat_sd_string */
- curproxy->conf.logformat_sd_string = default_rfc5424_sd_log_format;
+ curproxy->logformat_sd.str = default_rfc5424_sd_log_format;
}
break;
}
@@ -3393,31 +3434,21 @@ out_uri_auth_compat:
/* compile the log format */
if (!(curproxy->cap & PR_CAP_FE)) {
- if (curproxy->conf.logformat_string != default_http_log_format &&
- curproxy->conf.logformat_string != default_tcp_log_format &&
- curproxy->conf.logformat_string != clf_http_log_format)
- free(curproxy->conf.logformat_string);
- curproxy->conf.logformat_string = NULL;
- ha_free(&curproxy->conf.lfs_file);
- curproxy->conf.lfs_line = 0;
-
- if (curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format)
- free(curproxy->conf.logformat_sd_string);
- curproxy->conf.logformat_sd_string = NULL;
- ha_free(&curproxy->conf.lfsd_file);
- curproxy->conf.lfsd_line = 0;
- }
-
- if (curproxy->conf.logformat_string) {
+ lf_expr_deinit(&curproxy->logformat);
+ lf_expr_deinit(&curproxy->logformat_sd);
+ }
+
+ if (curproxy->logformat.str) {
curproxy->conf.args.ctx = ARGC_LOG;
- curproxy->conf.args.file = curproxy->conf.lfs_file;
- curproxy->conf.args.line = curproxy->conf.lfs_line;
+ curproxy->conf.args.file = curproxy->logformat.conf.file;
+ curproxy->conf.args.line = curproxy->logformat.conf.line;
err = NULL;
- if (!parse_logformat_string(curproxy->conf.logformat_string, curproxy, &curproxy->logformat,
+ if (!lf_expr_compile(&curproxy->logformat, &curproxy->conf.args,
LOG_OPT_MANDATORY|LOG_OPT_MERGE_SPACES,
- SMP_VAL_FE_LOG_END, &err)) {
+ SMP_VAL_FE_LOG_END, &err) ||
+ !lf_expr_postcheck(&curproxy->logformat, curproxy, &err)) {
ha_alert("Parsing [%s:%d]: failed to parse log-format : %s.\n",
- curproxy->conf.lfs_file, curproxy->conf.lfs_line, err);
+ curproxy->logformat.conf.file, curproxy->logformat.conf.line, err);
free(err);
cfgerr++;
}
@@ -3425,21 +3456,18 @@ out_uri_auth_compat:
curproxy->conf.args.line = 0;
}
- if (curproxy->conf.logformat_sd_string) {
+ if (curproxy->logformat_sd.str) {
curproxy->conf.args.ctx = ARGC_LOGSD;
- curproxy->conf.args.file = curproxy->conf.lfsd_file;
- curproxy->conf.args.line = curproxy->conf.lfsd_line;
+ curproxy->conf.args.file = curproxy->logformat_sd.conf.file;
+ curproxy->conf.args.line = curproxy->logformat_sd.conf.line;
err = NULL;
- if (!parse_logformat_string(curproxy->conf.logformat_sd_string, curproxy, &curproxy->logformat_sd,
+ if (!lf_expr_compile(&curproxy->logformat_sd, &curproxy->conf.args,
LOG_OPT_MANDATORY|LOG_OPT_MERGE_SPACES,
- SMP_VAL_FE_LOG_END, &err)) {
- ha_alert("Parsing [%s:%d]: failed to parse log-format-sd : %s.\n",
- curproxy->conf.lfsd_file, curproxy->conf.lfsd_line, err);
- free(err);
- cfgerr++;
- } else if (!add_to_logformat_list(NULL, NULL, LF_SEPARATOR, &curproxy->logformat_sd, &err)) {
+ SMP_VAL_FE_LOG_END, &err) ||
+ !add_to_logformat_list(NULL, NULL, LF_SEPARATOR, &curproxy->logformat_sd, &err) ||
+ !lf_expr_postcheck(&curproxy->logformat_sd, curproxy, &err)) {
ha_alert("Parsing [%s:%d]: failed to parse log-format-sd : %s.\n",
- curproxy->conf.lfsd_file, curproxy->conf.lfsd_line, err);
+ curproxy->logformat_sd.conf.file, curproxy->logformat_sd.conf.line, err);
free(err);
cfgerr++;
}
@@ -3447,21 +3475,22 @@ out_uri_auth_compat:
curproxy->conf.args.line = 0;
}
- if (curproxy->conf.uniqueid_format_string) {
+ if (curproxy->format_unique_id.str) {
int where = 0;
curproxy->conf.args.ctx = ARGC_UIF;
- curproxy->conf.args.file = curproxy->conf.uif_file;
- curproxy->conf.args.line = curproxy->conf.uif_line;
+ curproxy->conf.args.file = curproxy->format_unique_id.conf.file;
+ curproxy->conf.args.line = curproxy->format_unique_id.conf.line;
err = NULL;
if (curproxy->cap & PR_CAP_FE)
where |= SMP_VAL_FE_HRQ_HDR;
if (curproxy->cap & PR_CAP_BE)
where |= SMP_VAL_BE_HRQ_HDR;
- if (!parse_logformat_string(curproxy->conf.uniqueid_format_string, curproxy, &curproxy->format_unique_id,
- LOG_OPT_HTTP|LOG_OPT_MERGE_SPACES, where, &err)) {
+ if (!lf_expr_compile(&curproxy->format_unique_id, &curproxy->conf.args,
+ LOG_OPT_HTTP|LOG_OPT_MERGE_SPACES, where, &err) ||
+ !lf_expr_postcheck(&curproxy->format_unique_id, curproxy, &err)) {
ha_alert("Parsing [%s:%d]: failed to parse unique-id : %s.\n",
- curproxy->conf.uif_file, curproxy->conf.uif_line, err);
+ curproxy->format_unique_id.conf.file, curproxy->format_unique_id.conf.line, err);
free(err);
cfgerr++;
}
@@ -3469,16 +3498,17 @@ out_uri_auth_compat:
curproxy->conf.args.line = 0;
}
- if (curproxy->conf.error_logformat_string) {
+ if (curproxy->logformat_error.str) {
curproxy->conf.args.ctx = ARGC_LOG;
- curproxy->conf.args.file = curproxy->conf.elfs_file;
- curproxy->conf.args.line = curproxy->conf.elfs_line;
+ curproxy->conf.args.file = curproxy->logformat_error.conf.file;
+ curproxy->conf.args.line = curproxy->logformat_error.conf.line;
err = NULL;
- if (!parse_logformat_string(curproxy->conf.error_logformat_string, curproxy, &curproxy->logformat_error,
+ if (!lf_expr_compile(&curproxy->logformat_error, &curproxy->conf.args,
LOG_OPT_MANDATORY|LOG_OPT_MERGE_SPACES,
- SMP_VAL_FE_LOG_END, &err)) {
+ SMP_VAL_FE_LOG_END, &err) ||
+ !lf_expr_postcheck(&curproxy->logformat_error, curproxy, &err)) {
ha_alert("Parsing [%s:%d]: failed to parse error-log-format : %s.\n",
- curproxy->conf.elfs_file, curproxy->conf.elfs_line, err);
+ curproxy->logformat_error.conf.file, curproxy->logformat_error.conf.line, err);
free(err);
cfgerr++;
}
@@ -3655,8 +3685,6 @@ out_uri_auth_compat:
newsrv->conf.id.key = newsrv->puid = next_id;
eb32_insert(&curproxy->conf.used_server_id, &newsrv->conf.id);
}
- newsrv->conf.name.key = newsrv->id;
- ebis_insert(&curproxy->conf.used_server_name, &newsrv->conf.name);
next_id++;
newsrv = newsrv->next;
@@ -3723,12 +3751,6 @@ out_uri_auth_compat:
* on what LB algorithm was chosen.
*/
- if (curproxy->mode == PR_MODE_SYSLOG) {
- /* log load-balancing requires special init that is performed
- * during log-postparsing step
- */
- goto skip_server_lb_init;
- }
curproxy->lbprm.algo &= ~(BE_LB_LKUP | BE_LB_PROP_DYN);
switch (curproxy->lbprm.algo & BE_LB_KIND) {
case BE_LB_KIND_RR:
@@ -3767,8 +3789,13 @@ out_uri_auth_compat:
init_server_map(curproxy);
}
break;
+ case BE_LB_KIND_SA:
+ if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_SA_SS) {
+ curproxy->lbprm.algo |= BE_LB_PROP_DYN;
+ init_server_ss(curproxy);
+ }
+ break;
}
- skip_server_lb_init:
HA_RWLOCK_INIT(&curproxy->lbprm.lock);
if (curproxy->options & PR_O_LOGASAP)
@@ -3776,7 +3803,7 @@ out_uri_auth_compat:
if (!(curproxy->cap & PR_CAP_INT) && (curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
(curproxy->cap & PR_CAP_FE) && LIST_ISEMPTY(&curproxy->loggers) &&
- (!LIST_ISEMPTY(&curproxy->logformat) || !LIST_ISEMPTY(&curproxy->logformat_sd))) {
+ (!lf_expr_isempty(&curproxy->logformat) || !lf_expr_isempty(&curproxy->logformat_sd))) {
ha_warning("log format ignored for %s '%s' since it has no log address.\n",
proxy_type_str(curproxy), curproxy->id);
err_code |= ERR_WARN;
@@ -3798,6 +3825,12 @@ out_uri_auth_compat:
err_code |= ERR_WARN;
}
+ if (isttest(curproxy->monitor_uri)) {
+ ha_warning("'monitor-uri' statement ignored for %s '%s' as it requires HTTP mode.\n",
+ proxy_type_str(curproxy), curproxy->id);
+ err_code |= ERR_WARN;
+ }
+
if (!LIST_ISEMPTY(&curproxy->http_req_rules)) {
ha_warning("'http-request' rules ignored for %s '%s' as they require HTTP mode.\n",
proxy_type_str(curproxy), curproxy->id);
@@ -4181,6 +4214,11 @@ init_proxies_list_stage2:
/* listener ID not set, use automatic numbering with first
* spare entry starting with next_luid.
*/
+ if (listener->by_fe.p != &curproxy->conf.listeners) {
+ struct listener *prev_li = LIST_PREV(&listener->by_fe, typeof(prev_li), by_fe);
+ if (prev_li->luid)
+ next_id = prev_li->luid + 1;
+ }
next_id = get_next_id(&curproxy->conf.used_listener_id, next_id);
listener->conf.id.key = listener->luid = next_id;
eb32_insert(&curproxy->conf.used_listener_id, &listener->conf.id);