Skip to content

Commit 42710b7

Browse files
committed
MEDIUM: uri_auth: implement clean uri_auth cleaning
proxy auth_uri struct was manually cleaned up during deinit, but the logic behind was kind of akward because it was required to find out which ones were shared or not. Instead, let's switch to a proper refcount mechanism and free the auth_uri struct directly in proxy_free_common().
1 parent e1ec37e commit 42710b7

File tree

7 files changed

+34
-31
lines changed

7 files changed

+34
-31
lines changed

include/haproxy/uri_auth-t.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ struct stat_scope {
2929
/* later we may link them to support multiple URI matching */
3030
struct uri_auth {
3131
int uri_len; /* the prefix length */
32+
uint refcount; /* to free when unused */
3233
char *uri_prefix; /* the prefix we want to match */
3334
char *auth_realm; /* the realm reported to the client */
3435
char *node, *desc; /* node name & description reported in this stats */

include/haproxy/uri_auth.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ struct uri_auth *stats_add_scope(struct uri_auth **root, char *scope);
3434
struct uri_auth *stats_set_node(struct uri_auth **root, char *name);
3535
struct uri_auth *stats_set_desc(struct uri_auth **root, char *desc);
3636
void stats_uri_auth_free(struct uri_auth *uri_auth);
37+
void stats_uri_auth_take(struct uri_auth *uri_auth);
38+
void stats_uri_auth_drop(struct uri_auth *uri_auth);
3739

3840
#endif /* _HAPROXY_URI_AUTH_H */
3941

src/cfgparse-listen.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1761,8 +1761,11 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
17611761
LIST_APPEND(&curproxy->sticking_rules, &rule->list);
17621762
}
17631763
else if (strcmp(args[0], "stats") == 0) {
1764-
if (!(curproxy->cap & PR_CAP_DEF) && curproxy->uri_auth == curr_defproxy->uri_auth)
1765-
curproxy->uri_auth = NULL; /* we must detach from the default config */
1764+
if (!(curproxy->cap & PR_CAP_DEF) && curproxy->uri_auth == curr_defproxy->uri_auth) {
1765+
/* we must detach from the default config */
1766+
stats_uri_auth_drop(curproxy->uri_auth);
1767+
curproxy->uri_auth = NULL;
1768+
}
17661769

17671770
if (!*args[1]) {
17681771
goto stats_error_parsing;

src/cfgparse.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@
9090
#include <haproxy/tcpcheck.h>
9191
#include <haproxy/thread.h>
9292
#include <haproxy/tools.h>
93-
#include <haproxy/uri_auth-t.h>
93+
#include <haproxy/uri_auth.h>
9494

9595

9696
/* Used to chain configuration sections definitions. This list
@@ -3936,6 +3936,7 @@ int check_config_validity()
39363936
ha_warning("'stats' statement ignored for %s '%s' as it requires HTTP mode.\n",
39373937
proxy_type_str(curproxy), curproxy->id);
39383938
err_code |= ERR_WARN;
3939+
stats_uri_auth_drop(curproxy->uri_auth);
39393940
curproxy->uri_auth = NULL;
39403941
}
39413942

src/haproxy.c

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3200,7 +3200,6 @@ void deinit(void)
32003200
{
32013201
struct proxy *p = proxies_list, *p0;
32023202
struct cfgfile *cfg, *cfg_tmp;
3203-
struct uri_auth *uap, *ua = NULL;
32043203
struct logger *log, *logb;
32053204
struct build_opts_str *bol, *bolb;
32063205
struct post_deinit_fct *pdf, *pdfb;
@@ -3254,22 +3253,6 @@ void deinit(void)
32543253

32553254
deinit_signals();
32563255
while (p) {
3257-
/* build a list of unique uri_auths */
3258-
if (!ua)
3259-
ua = p->uri_auth;
3260-
else {
3261-
/* check if p->uri_auth is unique */
3262-
for (uap = ua; uap; uap=uap->next)
3263-
if (uap == p->uri_auth)
3264-
break;
3265-
3266-
if (!uap && p->uri_auth) {
3267-
/* add it, if it is */
3268-
p->uri_auth->next = ua;
3269-
ua = p->uri_auth;
3270-
}
3271-
}
3272-
32733256
p0 = p;
32743257
p = p->next;
32753258
free_proxy(p0);
@@ -3282,12 +3265,6 @@ void deinit(void)
32823265
/* destroy all referenced defaults proxies */
32833266
proxy_destroy_all_unref_defaults();
32843267

3285-
while (ua) {
3286-
uap = ua;
3287-
ua = ua->next;
3288-
stats_uri_auth_free(uap);
3289-
}
3290-
32913268
userlist_free(userlist);
32923269

32933270
cfg_unregister_sections();

src/proxy.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
#include <haproxy/tcpcheck.h>
5555
#include <haproxy/time.h>
5656
#include <haproxy/tools.h>
57+
#include <haproxy/uri_auth.h>
5758

5859

5960
int listeners; /* # of proxy listeners, set by cfgparse */
@@ -271,6 +272,8 @@ static inline void proxy_free_common(struct proxy *px)
271272
}
272273

273274
free_email_alert(px);
275+
stats_uri_auth_drop(px->uri_auth);
276+
px->uri_auth = NULL;
274277
}
275278

276279
void free_proxy(struct proxy *p)
@@ -1513,10 +1516,6 @@ void proxy_free_defaults(struct proxy *defproxy)
15131516

15141517
proxy_release_conf_errors(defproxy);
15151518
deinit_proxy_tcpcheck(defproxy);
1516-
1517-
/* FIXME: we cannot free uri_auth because it might already be used by
1518-
* another proxy (legacy code for stats URI ...). Refcount anyone ?
1519-
*/
15201519
}
15211520

15221521
/* delete a defproxy from the tree if still in it, frees its content and its
@@ -1803,7 +1802,11 @@ static int proxy_defproxy_cpy(struct proxy *curproxy, const struct proxy *defpro
18031802
}
18041803

18051804
curproxy->mode = defproxy->mode;
1806-
curproxy->uri_auth = defproxy->uri_auth; /* for stats */
1805+
1806+
/* for stats */
1807+
stats_uri_auth_drop(curproxy->uri_auth);
1808+
stats_uri_auth_take(defproxy->uri_auth);
1809+
curproxy->uri_auth = defproxy->uri_auth;
18071810

18081811
/* copy default loggers to curproxy */
18091812
list_for_each_entry(tmplogger, &defproxy->loggers, list) {

src/uri_auth.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ struct uri_auth *stats_check_init_uri_auth(struct uri_auth **root)
3838

3939
LIST_INIT(&u->http_req_rules);
4040
LIST_INIT(&u->admin_rules);
41+
stats_uri_auth_take(u);
4142
} else
4243
u = *root;
4344

@@ -342,6 +343,21 @@ void stats_uri_auth_free(struct uri_auth *uri_auth)
342343
free(uri_auth);
343344
}
344345

346+
void stats_uri_auth_drop(struct uri_auth *uri_auth)
347+
{
348+
if (!uri_auth)
349+
return;
350+
if (HA_ATOMIC_SUB_FETCH(&uri_auth->refcount, 1) == 0)
351+
stats_uri_auth_free(uri_auth);
352+
}
353+
354+
void stats_uri_auth_take(struct uri_auth *uri_auth)
355+
{
356+
if (!uri_auth)
357+
return;
358+
HA_ATOMIC_INC(&uri_auth->refcount);
359+
}
360+
345361
/*
346362
* Local variables:
347363
* c-indent-level: 8

0 commit comments

Comments
 (0)