From mike@flux.utah.edu  Mon Jan  3 21:33:00 2005
Return-Path: <mike@flux.utah.edu>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 371FF16A4CE
	for <FreeBSD-gnats-submit@freebsd.org>; Mon,  3 Jan 2005 21:33:00 +0000 (GMT)
Received: from bas.flux.utah.edu (bas.flux.utah.edu [155.98.60.2])
	by mx1.FreeBSD.org (Postfix) with ESMTP id C3A8C43D2F
	for <FreeBSD-gnats-submit@freebsd.org>; Mon,  3 Jan 2005 21:32:59 +0000 (GMT)
	(envelope-from mike@flux.utah.edu)
Received: from bas.flux.utah.edu (localhost [127.0.0.1])
	by bas.flux.utah.edu (8.12.11/8.12.5) with ESMTP id j03LWxcO036532
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 3 Jan 2005 14:32:59 -0700 (MST)
	(envelope-from mike@bas.flux.utah.edu)
Received: (from mike@localhost)
	by bas.flux.utah.edu (8.12.11/8.13.1/Submit) id j03LWwPc036531;
	Mon, 3 Jan 2005 14:32:58 -0700 (MST)
	(envelope-from mike)
Message-Id: <200501032132.j03LWwPc036531@bas.flux.utah.edu>
Date: Mon, 3 Jan 2005 14:32:58 -0700 (MST)
From: Mike Hibler <mike@flux.utah.edu>
Reply-To: Mike Hibler <mike@flux.utah.edu>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: [patch] nfsd loops with TCP + multiple -h options
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         75766
>Category:       bin
>Synopsis:       [patch] nfsd(8) loops with TCP + multiple -h options
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jan 03 21:40:20 GMT 2005
>Closed-Date:    Thu Aug 30 05:06:50 GMT 2007
>Last-Modified:  Thu Aug 30 05:06:50 GMT 2007
>Originator:     Mike Hibler
>Release:        FreeBSD 4.x
>Organization:
University of Utah
>Environment:
System: FreeBSD bas.flux.utah.edu 4.10-RELEASE-p5 FreeBSD 4.10-RELEASE-p5 #2: Thu Dec 30 16:50:05 MST 2004 root@bas.flux.utah.edu:/usr/obj/usr/src/sys/BAS i386


	
>Description:
	Running nfsd with TCP support (-t) and multiple -h options can lead
	to the nfsd master process spinning furiously.

	In short, when the master nfsd process returns from a select involving
	multiple fds, it only attempts to process the last fd rather than
	looping over all fds in the set.

	This bug exists in all 4.x versions as far as I know.
	
>How-To-Repeat:
	Run nfsd with TCP support (-t) and multiple -h options and attempt
	to connect via any network except that of the last interface listed
	with -h.
	
>Fix:
	Following is the minimal fix extracted from -CURRENT to fix the
	problem; i.e., stick a loop around the FD_ISSET() processing.
	Note that I did not bother to fix the "notyet" code.

--- nfsd.c	2005/01/03 20:37:09	1.1
+++ nfsd.c	2005/01/03 20:41:44
@@ -593,26 +593,29 @@
 				exit(1);
 			}
 		}
-		if (tcpflag && FD_ISSET(tcpsock, &ready)) {
-			len = sizeof(inetpeer);
-			if ((msgsock = accept(tcpsock,
-			    (struct sockaddr *)&inetpeer, &len)) < 0) {
-				syslog(LOG_ERR, "accept failed: %m");
-				if (errno == ECONNABORTED ||
-				    errno == EINTR)
-					continue;
-				exit(1);
+		for (tcpsock = 0; tcpsock <= maxsock; tcpsock++) {
+			if (FD_ISSET(tcpsock, &ready)) {
+				len = sizeof(inetpeer);
+				if ((msgsock = accept(tcpsock,
+				    (struct sockaddr *)&inetpeer, &len)) < 0) {
+					syslog(LOG_ERR, "accept failed: %m");
+					if (errno == ECONNABORTED ||
+					    errno == EINTR)
+						continue;
+					exit(1);
+				}
+				memset(inetpeer.sin_zero, 0,
+				       sizeof(inetpeer.sin_zero));
+				if (setsockopt(msgsock, SOL_SOCKET,
+					       SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0)
+					syslog(LOG_ERR,
+					       "setsockopt SO_KEEPALIVE: %m");
+				nfsdargs.sock = msgsock;
+				nfsdargs.name = (caddr_t)&inetpeer;
+				nfsdargs.namelen = sizeof(inetpeer);
+				nfssvc(NFSSVC_ADDSOCK, &nfsdargs);
+				(void)close(msgsock);
 			}
-			memset(inetpeer.sin_zero, 0, sizeof(inetpeer.sin_zero));
-			if (setsockopt(msgsock, SOL_SOCKET,
-			    SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0)
-				syslog(LOG_ERR,
-				    "setsockopt SO_KEEPALIVE: %m");
-			nfsdargs.sock = msgsock;
-			nfsdargs.name = (caddr_t)&inetpeer;
-			nfsdargs.namelen = sizeof(inetpeer);
-			nfssvc(NFSSVC_ADDSOCK, &nfsdargs);
-			(void)close(msgsock);
 		}
 #ifdef notyet
 		if (tp4flag && FD_ISSET(tp4sock, &ready)) {

	


>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->closed 
State-Changed-By: rodrigc 
State-Changed-When: Thu Aug 30 05:04:44 UTC 2007 
State-Changed-Why:  
This patch was added in 1.17 of nfsd.c in 2001. 
RELENG_4 is an end-of-life branch, so this fix probably won't get merged there. 

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