/* later we may link them to support multiple URI matching */
struct uri_auth {
int uri_len; /* the prefix length */
+ uint refcount; /* to free when unused */
char *uri_prefix; /* the prefix we want to match */
char *auth_realm; /* the realm reported to the client */
char *node, *desc; /* node name & description reported in this stats */
struct uri_auth *stats_set_node(struct uri_auth **root, char *name);
struct uri_auth *stats_set_desc(struct uri_auth **root, char *desc);
void stats_uri_auth_free(struct uri_auth *uri_auth);
+void stats_uri_auth_take(struct uri_auth *uri_auth);
+void stats_uri_auth_drop(struct uri_auth *uri_auth);
#endif /* _HAPROXY_URI_AUTH_H */
LIST_APPEND(&curproxy->sticking_rules, &rule->list);
}
else if (strcmp(args[0], "stats") == 0) {
- if (!(curproxy->cap & PR_CAP_DEF) && curproxy->uri_auth == curr_defproxy->uri_auth)
- curproxy->uri_auth = NULL; /* we must detach from the default config */
+ if (!(curproxy->cap & PR_CAP_DEF) && curproxy->uri_auth == curr_defproxy->uri_auth) {
+ /* we must detach from the default config */
+ stats_uri_auth_drop(curproxy->uri_auth);
+ curproxy->uri_auth = NULL;
+ }
if (!*args[1]) {
goto stats_error_parsing;
#include <haproxy/tcpcheck.h>
#include <haproxy/thread.h>
#include <haproxy/tools.h>
-#include <haproxy/uri_auth-t.h>
+#include <haproxy/uri_auth.h>
/* Used to chain configuration sections definitions. This list
ha_warning("'stats' statement ignored for %s '%s' as it requires HTTP mode.\n",
proxy_type_str(curproxy), curproxy->id);
err_code |= ERR_WARN;
+ stats_uri_auth_drop(curproxy->uri_auth);
curproxy->uri_auth = NULL;
}
{
struct proxy *p = proxies_list, *p0;
struct cfgfile *cfg, *cfg_tmp;
- struct uri_auth *uap, *ua = NULL;
struct logger *log, *logb;
struct build_opts_str *bol, *bolb;
struct post_deinit_fct *pdf, *pdfb;
deinit_signals();
while (p) {
- /* build a list of unique uri_auths */
- if (!ua)
- ua = p->uri_auth;
- else {
- /* check if p->uri_auth is unique */
- for (uap = ua; uap; uap=uap->next)
- if (uap == p->uri_auth)
- break;
-
- if (!uap && p->uri_auth) {
- /* add it, if it is */
- p->uri_auth->next = ua;
- ua = p->uri_auth;
- }
- }
-
p0 = p;
p = p->next;
free_proxy(p0);
/* destroy all referenced defaults proxies */
proxy_destroy_all_unref_defaults();
- while (ua) {
- uap = ua;
- ua = ua->next;
- stats_uri_auth_free(uap);
- }
-
userlist_free(userlist);
cfg_unregister_sections();
#include <haproxy/tcpcheck.h>
#include <haproxy/time.h>
#include <haproxy/tools.h>
+#include <haproxy/uri_auth.h>
int listeners; /* # of proxy listeners, set by cfgparse */
}
free_email_alert(px);
+ stats_uri_auth_drop(px->uri_auth);
+ px->uri_auth = NULL;
}
void free_proxy(struct proxy *p)
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 ?
- */
}
/* delete a defproxy from the tree if still in it, frees its content and its
}
curproxy->mode = defproxy->mode;
- curproxy->uri_auth = defproxy->uri_auth; /* for stats */
+
+ /* for stats */
+ stats_uri_auth_drop(curproxy->uri_auth);
+ stats_uri_auth_take(defproxy->uri_auth);
+ curproxy->uri_auth = defproxy->uri_auth;
/* copy default loggers to curproxy */
list_for_each_entry(tmplogger, &defproxy->loggers, list) {
LIST_INIT(&u->http_req_rules);
LIST_INIT(&u->admin_rules);
+ stats_uri_auth_take(u);
} else
u = *root;
free(uri_auth);
}
+void stats_uri_auth_drop(struct uri_auth *uri_auth)
+{
+ if (!uri_auth)
+ return;
+ if (HA_ATOMIC_SUB_FETCH(&uri_auth->refcount, 1) == 0)
+ stats_uri_auth_free(uri_auth);
+}
+
+void stats_uri_auth_take(struct uri_auth *uri_auth)
+{
+ if (!uri_auth)
+ return;
+ HA_ATOMIC_INC(&uri_auth->refcount);
+}
+
/*
* Local variables:
* c-indent-level: 8