MINOR: sockpair: implement the .rx_listening function

For socket pairs we don't rely on a real listening socket but we need to
have a properly connected UNIX stream socket. This is what the new
sockpair_accept_conn() tries to report. Some corner cases like half
shutdown will still not be detected but that should be sufficient for
most cases we really care about.
This commit is contained in:
Willy Tarreau 2020-10-13 17:27:34 +02:00
parent 29185140db
commit cc8b653483

View File

@ -47,6 +47,7 @@ static int sockpair_bind_listener(struct listener *listener, char *errmsg, int e
static void sockpair_enable_listener(struct listener *listener);
static void sockpair_disable_listener(struct listener *listener);
static int sockpair_connect_server(struct connection *conn, int flags);
static int sockpair_accept_conn(const struct receiver *rx);
struct proto_fam proto_fam_sockpair = {
.name = "sockpair",
@ -76,6 +77,7 @@ static struct protocol proto_sockpair = {
.rx_unbind = sock_unbind,
.rx_enable = sock_enable,
.rx_disable = sock_disable,
.rx_listening = sockpair_accept_conn,
.accept = &listener_accept,
.connect = &sockpair_connect_server,
.receivers = LIST_HEAD_INIT(proto_sockpair.receivers),
@ -432,6 +434,43 @@ int recv_fd_uxst(int sock)
return recv_fd;
}
/* Tests if the receiver supports accepting connections. Returns positive on
* success, 0 if not possible, negative if the socket is non-recoverable. In
* practice zero is never returned since we don't support suspending sockets.
* The real test consists in verifying we have a connected SOCK_STREAM of
* family AF_UNIX.
*/
static int sockpair_accept_conn(const struct receiver *rx)
{
struct sockaddr sa;
socklen_t len;
int val;
len = sizeof(val);
if (getsockopt(rx->fd, SOL_SOCKET, SO_TYPE, &val, &len) == -1)
return -1;
if (val != SOCK_STREAM)
return -1;
len = sizeof(sa);
if (getsockname(rx->fd, &sa, &len) != 0)
return -1;
if (sa.sa_family != AF_UNIX)
return -1;
len = sizeof(val);
if (getsockopt(rx->fd, SOL_SOCKET, SO_ACCEPTCONN, &val, &len) == -1)
return -1;
/* Note: cannot be a listening socket, must be established */
if (val)
return -1;
return 1;
}
/*
* Local variables:
* c-indent-level: 8