* 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,
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) */
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 */
#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>
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,
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);
/* 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) {
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);
* 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;
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
/* 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;
}
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
.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,
.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,
.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,
.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,
* 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;
#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>
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