]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: protocol: register the receiver's I/O handler and not the protocol's
authorWilly Tarreau <w@1wt.eu>
Thu, 15 Oct 2020 19:29:49 +0000 (21:29 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 15 Oct 2020 19:47:56 +0000 (21:47 +0200)
Now we define a new sock_accept_iocb() for socket-based stream protocols
and use it as a wrapper for listener_accept() which now takes a listener
and not an FD anymore. This will allow the receiver's I/O cb to be
redefined during registration, and more specifically to get rid of the
hard-coded hacks in protocol_bind_all() made for syslog.

The previous ->accept() callback in the protocol was removed since it
doesn't have anything to do with accept() anymore but is more generic.
A few places where listener_accept() was compared against the FD's IO
callback for debugging purposes on the CLI were updated.

12 files changed:
include/haproxy/listener.h
include/haproxy/protocol-t.h
include/haproxy/sock.h
src/cli.c
src/haproxy.c
src/listener.c
src/mworker.c
src/proto_sockpair.c
src/proto_tcp.c
src/proto_uxst.c
src/protocol.c
src/sock.c

index 24a126c2fcbfc90b0f4029f101f259d662a73563..722a9ea0e6233b2d48cbb7daec3cd97330d43d33 100644 (file)
@@ -110,7 +110,7 @@ void __delete_listener(struct listener *listener);
  * to an accept. It tries to accept as many connections as possible, and for each
  * calls the listener's accept handler (generally the frontend's accept handler).
  */
-void listener_accept(int fd);
+void listener_accept(struct listener *l);
 
 /* Returns a suitable value for a listener's backlog. It uses the listener's,
  * otherwise the frontend's backlog, otherwise the listener's maxconn,
index 5c9793b58c49d1b1be9f0385f184d43383d73e6b..d50c83882edff18c48500504feca8cfa19e0df3c 100644 (file)
@@ -108,7 +108,6 @@ struct protocol {
        void (*default_iocb)(int fd);                   /* generic I/O handler (typically accept callback) */
 
        /* functions acting on connections */
-       void (*accept)(int fd);                         /* generic accept function */
        int (*connect)(struct connection *, int flags); /* connect function if any, see below for flags values */
 
        struct list receivers;                          /* list of receivers using this protocol (under proto_lock) */
index 193d2e451b2a2942b32ea3df77bb0450396098cf..6e81b1b22bfb13e1be585aee47dbd3ac258306f8 100644 (file)
@@ -42,6 +42,7 @@ int sock_get_old_sockets(const char *unixsocket);
 int sock_find_compatible_fd(const struct receiver *rx);
 int sock_accepting_conn(const struct receiver *rx);
 struct connection *sock_accept_conn(struct listener *l, int *status);
+void sock_accept_iocb(int fd);
 
 #endif /* _HAPROXY_SOCK_H */
 
index 7f4ea328a647b98992b132fa57a11a3eba13a2a3..e39ef68b35a30c3de817ab209a712768f1072ffb 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -53,6 +53,7 @@
 #include <haproxy/sample-t.h>
 #include <haproxy/server.h>
 #include <haproxy/session.h>
+#include <haproxy/sock.h>
 #include <haproxy/stats-t.h>
 #include <haproxy/stream.h>
 #include <haproxy/stream_interface.h>
@@ -1020,7 +1021,7 @@ static int cli_io_handler_show_fd(struct appctx *appctx)
                        px = objt_proxy(((struct connection *)fdt.owner)->target);
                        is_back = conn_is_back((struct connection *)fdt.owner);
                }
-               else if (fdt.iocb == listener_accept)
+               else if (fdt.iocb == sock_accept_iocb)
                        li = fdt.owner;
 
                chunk_printf(&trash,
@@ -1064,7 +1065,7 @@ static int cli_io_handler_show_fd(struct appctx *appctx)
                        else
                                chunk_appendf(&trash, " nomux");
                }
-               else if (fdt.iocb == listener_accept) {
+               else if (fdt.iocb == sock_accept_iocb) {
                        chunk_appendf(&trash, ") l.st=%s fe=%s",
                                      listener_state_str(li),
                                      li->bind_conf->frontend->id);
@@ -1707,7 +1708,7 @@ static int _getsocks(char **args, char *payload, struct appctx *appctx, void *pr
                /* for now we can only retrieve namespaces and interfaces from
                 * pure listeners.
                 */
-               if (fdtab[cur_fd].iocb == listener_accept) {
+               if (fdtab[cur_fd].iocb == sock_accept_iocb) {
                        const struct listener *l = fdtab[cur_fd].owner;
 
                        if (l->rx.settings->interface) {
index 4ef79bc27a18f0a66132b91e2acf54dd289d8b41..83e57ce6e90b0913dedc33904cddbe71881e7e10 100644 (file)
@@ -2455,7 +2455,7 @@ void deinit(void)
                if (!fdtab || !fdtab[cur_fd].owner)
                        continue;
 
-               if (fdtab[cur_fd].iocb == listener_accept) {
+               if (fdtab[cur_fd].iocb == &sock_accept_iocb) {
                        struct listener *l = fdtab[cur_fd].owner;
 
                        BUG_ON(l->state != LI_INIT);
index 1cad1bb101e5d032f668d4642837d00cb100388b..320fc5eb71386067102ddba9ee818bd5e6898e6d 100644 (file)
@@ -685,9 +685,8 @@ int listener_backlog(const struct listener *l)
  * to an accept. It tries to accept as many connections as possible, and for each
  * calls the listener's accept handler (generally the frontend's accept handler).
  */
-void listener_accept(int fd)
+void listener_accept(struct listener *l)
 {
-       struct listener *l = fdtab[fd].owner;
        struct connection *cli_conn;
        struct proxy *p;
        unsigned int max_accept;
@@ -697,8 +696,6 @@ void listener_accept(int fd)
        int expire;
        int ret;
 
-       if (!l)
-               return;
        p = l->bind_conf->frontend;
 
        /* if l->maxaccept is -1, then max_accept is UINT_MAX. It is not really
index d45b35795236a81d646113ec896bb5542c7077f6..690f3f0257210b0f2a5908351d926171401d50f1 100644 (file)
@@ -334,7 +334,8 @@ restart_wait:
 /* This wrapper is called from the workers. It is registered instead of the
  * normal listener_accept() so the worker can exit() when it detects that the
  * master closed the IPC FD. If it's not a close, we just call the regular
- * listener_accept() function */
+ * listener_accept() function.
+ */
 void mworker_accept_wrapper(int fd)
 {
        char c;
@@ -351,7 +352,10 @@ void mworker_accept_wrapper(int fd)
                        }
                        break;
                } else if (ret > 0) {
-                       listener_accept(fd);
+                       struct listener *l = fdtab[fd].owner;
+
+                       if (l)
+                               listener_accept(l);
                        return;
                } else if (ret == 0) {
                        /* At this step the master is down before
index 8be1093c3d7c135f92e2b8a30c164b0c63d6a159..8e174601982c82b0415ddc6a8ce664879ac610ff 100644 (file)
@@ -81,7 +81,7 @@ static struct protocol proto_sockpair = {
        .rx_enable = sock_enable,
        .rx_disable = sock_disable,
        .rx_listening = sockpair_accepting_conn,
-       .accept = &listener_accept,
+       .default_iocb = &sock_accept_iocb,
        .connect = &sockpair_connect_server,
        .receivers = LIST_HEAD_INIT(proto_sockpair.receivers),
        .nb_receivers = 0,
index cf1166415cb6f2ca94f84b15dbcfa38fa58dd54f..d872ed318215d10d0b5ca19a3737f3804235c360 100644 (file)
@@ -74,7 +74,7 @@ static struct protocol proto_tcpv4 = {
        .rx_suspend = tcp_suspend_receiver,
        .rx_resume = tcp_resume_receiver,
        .rx_listening = sock_accepting_conn,
-       .accept = &listener_accept,
+       .default_iocb = &sock_accept_iocb,
        .connect = tcp_connect_server,
        .receivers = LIST_HEAD_INIT(proto_tcpv4.receivers),
        .nb_receivers = 0,
@@ -104,7 +104,7 @@ static struct protocol proto_tcpv6 = {
        .rx_suspend = tcp_suspend_receiver,
        .rx_resume = tcp_resume_receiver,
        .rx_listening = sock_accepting_conn,
-       .accept = &listener_accept,
+       .default_iocb = &sock_accept_iocb,
        .connect = tcp_connect_server,
        .receivers = LIST_HEAD_INIT(proto_tcpv6.receivers),
        .nb_receivers = 0,
index eb1cf9daa62b94d78267d9205d966d662ee46aff..d33f8c3a7af23722c41658f462c8bb09a80fa604 100644 (file)
@@ -67,7 +67,7 @@ static struct protocol proto_unix = {
        .rx_unbind = sock_unbind,
        .rx_suspend = uxst_suspend_receiver,
        .rx_listening = sock_accepting_conn,
-       .accept = &listener_accept,
+       .default_iocb = &sock_accept_iocb,
        .connect = &uxst_connect_server,
        .receivers = LIST_HEAD_INIT(proto_unix.receivers),
        .nb_receivers = 0,
index 82deaad4f8a2edd7a69a52cdd782d3cf77f653a5..18ca40a0dbe83871f71fcaa3262ff482217d766d 100644 (file)
@@ -78,12 +78,7 @@ int protocol_bind_all(int verbose)
                         * a handler when creating the receiver yet, so we still
                         * have to take care of special cases here.
                         */
-                       handler = listener->rx.proto->accept;
-                       if (!handler && listener->bind_conf->frontend->mode == PR_MODE_SYSLOG) {
-                               extern void syslog_fd_handler(int);
-                               handler = syslog_fd_handler;
-                       }
-
+                       handler = listener->rx.iocb;
                        lerr = proto->fam->bind(receiver, handler, &errmsg);
                        err |= lerr;
 
index 990db23a5a9a4fb202abe7ecc376ff3fa714e134..d640190329f77ec74eb30949ef3e7a6b79f5c3ac 100644 (file)
@@ -27,7 +27,7 @@
 
 #include <haproxy/api.h>
 #include <haproxy/connection.h>
-#include <haproxy/listener-t.h>
+#include <haproxy/listener.h>
 #include <haproxy/log.h>
 #include <haproxy/namespace.h>
 #include <haproxy/sock.h>
@@ -613,6 +613,21 @@ int sock_accepting_conn(const struct receiver *rx)
        return opt_val;
 }
 
+/* This is the FD handler IO callback for stream sockets configured for
+ * accepting incoming connections. It's a pass-through to listener_accept()
+ * which will iterate over the listener protocol's accept_conn() function.
+ * The FD's owner must be a listener.
+ */
+void sock_accept_iocb(int fd)
+{
+       struct listener *l = fdtab[fd].owner;
+
+       if (!l)
+               return;
+
+       listener_accept(l);
+}
+
 /*
  * Local variables:
  *  c-indent-level: 8