svn commit: r218139 - head/sbin/hastd

Pawel Jakub Dawidek pjd at FreeBSD.org
Mon Jan 31 18:35:17 UTC 2011


Author: pjd
Date: Mon Jan 31 18:35:17 2011
New Revision: 218139
URL: http://svn.freebsd.org/changeset/base/218139

Log:
  Implement two new functions for sending descriptor and receving descriptor
  over UNIX domain sockets and socket pairs.
  This is in preparation for capsicum.
  
  MFC after:	1 week

Modified:
  head/sbin/hastd/proto.c
  head/sbin/hastd/proto.h
  head/sbin/hastd/proto_common.c
  head/sbin/hastd/proto_impl.h
  head/sbin/hastd/proto_socketpair.c
  head/sbin/hastd/proto_uds.c

Modified: head/sbin/hastd/proto.c
==============================================================================
--- head/sbin/hastd/proto.c	Mon Jan 31 18:32:17 2011	(r218138)
+++ head/sbin/hastd/proto.c	Mon Jan 31 18:35:17 2011	(r218139)
@@ -217,6 +217,42 @@ proto_recv(const struct proto_conn *conn
 }
 
 int
+proto_descriptor_send(const struct proto_conn *conn, int fd)
+{
+	int ret;
+
+	PJDLOG_ASSERT(conn != NULL);
+	PJDLOG_ASSERT(conn->pc_magic == PROTO_CONN_MAGIC);
+	PJDLOG_ASSERT(conn->pc_proto != NULL);
+	PJDLOG_ASSERT(conn->pc_proto->hp_descriptor_send != NULL);
+
+	ret = conn->pc_proto->hp_descriptor_send(conn->pc_ctx, fd);
+	if (ret != 0) {
+		errno = ret;
+		return (-1);
+	}
+	return (0);
+}
+
+int
+proto_descriptor_recv(const struct proto_conn *conn, int *fdp)
+{
+	int ret;
+
+	PJDLOG_ASSERT(conn != NULL);
+	PJDLOG_ASSERT(conn->pc_magic == PROTO_CONN_MAGIC);
+	PJDLOG_ASSERT(conn->pc_proto != NULL);
+	PJDLOG_ASSERT(conn->pc_proto->hp_descriptor_recv != NULL);
+
+	ret = conn->pc_proto->hp_descriptor_recv(conn->pc_ctx, fdp);
+	if (ret != 0) {
+		errno = ret;
+		return (-1);
+	}
+	return (0);
+}
+
+int
 proto_descriptor(const struct proto_conn *conn)
 {
 

Modified: head/sbin/hastd/proto.h
==============================================================================
--- head/sbin/hastd/proto.h	Mon Jan 31 18:32:17 2011	(r218138)
+++ head/sbin/hastd/proto.h	Mon Jan 31 18:35:17 2011	(r218139)
@@ -43,6 +43,8 @@ int proto_server(const char *addr, struc
 int proto_accept(struct proto_conn *conn, struct proto_conn **newconnp);
 int proto_send(const struct proto_conn *conn, const void *data, size_t size);
 int proto_recv(const struct proto_conn *conn, void *data, size_t size);
+int proto_descriptor_send(const struct proto_conn *conn, int fd);
+int proto_descriptor_recv(const struct proto_conn *conn, int *fdp);
 int proto_descriptor(const struct proto_conn *conn);
 bool proto_address_match(const struct proto_conn *conn, const char *addr);
 void proto_local_address(const struct proto_conn *conn, char *addr,

Modified: head/sbin/hastd/proto_common.c
==============================================================================
--- head/sbin/hastd/proto_common.c	Mon Jan 31 18:32:17 2011	(r218138)
+++ head/sbin/hastd/proto_common.c	Mon Jan 31 18:35:17 2011	(r218139)
@@ -46,18 +46,18 @@ __FBSDID("$FreeBSD$");
 #endif
 
 int
-proto_common_send(int fd, const unsigned char *data, size_t size)
+proto_common_send(int sock, const unsigned char *data, size_t size)
 {
 	ssize_t done;
 	size_t sendsize;
 
-	PJDLOG_ASSERT(fd >= 0);
+	PJDLOG_ASSERT(sock >= 0);
 	PJDLOG_ASSERT(data != NULL);
 	PJDLOG_ASSERT(size > 0);
 
 	do {
 		sendsize = size < MAX_SEND_SIZE ? size : MAX_SEND_SIZE;
-		done = send(fd, data, sendsize, MSG_NOSIGNAL);
+		done = send(sock, data, sendsize, MSG_NOSIGNAL);
 		if (done == 0)
 			return (ENOTCONN);
 		else if (done < 0) {
@@ -73,16 +73,16 @@ proto_common_send(int fd, const unsigned
 }
 
 int
-proto_common_recv(int fd, unsigned char *data, size_t size)
+proto_common_recv(int sock, unsigned char *data, size_t size)
 {
 	ssize_t done;
 
-	PJDLOG_ASSERT(fd >= 0);
+	PJDLOG_ASSERT(sock >= 0);
 	PJDLOG_ASSERT(data != NULL);
 	PJDLOG_ASSERT(size > 0);
 
 	do {
-		done = recv(fd, data, size, MSG_WAITALL);
+		done = recv(sock, data, size, MSG_WAITALL);
 	} while (done == -1 && errno == EINTR);
 	if (done == 0)
 		return (ENOTCONN);
@@ -90,3 +90,66 @@ proto_common_recv(int fd, unsigned char 
 		return (errno);
 	return (0);
 }
+
+int
+proto_common_descriptor_send(int sock, int fd)
+{
+	unsigned char ctrl[CMSG_SPACE(sizeof(fd))];
+	struct msghdr msg;
+	struct cmsghdr *cmsg;
+
+	PJDLOG_ASSERT(sock >= 0);
+	PJDLOG_ASSERT(fd >= 0);
+
+	bzero(&msg, sizeof(msg));
+	bzero(&ctrl, sizeof(ctrl));
+
+	msg.msg_iov = NULL;
+	msg.msg_iovlen = 0;
+	msg.msg_control = ctrl;
+	msg.msg_controllen = sizeof(ctrl);
+
+	cmsg = CMSG_FIRSTHDR(&msg);
+	cmsg->cmsg_level = SOL_SOCKET;
+	cmsg->cmsg_type = SCM_RIGHTS;
+	cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
+	*((int *)CMSG_DATA(cmsg)) = fd;
+
+	if (sendmsg(sock, &msg, 0) == -1)
+		return (errno);
+
+	return (0);
+}
+
+int
+proto_common_descriptor_recv(int sock, int *fdp)
+{
+	unsigned char ctrl[CMSG_SPACE(sizeof(*fdp))];
+	struct msghdr msg;
+	struct cmsghdr *cmsg;
+
+	PJDLOG_ASSERT(sock >= 0);
+	PJDLOG_ASSERT(fdp != NULL);
+
+	bzero(&msg, sizeof(msg));
+	bzero(&ctrl, sizeof(ctrl));
+
+	msg.msg_iov = NULL;
+	msg.msg_iovlen = 0;
+	msg.msg_control = ctrl;
+	msg.msg_controllen = sizeof(ctrl);
+
+	if (recvmsg(sock, &msg, 0) == -1)
+		return (errno);
+
+	for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
+	    cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+		if (cmsg->cmsg_level == SOL_SOCKET &&
+		    cmsg->cmsg_type == SCM_RIGHTS) {
+			*fdp = *((int *)CMSG_DATA(cmsg));
+			return (0);
+		}
+	}
+
+	return (ENOENT);
+}

Modified: head/sbin/hastd/proto_impl.h
==============================================================================
--- head/sbin/hastd/proto_impl.h	Mon Jan 31 18:32:17 2011	(r218138)
+++ head/sbin/hastd/proto_impl.h	Mon Jan 31 18:35:17 2011	(r218139)
@@ -45,6 +45,8 @@ typedef int hp_server_t(const char *, vo
 typedef int hp_accept_t(void *, void **);
 typedef int hp_send_t(void *, const unsigned char *, size_t);
 typedef int hp_recv_t(void *, unsigned char *, size_t);
+typedef int hp_descriptor_send_t(void *, int);
+typedef int hp_descriptor_recv_t(void *, int *);
 typedef int hp_descriptor_t(const void *);
 typedef bool hp_address_match_t(const void *, const char *);
 typedef void hp_local_address_t(const void *, char *, size_t);
@@ -59,6 +61,8 @@ struct hast_proto {
 	hp_accept_t	*hp_accept;
 	hp_send_t	*hp_send;
 	hp_recv_t	*hp_recv;
+	hp_descriptor_send_t *hp_descriptor_send;
+	hp_descriptor_recv_t *hp_descriptor_recv;
 	hp_descriptor_t	*hp_descriptor;
 	hp_address_match_t *hp_address_match;
 	hp_local_address_t *hp_local_address;
@@ -69,7 +73,9 @@ struct hast_proto {
 
 void proto_register(struct hast_proto *proto, bool isdefault);
 
-int proto_common_send(int fd, const unsigned char *data, size_t size);
-int proto_common_recv(int fd, unsigned char *data, size_t size);
+int proto_common_send(int sock, const unsigned char *data, size_t size);
+int proto_common_recv(int sock, unsigned char *data, size_t size);
+int proto_common_descriptor_send(int sock, int fd);
+int proto_common_descriptor_recv(int sock, int *fdp);
 
 #endif	/* !_PROTO_IMPL_H_ */

Modified: head/sbin/hastd/proto_socketpair.c
==============================================================================
--- head/sbin/hastd/proto_socketpair.c	Mon Jan 31 18:32:17 2011	(r218138)
+++ head/sbin/hastd/proto_socketpair.c	Mon Jan 31 18:35:17 2011	(r218139)
@@ -161,6 +161,34 @@ sp_recv(void *ctx, unsigned char *data, 
 }
 
 static int
+sp_descriptor_send(void *ctx, int fd)
+{
+	struct sp_ctx *spctx = ctx;
+
+	PJDLOG_ASSERT(spctx != NULL);
+	PJDLOG_ASSERT(spctx->sp_magic == SP_CTX_MAGIC);
+	PJDLOG_ASSERT(spctx->sp_side == SP_SIDE_CLIENT);
+	PJDLOG_ASSERT(spctx->sp_fd[0] >= 0);
+	PJDLOG_ASSERT(fd > 0);
+
+	return (proto_common_descriptor_send(spctx->sp_fd[0], fd));
+}
+
+static int
+sp_descriptor_recv(void *ctx, int *fdp)
+{
+	struct sp_ctx *spctx = ctx;
+
+	PJDLOG_ASSERT(spctx != NULL);
+	PJDLOG_ASSERT(spctx->sp_magic == SP_CTX_MAGIC);
+	PJDLOG_ASSERT(spctx->sp_side == SP_SIDE_SERVER);
+	PJDLOG_ASSERT(spctx->sp_fd[1] >= 0);
+	PJDLOG_ASSERT(fdp != NULL);
+
+	return (proto_common_descriptor_recv(spctx->sp_fd[1], fdp));
+}
+
+static int
 sp_descriptor(const void *ctx)
 {
 	const struct sp_ctx *spctx = ctx;
@@ -224,6 +252,8 @@ static struct hast_proto sp_proto = {
 	.hp_client = sp_client,
 	.hp_send = sp_send,
 	.hp_recv = sp_recv,
+	.hp_descriptor_send = sp_descriptor_send,
+	.hp_descriptor_recv = sp_descriptor_recv,
 	.hp_descriptor = sp_descriptor,
 	.hp_close = sp_close
 };

Modified: head/sbin/hastd/proto_uds.c
==============================================================================
--- head/sbin/hastd/proto_uds.c	Mon Jan 31 18:32:17 2011	(r218138)
+++ head/sbin/hastd/proto_uds.c	Mon Jan 31 18:35:17 2011	(r218139)
@@ -226,6 +226,32 @@ uds_recv(void *ctx, unsigned char *data,
 }
 
 static int
+uds_descriptor_send(void *ctx, int fd)
+{
+	struct uds_ctx *uctx = ctx;
+
+	PJDLOG_ASSERT(uctx != NULL);
+	PJDLOG_ASSERT(uctx->uc_magic == UDS_CTX_MAGIC);
+	PJDLOG_ASSERT(uctx->uc_fd >= 0);
+	PJDLOG_ASSERT(fd >= 0);
+
+	return (proto_common_descriptor_send(uctx->uc_fd, fd));
+}
+
+static int
+uds_descriptor_recv(void *ctx, int *fdp)
+{
+	struct uds_ctx *uctx = ctx;
+
+	PJDLOG_ASSERT(uctx != NULL);
+	PJDLOG_ASSERT(uctx->uc_magic == UDS_CTX_MAGIC);
+	PJDLOG_ASSERT(uctx->uc_fd >= 0);
+	PJDLOG_ASSERT(fdp != NULL);
+
+	return (proto_common_descriptor_recv(uctx->uc_fd, fdp));
+}
+
+static int
 uds_descriptor(const void *ctx)
 {
 	const struct uds_ctx *uctx = ctx;
@@ -307,6 +333,8 @@ static struct hast_proto uds_proto = {
 	.hp_accept = uds_accept,
 	.hp_send = uds_send,
 	.hp_recv = uds_recv,
+	.hp_descriptor_send = uds_descriptor_send,
+	.hp_descriptor_recv = uds_descriptor_recv,
 	.hp_descriptor = uds_descriptor,
 	.hp_local_address = uds_local_address,
 	.hp_remote_address = uds_remote_address,


More information about the svn-src-all mailing list