From cff6d757e3ba609c08ef2aaa00f07e53551e5bf6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 3 Jun 2024 07:11:10 +0200 Subject: Adding upstream version 3.0.0. Signed-off-by: Daniel Baumann --- src/proxy.c | 274 +++++++++++++++++------------------------------------------- 1 file changed, 78 insertions(+), 196 deletions(-) (limited to 'src/proxy.c') diff --git a/src/proxy.c b/src/proxy.c index 19e6c4b..f1d9d7a 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -177,18 +178,6 @@ void free_stick_rules(struct list *rules) } } -static void free_logformat_list(struct list *lfs) -{ - struct logformat_node *lf, *lfb; - - list_for_each_entry_safe(lf, lfb, lfs, list) { - LIST_DELETE(&lf->list); - release_sample_expr(lf->expr); - free(lf->arg); - free(lf); - } -} - void free_server_rules(struct list *srules) { struct server_rule *srule, *sruleb; @@ -196,7 +185,7 @@ void free_server_rules(struct list *srules) list_for_each_entry_safe(srule, sruleb, srules, list) { LIST_DELETE(&srule->list); free_acl_cond(srule->cond); - free_logformat_list(&srule->expr); + lf_expr_deinit(&srule->expr); free(srule->file); free(srule); } @@ -235,34 +224,17 @@ void free_proxy(struct proxy *p) #if defined(CONFIG_HAP_TRANSPARENT) free(p->conn_src.bind_hdr_name); #endif - if (p->conf.logformat_string != default_http_log_format && - p->conf.logformat_string != default_tcp_log_format && - p->conf.logformat_string != clf_http_log_format && - p->conf.logformat_string != default_https_log_format && - p->conf.logformat_string != httpclient_log_format) - free(p->conf.logformat_string); - - free(p->conf.lfs_file); - free(p->conf.uniqueid_format_string); istfree(&p->header_unique_id); - free(p->conf.uif_file); if ((p->lbprm.algo & BE_LB_LKUP) == BE_LB_LKUP_MAP) free(p->lbprm.map.srv); - if (p->mode == PR_MODE_SYSLOG) - free(p->lbprm.log.srv); - - if (p->conf.logformat_sd_string != default_rfc5424_sd_log_format) - free(p->conf.logformat_sd_string); - free(p->conf.lfsd_file); - - free(p->conf.error_logformat_string); - free(p->conf.elfs_file); list_for_each_entry_safe(cond, condb, &p->mon_fail_cond, list) { LIST_DELETE(&cond->list); free_acl_cond(cond); } + guid_remove(&p->guid); + EXTRA_COUNTERS_FREE(p->extra_counters_fe); EXTRA_COUNTERS_FREE(p->extra_counters_be); @@ -278,7 +250,7 @@ void free_proxy(struct proxy *p) LIST_DELETE(&rule->list); free_acl_cond(rule->cond); if (rule->dynamic) - free_logformat_list(&rule->be.expr); + lf_expr_deinit(&rule->be.expr); free(rule->file); free(rule); } @@ -293,10 +265,10 @@ void free_proxy(struct proxy *p) free_logger(log); } - free_logformat_list(&p->logformat); - free_logformat_list(&p->logformat_sd); - free_logformat_list(&p->format_unique_id); - free_logformat_list(&p->logformat_error); + lf_expr_deinit(&p->logformat); + lf_expr_deinit(&p->logformat_sd); + lf_expr_deinit(&p->format_unique_id); + lf_expr_deinit(&p->logformat_error); free_act_rules(&p->tcp_req.inspect_rules); free_act_rules(&p->tcp_rep.inspect_rules); @@ -344,6 +316,7 @@ void free_proxy(struct proxy *p) srv_free_params(&p->defsrv); list_for_each_entry_safe(l, l_next, &p->conf.listeners, by_fe) { + guid_remove(&l->guid); LIST_DELETE(&l->by_fe); LIST_DELETE(&l->by_bind); free(l->name); @@ -363,6 +336,7 @@ void free_proxy(struct proxy *p) free(bind_conf->arg); free(bind_conf->settings.interface); LIST_DELETE(&bind_conf->by_fe); + free(bind_conf->guid_prefix); free(bind_conf->rhttp_srvname); free(bind_conf); } @@ -1041,6 +1015,33 @@ static int proxy_parse_tcpka_intvl(char **args, int section, struct proxy *proxy } #endif +static int proxy_parse_guid(char **args, int section_type, struct proxy *curpx, + const struct proxy *defpx, const char *file, int line, + char **err) +{ + const char *guid; + char *guid_err = NULL; + + if (curpx->cap & PR_CAP_DEF) { + ha_alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, line, args[0]); + return -1; + } + + if (!*args[1]) { + memprintf(err, "'%s' : expects an argument", args[0]); + return -1; + } + + guid = args[1]; + if (guid_insert(&curpx->obj_type, guid, &guid_err)) { + memprintf(err, "'%s': %s", args[0], guid_err); + ha_free(&guid_err); + return -1; + } + + return 0; +} + /* This function inserts proxy into the tree of known proxies (regular * ones or defaults depending on px->cap & PR_CAP_DEF). The proxy's name is * used as the storing key so it must already have been initialized. @@ -1275,50 +1276,6 @@ struct server *findserver(const struct proxy *px, const char *name) { return target; } -/* - * This function finds a server with matching " x " within - * selected proxy . - * Using the combination of proxy-uid + revision id ensures that the function - * will either return the server we're expecting or NULL if it has been removed - * from the proxy. - */ -struct server *findserver_unique_id(const struct proxy *px, int puid, uint32_t rid) { - - struct server *cursrv; - - if (!px) - return NULL; - - for (cursrv = px->srv; cursrv; cursrv = cursrv->next) { - if (cursrv->puid == puid && cursrv->rid == rid) - return cursrv; - } - - return NULL; -} - -/* - * This function finds a server with matching " x " within - * selected proxy . - * Using the combination of name + revision id ensures that the function will - * either return the server we're expecting or NULL if it has been removed - * from the proxy. - */ -struct server *findserver_unique_name(const struct proxy *px, const char *name, uint32_t rid) { - - struct server *cursrv; - - if (!px) - return NULL; - - for (cursrv = px->srv; cursrv; cursrv = cursrv->next) { - if (!strcmp(cursrv->id, name) && cursrv->rid == rid) - return cursrv; - } - - return NULL; -} - /* This function checks that the designated proxy has no http directives * enabled. It will output a warning if there are, and will fix some of them. * It returns the number of fatal errors encountered. This should be called @@ -1331,35 +1288,25 @@ int proxy_cfg_ensure_no_http(struct proxy *curproxy) ha_warning("cookie will be ignored for %s '%s' (needs 'mode http').\n", proxy_type_str(curproxy), curproxy->id); } - if (isttest(curproxy->monitor_uri)) { - ha_warning("monitor-uri will be ignored for %s '%s' (needs 'mode http').\n", - proxy_type_str(curproxy), curproxy->id); - } if (curproxy->lbprm.algo & BE_LB_NEED_HTTP) { curproxy->lbprm.algo &= ~BE_LB_ALGO; curproxy->lbprm.algo |= BE_LB_ALGO_RR; ha_warning("Layer 7 hash not possible for %s '%s' (needs 'mode http'). Falling back to round robin.\n", proxy_type_str(curproxy), curproxy->id); } - if (curproxy->to_log & (LW_REQ | LW_RESP)) { - curproxy->to_log &= ~(LW_REQ | LW_RESP); - ha_warning("parsing [%s:%d] : HTTP log/header format not usable with %s '%s' (needs 'mode http').\n", - curproxy->conf.lfs_file, curproxy->conf.lfs_line, - proxy_type_str(curproxy), curproxy->id); - } - if (curproxy->conf.logformat_string == default_http_log_format || - curproxy->conf.logformat_string == clf_http_log_format) { + if (curproxy->logformat.str == default_http_log_format || + curproxy->logformat.str == clf_http_log_format) { /* Note: we don't change the directive's file:line number */ - curproxy->conf.logformat_string = default_tcp_log_format; + curproxy->logformat.str = default_tcp_log_format; ha_warning("parsing [%s:%d] : 'option httplog' not usable with %s '%s' (needs 'mode http'). Falling back to 'option tcplog'.\n", - curproxy->conf.lfs_file, curproxy->conf.lfs_line, + curproxy->logformat.conf.file, curproxy->logformat.conf.line, proxy_type_str(curproxy), curproxy->id); } - else if (curproxy->conf.logformat_string == default_https_log_format) { + else if (curproxy->logformat.str == default_https_log_format) { /* Note: we don't change the directive's file:line number */ - curproxy->conf.logformat_string = default_tcp_log_format; + curproxy->logformat.str = default_tcp_log_format; ha_warning("parsing [%s:%d] : 'option httpslog' not usable with %s '%s' (needs 'mode http'). Falling back to 'option tcplog'.\n", - curproxy->conf.lfs_file, curproxy->conf.lfs_line, + curproxy->logformat.conf.file, curproxy->logformat.conf.line, proxy_type_str(curproxy), curproxy->id); } @@ -1410,14 +1357,11 @@ void init_new_proxy(struct proxy *p) LIST_INIT(&p->tcp_req.l5_rules); MT_LIST_INIT(&p->listener_queue); LIST_INIT(&p->loggers); - LIST_INIT(&p->logformat); - LIST_INIT(&p->logformat_sd); - LIST_INIT(&p->format_unique_id); - LIST_INIT(&p->logformat_error); LIST_INIT(&p->conf.bind); LIST_INIT(&p->conf.listeners); LIST_INIT(&p->conf.errors); LIST_INIT(&p->conf.args.list); + LIST_INIT(&p->conf.lf_checks); LIST_INIT(&p->filter_configs); LIST_INIT(&p->tcpcheck_rules.preset_vars); @@ -1436,6 +1380,8 @@ void init_new_proxy(struct proxy *p) /* Default to only allow L4 retries */ p->retry_type = PR_RE_CONN_FAILED; + guid_init(&p->guid); + p->extra_counters_fe = NULL; p->extra_counters_be = NULL; @@ -1460,29 +1406,12 @@ void proxy_preset_defaults(struct proxy *defproxy) defproxy->options2 |= PR_O2_INDEPSTR; defproxy->max_out_conns = MAX_SRV_LIST; - defproxy->defsrv.check.inter = DEF_CHKINTR; - defproxy->defsrv.check.fastinter = 0; - defproxy->defsrv.check.downinter = 0; - defproxy->defsrv.agent.inter = DEF_CHKINTR; - defproxy->defsrv.agent.fastinter = 0; - defproxy->defsrv.agent.downinter = 0; - defproxy->defsrv.check.rise = DEF_RISETIME; - defproxy->defsrv.check.fall = DEF_FALLTIME; - defproxy->defsrv.agent.rise = DEF_AGENT_RISETIME; - defproxy->defsrv.agent.fall = DEF_AGENT_FALLTIME; - defproxy->defsrv.check.port = 0; - defproxy->defsrv.agent.port = 0; - defproxy->defsrv.maxqueue = 0; - defproxy->defsrv.minconn = 0; - defproxy->defsrv.maxconn = 0; - defproxy->defsrv.max_reuse = -1; - defproxy->defsrv.max_idle_conns = -1; - defproxy->defsrv.pool_purge_delay = 5000; - defproxy->defsrv.slowstart = 0; - defproxy->defsrv.onerror = DEF_HANA_ONERR; - defproxy->defsrv.consecutive_errors_limit = DEF_HANA_ERRLIMIT; - defproxy->defsrv.uweight = defproxy->defsrv.iweight = 1; - LIST_INIT(&defproxy->defsrv.pp_tlvs); + srv_settings_init(&defproxy->defsrv); + + lf_expr_init(&defproxy->logformat); + lf_expr_init(&defproxy->logformat_sd); + lf_expr_init(&defproxy->format_unique_id); + lf_expr_init(&defproxy->logformat_error); defproxy->email_alert.level = LOG_ALERT; defproxy->load_server_state_from_file = PR_SRV_STATE_FILE_UNSPEC; @@ -1554,27 +1483,16 @@ void proxy_free_defaults(struct proxy *defproxy) h = h_next; } - if (defproxy->conf.logformat_string != default_http_log_format && - defproxy->conf.logformat_string != default_tcp_log_format && - defproxy->conf.logformat_string != clf_http_log_format && - defproxy->conf.logformat_string != default_https_log_format) { - ha_free(&defproxy->conf.logformat_string); - } - - if (defproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format) - ha_free(&defproxy->conf.logformat_sd_string); + lf_expr_deinit(&defproxy->logformat); + lf_expr_deinit(&defproxy->logformat_sd); + lf_expr_deinit(&defproxy->logformat_error); + lf_expr_deinit(&defproxy->format_unique_id); list_for_each_entry_safe(log, logb, &defproxy->loggers, list) { LIST_DEL_INIT(&log->list); free_logger(log); } - ha_free(&defproxy->conf.uniqueid_format_string); - ha_free(&defproxy->conf.error_logformat_string); - ha_free(&defproxy->conf.lfs_file); - ha_free(&defproxy->conf.lfsd_file); - ha_free(&defproxy->conf.uif_file); - ha_free(&defproxy->conf.elfs_file); chunk_destroy(&defproxy->log_tag); free_email_alert(defproxy); @@ -1652,6 +1570,7 @@ void proxy_unref_defaults(struct proxy *px) */ struct proxy *alloc_new_proxy(const char *name, unsigned int cap, char **errmsg) { + uint last_change; struct proxy *curproxy; if ((curproxy = calloc(1, sizeof(*curproxy))) == NULL) { @@ -1660,7 +1579,13 @@ struct proxy *alloc_new_proxy(const char *name, unsigned int cap, char **errmsg) } init_new_proxy(curproxy); - curproxy->last_change = ns_to_sec(now_ns); + + last_change = ns_to_sec(now_ns); + if (cap & PR_CAP_FE) + curproxy->fe_counters.last_change = last_change; + if (cap & PR_CAP_BE) + curproxy->be_counters.last_change = last_change; + curproxy->id = strdup(name); curproxy->cap = cap; @@ -1815,39 +1740,9 @@ static int proxy_defproxy_cpy(struct proxy *curproxy, const struct proxy *defpro if (defproxy->defbe.name) curproxy->defbe.name = strdup(defproxy->defbe.name); - /* get either a pointer to the logformat string or a copy of it */ - curproxy->conf.logformat_string = defproxy->conf.logformat_string; - if (curproxy->conf.logformat_string && - curproxy->conf.logformat_string != default_http_log_format && - curproxy->conf.logformat_string != default_tcp_log_format && - curproxy->conf.logformat_string != clf_http_log_format && - curproxy->conf.logformat_string != default_https_log_format) - curproxy->conf.logformat_string = strdup(curproxy->conf.logformat_string); - - if (defproxy->conf.lfs_file) { - curproxy->conf.lfs_file = strdup(defproxy->conf.lfs_file); - curproxy->conf.lfs_line = defproxy->conf.lfs_line; - } - - /* get either a pointer to the logformat string for RFC5424 structured-data or a copy of it */ - curproxy->conf.logformat_sd_string = defproxy->conf.logformat_sd_string; - if (curproxy->conf.logformat_sd_string && - curproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format) - curproxy->conf.logformat_sd_string = strdup(curproxy->conf.logformat_sd_string); - - if (defproxy->conf.lfsd_file) { - curproxy->conf.lfsd_file = strdup(defproxy->conf.lfsd_file); - curproxy->conf.lfsd_line = defproxy->conf.lfsd_line; - } - - curproxy->conf.error_logformat_string = defproxy->conf.error_logformat_string; - if (curproxy->conf.error_logformat_string) - curproxy->conf.error_logformat_string = strdup(curproxy->conf.error_logformat_string); - - if (defproxy->conf.elfs_file) { - curproxy->conf.elfs_file = strdup(defproxy->conf.elfs_file); - curproxy->conf.elfs_line = defproxy->conf.elfs_line; - } + lf_expr_dup(&defproxy->logformat, &curproxy->logformat); + lf_expr_dup(&defproxy->logformat_sd, &curproxy->logformat_sd); + lf_expr_dup(&defproxy->logformat_error, &curproxy->logformat_error); } if (curproxy->cap & PR_CAP_BE) { @@ -1877,17 +1772,10 @@ static int proxy_defproxy_cpy(struct proxy *curproxy, const struct proxy *defpro LIST_APPEND(&curproxy->loggers, &node->list); } - curproxy->conf.uniqueid_format_string = defproxy->conf.uniqueid_format_string; - if (curproxy->conf.uniqueid_format_string) - curproxy->conf.uniqueid_format_string = strdup(curproxy->conf.uniqueid_format_string); + lf_expr_dup(&defproxy->format_unique_id, &curproxy->format_unique_id); chunk_dup(&curproxy->log_tag, &defproxy->log_tag); - if (defproxy->conf.uif_file) { - curproxy->conf.uif_file = strdup(defproxy->conf.uif_file); - curproxy->conf.uif_line = defproxy->conf.uif_line; - } - /* copy default header unique id */ if (isttest(defproxy->header_unique_id)) { const struct ist copy = istdup(defproxy->header_unique_id); @@ -2008,11 +1896,11 @@ void proxy_cond_disable(struct proxy *p) */ if ((p->mode == PR_MODE_TCP || p->mode == PR_MODE_HTTP || p->mode == PR_MODE_SYSLOG) && !(p->cap & PR_CAP_INT)) ha_warning("Proxy %s stopped (cumulated conns: FE: %lld, BE: %lld).\n", - p->id, p->fe_counters.cum_conn, p->be_counters.cum_conn); + p->id, p->fe_counters.cum_conn, p->be_counters.cum_sess); if ((p->mode == PR_MODE_TCP || p->mode == PR_MODE_HTTP) && !(p->cap & PR_CAP_INT)) send_log(p, LOG_WARNING, "Proxy %s stopped (cumulated conns: FE: %lld, BE: %lld).\n", - p->id, p->fe_counters.cum_conn, p->be_counters.cum_conn); + p->id, p->fe_counters.cum_conn, p->be_counters.cum_sess); if (p->table && p->table->size && p->table->sync_task) task_wakeup(p->table->sync_task, TASK_WOKEN_MSG); @@ -2099,7 +1987,7 @@ struct task *manage_proxy(struct task *t, void *context, unsigned int state) goto out; if (p->fe_sps_lim && - (wait = next_event_delay(&p->fe_sess_per_sec, p->fe_sps_lim, 0))) { + (wait = next_event_delay(&p->fe_counters.sess_per_sec, p->fe_sps_lim, 0))) { /* we're blocking because a limit was reached on the number of * requests/s on the frontend. We want to re-check ASAP, which * means in 1 ms before estimated expiration date, because the @@ -2722,6 +2610,7 @@ static struct cfg_kw_list cfg_kws = {ILH, { { CFG_LISTEN, "clitcpka-intvl", proxy_parse_tcpka_intvl }, { CFG_LISTEN, "srvtcpka-intvl", proxy_parse_tcpka_intvl }, #endif + { CFG_LISTEN, "guid", proxy_parse_guid }, { 0, NULL, NULL }, }}; @@ -2819,9 +2708,8 @@ static void dump_server_addr(const struct sockaddr_storage *addr, char *addr_str * ->px, the proxy's id ->only_pxid, the server's pointer from ->sv, and the * choice of what to dump from ->show_conn. */ -static int dump_servers_state(struct stconn *sc) +static int dump_servers_state(struct appctx *appctx) { - struct appctx *appctx = __sc_appctx(sc); struct show_srv_ctx *ctx = appctx->svcctx; struct proxy *px = ctx->px; struct server *srv; @@ -2842,7 +2730,7 @@ static int dump_servers_state(struct stconn *sc) dump_server_addr(&srv->check.addr, srv_check_addr); dump_server_addr(&srv->agent.addr, srv_agent_addr); - srv_time_since_last_change = ns_to_sec(now_ns) - srv->last_change; + srv_time_since_last_change = ns_to_sec(now_ns) - srv->counters.last_change; bk_f_forced_id = px->options & PR_O_FORCED_ID ? 1 : 0; srv_f_forced_id = srv->flags & SRV_F_FORCED_ID ? 1 : 0; @@ -2904,7 +2792,6 @@ static int dump_servers_state(struct stconn *sc) static int cli_io_handler_servers_state(struct appctx *appctx) { struct show_srv_ctx *ctx = appctx->svcctx; - struct stconn *sc = appctx_sc(appctx); struct proxy *curproxy; if (ctx->state == SHOW_SRV_HEAD) { @@ -2928,7 +2815,7 @@ static int cli_io_handler_servers_state(struct appctx *appctx) curproxy = ctx->px; /* servers are only in backends */ if ((curproxy->cap & PR_CAP_BE) && !(curproxy->cap & PR_CAP_INT)) { - if (!dump_servers_state(sc)) + if (!dump_servers_state(appctx)) return 0; } /* only the selected proxy is dumped */ @@ -3263,13 +3150,8 @@ static int cli_parse_show_errors(char **args, char *payload, struct appctx *appc static int cli_io_handler_show_errors(struct appctx *appctx) { struct show_errors_ctx *ctx = appctx->svcctx; - struct stconn *sc = appctx_sc(appctx); extern const char *monthname[12]; - /* FIXME: Don't watch the other side !*/ - if (unlikely(sc_opposite(sc)->flags & SC_FL_SHUT_DONE)) - return 1; - chunk_reset(&trash); if (!ctx->px) { @@ -3399,7 +3281,7 @@ static int cli_io_handler_show_errors(struct appctx *appctx) newline = ctx->bol; newptr = dump_text_line(&trash, es->buf, global.tune.bufsize, es->buf_len, &newline, ctx->ptr); if (newptr == ctx->ptr) { - sc_need_room(sc, 0); + applet_fl_set(appctx, APPCTX_FL_OUTBLK_FULL); goto cant_send_unlock; } -- cgit v1.2.3