mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 15:47:01 +02:00
MINOR: protocol: register the receiver's I/O handler and not the protocol's
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.
This commit is contained in:
parent
e140a6921f
commit
a74cb38e7c
@ -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
|
* 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).
|
* 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,
|
/* Returns a suitable value for a listener's backlog. It uses the listener's,
|
||||||
* otherwise the frontend's backlog, otherwise the listener's maxconn,
|
* otherwise the frontend's backlog, otherwise the listener's maxconn,
|
||||||
|
@ -108,7 +108,6 @@ struct protocol {
|
|||||||
void (*default_iocb)(int fd); /* generic I/O handler (typically accept callback) */
|
void (*default_iocb)(int fd); /* generic I/O handler (typically accept callback) */
|
||||||
|
|
||||||
/* functions acting on connections */
|
/* 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 */
|
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) */
|
struct list receivers; /* list of receivers using this protocol (under proto_lock) */
|
||||||
|
@ -42,6 +42,7 @@ int sock_get_old_sockets(const char *unixsocket);
|
|||||||
int sock_find_compatible_fd(const struct receiver *rx);
|
int sock_find_compatible_fd(const struct receiver *rx);
|
||||||
int sock_accepting_conn(const struct receiver *rx);
|
int sock_accepting_conn(const struct receiver *rx);
|
||||||
struct connection *sock_accept_conn(struct listener *l, int *status);
|
struct connection *sock_accept_conn(struct listener *l, int *status);
|
||||||
|
void sock_accept_iocb(int fd);
|
||||||
|
|
||||||
#endif /* _HAPROXY_SOCK_H */
|
#endif /* _HAPROXY_SOCK_H */
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@
|
|||||||
#include <haproxy/sample-t.h>
|
#include <haproxy/sample-t.h>
|
||||||
#include <haproxy/server.h>
|
#include <haproxy/server.h>
|
||||||
#include <haproxy/session.h>
|
#include <haproxy/session.h>
|
||||||
|
#include <haproxy/sock.h>
|
||||||
#include <haproxy/stats-t.h>
|
#include <haproxy/stats-t.h>
|
||||||
#include <haproxy/stream.h>
|
#include <haproxy/stream.h>
|
||||||
#include <haproxy/stream_interface.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);
|
px = objt_proxy(((struct connection *)fdt.owner)->target);
|
||||||
is_back = conn_is_back((struct connection *)fdt.owner);
|
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;
|
li = fdt.owner;
|
||||||
|
|
||||||
chunk_printf(&trash,
|
chunk_printf(&trash,
|
||||||
@ -1064,7 +1065,7 @@ static int cli_io_handler_show_fd(struct appctx *appctx)
|
|||||||
else
|
else
|
||||||
chunk_appendf(&trash, " nomux");
|
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",
|
chunk_appendf(&trash, ") l.st=%s fe=%s",
|
||||||
listener_state_str(li),
|
listener_state_str(li),
|
||||||
li->bind_conf->frontend->id);
|
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
|
/* for now we can only retrieve namespaces and interfaces from
|
||||||
* pure listeners.
|
* 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;
|
const struct listener *l = fdtab[cur_fd].owner;
|
||||||
|
|
||||||
if (l->rx.settings->interface) {
|
if (l->rx.settings->interface) {
|
||||||
|
@ -2455,7 +2455,7 @@ void deinit(void)
|
|||||||
if (!fdtab || !fdtab[cur_fd].owner)
|
if (!fdtab || !fdtab[cur_fd].owner)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (fdtab[cur_fd].iocb == listener_accept) {
|
if (fdtab[cur_fd].iocb == &sock_accept_iocb) {
|
||||||
struct listener *l = fdtab[cur_fd].owner;
|
struct listener *l = fdtab[cur_fd].owner;
|
||||||
|
|
||||||
BUG_ON(l->state != LI_INIT);
|
BUG_ON(l->state != LI_INIT);
|
||||||
|
@ -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
|
* 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).
|
* 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 connection *cli_conn;
|
||||||
struct proxy *p;
|
struct proxy *p;
|
||||||
unsigned int max_accept;
|
unsigned int max_accept;
|
||||||
@ -697,8 +696,6 @@ void listener_accept(int fd)
|
|||||||
int expire;
|
int expire;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!l)
|
|
||||||
return;
|
|
||||||
p = l->bind_conf->frontend;
|
p = l->bind_conf->frontend;
|
||||||
|
|
||||||
/* if l->maxaccept is -1, then max_accept is UINT_MAX. It is not really
|
/* if l->maxaccept is -1, then max_accept is UINT_MAX. It is not really
|
||||||
|
@ -334,7 +334,8 @@ void mworker_catch_sigchld(struct sig_handler *sh)
|
|||||||
/* This wrapper is called from the workers. It is registered instead of the
|
/* 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
|
* 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
|
* 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)
|
void mworker_accept_wrapper(int fd)
|
||||||
{
|
{
|
||||||
char c;
|
char c;
|
||||||
@ -351,7 +352,10 @@ void mworker_accept_wrapper(int fd)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} else if (ret > 0) {
|
} else if (ret > 0) {
|
||||||
listener_accept(fd);
|
struct listener *l = fdtab[fd].owner;
|
||||||
|
|
||||||
|
if (l)
|
||||||
|
listener_accept(l);
|
||||||
return;
|
return;
|
||||||
} else if (ret == 0) {
|
} else if (ret == 0) {
|
||||||
/* At this step the master is down before
|
/* At this step the master is down before
|
||||||
|
@ -81,7 +81,7 @@ static struct protocol proto_sockpair = {
|
|||||||
.rx_enable = sock_enable,
|
.rx_enable = sock_enable,
|
||||||
.rx_disable = sock_disable,
|
.rx_disable = sock_disable,
|
||||||
.rx_listening = sockpair_accepting_conn,
|
.rx_listening = sockpair_accepting_conn,
|
||||||
.accept = &listener_accept,
|
.default_iocb = &sock_accept_iocb,
|
||||||
.connect = &sockpair_connect_server,
|
.connect = &sockpair_connect_server,
|
||||||
.receivers = LIST_HEAD_INIT(proto_sockpair.receivers),
|
.receivers = LIST_HEAD_INIT(proto_sockpair.receivers),
|
||||||
.nb_receivers = 0,
|
.nb_receivers = 0,
|
||||||
|
@ -74,7 +74,7 @@ static struct protocol proto_tcpv4 = {
|
|||||||
.rx_suspend = tcp_suspend_receiver,
|
.rx_suspend = tcp_suspend_receiver,
|
||||||
.rx_resume = tcp_resume_receiver,
|
.rx_resume = tcp_resume_receiver,
|
||||||
.rx_listening = sock_accepting_conn,
|
.rx_listening = sock_accepting_conn,
|
||||||
.accept = &listener_accept,
|
.default_iocb = &sock_accept_iocb,
|
||||||
.connect = tcp_connect_server,
|
.connect = tcp_connect_server,
|
||||||
.receivers = LIST_HEAD_INIT(proto_tcpv4.receivers),
|
.receivers = LIST_HEAD_INIT(proto_tcpv4.receivers),
|
||||||
.nb_receivers = 0,
|
.nb_receivers = 0,
|
||||||
@ -104,7 +104,7 @@ static struct protocol proto_tcpv6 = {
|
|||||||
.rx_suspend = tcp_suspend_receiver,
|
.rx_suspend = tcp_suspend_receiver,
|
||||||
.rx_resume = tcp_resume_receiver,
|
.rx_resume = tcp_resume_receiver,
|
||||||
.rx_listening = sock_accepting_conn,
|
.rx_listening = sock_accepting_conn,
|
||||||
.accept = &listener_accept,
|
.default_iocb = &sock_accept_iocb,
|
||||||
.connect = tcp_connect_server,
|
.connect = tcp_connect_server,
|
||||||
.receivers = LIST_HEAD_INIT(proto_tcpv6.receivers),
|
.receivers = LIST_HEAD_INIT(proto_tcpv6.receivers),
|
||||||
.nb_receivers = 0,
|
.nb_receivers = 0,
|
||||||
|
@ -67,7 +67,7 @@ static struct protocol proto_unix = {
|
|||||||
.rx_unbind = sock_unbind,
|
.rx_unbind = sock_unbind,
|
||||||
.rx_suspend = uxst_suspend_receiver,
|
.rx_suspend = uxst_suspend_receiver,
|
||||||
.rx_listening = sock_accepting_conn,
|
.rx_listening = sock_accepting_conn,
|
||||||
.accept = &listener_accept,
|
.default_iocb = &sock_accept_iocb,
|
||||||
.connect = &uxst_connect_server,
|
.connect = &uxst_connect_server,
|
||||||
.receivers = LIST_HEAD_INIT(proto_unix.receivers),
|
.receivers = LIST_HEAD_INIT(proto_unix.receivers),
|
||||||
.nb_receivers = 0,
|
.nb_receivers = 0,
|
||||||
|
@ -78,12 +78,7 @@ int protocol_bind_all(int verbose)
|
|||||||
* a handler when creating the receiver yet, so we still
|
* a handler when creating the receiver yet, so we still
|
||||||
* have to take care of special cases here.
|
* have to take care of special cases here.
|
||||||
*/
|
*/
|
||||||
handler = listener->rx.proto->accept;
|
handler = listener->rx.iocb;
|
||||||
if (!handler && listener->bind_conf->frontend->mode == PR_MODE_SYSLOG) {
|
|
||||||
extern void syslog_fd_handler(int);
|
|
||||||
handler = syslog_fd_handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
lerr = proto->fam->bind(receiver, handler, &errmsg);
|
lerr = proto->fam->bind(receiver, handler, &errmsg);
|
||||||
err |= lerr;
|
err |= lerr;
|
||||||
|
|
||||||
|
17
src/sock.c
17
src/sock.c
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#include <haproxy/api.h>
|
#include <haproxy/api.h>
|
||||||
#include <haproxy/connection.h>
|
#include <haproxy/connection.h>
|
||||||
#include <haproxy/listener-t.h>
|
#include <haproxy/listener.h>
|
||||||
#include <haproxy/log.h>
|
#include <haproxy/log.h>
|
||||||
#include <haproxy/namespace.h>
|
#include <haproxy/namespace.h>
|
||||||
#include <haproxy/sock.h>
|
#include <haproxy/sock.h>
|
||||||
@ -613,6 +613,21 @@ int sock_accepting_conn(const struct receiver *rx)
|
|||||||
return opt_val;
|
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:
|
* Local variables:
|
||||||
* c-indent-level: 8
|
* c-indent-level: 8
|
||||||
|
Loading…
Reference in New Issue
Block a user