diff --git a/include/haproxy/proxy.h b/include/haproxy/proxy.h index e62007f00..81d6b0bc4 100644 --- a/include/haproxy/proxy.h +++ b/include/haproxy/proxy.h @@ -57,6 +57,7 @@ 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); +void proxy_free_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, diff --git a/src/cfgparse-listen.c b/src/cfgparse-listen.c index 6a43857a3..edcc04138 100644 --- a/src/cfgparse-listen.c +++ b/src/cfgparse-listen.c @@ -236,55 +236,13 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) goto out; } else if (strcmp(args[0], "defaults") == 0) { /* use this one to assign default values */ - /* some variables may have already been initialized earlier */ - /* FIXME-20070101: we should do this too at the end of the - * config parsing to free all default values. - */ if (alertif_too_many_args(1, file, linenum, args, &err_code)) { err_code |= ERR_ABORT; goto out; } - free(defproxy.conf.file); - free(defproxy.check_command); - free(defproxy.check_path); - free(defproxy.cookie_name); - free(defproxy.rdp_cookie_name); - free(defproxy.dyncookie_key); - free(defproxy.cookie_domain); - free(defproxy.cookie_attrs); - free(defproxy.lbprm.arg_str); - free(defproxy.capture_name); - free(defproxy.monitor_uri); - free(defproxy.defbe.name); - free(defproxy.conn_src.iface_name); - free(defproxy.fwdfor_hdr_name); - defproxy.fwdfor_hdr_len = 0; - free(defproxy.orgto_hdr_name); - defproxy.orgto_hdr_len = 0; - free(defproxy.server_id_hdr_name); - defproxy.server_id_hdr_len = 0; - - 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) - free(defproxy.conf.logformat_string); - - free(defproxy.conf.uniqueid_format_string); - free(defproxy.conf.lfs_file); - free(defproxy.conf.uif_file); - chunk_destroy(&defproxy.log_tag); - free_email_alert(&defproxy); - - if (defproxy.conf.logformat_sd_string != default_rfc5424_sd_log_format) - free(defproxy.conf.logformat_sd_string); - free(defproxy.conf.lfsd_file); - - proxy_release_conf_errors(&defproxy); - - deinit_proxy_tcpcheck(&defproxy); - - /* we cannot free uri_auth because it might already be used */ + /* let's first free previous defaults */ + proxy_free_defaults(&defproxy); init_new_proxy(&defproxy); proxy_preset_defaults(&defproxy); curproxy = &defproxy; diff --git a/src/proxy.c b/src/proxy.c index 6a1c9dff9..a60d4530d 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -1099,6 +1099,57 @@ void proxy_preset_defaults(struct proxy *defproxy) #endif } +/* Frees all dynamic settings allocated on a default proxy that's about to be + * destroyed. This is a subset of the complete proxy deinit code, but these + * should probably be merged ultimately. Note that most of the fields are not + * even reset, so extreme care is required here, and calling + * proxy_preset_defaults() afterwards would be safer. + */ +void proxy_free_defaults(struct proxy *defproxy) +{ + free(defproxy->conf.file); + free(defproxy->check_command); + free(defproxy->check_path); + free(defproxy->cookie_name); + free(defproxy->rdp_cookie_name); + free(defproxy->dyncookie_key); + free(defproxy->cookie_domain); + free(defproxy->cookie_attrs); + free(defproxy->lbprm.arg_str); + free(defproxy->capture_name); + free(defproxy->monitor_uri); + free(defproxy->defbe.name); + free(defproxy->conn_src.iface_name); + free(defproxy->fwdfor_hdr_name); + defproxy->fwdfor_hdr_len = 0; + free(defproxy->orgto_hdr_name); + defproxy->orgto_hdr_len = 0; + free(defproxy->server_id_hdr_name); + defproxy->server_id_hdr_len = 0; + + 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) + free(defproxy->conf.logformat_string); + + if (defproxy->conf.logformat_sd_string != default_rfc5424_sd_log_format) + free(defproxy->conf.logformat_sd_string); + + free(defproxy->conf.uniqueid_format_string); + free(defproxy->conf.lfs_file); + free(defproxy->conf.lfsd_file); + free(defproxy->conf.uif_file); + chunk_destroy(&defproxy->log_tag); + + free_email_alert(defproxy); + proxy_release_conf_errors(defproxy); + deinit_proxy_tcpcheck(defproxy); + + /* FIXME: we cannot free uri_auth because it might already be used by + * another proxy (legacy code for stats URI ...). Refcount anyone ? + */ +} + /* 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