From c95bad5013a288f9e5f94baab91f5cebbc68b237 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Thu, 22 Dec 2016 00:13:31 +0100 Subject: [PATCH] MEDIUM: move listener->frontend to bind_conf->frontend Historically, all listeners have a pointer to the frontend. But since the introduction of SSL, we now have an intermediary layer called bind_conf corresponding to a "bind" line. It makes no sense to have the frontend on each listener given that it's the same for all listeners belonging to a same bind_conf. Also certain parts like SSL can only operate on bind_conf and need the frontend. This patch fixes this by moving the frontend pointer from the listener to the bind_conf. The extra indirection is quite cheap given and the places were this is used are very scarce. --- include/proto/listener.h | 8 ++++---- include/types/listener.h | 2 +- src/cfgparse.c | 5 ++--- src/cli.c | 2 +- src/hlua_fcn.c | 4 ++-- src/listener.c | 2 +- src/peers.c | 2 +- src/session.c | 2 +- 8 files changed, 13 insertions(+), 14 deletions(-) diff --git a/include/proto/listener.h b/include/proto/listener.h index f67ca5eff..0af456381 100644 --- a/include/proto/listener.h +++ b/include/proto/listener.h @@ -119,19 +119,18 @@ struct bind_kw *bind_find_kw(const char *kw); /* Dumps all registered "bind" keywords to the string pointer. */ void bind_dump_kws(char **out); -/* allocate an bind_conf struct for a bind line, and chain it to list head . +/* allocate an bind_conf struct for a bind line, and chain it to the frontend . * If is not NULL, it is duplicated into ->arg to store useful config * information for error reporting. */ -static inline struct bind_conf *bind_conf_alloc(struct list *lh, const char *file, +static inline struct bind_conf *bind_conf_alloc(struct proxy *fe, const char *file, int line, const char *arg, struct xprt_ops *xprt) { struct bind_conf *bind_conf = (void *)calloc(1, sizeof(struct bind_conf)); bind_conf->file = strdup(file); bind_conf->line = line; - if (lh) - LIST_ADDQ(lh, &bind_conf->by_fe); + LIST_ADDQ(&fe->conf.bind, &bind_conf->by_fe); if (arg) bind_conf->arg = strdup(arg); @@ -139,6 +138,7 @@ static inline struct bind_conf *bind_conf_alloc(struct list *lh, const char *fil bind_conf->ux.gid = -1; bind_conf->ux.mode = 0; bind_conf->xprt = xprt; + bind_conf->frontend = fe; LIST_INIT(&bind_conf->listeners); return bind_conf; diff --git a/include/types/listener.h b/include/types/listener.h index b203c6cd7..03f4a72b5 100644 --- a/include/types/listener.h +++ b/include/types/listener.h @@ -142,6 +142,7 @@ struct bind_conf { X509 *ca_sign_cert; /* CA certificate referenced by ca_file */ EVP_PKEY *ca_sign_pkey; /* CA private key referenced by ca_key */ #endif + struct proxy *frontend; /* the frontend all these listeners belong to, or NULL */ struct xprt_ops *xprt; /* transport-layer operations for all listeners */ int is_ssl; /* SSL is required for these listeners */ int generate_certs; /* 1 if generate-certificates option is set, else 0 */ @@ -181,7 +182,6 @@ struct listener { struct list proto_list; /* list in the protocol header */ int (*accept)(struct listener *l, int fd, struct sockaddr_storage *addr); /* upper layer's accept() */ struct task * (*handler)(struct task *t); /* protocol handler. It is a task */ - struct proxy *frontend; /* the frontend this listener belongs to, or NULL */ enum obj_type *default_target; /* default target to use for accepted sessions or NULL */ struct list wait_queue; /* link element to make the listener wait for something (LI_LIMITED) */ unsigned int analysers; /* bitmap of required protocol analysers */ diff --git a/src/cfgparse.c b/src/cfgparse.c index 3fe3cc6b4..7b5572f79 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -297,7 +297,6 @@ int str2listener(char *str, struct proxy *curproxy, struct bind_conf *bind_conf, l->obj_type = OBJ_TYPE_LISTENER; LIST_ADDQ(&curproxy->conf.listeners, &l->by_fe); LIST_ADDQ(&bind_conf->listeners, &l->by_bind); - l->frontend = curproxy; l->bind_conf = bind_conf; l->fd = fd; @@ -2032,7 +2031,7 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm) curpeers->peers_fe->conf.args.line = curpeers->peers_fe->conf.line = linenum; peers_setup_frontend(curpeers->peers_fe); - bind_conf = bind_conf_alloc(&curpeers->peers_fe->conf.bind, file, linenum, args[2], &raw_sock); + bind_conf = bind_conf_alloc(curpeers->peers_fe, file, linenum, args[2], &raw_sock); if (!str2listener(args[2], curpeers->peers_fe, bind_conf, file, linenum, &errmsg)) { if (errmsg && *errmsg) { @@ -2881,7 +2880,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm) goto out; } - bind_conf = bind_conf_alloc(&curproxy->conf.bind, file, linenum, args[1], &raw_sock); + bind_conf = bind_conf_alloc(curproxy, file, linenum, args[1], &raw_sock); /* use default settings for unix sockets */ bind_conf->ux.uid = global.unix_bind.ux.uid; diff --git a/src/cli.c b/src/cli.c index 86fb2eaa2..4ccc49a90 100644 --- a/src/cli.c +++ b/src/cli.c @@ -215,7 +215,7 @@ static int stats_parse_global(char **args, int section_type, struct proxy *curpx } } - bind_conf = bind_conf_alloc(&global.stats_fe->conf.bind, file, line, args[2], &raw_sock); + bind_conf = bind_conf_alloc(global.stats_fe, file, line, args[2], &raw_sock); bind_conf->level = ACCESS_LVL_OPER; /* default access level */ if (!str2listener(args[2], global.stats_fe, bind_conf, file, line, err)) { diff --git a/src/hlua_fcn.c b/src/hlua_fcn.c index 5ac533a00..5951fe16d 100644 --- a/src/hlua_fcn.c +++ b/src/hlua_fcn.c @@ -470,12 +470,12 @@ int hlua_listener_get_stats(lua_State *L) li = hlua_check_listener(L, 1); - if (!li->frontend) { + if (!li->bind_conf->frontend) { lua_pushnil(L); return 1; } - stats_fill_li_stats(li->frontend, li, ST_SHLGNDS, stats, STATS_LEN); + stats_fill_li_stats(li->bind_conf->frontend, li, ST_SHLGNDS, stats, STATS_LEN); lua_newtable(L); for (i=0; ifrontend; + struct proxy *p = l->bind_conf->frontend; int max_accept = l->maxaccept ? l->maxaccept : 1; int expire; int cfd; diff --git a/src/peers.c b/src/peers.c index 1a280a570..8ffc0cb59 100644 --- a/src/peers.c +++ b/src/peers.c @@ -1753,7 +1753,7 @@ void peers_setup_frontend(struct proxy *fe) static struct appctx *peer_session_create(struct peers *peers, struct peer *peer) { struct listener *l = LIST_NEXT(&peers->peers_fe->conf.listeners, struct listener *, by_fe); - struct proxy *p = l->frontend; /* attached frontend */ + struct proxy *p = l->bind_conf->frontend; /* attached frontend */ struct appctx *appctx; struct session *sess; struct stream *s; diff --git a/src/session.c b/src/session.c index d96240095..f984c7bbb 100644 --- a/src/session.c +++ b/src/session.c @@ -115,7 +115,7 @@ static void session_count_new(struct session *sess) int session_accept_fd(struct listener *l, int cfd, struct sockaddr_storage *addr) { struct connection *cli_conn; - struct proxy *p = l->frontend; + struct proxy *p = l->bind_conf->frontend; struct session *sess; struct stream *strm; struct task *t;