#include <haproxy/list.h>
#include <haproxy/listener.h>
#include <haproxy/protocol.h>
+#include <haproxy/proto_sockpair.h>
#include <haproxy/time.h>
#include <haproxy/tools.h>
#include <haproxy/version.h>
.l3_addrlen = sizeof(((struct sockaddr_un*)0)->sun_path),/* path len */
.accept = &listener_accept,
.connect = &sockpair_connect_server,
+ .bind = sockpair_bind_receiver,
.listen = sockpair_bind_listener,
.enable_all = enable_all_listeners,
.disable_all = disable_all_listeners,
proto_sockpair.nb_listeners++;
}
+/* Binds receiver <rx>, and assigns <handler> and rx->owner as the callback and
+ * context, respectively, with <tm> as the thread mask. Returns and error code
+ * made of ERR_* bits on failure or ERR_NONE on success. On failure, an error
+ * message may be passed into <errmsg>. Note that the binding address is only
+ * an FD to receive the incoming FDs on. Thus by definition there is no real
+ * "bind" operation, this only completes the receiver. Such FDs are not
+ * inherited upon reload.
+ */
+int sockpair_bind_receiver(struct receiver *rx, void (*handler)(int fd), char **errmsg)
+{
+ int err;
+
+ /* ensure we never return garbage */
+ if (errmsg)
+ *errmsg = 0;
+
+ err = ERR_NONE;
+
+ if (rx->flags & RX_F_BOUND)
+ return ERR_NONE;
+
+ if (rx->fd == -1) {
+ err |= ERR_FATAL | ERR_ALERT;
+ memprintf(errmsg, "sockpair may be only used with inherited FDs");
+ goto bind_return;
+ }
+
+ if (rx->fd >= global.maxsock) {
+ err |= ERR_FATAL | ERR_ABORT | ERR_ALERT;
+ memprintf(errmsg, "not enough free sockets (raise '-n' parameter)");
+ goto bind_close_return;
+ }
+
+ if (fcntl(rx->fd, F_SETFL, O_NONBLOCK) == -1) {
+ err |= ERR_FATAL | ERR_ALERT;
+ memprintf(errmsg, "cannot make socket non-blocking");
+ goto bind_close_return;
+ }
+
+ rx->flags |= RX_F_BOUND;
+
+ fd_insert(rx->fd, rx->owner, handler, thread_mask(rx->settings->bind_thread) & all_threads_mask);
+ return err;
+
+ bind_return:
+ if (errmsg && *errmsg)
+ memprintf(errmsg, "%s [fd %d]", *errmsg, rx->fd);
+
+ return err;
+
+ bind_close_return:
+ close(rx->fd);
+ goto bind_return;
+}
+
/* This function changes the state from ASSIGNED to LISTEN. The socket is NOT
* enabled for polling. The return value is composed from ERR_NONE,
* ERR_RETRYABLE and ERR_FATAL. It may return a warning or an error message in