From: Amaury Denoyelle Date: Tue, 23 Mar 2021 16:27:05 +0000 (+0100) Subject: REORG: split proxy allocation functions X-Git-Tag: v2.4-dev14~22 X-Git-Url: http://git.haproxy.org/?a=commitdiff_plain;h=476b9ad97a23d31905bdf63749a5b5ff5626426a;p=haproxy-2.5.git REORG: split proxy allocation functions Create a new function parse_new_proxy specifically designed to allocate a new proxy from the configuration file and copy settings from the default proxy. The function alloc_new_proxy is reduced to a minimal allocation. It is used for default proxy allocation and could also be used for internal proxies such as the lua Socket proxy. --- diff --git a/include/haproxy/proxy.h b/include/haproxy/proxy.h index b81783a..ae50c37 100644 --- a/include/haproxy/proxy.h +++ b/include/haproxy/proxy.h @@ -61,8 +61,11 @@ void proxy_preset_defaults(struct proxy *defproxy); void proxy_free_defaults(struct proxy *defproxy); void proxy_destroy_defaults(struct proxy *px); void proxy_destroy_all_defaults(); -struct proxy *alloc_new_proxy(const char *name, unsigned int cap, const char *file, int linenum, - const struct proxy *defproxy, char **errmsg); +struct proxy *alloc_new_proxy(const char *name, unsigned int cap, + char **errmsg); +struct proxy *parse_new_proxy(const char *name, unsigned int cap, + const char *file, int linenum, + const struct proxy *defproxy); int get_backend_server(const char *bk_name, const char *sv_name, struct proxy **bk, struct server **sv); void proxy_capture_error(struct proxy *proxy, int is_back, diff --git a/src/cfgparse-listen.c b/src/cfgparse-listen.c index aa2b5eb..739dc83 100644 --- a/src/cfgparse-listen.c +++ b/src/cfgparse-listen.c @@ -211,7 +211,9 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) if (!last_defproxy) { /* we need a default proxy and none was created yet */ - last_defproxy = alloc_new_proxy("", PR_CAP_DEF|PR_CAP_LISTEN, "INIT", 0, NULL, &errmsg); + last_defproxy = alloc_new_proxy("", PR_CAP_DEF|PR_CAP_LISTEN, &errmsg); + proxy_preset_defaults(last_defproxy); + curr_defproxy = last_defproxy; if (!last_defproxy) { ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg); @@ -314,9 +316,8 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) } } - curproxy = alloc_new_proxy(name, rc, file, linenum, curr_defproxy, &errmsg); + curproxy = parse_new_proxy(name, rc, file, linenum, curr_defproxy); if (!curproxy) { - ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg); err_code |= ERR_ALERT | ERR_ABORT; goto out; } diff --git a/src/proxy.c b/src/proxy.c index 843941e..2514b16 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -1237,17 +1237,12 @@ void proxy_destroy_all_defaults() } } -/* Allocates a new proxy of type found at position , - * preset it from the defaults of and returns it. Un case of error, - * an alert is printed and NULL is returned. If is not NULL, an error - * message will be returned there in case of fatal error. If is NULL, - * the documented default settings will be used instead. +/* Allocates a new proxy of type . + * Returns the proxy instance on success. On error, NULL is returned. */ -struct proxy *alloc_new_proxy(const char *name, unsigned int cap, const char *file, int linenum, const struct proxy *defproxy, char **errmsg) +struct proxy *alloc_new_proxy(const char *name, unsigned int cap, char **errmsg) { - struct logsrv *tmplogsrv; struct proxy *curproxy; - char *tmpmsg = NULL; if ((curproxy = calloc(1, sizeof(*curproxy))) == NULL) { memprintf(errmsg, "proxy '%s': out of memory", name); @@ -1255,17 +1250,32 @@ struct proxy *alloc_new_proxy(const char *name, unsigned int cap, const char *fi } init_new_proxy(curproxy); - curproxy->conf.args.file = curproxy->conf.file = strdup(file); - curproxy->conf.args.line = curproxy->conf.line = linenum; curproxy->last_change = now.tv_sec; curproxy->id = strdup(name); curproxy->cap = cap; proxy_store_name(curproxy); - if (!defproxy) { - proxy_preset_defaults(curproxy); - goto done; - } + done: + return curproxy; + + fail: + /* Note: in case of fatal error here, we WILL make valgrind unhappy, + * but its not worth trying to unroll everything here just before + * quitting. + */ + free(curproxy); + return NULL; +} + +/* Copy the proxy settings from to . + * Returns 0 on success. + * Returns 1 on error. will be allocated with an error description. + */ +static int proxy_defproxy_cpy(struct proxy *curproxy, const struct proxy *defproxy, + char **errmsg) +{ + struct logsrv *tmplogsrv; + char *tmpmsg = NULL; /* set default values from the specified default proxy */ memcpy(&curproxy->defsrv, &defproxy->defsrv, sizeof(curproxy->defsrv)); @@ -1298,7 +1308,8 @@ struct proxy *alloc_new_proxy(const char *name, unsigned int cap, const char *fi /* initialize error relocations */ if (!proxy_dup_default_conf_errors(curproxy, defproxy, &tmpmsg)) { memprintf(errmsg, "proxy '%s' : %s", curproxy->id, tmpmsg); - goto fail; + free(tmpmsg); + return 1; } if (curproxy->cap & PR_CAP_FE) { @@ -1327,8 +1338,8 @@ struct proxy *alloc_new_proxy(const char *name, unsigned int cap, const char *fi if (!LIST_ISEMPTY(&defproxy->tcpcheck_rules.preset_vars)) { if (!dup_tcpcheck_vars(&curproxy->tcpcheck_rules.preset_vars, &defproxy->tcpcheck_rules.preset_vars)) { - memprintf(errmsg, "proxy '%s': failed to duplicate tcpcheck preset-vars", name); - goto fail; + memprintf(errmsg, "proxy '%s': failed to duplicate tcpcheck preset-vars", curproxy->id); + return 1; } } @@ -1441,8 +1452,8 @@ struct proxy *alloc_new_proxy(const char *name, unsigned int cap, const char *fi struct logsrv *node = malloc(sizeof(*node)); if (!node) { - memprintf(errmsg, "proxy '%s': out of memory", name); - goto fail; + memprintf(errmsg, "proxy '%s': out of memory", curproxy->id); + return 1; } memcpy(node, tmplogsrv, sizeof(struct logsrv)); node->ref = tmplogsrv->ref; @@ -1466,8 +1477,8 @@ struct proxy *alloc_new_proxy(const char *name, unsigned int cap, const char *fi const struct ist copy = istdup(defproxy->header_unique_id); if (!isttest(copy)) { - memprintf(errmsg, "proxy '%s': out of memory for unique-id-header", name); - goto fail; + memprintf(errmsg, "proxy '%s': out of memory for unique-id-header", curproxy->id); + return 1; } curproxy->header_unique_id = copy; } @@ -1497,16 +1508,43 @@ struct proxy *alloc_new_proxy(const char *name, unsigned int cap, const char *fi curproxy->email_alert.level = defproxy->email_alert.level; curproxy->email_alert.set = defproxy->email_alert.set; - done: + return 0; +} + +/* Allocates a new proxy of type found at position , + * preset it from the defaults of and returns it. In case of error, + * an alert is printed and NULL is returned. + */ +struct proxy *parse_new_proxy(const char *name, unsigned int cap, + const char *file, int linenum, + const struct proxy *defproxy) +{ + struct proxy *curproxy = NULL; + char *errmsg; + + if (!(curproxy = alloc_new_proxy(name, cap, &errmsg))) { + ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg); + free(errmsg); + return NULL; + } + + if (defproxy) { + if (proxy_defproxy_cpy(curproxy, defproxy, &errmsg)) { + ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg); + free(errmsg); + + ha_free(&curproxy); + return NULL; + } + } + else { + proxy_preset_defaults(curproxy); + } + + curproxy->conf.args.file = curproxy->conf.file = strdup(file); + curproxy->conf.args.line = curproxy->conf.line = linenum; + return curproxy; - fail: - /* Note: in case of fatal error here, we WILL make valgrind unhappy, - * but its not worth trying to unroll everything here just before - * quitting. - */ - free(tmpmsg); - free(curproxy); - return NULL; } /* to be called under the proxy lock after stopping some listeners. This will