usr/src/uts/common/syscall/sendfile.c
changeset 898 64b2a371a6bd
parent 741 40027a3621ac
child 1548 f5237ec2d4c2
--- a/usr/src/uts/common/syscall/sendfile.c	Sat Nov 12 07:57:48 2005 -0800
+++ b/usr/src/uts/common/syscall/sendfile.c	Sat Nov 12 18:58:05 2005 -0800
@@ -89,6 +89,7 @@
 {
 	struct stdata *stp;
 	struct queue *wqp;
+	mblk_t *newmp;
 	char waitflag;
 	int tempmode;
 	int error = 0;
@@ -137,6 +138,15 @@
 	do {
 		if (canputnext(wqp)) {
 			mutex_exit(&stp->sd_lock);
+			if (stp->sd_wputdatafunc != NULL) {
+				newmp = (stp->sd_wputdatafunc)(vp, mp, NULL,
+				    NULL, NULL, NULL);
+				if (newmp == NULL) {
+					/* The caller will free mp */
+					return (ECOMM);
+				}
+				mp = newmp;
+			}
 			putnext(wqp, mp);
 			return (0);
 		}
@@ -494,6 +504,8 @@
 	size_t	iov_len;
 	mblk_t  *head, *tmp;
 	size_t  size = total_size;
+	size_t  extra;
+	int tail_len;
 
 	fflag = fp->f_flag;
 	vp = fp->f_vnode;
@@ -502,8 +514,11 @@
 	ASSERT(maxblk > 0);
 
 	wroff = (int)vp->v_stream->sd_wroff;
+	tail_len = (int)vp->v_stream->sd_tail;
+	extra = wroff + tail_len;
+
 	buf_left = MIN(total_size, maxblk);
-	head = dmp = allocb(buf_left + wroff, BPRI_HI);
+	head = dmp = allocb(buf_left + extra, BPRI_HI);
 	if (head == NULL)
 		return (ENOMEM);
 	head->b_wptr = head->b_rptr = head->b_rptr + wroff;
@@ -552,7 +567,7 @@
 					tmp = dmp;
 					buf_left = MIN(total_size, maxblk);
 					iov_len = MIN(buf_left, sfv_len);
-					dmp = allocb(buf_left + wroff, BPRI_HI);
+					dmp = allocb(buf_left + extra, BPRI_HI);
 					if (dmp == NULL) {
 						freemsg(head);
 						return (ENOMEM);
@@ -647,7 +662,7 @@
 					tmp = dmp;
 					buf_left = MIN(total_size, maxblk);
 					iov_len = MIN(buf_left, sfv_len);
-					dmp = allocb(buf_left + wroff, BPRI_HI);
+					dmp = allocb(buf_left + extra, BPRI_HI);
 					if (dmp == NULL) {
 						VOP_RWUNLOCK(readvp, readflg,
 									NULL);
@@ -753,10 +768,23 @@
 #endif
 	mblk_t	*dmp = NULL;
 	char	*buf = NULL;
+	size_t  extra;
+	int maxblk, wroff, tail_len;
+	struct sonode *so;
+	stdata_t *stp;
 
 	fflag = fp->f_flag;
 	vp = fp->f_vnode;
 
+	if (vp->v_type == VSOCK) {
+		so = VTOSO(vp);
+		stp = vp->v_stream;
+		wroff = (int)stp->sd_wroff;
+		tail_len = (int)stp->sd_tail;
+		maxblk = (int)stp->sd_maxblk;
+		extra = wroff + tail_len;
+	}
+
 	auio.uio_extflg = UIO_COPY_DEFAULT;
 	for (i = 0; i < copy_cnt; i++) {
 		if (ISSIG(curthread, JUSTLOOKING))
@@ -829,9 +857,8 @@
 				/*
 				 * Optimize for the socket case
 				 */
-				int wroff = (int)vp->v_stream->sd_wroff;
 
-				dmp = allocb(sfv_len + wroff, BPRI_HI);
+				dmp = allocb(sfv_len + extra, BPRI_HI);
 				if (dmp == NULL)
 					return (ENOMEM);
 				dmp->b_wptr = dmp->b_rptr = dmp->b_rptr + wroff;
@@ -926,6 +953,14 @@
 					releasef(sfv->sfv_fd);
 					return (ENOMEM);
 				}
+			} else {
+				/*
+				 * For sockets acting as an SSL proxy, we
+				 * need to adjust the size to the maximum
+				 * SSL record size set in the stream head.
+				 */
+				if (so->so_kssl_ctx != NULL)
+					size = MIN(size, maxblk);
 			}
 
 			while (sfv_len > 0) {
@@ -934,13 +969,15 @@
 				iov_len = MIN(size, sfv_len);
 
 				if (vp->v_type == VSOCK) {
-					dmp = allocb(iov_len, BPRI_HI);
+					dmp = allocb(iov_len + extra, BPRI_HI);
 					if (dmp == NULL) {
 						VOP_RWUNLOCK(readvp, readflg,
 						    NULL);
 						releasef(sfv->sfv_fd);
 						return (ENOMEM);
 					}
+					dmp->b_wptr = dmp->b_rptr =
+					    dmp->b_rptr + wroff;
 					ptr = (caddr_t)dmp->b_rptr;
 				} else {
 					ptr = buf;
@@ -1129,7 +1166,8 @@
 			}
 
 			if ((so->so_state & SS_DIRECT) &&
-			    (so->so_priv != NULL)) {
+			    (so->so_priv != NULL) &&
+			    (so->so_kssl_ctx == NULL)) {
 				maxblk = ((tcp_t *)so->so_priv)->tcp_mss;
 			} else {
 				maxblk = (int)vp->v_stream->sd_maxblk;