From owner-freebsd-net Tue Jan 22 10:27:29 2002 Delivered-To: freebsd-net@freebsd.org Received: from crufty.research.bell-labs.com (crufty.research.bell-labs.com [204.178.16.49]) by hub.freebsd.org (Postfix) with SMTP id D980C37B404 for ; Tue, 22 Jan 2002 10:27:19 -0800 (PST) Received: from scummy.research.bell-labs.com ([135.104.2.10]) by crufty; Tue Jan 22 13:21:08 EST 2002 Received: from aura.research.bell-labs.com (aura.research.bell-labs.com [135.104.46.10]) by scummy.research.bell-labs.com (8.11.6/8.11.6) with ESMTP id g0MIQLL66216 for ; Tue, 22 Jan 2002 13:26:21 -0500 (EST) Received: (from sandeepj@localhost) by aura.research.bell-labs.com (8.9.1/8.9.1) id NAA15250 for freebsd-net@freebsd.org; Tue, 22 Jan 2002 13:26:21 -0500 (EST) Date: Tue, 22 Jan 2002 13:26:21 -0500 (EST) Message-Id: <200201221826.NAA15250@aura.research.bell-labs.com> From: sandeepj@research.bell-labs.com (Sandeep Joshi) To: freebsd-net@freebsd.org Subject: soreceive error handling question Sender: owner-freebsd-net@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org I am seeing some unexplained behaviour while calling TCP "soreceive" directly within some kernel code. Can someone (or someone else..) tell me if this is a bug/feature. (This is seen on 4.3REL & 4.4 REL) The (abbreviated) code does as follows: ---------------------------- (Fig 1) do { /* SS_NBIO is not set, rcv_timeo is non-zero */ err = soreceive(so, 0, &uio, 0, 0, MSG_WAITALL); ..process uio data appropriate.. } while (err == 0); ---------------------------- This works fine... until the thing at the other end of the socket goes down and sends us a FIN. At this point, the above code fragment hangs in an infinite loop, since soreceive keeps returning a zero error code but no data. so->so_state has changed to 0x34, which is SS_CANTRCVMORE and SS_ISCONNECTED. This is due to tcp_input() calling socantrcvmore() on TH_FIN. And there is no read data pending (so_rcv.sb_mb) in the socket. I suspect that soreceive() enters the code path below and returns from "release:" without having the error set. ----------------------------(Fig 2) > if (so->so_state & SS_CANTRCVMORE) { > if (m) > goto dontblock; > else > goto release; > } ---------------------------- The code calling soreceive (Fig 1) was enhanced to break if (so_state & SS_CANTRCVMORE). This prevented the infinite loop. Is this extra check required OR is there a problem in soreceive ? I am unable to determine why read(socket_fd) (i.e. soo_read) does not exhibit similar error behaviour. Any clarifications welcome.. Thanks -Sandeep To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-net" in the body of the message