PERFORCE change 100226 for review

John Baldwin jhb at FreeBSD.org
Wed Jun 28 19:30:27 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=100226

Change 100226 by jhb at jhb_mutex on 2006/06/28 19:30:07

	- Use kern_connect(), kern_getpeername(), and kern_accept().
	- Replace svr4_sendit() and svr4_recvit() with calls to
	  kern_sendit() and kern_recvit() eliminating some more
	  stackgap along the way.

Affected files ...

.. //depot/projects/smpng/sys/compat/svr4/svr4_stream.c#30 edit

Differences ...

==== //depot/projects/smpng/sys/compat/svr4/svr4_stream.c#30 (text+ko) ====

@@ -133,245 +133,6 @@
 			      struct thread *);
 static int ti_bind(struct file *, int, struct svr4_strioctl *, struct thread *);
 
-/* infrastructure */
-static int svr4_sendit(struct thread *td, int s, struct msghdr *mp, int flags);
-
-static int svr4_recvit(struct thread *td, int s, struct msghdr *mp,
-			    caddr_t namelenp);
-
-/* <sigh>  Ok, so we shouldn't use sendit() in uipc_syscalls.c because
- * it isn't part of a "public" interface;  We're supposed to use
- * pru_sosend instead.  Same goes for recvit()/pru_soreceive() for
- * that matter.  Solution:  Suck sendit()/recvit() into here where we
- * can do what we like.
- * 
- * I hate code duplication. 
- * 
- * I will take out all the #ifdef COMPAT_OLDSOCK gumph, though.
- */
-static int
-svr4_sendit(td, s, mp, flags)
-	register struct thread *td;
-	int s;
-	register struct msghdr *mp;
-	int flags;
-{
-	struct uio auio;
-	register struct iovec *iov;
-	register int i;
-	struct mbuf *control;
-	struct sockaddr *to;
-	int len, error;
-	struct socket *so;
-#ifdef KTRACE
-	struct uio *ktruio = NULL;
-#endif
-
-	/*
-	 * XXXRW: Instead of using fgetsock(), just rely on the file
-	 * descriptor reference.
-	 */
-	if ((error = fgetsock(td, s, &so, NULL)) != 0)
-		return (error);
-
-#ifdef MAC
-	SOCK_LOCK(so);
-	error = mac_check_socket_send(td->td_ucred, so);
-	SOCK_UNLOCK(so);
-	if (error)
-		goto done1;
-#endif
-
-	auio.uio_iov = mp->msg_iov;
-	auio.uio_iovcnt = mp->msg_iovlen;
-	auio.uio_segflg = UIO_USERSPACE;
-	auio.uio_rw = UIO_WRITE;
-	auio.uio_td = td;
-	auio.uio_offset = 0;			/* XXX */
-	auio.uio_resid = 0;
-	iov = mp->msg_iov;
-	for (i = 0; i < mp->msg_iovlen; i++, iov++) {
-		if ((auio.uio_resid += iov->iov_len) < 0) {
-			error = EINVAL;
-			goto done1;
-		}
-	}
-	if (mp->msg_name) {
-		error = getsockaddr(&to, mp->msg_name, mp->msg_namelen);
-		if (error)
-			goto done1;
-	} else {
-		to = 0;
-	}
-	if (mp->msg_control) {
-		if (mp->msg_controllen < sizeof(struct cmsghdr)) {
-			error = EINVAL;
-			goto bad;
-		}
-		error = sockargs(&control, mp->msg_control,
-		    mp->msg_controllen, MT_CONTROL);
-		if (error)
-			goto bad;
-	} else {
-		control = 0;
-	}
-#ifdef KTRACE
-	if (KTRPOINT(td, KTR_GENIO))
-		ktruio = cloneuio(&auio);
-#endif
-	len = auio.uio_resid;
-	error = so->so_proto->pr_usrreqs->pru_sosend(so, to, &auio, 0, control,
-						     flags, td);
-	if (error) {
-		if (auio.uio_resid != len && (error == ERESTART ||
-		    error == EINTR || error == EWOULDBLOCK))
-			error = 0;
-		if (error == EPIPE) {
-			PROC_LOCK(td->td_proc);
-			psignal(td->td_proc, SIGPIPE);
-			PROC_UNLOCK(td->td_proc);
-		}
-	}
-	if (error == 0)
-		td->td_retval[0] = len - auio.uio_resid;
-#ifdef KTRACE
-	if (ktruio != NULL) {
-		ktruio->uio_resid = td->td_retval[0];
-		ktrgenio(s, UIO_WRITE, ktruio, error);
-	}
-#endif
-bad:
-	if (to)
-		FREE(to, M_SONAME);
-done1:
-	fputsock(so);
-	return (error);
-}
-
-static int
-svr4_recvit(td, s, mp, namelenp)
-	register struct thread *td;
-	int s;
-	register struct msghdr *mp;
-	caddr_t namelenp;
-{
-	struct uio auio;
-	register struct iovec *iov;
-	register int i;
-	int len, error;
-	struct mbuf *m, *control = 0;
-	caddr_t ctlbuf;
-	struct socket *so;
-	struct sockaddr *fromsa = 0;
-#ifdef KTRACE
-	struct uio *ktruio = NULL;
-#endif
-
-	/*
-	 * XXXRW: Instead of using fgetsock(), just rely on the file
-	 * descriptor reference.
-	 */
-	if ((error = fgetsock(td, s, &so, NULL)) != 0)
-		return (error);
-
-#ifdef MAC
-	SOCK_LOCK(so);
-	error = mac_check_socket_receive(td->td_ucred, so);
-	SOCK_UNLOCK(so);
-	if (error)
-		goto done1;
-#endif
-
-	auio.uio_iov = mp->msg_iov;
-	auio.uio_iovcnt = mp->msg_iovlen;
-	auio.uio_segflg = UIO_USERSPACE;
-	auio.uio_rw = UIO_READ;
-	auio.uio_td = td;
-	auio.uio_offset = 0;			/* XXX */
-	auio.uio_resid = 0;
-	iov = mp->msg_iov;
-	for (i = 0; i < mp->msg_iovlen; i++, iov++) {
-		if ((auio.uio_resid += iov->iov_len) < 0) {
-			error = EINVAL;
-			goto done1;
-		}
-	}
-#ifdef KTRACE
-	if (KTRPOINT(td, KTR_GENIO)) 
-		ktruio = cloneuio(&auio);
-#endif
-	len = auio.uio_resid;
-	error = so->so_proto->pr_usrreqs->pru_soreceive(so, &fromsa, &auio,
-	    (struct mbuf **)0, mp->msg_control ? &control : (struct mbuf **)0,
-	    &mp->msg_flags);
-	if (error) {
-		if (auio.uio_resid != len && (error == ERESTART ||
-		    error == EINTR || error == EWOULDBLOCK))
-			error = 0;
-	}
-#ifdef KTRACE
-	if (ktruio != NULL) {
-		ktruio->uio_resid = len - auio.uio_resid;
-		ktrgenio(s, UIO_READ, ktruio, error);
-	}
-#endif
-	if (error)
-		goto out;
-	td->td_retval[0] = len - auio.uio_resid;
-	if (mp->msg_name) {
-		len = mp->msg_namelen;
-		if (len <= 0 || fromsa == 0)
-			len = 0;
-		else {
-			/* save sa_len before it is destroyed by MSG_COMPAT */
-			len = MIN(len, fromsa->sa_len);
-			error = copyout(fromsa,
-			    (caddr_t)mp->msg_name, (unsigned)len);
-			if (error)
-				goto out;
-		}
-		mp->msg_namelen = len;
-		if (namelenp &&
-		    (error = copyout((caddr_t)&len, namelenp, sizeof (int)))) {
-			goto out;
-		}
-	}
-	if (mp->msg_control) {
-		len = mp->msg_controllen;
-		m = control;
-		mp->msg_controllen = 0;
-		ctlbuf = (caddr_t) mp->msg_control;
-
-		while (m && len > 0) {
-			unsigned int tocopy;
-
-			if (len >= m->m_len) 
-				tocopy = m->m_len;
-			else {
-				mp->msg_flags |= MSG_CTRUNC;
-				tocopy = len;
-			}
-		
-			if ((error = copyout((caddr_t)mtod(m, caddr_t),
-					ctlbuf, tocopy)) != 0)
-				goto out;
-
-			ctlbuf += tocopy;
-			len -= tocopy;
-			m = m->m_next;
-		}
-		mp->msg_controllen = ctlbuf - (caddr_t)mp->msg_control;
-	}
-out:
-	if (fromsa)
-		FREE(fromsa, M_SONAME);
-	if (control)
-		m_freem(control);
-done1:
-	fputsock(so);
-	return (error);
-}
-
 #ifdef DEBUG_SVR4
 static void bufprint(u_char *, size_t);
 static int show_ioc(const char *, struct svr4_strioctl *);
@@ -1702,11 +1463,10 @@
 	struct svr4_strmcmd sc;
 	struct sockaddr_in sain;
 	struct sockaddr_un saun;
-	void *skp, *sup;
+	struct sockaddr *sa;
 	int sasize, *retval;
 	struct svr4_strm *st;
 	int error;
-	caddr_t sg;
 
 	retval = td->td_retval;
 
@@ -1780,9 +1540,10 @@
 	                return EINVAL;
 	        }
 	        netaddr_to_sockaddr_in(&sain, &sc);
-	        skp = &sain;
+		sa = (struct sockaddr *)&sain;
 	        sasize = sizeof(sain);
-	        error = sain.sin_family != st->s_family;
+		if (sain.sin_family != st->s_family)
+			error = EINVAL;
 		break;
 
 	case AF_LOCAL:
@@ -1796,11 +1557,12 @@
 			/* Maybe we've been given a device/inode pair */
 			dev_t *dev = SVR4_ADDROF(&sc);
 			ino_t *ino = (ino_t *) &dev[1];
-			skp = svr4_find_socket(td, fp, *dev, *ino);
-			if (skp == NULL) {
-				skp = &saun;
+			sa = (struct sockaddr *)
+			    svr4_find_socket(td, fp, *dev, *ino);
+			if (sa == NULL) {
+				sa = (struct sockaddr *)&saun;
 				/* I guess we have it by name */
-				netaddr_to_sockaddr_un(skp, &sc);
+				netaddr_to_sockaddr_un(&saun, &sc);
 			}
 			sasize = sizeof(saun);
 		}
@@ -1812,22 +1574,11 @@
 		return ENOSYS;
 	}
 
-	sg = stackgap_init();
-	sup = stackgap_alloc(&sg, sasize);
-
-	if ((error = copyout(skp, sup, sasize)) != 0)
-		return error;
-
 	switch (st->s_cmd = sc.cmd) {
 	case SVR4_TI_CONNECT_REQUEST:	/* connect 	*/
 		{
-			struct connect_args co;
 
-			co.s = uap->fd;
-			co.name = (void *) sup;
-			co.namelen = (int) sasize;
-			
-			return connect(td, &co);
+			return (kern_connect(td, uap->fd, sa));
 		}
 
 	case SVR4_TI_SENDTO_REQUEST:	/* sendto 	*/
@@ -1835,7 +1586,7 @@
 			struct msghdr msg;
 			struct iovec aiov;
 
-			msg.msg_name = (caddr_t) sup;
+			msg.msg_name = sa;
 			msg.msg_namelen = sasize;
 			msg.msg_iov = &aiov;
 			msg.msg_iovlen = 1;
@@ -1843,12 +1594,8 @@
 			msg.msg_flags = 0;
 			aiov.iov_base = dat.buf;
 			aiov.iov_len = dat.len;
-#if 0
-			error = so->so_proto->pr_usrreqs->pru_sosend(so, 0, 
-					      uio, 0, 0, 0, uio->uio_td);
-#endif
-			error = svr4_sendit(td, uap->fd, &msg,
-				       uap->flags);
+			error = kern_sendit(td, uap->fd, &msg, uap->flags,
+			    NULL, UIO_USERSPACE);
 			DPRINTF(("sendto_request error: %d\n", error));
 			*retval = 0;
 			return error;
@@ -1885,8 +1632,6 @@
 	struct svr4_sys_getmsg_args *uap;
 	struct file *fp;
 {
-	struct getpeername_args ga;
-	struct accept_args aa;
 	struct svr4_strbuf dat, ctl;
 	struct svr4_strmcmd sc;
 	int error, *retval;
@@ -1894,14 +1639,13 @@
 	struct iovec aiov;
 	struct sockaddr_in sain;
 	struct sockaddr_un saun;
-	void *skp, *sup;
-	int sasize;
+	struct sockaddr *sa;
+	socklen_t sasize;
 	struct svr4_strm *st;
-	int *flen;
 	int fl;
-	caddr_t sg;
 
 	retval = td->td_retval;
+	error = 0;
 
 	FILE_LOCK_ASSERT(fp, MA_NOTOWNED);
 
@@ -1947,12 +1691,10 @@
 
 	switch (st->s_family) {
 	case AF_INET:
-		skp = &sain;
 		sasize = sizeof(sain);
 		break;
 
 	case AF_LOCAL:
-		skp = &saun;
 		sasize = sizeof(saun);
 		break;
 
@@ -1962,14 +1704,6 @@
 		return ENOSYS;
 	}
 
-	sg = stackgap_init();
-	sup = stackgap_alloc(&sg, sasize);
-	flen = (int *) stackgap_alloc(&sg, sizeof(*flen));
-
-	fl = sasize;
-	if ((error = copyout(&fl, flen, sizeof(fl))) != 0)
-		return error;
-
 	switch (st->s_cmd) {
 	case SVR4_TI_CONNECT_REQUEST:
 		DPRINTF(("getmsg: TI_CONNECT_REQUEST\n"));
@@ -1993,18 +1727,12 @@
 		 * a connect verification.
 		 */
 
-		ga.fdes = uap->fd;
-		ga.asa = (void *) sup;
-		ga.alen = flen;
-		
-		if ((error = getpeername(td, &ga)) != 0) {
+		error = kern_getpeername(td, uap->fd, &sa, &sasize);
+		if (error) {
 			DPRINTF(("getmsg: getpeername failed %d\n", error));
 			return error;
 		}
 
-		if ((error = copyin(sup, skp, sasize)) != 0)
-			return error;
-		
 		sc.cmd = SVR4_TI_CONNECT_REPLY;
 		sc.pad[0] = 0x4;
 		sc.offs = 0x18;
@@ -2014,17 +1742,19 @@
 		switch (st->s_family) {
 		case AF_INET:
 			sc.len = sasize;
-			sockaddr_to_netaddr_in(&sc, &sain);
+			sockaddr_to_netaddr_in(&sc, (struct sockaddr_in *)sa);
 			break;
 
 		case AF_LOCAL:
 			sc.len = sasize + 4;
-			sockaddr_to_netaddr_un(&sc, &saun);
+			sockaddr_to_netaddr_un(&sc, (struct sockaddr_un *)sa);
 			break;
 
 		default:
+			free(sa, M_SONAME);
 			return ENOSYS;
 		}
+		free(sa, M_SONAME);
 
 		ctl.len = 40;
 		dat.len = -1;
@@ -2052,11 +1782,9 @@
 		/*
 		 * We are after a listen, so we try to accept...
 		 */
-		aa.s = uap->fd;
-		aa.name = (void *) sup;
-		aa.anamelen = flen;
-		
-		if ((error = accept(td, &aa)) != 0) {
+
+		error = kern_accept(td, uap->fd, &sa, &sasize, 0);
+		if (error) {
 			DPRINTF(("getmsg: accept failed %d\n", error));
 			return error;
 		}
@@ -2065,9 +1793,6 @@
 
 		DPRINTF(("getmsg: Accept fd = %d\n", st->s_afd));
 
-		if ((error = copyin(sup, skp, sasize)) != 0)
-			return error;
-		
 		sc.cmd = SVR4_TI_ACCEPT_REPLY;
 		sc.offs = 0x18;
 		sc.pad[0] = 0x0;
@@ -2075,7 +1800,7 @@
 		switch (st->s_family) {
 		case AF_INET:
 			sc.pad[1] = 0x28;
-			sockaddr_to_netaddr_in(&sc, &sain);
+			sockaddr_to_netaddr_in(&sc, (struct sockaddr_in *)&sa);
 			ctl.len = 40;
 			sc.len = sasize;
 			break;
@@ -2089,8 +1814,10 @@
 			break;
 
 		default:
+			free(sa, M_SONAME);
 			return ENOSYS;
 		}
+		free(sa, M_SONAME);
 
 		dat.len = -1;
 		fl = 0;
@@ -2110,10 +1837,12 @@
 
 		switch (st->s_family) {
 		case AF_INET:
+			sa = (struct sockaddr *)&sain;
 			sockaddr_to_netaddr_in(&sc, &sain);
 			break;
 
 		case AF_LOCAL:
+			sa = (struct sockaddr *)&saun;
 			sockaddr_to_netaddr_un(&sc, &saun);
 			break;
 
@@ -2121,7 +1850,7 @@
 			return ENOSYS;
 		}
 
-		msg.msg_name = (caddr_t) sup;
+		msg.msg_name = sa;
 		msg.msg_namelen = sasize;
 		msg.msg_iov = &aiov;
 		msg.msg_iovlen = 1;
@@ -2130,16 +1859,14 @@
 		aiov.iov_len = dat.maxlen;
 		msg.msg_flags = 0;
 
-		error = svr4_recvit(td, uap->fd, &msg, (caddr_t) flen);
+		error = kern_recvit(td, uap->fd, &msg, NULL, UIO_USERSPACE,
+		    UIO_SYSSPACE, NULL);
 
 		if (error) {
 			DPRINTF(("getmsg: recvit failed %d\n", error));
 			return error;
 		}
 
-		if ((error = copyin(msg.msg_name, skp, sasize)) != 0)
-			return error;
-
 		sc.cmd = SVR4_TI_RECVFROM_IND;
 
 		switch (st->s_family) {


More information about the p4-projects mailing list