]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: listener: move the transport layer pointer to the bind_conf
authorWilly Tarreau <w@1wt.eu>
Wed, 21 Dec 2016 21:04:54 +0000 (22:04 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 22 Dec 2016 22:26:37 +0000 (23:26 +0100)
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.

include/proto/listener.h
include/types/listener.h
src/cfgparse.c
src/cli.c
src/log.c
src/session.c
src/ssl_sock.c

index 75bae86d90ddcf46b11962f3788c9b3387248b16..f67ca5eff0fffed8e0bf332c800e0ae663c85deb 100644 (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;
index d06e4e7c850eb0653bdc2ee2e638f2f7b6389d7f..b203c6cd72c65a260798d7a082ec0fb9e22e8ef9 100644 (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 */
index 1c9b430c575e9fa7dfe1a9617a4bd22e02224eb3..3fe3cc6b4a2aea352401bd534f79972ff6693866 100644 (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;
index e6e9b45a855b52aa2873d416b6078d07d545f779..86fb2eaa2edd96e271f20655585e9df097bf6d11 100644 (file)
--- 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]);
+               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)) {
index 3a6f781d910b59c3f07d8902aeed88b7967e4f96..27d53f7eb954cc73ed60ca32061f5affcc5b0171 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -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);
index 35177cf208be42aaf2af190c6100c9fac27ec23b..d96240095ac07612672837843b055e7efa742530 100644 (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)
index 6739fbc9fa233623a6ed6166ae1370e87f5cd5fb..617c00297a42f1b9e99af5afe0636bcefc13ac6d 100644 (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;
 }