Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 22 Mar 2017 06:43:10 +0000 (UTC)
From:      Ed Schouten <ed@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r315700 - in head/sys/compat: cloudabi cloudabi32 cloudabi64
Message-ID:  <201703220643.v2M6hArU057914@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ed
Date: Wed Mar 22 06:43:10 2017
New Revision: 315700
URL: https://svnweb.freebsd.org/changeset/base/315700

Log:
  Make file descriptor passing work for CloudABI's sendmsg().
  
  Reduce the potential amount of code duplication between cloudabi32 and
  cloudabi64 by creating a cloudabi_sock_recv() utility function. The
  cloudabi32 and cloudabi64 modules will then only contain code to convert
  the iovecs to the native pointer size.
  
  In cloudabi_sock_recv(), we can now construct an SCM_RIGHTS cmsghdr in
  an mbuf and pass that on to kern_sendit().

Modified:
  head/sys/compat/cloudabi/cloudabi_sock.c
  head/sys/compat/cloudabi/cloudabi_util.h
  head/sys/compat/cloudabi32/cloudabi32_sock.c
  head/sys/compat/cloudabi64/cloudabi64_sock.c

Modified: head/sys/compat/cloudabi/cloudabi_sock.c
==============================================================================
--- head/sys/compat/cloudabi/cloudabi_sock.c	Wed Mar 22 05:27:20 2017	(r315699)
+++ head/sys/compat/cloudabi/cloudabi_sock.c	Wed Mar 22 06:43:10 2017	(r315700)
@@ -30,7 +30,9 @@ __FBSDID("$FreeBSD$");
 #include <sys/capsicum.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>
+#include <sys/mbuf.h>
 #include <sys/mutex.h>
+#include <sys/proc.h>
 #include <sys/protosw.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
@@ -243,3 +245,51 @@ cloudabi_sys_sock_stat_get(struct thread
 	fdrop(fp, td);
 	return (copyout(&ss, uap->buf, sizeof(ss)));
 }
+
+int
+cloudabi_sock_send(struct thread *td, cloudabi_fd_t fd, struct iovec *data,
+    size_t datalen, const cloudabi_fd_t *fds, size_t fdslen,
+    cloudabi_msgflags_t flags, size_t *rdatalen)
+{
+	struct msghdr hdr = {
+		.msg_iov = data,
+		.msg_iovlen = datalen,
+	};
+	struct mbuf *control;
+	int error, mflags;
+
+	/* Convert flags. */
+	mflags = MSG_NOSIGNAL;
+	if (flags & CLOUDABI_MSG_EOR)
+		mflags |= MSG_EOR;
+
+	/* Convert file descriptor array to an SCM_RIGHTS message. */
+	if (fdslen > MCLBYTES || CMSG_SPACE(fdslen * sizeof(int)) > MCLBYTES) {
+		return (EINVAL);
+	} else if (fdslen > 0) {
+		struct cmsghdr *chdr;
+
+		control = m_get2(CMSG_SPACE(fdslen * sizeof(int)),
+		    M_WAITOK, MT_CONTROL, 0);
+		control->m_len = CMSG_SPACE(fdslen * sizeof(int));
+
+		chdr = mtod(control, struct cmsghdr *);
+		chdr->cmsg_len = CMSG_LEN(fdslen * sizeof(int));
+		chdr->cmsg_level = SOL_SOCKET;
+		chdr->cmsg_type = SCM_RIGHTS;
+		error = copyin(fds, CMSG_DATA(chdr), fdslen * sizeof(int));
+		if (error != 0) {
+			m_free(control);
+			return (error);
+		}
+	} else {
+		control = NULL;
+	}
+
+	error = kern_sendit(td, fd, &hdr, mflags, control, UIO_USERSPACE);
+	if (error != 0)
+		return (error);
+	*rdatalen = td->td_retval[0];
+	td->td_retval[0] = 0;
+	return (0);
+}

Modified: head/sys/compat/cloudabi/cloudabi_util.h
==============================================================================
--- head/sys/compat/cloudabi/cloudabi_util.h	Wed Mar 22 05:27:20 2017	(r315699)
+++ head/sys/compat/cloudabi/cloudabi_util.h	Wed Mar 22 06:43:10 2017	(r315700)
@@ -77,6 +77,10 @@ int cloudabi_futex_lock_wrlock(struct th
     cloudabi_scope_t, cloudabi_clockid_t, cloudabi_timestamp_t,
     cloudabi_timestamp_t);
 
+/* Socket operations. */
+int cloudabi_sock_send(struct thread *, cloudabi_fd_t, struct iovec *, size_t,
+    const cloudabi_fd_t *, size_t, cloudabi_msgflags_t, size_t *);
+
 /* vDSO setup and teardown. */
 void cloudabi_vdso_init(struct sysentvec *, char *, char *);
 void cloudabi_vdso_destroy(struct sysentvec *);

Modified: head/sys/compat/cloudabi32/cloudabi32_sock.c
==============================================================================
--- head/sys/compat/cloudabi32/cloudabi32_sock.c	Wed Mar 22 05:27:20 2017	(r315699)
+++ head/sys/compat/cloudabi32/cloudabi32_sock.c	Wed Mar 22 06:43:10 2017	(r315700)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2015 Nuxi, https://nuxi.nl/
+ * Copyright (c) 2015-2017 Nuxi, https://nuxi.nl/
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -105,44 +105,37 @@ cloudabi32_sys_sock_send(struct thread *
 	cloudabi32_send_in_t si;
 	cloudabi32_send_out_t so = {};
 	cloudabi32_ciovec_t iovobj;
-	struct msghdr msghdr = {};
+	struct iovec *iov;
 	const cloudabi32_ciovec_t *user_iov;
-	size_t i;
-	int error, flags;
+	size_t datalen, i;
+	int error;
 
 	error = copyin(uap->in, &si, sizeof(si));
 	if (error != 0)
 		return (error);
 
-	/* Convert results in cloudabi_send_in_t to struct msghdr. */
+	/* Convert iovecs to native format. */
 	if (si.si_data_len > UIO_MAXIOV)
 		return (EINVAL);
-	msghdr.msg_iovlen = si.si_data_len;
-	msghdr.msg_iov = malloc(msghdr.msg_iovlen * sizeof(struct iovec),
+	iov = malloc(si.si_data_len * sizeof(struct iovec),
 	    M_SOCKET, M_WAITOK);
 	user_iov = TO_PTR(si.si_data);
-	for (i = 0; i < msghdr.msg_iovlen; i++) {
+	for (i = 0; i < si.si_data_len; i++) {
 		error = copyin(&user_iov[i], &iovobj, sizeof(iovobj));
 		if (error != 0) {
-			free(msghdr.msg_iov, M_SOCKET);
+			free(iov, M_SOCKET);
 			return (error);
 		}
-		msghdr.msg_iov[i].iov_base = TO_PTR(iovobj.buf);
-		msghdr.msg_iov[i].iov_len = iovobj.buf_len;
+		iov[i].iov_base = TO_PTR(iovobj.buf);
+		iov[i].iov_len = iovobj.buf_len;
 	}
 
-	flags = MSG_NOSIGNAL;
-	if (si.si_flags & CLOUDABI_MSG_EOR)
-		flags |= MSG_EOR;
-
-	/* TODO(ed): Add file descriptor passing. */
-	error = kern_sendit(td, uap->sock, &msghdr, flags, NULL, UIO_USERSPACE);
-	free(msghdr.msg_iov, M_SOCKET);
+	error = cloudabi_sock_send(td, uap->sock, iov, si.si_data_len,
+	    TO_PTR(si.si_fds), si.si_fds_len, si.si_flags, &datalen);
+	free(iov, M_SOCKET);
 	if (error != 0)
 		return (error);
 
-	/* Convert results in msghdr to cloudabi_send_out_t. */
-	so.so_datalen = td->td_retval[0];
-	td->td_retval[0] = 0;
+	so.so_datalen = datalen;
 	return (copyout(&so, uap->out, sizeof(so)));
 }

Modified: head/sys/compat/cloudabi64/cloudabi64_sock.c
==============================================================================
--- head/sys/compat/cloudabi64/cloudabi64_sock.c	Wed Mar 22 05:27:20 2017	(r315699)
+++ head/sys/compat/cloudabi64/cloudabi64_sock.c	Wed Mar 22 06:43:10 2017	(r315700)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2015 Nuxi, https://nuxi.nl/
+ * Copyright (c) 2015-2017 Nuxi, https://nuxi.nl/
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -105,44 +105,37 @@ cloudabi64_sys_sock_send(struct thread *
 	cloudabi64_send_in_t si;
 	cloudabi64_send_out_t so = {};
 	cloudabi64_ciovec_t iovobj;
-	struct msghdr msghdr = {};
+	struct iovec *iov;
 	const cloudabi64_ciovec_t *user_iov;
-	size_t i;
-	int error, flags;
+	size_t datalen, i;
+	int error;
 
 	error = copyin(uap->in, &si, sizeof(si));
 	if (error != 0)
 		return (error);
 
-	/* Convert results in cloudabi_send_in_t to struct msghdr. */
+	/* Convert iovecs to native format. */
 	if (si.si_data_len > UIO_MAXIOV)
 		return (EINVAL);
-	msghdr.msg_iovlen = si.si_data_len;
-	msghdr.msg_iov = malloc(msghdr.msg_iovlen * sizeof(struct iovec),
+	iov = malloc(si.si_data_len * sizeof(struct iovec),
 	    M_SOCKET, M_WAITOK);
 	user_iov = TO_PTR(si.si_data);
-	for (i = 0; i < msghdr.msg_iovlen; i++) {
+	for (i = 0; i < si.si_data_len; i++) {
 		error = copyin(&user_iov[i], &iovobj, sizeof(iovobj));
 		if (error != 0) {
-			free(msghdr.msg_iov, M_SOCKET);
+			free(iov, M_SOCKET);
 			return (error);
 		}
-		msghdr.msg_iov[i].iov_base = TO_PTR(iovobj.buf);
-		msghdr.msg_iov[i].iov_len = iovobj.buf_len;
+		iov[i].iov_base = TO_PTR(iovobj.buf);
+		iov[i].iov_len = iovobj.buf_len;
 	}
 
-	flags = MSG_NOSIGNAL;
-	if (si.si_flags & CLOUDABI_MSG_EOR)
-		flags |= MSG_EOR;
-
-	/* TODO(ed): Add file descriptor passing. */
-	error = kern_sendit(td, uap->sock, &msghdr, flags, NULL, UIO_USERSPACE);
-	free(msghdr.msg_iov, M_SOCKET);
+	error = cloudabi_sock_send(td, uap->sock, iov, si.si_data_len,
+	    TO_PTR(si.si_fds), si.si_fds_len, si.si_flags, &datalen);
+	free(iov, M_SOCKET);
 	if (error != 0)
 		return (error);
 
-	/* Convert results in msghdr to cloudabi_send_out_t. */
-	so.so_datalen = td->td_retval[0];
-	td->td_retval[0] = 0;
+	so.so_datalen = datalen;
 	return (copyout(&so, uap->out, sizeof(so)));
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201703220643.v2M6hArU057914>