diff options
Diffstat (limited to '')
-rw-r--r-- | src/cfgparse.c | 222 |
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); |