MINOR: listener: move the transport layer pointer to the bind_conf

A mistake was made when the socket layer was cut into proto and
transport, the transport was attached to the listener while all
listeners in a single "bind" line always have exactly the same
transport. It doesn't seem obvious but this is the reason why there
are so many #ifdefs USE_OPENSSL in cfgparse : a lot of operations
have to be open-coded because cfgparse only manipulates bind_conf
and we don't have the information of the transport layer here.

Very little code makes use of the transport layer, mainly session
setup and log. These places can afford an extra pointer indirection
(the listener points to the bind_conf). This change is thus very small,
it saves a little bit of memory (8B per listener) and makes the code
more flexible.
This commit is contained in:
Willy Tarreau 2016-12-21 22:04:54 +01:00
parent 5820a36690
commit 71a8c7c49e
7 changed files with 13 additions and 16 deletions

View File

@ -123,7 +123,8 @@ void bind_dump_kws(char **out);
* 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, int line, const char *arg)
static inline struct bind_conf *bind_conf_alloc(struct list *lh, const char *file,
int line, const char *arg, struct xprt_ops *xprt)
{
struct bind_conf *bind_conf = (void *)calloc(1, sizeof(struct bind_conf));
@ -137,6 +138,7 @@ static inline struct bind_conf *bind_conf_alloc(struct list *lh, const char *fil
bind_conf->ux.uid = -1;
bind_conf->ux.gid = -1;
bind_conf->ux.mode = 0;
bind_conf->xprt = xprt;
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 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 */
unsigned long bind_proc; /* bitmask of processes allowed to use these listeners */
@ -173,7 +174,6 @@ struct listener {
int options; /* socket options : LI_O_* */
struct fe_counters *counters; /* statistics counters */
struct protocol *proto; /* protocol this listener belongs to */
struct xprt_ops *xprt; /* transport-layer operations for this socket */
int nbconn; /* current number of connections on this listener */
int maxconn; /* maximum connections allowed on this listener */
unsigned int backlog; /* if set, listen backlog */

View File

@ -302,7 +302,6 @@ int str2listener(char *str, struct proxy *curproxy, struct bind_conf *bind_conf,
l->fd = fd;
memcpy(&l->addr, &ss, sizeof(ss));
l->xprt = &raw_sock;
l->state = LI_INIT;
if (ss.ss_family == AF_INET) {
@ -2033,7 +2032,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]);
bind_conf = bind_conf_alloc(&curpeers->peers_fe->conf.bind, file, linenum, args[2], &raw_sock);
if (!str2listener(args[2], curpeers->peers_fe, bind_conf, file, linenum, &errmsg)) {
if (errmsg && *errmsg) {
@ -2882,7 +2881,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]);
bind_conf = bind_conf_alloc(&curproxy->conf.bind, 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]);
bind_conf = bind_conf_alloc(&global.stats_fe->conf.bind, 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

@ -1630,7 +1630,7 @@ int build_logline(struct stream *s, char *dst, size_t maxsize, struct list *list
goto out;
tmplog += iret;
#ifdef USE_OPENSSL
if (sess->listener->xprt == &ssl_sock)
if (sess->listener->bind_conf->xprt == &ssl_sock)
LOGCHAR('~');
#endif
if (tmp->options & LOG_OPT_QUOTE)
@ -1642,7 +1642,7 @@ int build_logline(struct stream *s, char *dst, size_t maxsize, struct list *list
src = NULL;
conn = objt_conn(sess->origin);
if (conn) {
if (sess->listener->xprt == &ssl_sock)
if (sess->listener->bind_conf->xprt == &ssl_sock)
src = ssl_sock_get_cipher_name(conn);
}
ret = lf_text(tmplog, src, dst + maxsize - tmplog, tmp);
@ -1656,7 +1656,7 @@ int build_logline(struct stream *s, char *dst, size_t maxsize, struct list *list
src = NULL;
conn = objt_conn(sess->origin);
if (conn) {
if (sess->listener->xprt == &ssl_sock)
if (sess->listener->bind_conf->xprt == &ssl_sock)
src = ssl_sock_get_proto_version(conn);
}
ret = lf_text(tmplog, src, dst + maxsize - tmplog, tmp);

View File

@ -127,7 +127,7 @@ int session_accept_fd(struct listener *l, int cfd, struct sockaddr_storage *addr
if (unlikely((cli_conn = conn_new()) == NULL))
goto out_close;
conn_prepare(cli_conn, l->proto, l->xprt);
conn_prepare(cli_conn, l->proto, l->bind_conf->xprt);
cli_conn->t.sock.fd = cfd;
cli_conn->addr.from = *addr;
@ -292,7 +292,7 @@ int session_accept_fd(struct listener *l, int cfd, struct sockaddr_storage *addr
conn_xprt_close(cli_conn);
conn_free(cli_conn);
out_close:
if (ret < 0 && l->xprt == &raw_sock && p->mode == PR_MODE_HTTP) {
if (ret < 0 && l->bind_conf->xprt == &raw_sock && p->mode == PR_MODE_HTTP) {
/* critical error, no more memory, try to emit a 500 response */
struct chunk *err_msg = &p->errmsg[HTTP_ERR_500];
if (!err_msg->str)

View File

@ -5491,17 +5491,13 @@ static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bi
/* parse the "ssl" bind keyword */
static int bind_parse_ssl(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
{
struct listener *l;
conf->xprt = &ssl_sock;
conf->is_ssl = 1;
if (global.listen_default_ciphers && !conf->ciphers)
conf->ciphers = strdup(global.listen_default_ciphers);
conf->ssl_options |= global.listen_default_ssloptions;
list_for_each_entry(l, &conf->listeners, by_bind)
l->xprt = &ssl_sock;
return 0;
}