Date: Mon, 31 Jan 2011 18:35:17 +0000 (UTC) From: Pawel Jakub Dawidek <pjd@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r218139 - head/sbin/hastd Message-ID: <201101311835.p0VIZHgv039561@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201101311835.p0VIZHgv039561>