From: Willy Tarreau Date: Fri, 12 Feb 2021 12:52:11 +0000 (+0100) Subject: MINOR: proxy: support storing defaults sections into their own tree X-Git-Tag: v2.4-dev8~29 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0a0f6a7e4f6536d80f072263a2484acbe11a6e6c;p=thirdparty%2Fhaproxy.git MINOR: proxy: support storing defaults sections into their own tree Now we'll have a tree of named defaults sections. The regular insertion and lookup functions take care of the capability in order to select the appropriate tree. A new function proxy_destroy_defaults() removes a proxy from this tree and frees it entirely. --- diff --git a/include/haproxy/proxy.h b/include/haproxy/proxy.h index 81d6b0bc45..b4b04c5590 100644 --- a/include/haproxy/proxy.h +++ b/include/haproxy/proxy.h @@ -58,6 +58,7 @@ 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); +void proxy_destroy_defaults(struct proxy *px); 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/proxy.c b/src/proxy.c index 53518807f6..e7030415d0 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -53,6 +53,7 @@ int listeners; /* # of proxy listeners, set by cfgparse */ struct proxy *proxies_list = NULL; /* list of all existing proxies */ struct eb_root used_proxy_id = EB_ROOT; /* list of proxy IDs in use */ struct eb_root proxy_by_name = EB_ROOT; /* tree of proxies sorted by name */ +struct eb_root defproxy_by_name = EB_ROOT; /* tree of default proxies sorted by name (dups possible) */ unsigned int error_snapshot_id = 0; /* global ID assigned to each error then incremented */ /* proxy->options */ @@ -738,13 +739,16 @@ static int proxy_parse_tcpka_intvl(char **args, int section, struct proxy *proxy } #endif -/* This function inserts proxy into the tree of known proxies. The proxy's - * name is used as the storing key so it must already have been initialized. +/* This function inserts proxy into the tree of known proxies (regular + * ones or defaults depending on px->cap & PR_CAP_DEF). The proxy's name is + * used as the storing key so it must already have been initialized. */ void proxy_store_name(struct proxy *px) { + struct eb_root *root = (px->cap & PR_CAP_DEF) ? &defproxy_by_name : &proxy_by_name; + px->conf.by_name.key = px->id; - ebis_insert(&proxy_by_name, &px->conf.by_name); + ebis_insert(root, &px->conf.by_name); } /* Returns a pointer to the first proxy matching capabilities and id @@ -774,21 +778,25 @@ struct proxy *proxy_find_by_id(int id, int cap, int table) /* Returns a pointer to the first proxy matching either name , or id * if begins with a '#'. NULL is returned if no match is found. - * If is non-zero, it only considers proxies having a table. + * If
is non-zero, it only considers proxies having a table. The search + * is made into the regular proxies, unless has PR_CAP_DEF set in which + * case it's searched into the defproxy tree. */ struct proxy *proxy_find_by_name(const char *name, int cap, int table) { struct proxy *curproxy; - if (*name == '#') { + if (*name == '#' && !(cap & PR_CAP_DEF)) { curproxy = proxy_find_by_id(atoi(name + 1), cap, table); if (curproxy) return curproxy; } else { + struct eb_root *root; struct ebpt_node *node; - for (node = ebis_lookup(&proxy_by_name, name); node; node = ebpt_next(node)) { + root = (cap & PR_CAP_DEF) ? &defproxy_by_name : &proxy_by_name; + for (node = ebis_lookup(root, name); node; node = ebpt_next(node)) { curproxy = container_of(node, struct proxy, conf.by_name); if (strcmp(curproxy->id, name) != 0) @@ -1156,6 +1164,21 @@ void proxy_free_defaults(struct proxy *defproxy) */ } +/* delete a defproxy from the tree if still in it, frees its content and its + * storage. Nothing is done if is NULL or if it doesn't have PR_CAP_DEF + * set, allowing to pass it the direct result of a lookup function. + */ +void proxy_destroy_defaults(struct proxy *px) +{ + if (!px) + return; + if (!(px->cap & PR_CAP_DEF)) + return; + ebpt_delete(&px->conf.by_name); + proxy_free_defaults(px); + free(px); +} + /* 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