From owner-freebsd-hackers@FreeBSD.ORG Fri Jan 23 07:50:36 2004 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 8660616A4CE for ; Fri, 23 Jan 2004 07:50:36 -0800 (PST) Received: from mailtoaster1.pipeline.ch (mailtoaster1.pipeline.ch [62.48.0.70]) by mx1.FreeBSD.org (Postfix) with ESMTP id 1599A43D48 for ; Fri, 23 Jan 2004 07:50:32 -0800 (PST) (envelope-from andre@freebsd.org) Received: (qmail 23804 invoked from network); 23 Jan 2004 15:50:31 -0000 Received: from unknown (HELO freebsd.org) ([62.48.0.47]) (envelope-sender ) by mailtoaster1.pipeline.ch (qmail-ldap-1.03) with SMTP for ; 23 Jan 2004 15:50:31 -0000 Message-ID: <401142C9.70502@freebsd.org> Date: Fri, 23 Jan 2004 16:50:33 +0100 From: Andre Oppermann User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.6) Gecko/20040113 X-Accept-Language: en-us, en MIME-Version: 1.0 To: Stuart Pook References: In-Reply-To: Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit cc: freebsd-hackers@freebsd.org Subject: Re: send(2) does not block, send(2) man page wrong? X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 23 Jan 2004 15:50:36 -0000 Stuart Pook wrote: > The documentation for send(2) says > > If no messages space is available at the socket to hold the message to be > transmitted, then send() normally blocks, unless the socket has been > placed in non-blocking I/O mode. The select(2) call may be used to > determine when it is possible to send more data. > > I cannot get send (or sendto which is what really interests me) > to block on FreeBSD 4.9. When I send as fast as I can to a socket, > send rapidly fails with ENOBUFS. I am not surprised that the kernel is > running out of mbufs but I am surprised that send does not block until > more become available. > > Select does not block either. It always says that I can write to the > socket and then send fails with ENOBUFS. send() for UDP should block if the socket is filled and the interface can't drain the data fast enough. > The udp_output function in /sys/netinet/udp_usrreq.c, seems clear: > > /* > * Calculate data length and get a mbuf > * for UDP and IP headers. > */ > M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT); > if (m == 0) { > error = ENOBUFS; > if (addr) > splx(s); > goto release; > } > > There is no sign of send blocking waiting for a mbuf or of it returning > EAGAIN if the socket is non-blocking. > > Is the documentation for send(2) wrong or is there some way to make > send and sendto block? Good question. There is not feedback loop like in tcp, so handling this blocking and releasing would be a little bit harder to do for UDP. > I have used setsockopt(s, SOL_SOCKET, SO_SNDBUF) to reduce the size > of the output queue for the socket but send still returns ENOBUFS and > never blocks or returns EAGAIN. > > I note that send on Linux and Solaris blocks and that on these systems > select can be used to wait until the send will not block. > > I have written a test program, > http://www.infres.enst.fr/~pook/send/server.c, that shows that send does > not block on FreeBSD. It does with Linux and Solaris. Do you know what the behaviour of Net- and/or OpenBSD is? -- Andre