diff --git a/include/haproxy/listener.h b/include/haproxy/listener.h index 24a126c2f..722a9ea0e 100644 --- a/include/haproxy/listener.h +++ b/include/haproxy/listener.h @@ -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, diff --git a/include/haproxy/protocol-t.h b/include/haproxy/protocol-t.h index 5c9793b58..d50c83882 100644 --- a/include/haproxy/protocol-t.h +++ b/include/haproxy/protocol-t.h @@ -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) */ diff --git a/include/haproxy/sock.h b/include/haproxy/sock.h index 193d2e451..6e81b1b22 100644 --- a/include/haproxy/sock.h +++ b/include/haproxy/sock.h @@ -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 */ diff --git a/src/cli.c b/src/cli.c index 7f4ea328a..e39ef68b3 100644 --- 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) { diff --git a/src/haproxy.c b/src/haproxy.c index 4ef79bc27..83e57ce6e 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -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); diff --git a/src/listener.c b/src/listener.c index 1cad1bb10..320fc5eb7 100644 --- a/src/listener.c +++ b/src/listener.c @@ -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 diff --git a/src/mworker.c b/src/mworker.c index d45b35795..690f3f025 100644 --- a/src/mworker.c +++ b/src/mworker.c @@ -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 diff --git a/src/proto_sockpair.c b/src/proto_sockpair.c index 8be1093c3..8e1746019 100644 --- a/src/proto_sockpair.c +++ b/src/proto_sockpair.c @@ -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, diff --git a/src/proto_tcp.c b/src/proto_tcp.c index cf1166415..d872ed318 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -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, diff --git a/src/proto_uxst.c b/src/proto_uxst.c index eb1cf9daa..d33f8c3a7 100644 --- a/src/proto_uxst.c +++ b/src/proto_uxst.c @@ -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, diff --git a/src/protocol.c b/src/protocol.c index 82deaad4f..18ca40a0d 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -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; diff --git a/src/sock.c b/src/sock.c index 990db23a5..d64019032 100644 --- a/src/sock.c +++ b/src/sock.c @@ -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