mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-05 11:39:33 +00:00
MEDIUM: sockpair: implement sockpair_bind_receiver()
Note that for now we don't have a sockpair.c file to host that unusual family, so the new function was placed directly into proto_sockpair.c. It's no big deal given that this family is currently not shared with multiple protocols. The function does almost nothing but setting up the receiver. This is normal as the socket the FDs are passed onto are supposed to have been already created somewhere else, and the only usable identifier for such a socket pair is the receiving FD itself. The function was assigned to sockpair's ->bind() and is not used yet.
This commit is contained in:
parent
cd5e5eaf50
commit
62292b28a3
@ -23,6 +23,7 @@
|
||||
|
||||
int recv_fd_uxst(int sock);
|
||||
int send_fd_uxst(int fd, int send_fd);
|
||||
int sockpair_bind_receiver(struct receiver *rx, void (*handler)(int fd), char **errmsg);
|
||||
|
||||
#endif /* _HAPROXY_PROTO_SOCKPAIR_H */
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
#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>
|
||||
@ -55,6 +56,7 @@ static struct protocol proto_sockpair = {
|
||||
.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,
|
||||
@ -85,6 +87,61 @@ static void sockpair_add_listener(struct listener *listener, int port)
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user