diff --git a/include/haproxy/proxy.h b/include/haproxy/proxy.h index dfaf9962f..e62007f00 100644 --- a/include/haproxy/proxy.h +++ b/include/haproxy/proxy.h @@ -57,6 +57,8 @@ struct server *findserver(const struct proxy *px, const char *name); int proxy_cfg_ensure_no_http(struct proxy *curproxy); void init_new_proxy(struct proxy *p); void proxy_preset_defaults(struct proxy *defproxy); +struct proxy *alloc_new_proxy(const char *name, unsigned int cap, const char *file, int linenum, + const struct proxy *defproxy, char **errmsg); 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 cdc3f5bf4..6a43857a3 100644 --- a/src/cfgparse-listen.c +++ b/src/cfgparse-listen.c @@ -174,7 +174,6 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) unsigned val; int err_code = 0; struct acl_cond *cond = NULL; - struct logsrv *tmplogsrv; char *errmsg = NULL; struct bind_conf *bind_conf; @@ -218,261 +217,21 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) err_code |= ERR_ALERT | ERR_FATAL; } - if ((curproxy = calloc(1, sizeof(*curproxy))) == NULL) { - ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum); - err_code |= ERR_ALERT | ERR_ABORT; - goto out; - } - - init_new_proxy(curproxy); - curproxy->next = proxies_list; - proxies_list = 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(args[1]); - curproxy->cap = rc; - proxy_store_name(curproxy); - if (alertif_too_many_args(1, file, linenum, args, &err_code)) { - if (curproxy->cap & PR_CAP_FE) + if (rc & PR_CAP_FE) ha_alert("parsing [%s:%d] : please use the 'bind' keyword for listening addresses.\n", file, linenum); goto out; } - /* set default values */ - memcpy(&curproxy->defsrv, &defproxy.defsrv, sizeof(curproxy->defsrv)); - curproxy->defsrv.id = "default-server"; - - curproxy->disabled = defproxy.disabled; - curproxy->options = defproxy.options; - curproxy->options2 = defproxy.options2; - curproxy->no_options = defproxy.no_options; - curproxy->no_options2 = defproxy.no_options2; - curproxy->bind_proc = defproxy.bind_proc; - curproxy->except_net = defproxy.except_net; - curproxy->except_mask = defproxy.except_mask; - curproxy->except_to = defproxy.except_to; - curproxy->except_mask_to = defproxy.except_mask_to; - curproxy->retry_type = defproxy.retry_type; - - if (defproxy.fwdfor_hdr_len) { - curproxy->fwdfor_hdr_len = defproxy.fwdfor_hdr_len; - curproxy->fwdfor_hdr_name = strdup(defproxy.fwdfor_hdr_name); - } - - if (defproxy.orgto_hdr_len) { - curproxy->orgto_hdr_len = defproxy.orgto_hdr_len; - curproxy->orgto_hdr_name = strdup(defproxy.orgto_hdr_name); - } - - if (defproxy.server_id_hdr_len) { - curproxy->server_id_hdr_len = defproxy.server_id_hdr_len; - curproxy->server_id_hdr_name = strdup(defproxy.server_id_hdr_name); - } - - /* initialize error relocations */ - if (!proxy_dup_default_conf_errors(curproxy, &defproxy, &errmsg)) { - ha_alert("parsing [%s:%d] : proxy '%s' : %s\n", file, linenum, curproxy->id, errmsg); - err_code |= ERR_ALERT | ERR_FATAL; + curproxy = alloc_new_proxy(args[1], rc, file, linenum, &defproxy, &errmsg); + if (!curproxy) { + /* message already printed by alloc_new_proxy() */ + ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg); + err_code |= ERR_ALERT | ERR_ABORT; goto out; } - - if (curproxy->cap & PR_CAP_FE) { - curproxy->maxconn = defproxy.maxconn; - curproxy->backlog = defproxy.backlog; - curproxy->fe_sps_lim = defproxy.fe_sps_lim; - - curproxy->to_log = defproxy.to_log & ~LW_COOKIE & ~LW_REQHDR & ~ LW_RSPHDR; - curproxy->max_out_conns = defproxy.max_out_conns; - - curproxy->clitcpka_cnt = defproxy.clitcpka_cnt; - curproxy->clitcpka_idle = defproxy.clitcpka_idle; - curproxy->clitcpka_intvl = defproxy.clitcpka_intvl; - } - - if (curproxy->cap & PR_CAP_BE) { - curproxy->lbprm.algo = defproxy.lbprm.algo; - curproxy->lbprm.hash_balance_factor = defproxy.lbprm.hash_balance_factor; - curproxy->fullconn = defproxy.fullconn; - curproxy->conn_retries = defproxy.conn_retries; - curproxy->redispatch_after = defproxy.redispatch_after; - curproxy->max_ka_queue = defproxy.max_ka_queue; - - curproxy->tcpcheck_rules.flags = (defproxy.tcpcheck_rules.flags & ~TCPCHK_RULES_UNUSED_RS); - curproxy->tcpcheck_rules.list = defproxy.tcpcheck_rules.list; - if (!LIST_ISEMPTY(&defproxy.tcpcheck_rules.preset_vars)) { - if (!dup_tcpcheck_vars(&curproxy->tcpcheck_rules.preset_vars, - &defproxy.tcpcheck_rules.preset_vars)) { - ha_alert("parsing [%s:%d] : failed to duplicate tcpcheck preset-vars\n", - file, linenum); - err_code |= ERR_ALERT | ERR_FATAL; - goto out; - } - } - - curproxy->ck_opts = defproxy.ck_opts; - if (defproxy.cookie_name) - curproxy->cookie_name = strdup(defproxy.cookie_name); - curproxy->cookie_len = defproxy.cookie_len; - - if (defproxy.dyncookie_key) - curproxy->dyncookie_key = strdup(defproxy.dyncookie_key); - if (defproxy.cookie_domain) - curproxy->cookie_domain = strdup(defproxy.cookie_domain); - - if (defproxy.cookie_maxidle) - curproxy->cookie_maxidle = defproxy.cookie_maxidle; - - if (defproxy.cookie_maxlife) - curproxy->cookie_maxlife = defproxy.cookie_maxlife; - - if (defproxy.rdp_cookie_name) - curproxy->rdp_cookie_name = strdup(defproxy.rdp_cookie_name); - curproxy->rdp_cookie_len = defproxy.rdp_cookie_len; - - if (defproxy.cookie_attrs) - curproxy->cookie_attrs = strdup(defproxy.cookie_attrs); - - if (defproxy.lbprm.arg_str) - curproxy->lbprm.arg_str = strdup(defproxy.lbprm.arg_str); - curproxy->lbprm.arg_len = defproxy.lbprm.arg_len; - curproxy->lbprm.arg_opt1 = defproxy.lbprm.arg_opt1; - curproxy->lbprm.arg_opt2 = defproxy.lbprm.arg_opt2; - curproxy->lbprm.arg_opt3 = defproxy.lbprm.arg_opt3; - - if (defproxy.conn_src.iface_name) - curproxy->conn_src.iface_name = strdup(defproxy.conn_src.iface_name); - curproxy->conn_src.iface_len = defproxy.conn_src.iface_len; - curproxy->conn_src.opts = defproxy.conn_src.opts; -#if defined(CONFIG_HAP_TRANSPARENT) - curproxy->conn_src.tproxy_addr = defproxy.conn_src.tproxy_addr; -#endif - curproxy->load_server_state_from_file = defproxy.load_server_state_from_file; - - curproxy->srvtcpka_cnt = defproxy.srvtcpka_cnt; - curproxy->srvtcpka_idle = defproxy.srvtcpka_idle; - curproxy->srvtcpka_intvl = defproxy.srvtcpka_intvl; - } - - if (curproxy->cap & PR_CAP_FE) { - if (defproxy.capture_name) - curproxy->capture_name = strdup(defproxy.capture_name); - curproxy->capture_namelen = defproxy.capture_namelen; - curproxy->capture_len = defproxy.capture_len; - } - - if (curproxy->cap & PR_CAP_FE) { - curproxy->timeout.client = defproxy.timeout.client; - curproxy->timeout.clientfin = defproxy.timeout.clientfin; - curproxy->timeout.tarpit = defproxy.timeout.tarpit; - curproxy->timeout.httpreq = defproxy.timeout.httpreq; - curproxy->timeout.httpka = defproxy.timeout.httpka; - if (defproxy.monitor_uri) - curproxy->monitor_uri = strdup(defproxy.monitor_uri); - curproxy->monitor_uri_len = defproxy.monitor_uri_len; - 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 = 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; - } - } - - if (curproxy->cap & PR_CAP_BE) { - curproxy->timeout.connect = defproxy.timeout.connect; - curproxy->timeout.server = defproxy.timeout.server; - curproxy->timeout.serverfin = defproxy.timeout.serverfin; - curproxy->timeout.check = defproxy.timeout.check; - curproxy->timeout.queue = defproxy.timeout.queue; - curproxy->timeout.tarpit = defproxy.timeout.tarpit; - curproxy->timeout.httpreq = defproxy.timeout.httpreq; - curproxy->timeout.httpka = defproxy.timeout.httpka; - curproxy->timeout.tunnel = defproxy.timeout.tunnel; - curproxy->conn_src.source_addr = defproxy.conn_src.source_addr; - } - - curproxy->mode = defproxy.mode; - curproxy->uri_auth = defproxy.uri_auth; /* for stats */ - - /* copy default logsrvs to curproxy */ - list_for_each_entry(tmplogsrv, &defproxy.logsrvs, list) { - struct logsrv *node = malloc(sizeof(*node)); - memcpy(node, tmplogsrv, sizeof(struct logsrv)); - node->ref = tmplogsrv->ref; - LIST_INIT(&node->list); - LIST_ADDQ(&curproxy->logsrvs, &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); - - 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); - if (!isttest(copy)) { - ha_alert("parsing [%s:%d] : failed to allocate memory for unique-id-header\n", file, linenum); - err_code |= ERR_ALERT | ERR_FATAL; - goto out; - } - curproxy->header_unique_id = copy; - } - - /* default compression options */ - if (defproxy.comp != NULL) { - curproxy->comp = calloc(1, sizeof(*curproxy->comp)); - curproxy->comp->algos = defproxy.comp->algos; - curproxy->comp->types = defproxy.comp->types; - } - - curproxy->grace = defproxy.grace; - curproxy->conf.used_listener_id = EB_ROOT; - curproxy->conf.used_server_id = EB_ROOT; - curproxy->used_server_addr = EB_ROOT_UNIQUE; - - if (defproxy.check_path) - curproxy->check_path = strdup(defproxy.check_path); - if (defproxy.check_command) - curproxy->check_command = strdup(defproxy.check_command); - - if (defproxy.email_alert.mailers.name) - curproxy->email_alert.mailers.name = strdup(defproxy.email_alert.mailers.name); - if (defproxy.email_alert.from) - curproxy->email_alert.from = strdup(defproxy.email_alert.from); - if (defproxy.email_alert.to) - curproxy->email_alert.to = strdup(defproxy.email_alert.to); - if (defproxy.email_alert.myhostname) - curproxy->email_alert.myhostname = strdup(defproxy.email_alert.myhostname); - curproxy->email_alert.level = defproxy.email_alert.level; - curproxy->email_alert.set = defproxy.email_alert.set; + curproxy->next = proxies_list; + proxies_list = curproxy; goto out; } diff --git a/src/proxy.c b/src/proxy.c index 009ebbc12..394ba14e7 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -44,6 +45,7 @@ #include #include #include +#include #include @@ -1092,6 +1094,276 @@ void proxy_preset_defaults(struct proxy *defproxy) #endif } +/* 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. + */ +struct proxy *alloc_new_proxy(const char *name, unsigned int cap, const char *file, int linenum, const struct proxy *defproxy, 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); + goto fail; + } + + 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); + + /* set default values */ + memcpy(&curproxy->defsrv, &defproxy->defsrv, sizeof(curproxy->defsrv)); + curproxy->defsrv.id = "default-server"; + + curproxy->disabled = defproxy->disabled; + curproxy->options = defproxy->options; + curproxy->options2 = defproxy->options2; + curproxy->no_options = defproxy->no_options; + curproxy->no_options2 = defproxy->no_options2; + curproxy->bind_proc = defproxy->bind_proc; + curproxy->except_net = defproxy->except_net; + curproxy->except_mask = defproxy->except_mask; + curproxy->except_to = defproxy->except_to; + curproxy->except_mask_to = defproxy->except_mask_to; + curproxy->retry_type = defproxy->retry_type; + + if (defproxy->fwdfor_hdr_len) { + curproxy->fwdfor_hdr_len = defproxy->fwdfor_hdr_len; + curproxy->fwdfor_hdr_name = strdup(defproxy->fwdfor_hdr_name); + } + + if (defproxy->orgto_hdr_len) { + curproxy->orgto_hdr_len = defproxy->orgto_hdr_len; + curproxy->orgto_hdr_name = strdup(defproxy->orgto_hdr_name); + } + + if (defproxy->server_id_hdr_len) { + curproxy->server_id_hdr_len = defproxy->server_id_hdr_len; + curproxy->server_id_hdr_name = strdup(defproxy->server_id_hdr_name); + } + + /* initialize error relocations */ + if (!proxy_dup_default_conf_errors(curproxy, defproxy, &tmpmsg)) { + memprintf(errmsg, "proxy '%s' : %s", curproxy->id, tmpmsg); + goto fail; + } + + if (curproxy->cap & PR_CAP_FE) { + curproxy->maxconn = defproxy->maxconn; + curproxy->backlog = defproxy->backlog; + curproxy->fe_sps_lim = defproxy->fe_sps_lim; + + curproxy->to_log = defproxy->to_log & ~LW_COOKIE & ~LW_REQHDR & ~ LW_RSPHDR; + curproxy->max_out_conns = defproxy->max_out_conns; + + curproxy->clitcpka_cnt = defproxy->clitcpka_cnt; + curproxy->clitcpka_idle = defproxy->clitcpka_idle; + curproxy->clitcpka_intvl = defproxy->clitcpka_intvl; + } + + if (curproxy->cap & PR_CAP_BE) { + curproxy->lbprm.algo = defproxy->lbprm.algo; + curproxy->lbprm.hash_balance_factor = defproxy->lbprm.hash_balance_factor; + curproxy->fullconn = defproxy->fullconn; + curproxy->conn_retries = defproxy->conn_retries; + curproxy->redispatch_after = defproxy->redispatch_after; + curproxy->max_ka_queue = defproxy->max_ka_queue; + + curproxy->tcpcheck_rules.flags = (defproxy->tcpcheck_rules.flags & ~TCPCHK_RULES_UNUSED_RS); + curproxy->tcpcheck_rules.list = defproxy->tcpcheck_rules.list; + 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; + } + } + + curproxy->ck_opts = defproxy->ck_opts; + if (defproxy->cookie_name) + curproxy->cookie_name = strdup(defproxy->cookie_name); + curproxy->cookie_len = defproxy->cookie_len; + + if (defproxy->dyncookie_key) + curproxy->dyncookie_key = strdup(defproxy->dyncookie_key); + if (defproxy->cookie_domain) + curproxy->cookie_domain = strdup(defproxy->cookie_domain); + + if (defproxy->cookie_maxidle) + curproxy->cookie_maxidle = defproxy->cookie_maxidle; + + if (defproxy->cookie_maxlife) + curproxy->cookie_maxlife = defproxy->cookie_maxlife; + + if (defproxy->rdp_cookie_name) + curproxy->rdp_cookie_name = strdup(defproxy->rdp_cookie_name); + curproxy->rdp_cookie_len = defproxy->rdp_cookie_len; + + if (defproxy->cookie_attrs) + curproxy->cookie_attrs = strdup(defproxy->cookie_attrs); + + if (defproxy->lbprm.arg_str) + curproxy->lbprm.arg_str = strdup(defproxy->lbprm.arg_str); + curproxy->lbprm.arg_len = defproxy->lbprm.arg_len; + curproxy->lbprm.arg_opt1 = defproxy->lbprm.arg_opt1; + curproxy->lbprm.arg_opt2 = defproxy->lbprm.arg_opt2; + curproxy->lbprm.arg_opt3 = defproxy->lbprm.arg_opt3; + + if (defproxy->conn_src.iface_name) + curproxy->conn_src.iface_name = strdup(defproxy->conn_src.iface_name); + curproxy->conn_src.iface_len = defproxy->conn_src.iface_len; + curproxy->conn_src.opts = defproxy->conn_src.opts; +#if defined(CONFIG_HAP_TRANSPARENT) + curproxy->conn_src.tproxy_addr = defproxy->conn_src.tproxy_addr; +#endif + curproxy->load_server_state_from_file = defproxy->load_server_state_from_file; + + curproxy->srvtcpka_cnt = defproxy->srvtcpka_cnt; + curproxy->srvtcpka_idle = defproxy->srvtcpka_idle; + curproxy->srvtcpka_intvl = defproxy->srvtcpka_intvl; + } + + if (curproxy->cap & PR_CAP_FE) { + if (defproxy->capture_name) + curproxy->capture_name = strdup(defproxy->capture_name); + curproxy->capture_namelen = defproxy->capture_namelen; + curproxy->capture_len = defproxy->capture_len; + } + + if (curproxy->cap & PR_CAP_FE) { + curproxy->timeout.client = defproxy->timeout.client; + curproxy->timeout.clientfin = defproxy->timeout.clientfin; + curproxy->timeout.tarpit = defproxy->timeout.tarpit; + curproxy->timeout.httpreq = defproxy->timeout.httpreq; + curproxy->timeout.httpka = defproxy->timeout.httpka; + if (defproxy->monitor_uri) + curproxy->monitor_uri = strdup(defproxy->monitor_uri); + curproxy->monitor_uri_len = defproxy->monitor_uri_len; + 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 = 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; + } + } + + if (curproxy->cap & PR_CAP_BE) { + curproxy->timeout.connect = defproxy->timeout.connect; + curproxy->timeout.server = defproxy->timeout.server; + curproxy->timeout.serverfin = defproxy->timeout.serverfin; + curproxy->timeout.check = defproxy->timeout.check; + curproxy->timeout.queue = defproxy->timeout.queue; + curproxy->timeout.tarpit = defproxy->timeout.tarpit; + curproxy->timeout.httpreq = defproxy->timeout.httpreq; + curproxy->timeout.httpka = defproxy->timeout.httpka; + curproxy->timeout.tunnel = defproxy->timeout.tunnel; + curproxy->conn_src.source_addr = defproxy->conn_src.source_addr; + } + + curproxy->mode = defproxy->mode; + curproxy->uri_auth = defproxy->uri_auth; /* for stats */ + + /* copy default logsrvs to curproxy */ + list_for_each_entry(tmplogsrv, &defproxy->logsrvs, list) { + struct logsrv *node = malloc(sizeof(*node)); + + if (!node) { + memprintf(errmsg, "proxy '%s': out of memory", name); + goto fail; + } + memcpy(node, tmplogsrv, sizeof(struct logsrv)); + node->ref = tmplogsrv->ref; + LIST_INIT(&node->list); + LIST_ADDQ(&curproxy->logsrvs, &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); + + 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); + + if (!isttest(copy)) { + memprintf(errmsg, "proxy '%s': out of memory for unique-id-header", name); + goto fail; + } + curproxy->header_unique_id = copy; + } + + /* default compression options */ + if (defproxy->comp != NULL) { + curproxy->comp = calloc(1, sizeof(*curproxy->comp)); + curproxy->comp->algos = defproxy->comp->algos; + curproxy->comp->types = defproxy->comp->types; + } + + curproxy->grace = defproxy->grace; + curproxy->conf.used_listener_id = EB_ROOT; + curproxy->conf.used_server_id = EB_ROOT; + curproxy->used_server_addr = EB_ROOT_UNIQUE; + + if (defproxy->check_path) + curproxy->check_path = strdup(defproxy->check_path); + if (defproxy->check_command) + curproxy->check_command = strdup(defproxy->check_command); + + if (defproxy->email_alert.mailers.name) + curproxy->email_alert.mailers.name = strdup(defproxy->email_alert.mailers.name); + if (defproxy->email_alert.from) + curproxy->email_alert.from = strdup(defproxy->email_alert.from); + if (defproxy->email_alert.to) + curproxy->email_alert.to = strdup(defproxy->email_alert.to); + if (defproxy->email_alert.myhostname) + curproxy->email_alert.myhostname = strdup(defproxy->email_alert.myhostname); + curproxy->email_alert.level = defproxy->email_alert.level; + curproxy->email_alert.set = defproxy->email_alert.set; + 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 * automatically update the p->disabled flag after stopping the last one, and * will emit a log indicating the proxy's condition. The function is idempotent