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.
This commit is contained in:
Willy Tarreau 2016-12-22 00:13:31 +01:00
parent 71a8c7c49e
commit c95bad5013
8 changed files with 13 additions and 14 deletions

View File

@ -119,19 +119,18 @@ struct bind_kw *bind_find_kw(const char *kw);
/* Dumps all registered "bind" keywords to the <out> string pointer. */
void bind_dump_kws(char **out);
/* allocate an bind_conf struct for a bind line, and chain it to list head <lh>.
/* allocate an bind_conf struct for a bind line, and chain it to the frontend <fe>.
* If <arg> 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;

View File

@ -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 */

View File

@ -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;

View File

@ -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)) {

View File

@ -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; i<ST_F_TOTAL_FIELDS; i++) {

View File

@ -295,7 +295,7 @@ void delete_listener(struct listener *listener)
void listener_accept(int fd)
{
struct listener *l = fdtab[fd].owner;
struct proxy *p = l->frontend;
struct proxy *p = l->bind_conf->frontend;
int max_accept = l->maxaccept ? l->maxaccept : 1;
int expire;
int cfd;

View File

@ -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;

View File

@ -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;