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.
diff --git a/src/proto_sockpair.c b/src/proto_sockpair.c
index 4ac5b76..48b598b 100644
--- a/src/proto_sockpair.c
+++ b/src/proto_sockpair.c
@@ -47,6 +47,7 @@
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 @@
.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 @@
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