From dan@dan.emsphone.com  Thu Feb 21 15:54:16 2008
Return-Path: <dan@dan.emsphone.com>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 4EB2316A400
	for <FreeBSD-gnats-submit@freebsd.org>; Thu, 21 Feb 2008 15:54:16 +0000 (UTC)
	(envelope-from dan@dan.emsphone.com)
Received: from dan.emsphone.com (dan.emsphone.com [199.67.51.101])
	by mx1.freebsd.org (Postfix) with ESMTP id 1A41F13C448
	for <FreeBSD-gnats-submit@freebsd.org>; Thu, 21 Feb 2008 15:54:15 +0000 (UTC)
	(envelope-from dan@dan.emsphone.com)
Received: (from dan@localhost)
	by dan.emsphone.com (8.14.2/8.14.2) id m1LFsEcb074499;
	Thu, 21 Feb 2008 09:54:14 -0600 (CST)
	(envelope-from dan)
Message-Id: <200802211554.m1LFsEcb074499@dan.emsphone.com>
Date: Thu, 21 Feb 2008 09:54:14 -0600 (CST)
From: Dan Nelson <dnelson@allantgroup.com>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: sendfile(2) doesn't send trailers
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         120948
>Category:       kern
>Synopsis:       sendfile(2) doesn't send trailers
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    cperciva
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Feb 21 16:00:05 UTC 2008
>Closed-Date:    Tue Feb 17 17:39:13 UTC 2009
>Last-Modified:  Tue Feb 17 17:39:13 UTC 2009
>Originator:     Dan Nelson
>Release:        FreeBSD 7.0-PRERELEASE i386
>Organization:
The Allant Group
>Environment:
System: FreeBSD dan.emsphone.com 7.0-PRERELEASE FreeBSD 7.0-PRERELEASE #534: Thu Feb 21 09:24:12 CST 2008 zsh@dan.emsphone.com:/usr/src-7/sys/i386/compile/DANSMP i386


	
>Description:

rev 1.240 of uipc_syscalls.c converted the "send file" part of
sendfile(2) from a counted for-loop to an infinite loop, but the code
for breaking out of the loop jumps to the wrong place on success, and
the code for sending the trailer is never called.

	
>How-To-Repeat:
	

Try the following program.  Example of correct output:

Should receive 48 bytes:
rv=0, count=48
rv=48, data=<[this is header]FreeBSD 7.0-PRER[this is trailr]>



#include <arpa/inet.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>

int main(void)
{
	int socks[3];
	int fd;
	unsigned int len;
	int rv;
	char buffer[8192];
	off_t count = 0;
	struct sockaddr_in sin;
	struct iovec h, t;
	struct sf_hdtr hdtr;

	printf("Should receive 48 bytes:\n");
	memset(socks, 0, sizeof(socks));
	socks[0] = socket(PF_INET, SOCK_STREAM, 0);
	socks[1] = socket(PF_INET, SOCK_STREAM, 0);
	sin.sin_len = sizeof(sin);
	sin.sin_family = AF_INET;
	inet_aton("0.0.0.0", &sin.sin_addr);
	sin.sin_port = 0;
	bind(socks[0], &sin, sizeof(sin));
	listen(socks[0], 16);
	len = sizeof(sin);
	getsockname(socks[0], &sin, &len);
	connect(socks[1], &sin, sizeof(sin));
	socks[2] = accept(socks[0], NULL, 0);

	/* send 3 16-byte chunks: header, file, trailer */

	h.iov_base = "[this is header]";
	h.iov_len = strlen(h.iov_base);
	t.iov_base = "[this is trailr]";
	t.iov_len = strlen(t.iov_base);
	hdtr.headers = &h;
	hdtr.hdr_cnt = 1;
	hdtr.trailers = &t;
	hdtr.trl_cnt = 1;

	fd = open("/etc/motd", O_RDONLY);
	rv = sendfile(fd, socks[1], 0, 16, &hdtr, &count, 0); 
	printf("rv=%d, count=%lld\n", rv, count);
	sleep(1);
	memset(buffer, 0, 8192);
	rv = read(socks[2], &buffer, 8192);
	printf("rv=%d, data=<%s>\n", rv, buffer);
	return 0;
}


>Fix:

	

This works for me:

Index: uipc_syscalls.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/uipc_syscalls.c,v
retrieving revision 1.259.2.2
diff -u -r1.259.2.2 uipc_syscalls.c
--- uipc_syscalls.c	14 Feb 2008 11:44:59 -0000	1.259.2.2
+++ uipc_syscalls.c	21 Feb 2008 15:11:24 -0000
@@ -2172,7 +2172,9 @@
 		}
 
 		/* Quit outer loop on error or when we're done. */
-		if (error || done)
+		if (done) 
+			break;
+		if (error)
 			goto done;
 	}
 


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->kib 
Responsible-Changed-By: remko 
Responsible-Changed-When: Thu Feb 21 20:06:24 UTC 2008 
Responsible-Changed-Why:  
Hi kib, can you have a look at this please? 

http://www.freebsd.org/cgi/query-pr.cgi?pr=120948 
State-Changed-From-To: open->patched 
State-Changed-By: cperciva 
State-Changed-When: Sun Feb 24 00:09:00 UTC 2008 
State-Changed-Why:  
Committed to HEAD, will MFC in a few days. 


Responsible-Changed-From-To: kib->cperciva 
Responsible-Changed-By: cperciva 
Responsible-Changed-When: Sun Feb 24 00:09:00 UTC 2008 
Responsible-Changed-Why:  
Claim ownership of this PR to remind myself to MFC the fix. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=120948 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/120948: commit references a PR
Date: Sun, 24 Feb 2008 00:07:06 +0000 (UTC)

 cperciva    2008-02-24 00:07:00 UTC
 
   FreeBSD src repository
 
   Modified files:
     sys/kern             uipc_syscalls.c 
   Log:
   After finishing sending file data in sendfile(2), don't forget to send
   the provided trailers.  This has been broken since revision 1.240.
   
   Submitted by:   Dan Nelson
   PR:             kern/120948
   "sounds ok to me" from: phk
   MFC after:      3 days
   
   Revision  Changes    Path
   1.269     +3 -1      src/sys/kern/uipc_syscalls.c
 _______________________________________________
 cvs-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/cvs-all
 To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
 

From: Gavin Atkinson <gavin@FreeBSD.org>
To: cperciva@FreeBSD.org
Cc: bug-followup@FreeBSD.org
Subject: Re: kern/120948: sendfile(2) doesn't send trailers
Date: Fri, 06 Jun 2008 19:23:27 +0100

 Hi,
 
 As far as I can tell, this PR can be closed, as the fix was MFC'd in
 sys/kern/uipc_syscalls.c 1.259.2.3, and the bug doesn't look to have
 ever existed in RELENG_6.  Are you happy for it to be closed?
 
 Thanks,
 
 Gavin
State-Changed-From-To: patched->closed 
State-Changed-By: gavin 
State-Changed-When: Tue Feb 17 17:37:15 UTC 2009 
State-Changed-Why:  
Close, fix was MFC'd to RELENG_7 (sys/kern/uipc_syscalls.c 1.259.2.3) 
and doesn't look to have ever existed in RELENG_6. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=120948 
>Unformatted:
