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_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 @@
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 @@
}
}
- 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 @@
}
}
-/* Allocates a new proxy <name> of type <cap> found at position <file:linenum>,
- * preset it from the defaults of <defproxy> and returns it. Un case of error,
- * an alert is printed and NULL is returned. If <errmsg> is not NULL, an error
- * message will be returned there in case of fatal error. If <defproxy> is NULL,
- * the documented default settings will be used instead.
+/* Allocates a new proxy <name> of type <cap>.
+ * 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 @@
}
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 <defproxy> to <curproxy>.
+ * Returns 0 on success.
+ * Returns 1 on error. <errmsg> 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 @@
/* 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 @@
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 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 @@
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 @@
curproxy->email_alert.level = defproxy->email_alert.level;
curproxy->email_alert.set = defproxy->email_alert.set;
- done:
+ return 0;
+}
+
+/* Allocates a new proxy <name> of type <cap> found at position <file:linenum>,
+ * preset it from the defaults of <defproxy> 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