diff --git a/include/proto/proxy.h b/include/proto/proxy.h index 4a4b2857f..116c00a16 100644 --- a/include/proto/proxy.h +++ b/include/proto/proxy.h @@ -30,6 +30,11 @@ #include #include +extern struct proxy *proxy; +extern struct eb_root used_proxy_id; /* list of proxy IDs in use */ +extern unsigned int error_snapshot_id; /* global ID assigned to each error then incremented */ +extern struct eb_root proxy_by_name; /* tree of proxies sorted by name */ + int start_proxies(int verbose); struct task *manage_proxy(struct task *t); void soft_stop(void); @@ -42,6 +47,7 @@ int session_set_backend(struct session *s, struct proxy *be); const char *proxy_cap_str(int cap); const char *proxy_mode_str(int mode); +void proxy_store_name(struct proxy *px); struct proxy *findproxy_mode(const char *name, int mode, int cap); struct proxy *findproxy(const char *name, int cap); struct server *findserver(const struct proxy *px, const char *name); diff --git a/include/types/proxy.h b/include/types/proxy.h index af2a3abd3..1a778bd91 100644 --- a/include/types/proxy.h +++ b/include/types/proxy.h @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -363,6 +364,7 @@ struct proxy { struct list bind; /* list of bind settings */ struct list listeners; /* list of listeners belonging to this frontend */ struct arg_list args; /* sample arg list that need to be resolved */ + struct ebpt_node by_name; /* proxies are stored sorted by name here */ char *logformat_string; /* log format string */ char *lfs_file; /* file name where the logformat string appears (strdup) */ int lfs_line; /* file name where the logformat string appears */ @@ -423,10 +425,6 @@ struct redirect_rule { char *cookie_str; }; -extern struct proxy *proxy; -extern struct eb_root used_proxy_id; /* list of proxy IDs in use */ -extern unsigned int error_snapshot_id; /* global ID assigned to each error then incremented */ - #endif /* _TYPES_PROXY_H */ /* diff --git a/src/cfgparse.c b/src/cfgparse.c index f13b9679d..ceaa96e4a 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -1826,6 +1826,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) curproxy->last_change = now.tv_sec; curproxy->id = strdup(args[1]); curproxy->cap = rc; + proxy_store_name(curproxy); /* parse the listener address if any */ if ((curproxy->cap & PR_CAP_FE) && *args[2]) { diff --git a/src/proxy.c b/src/proxy.c index ef0f63de1..3cbc1b4ac 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -44,6 +44,7 @@ int listeners; /* # of proxy listeners, set by cfgparse */ struct proxy *proxy = 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 */ unsigned int error_snapshot_id = 0; /* global ID assigned to each error then incremented */ /* @@ -278,6 +279,15 @@ static int proxy_parse_rate_limit(char **args, int section, struct proxy *proxy, return retval; } +/* 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. + */ +void proxy_store_name(struct proxy *px) +{ + px->conf.by_name.key = px->id; + ebis_insert(&proxy_by_name, &px->conf.by_name); +} + /* * This function finds a proxy with matching name, mode and with satisfying * capabilities. It also checks if there are more matching proxies with @@ -287,9 +297,15 @@ static int proxy_parse_rate_limit(char **args, int section, struct proxy *proxy, struct proxy *findproxy_mode(const char *name, int mode, int cap) { struct proxy *curproxy, *target = NULL; + struct ebpt_node *node; - for (curproxy = proxy; curproxy; curproxy = curproxy->next) { - if ((curproxy->cap & cap)!=cap || strcmp(curproxy->id, name)) + for (node = ebis_lookup(&proxy_by_name, name); node; node = ebpt_next(node)) { + curproxy = container_of(node, struct proxy, conf.by_name); + + if (strcmp(curproxy->id, name) != 0) + break; + + if ((curproxy->cap & cap) != cap) continue; if (curproxy->mode != mode &&