From owner-freebsd-hackers@FreeBSD.ORG Fri Jan 23 18:02:48 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 6CA8016A4FE; Fri, 23 Jan 2004 18:02:48 -0800 (PST) Received: from gw.catspoiler.org (217-ip-163.nccn.net [209.79.217.163]) by mx1.FreeBSD.org (Postfix) with ESMTP id 040B243D39; Fri, 23 Jan 2004 18:02:47 -0800 (PST) (envelope-from truckman@FreeBSD.org) Received: from FreeBSD.org (mousie.catspoiler.org [192.168.101.2]) by gw.catspoiler.org (8.12.9p2/8.12.9) with ESMTP id i0O22b7E068823; Fri, 23 Jan 2004 18:02:41 -0800 (PST) (envelope-from truckman@FreeBSD.org) Message-Id: <200401240202.i0O22b7E068823@gw.catspoiler.org> Date: Fri, 23 Jan 2004 18:02:37 -0800 (PST) From: Don Lewis To: Stuart.Pook@infres.enst.fr In-Reply-To: MIME-Version: 1.0 Content-Type: TEXT/plain; charset=us-ascii cc: freebsd-hackers@FreeBSD.org cc: andre@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: Sat, 24 Jan 2004 02:02:48 -0000 On 23 Jan, Stuart Pook wrote: >> send() for UDP should block if the socket is filled and the interface >> can't drain the data fast enough. > > It doesn't (at least I cannot make it 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. > > Send(2) indicates that it should do so. > >> > 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? > > NetBSD is the same as FreeBSD. I have not tested OpenBSD. > MacOS X is similiar to FreeBSD in that send doesn't block, howver > the send does not give an error: the packet is just thrown away. Which is the same result as you would get if the bottleneck is just one network hop away instead of at the local NIC. Even if you changed the network stack to block or return an error when it detected that it was tossing packets away, the application has no way of knowing that all, a majority of, or even any of its data was getting though even though it wasn't blocked by send() and didn't receive any error returns. Think about the case of a gigabit LAN connected to the Internet over a modem link. Even with a stack that blocked send() so that no packets were lost in the stack, the application would think it was sending data to a peer on the Internet at gigabit speeds, but in reality most of the traffic would be silently dropped. Even within the LAN, traffic could be dropped if the outgoing switch port was more congested than the link from the sending host to the NIC. If you want to send a lot of data as fast as possible using UDP, then you'll probably need to reinvent the TCP congestion avoidance algorithms in your application so that you don't overly impact the network. The application can't rely on send() blocking or returning errors, since you don't know that the local network interface is the bottleneck. Since the bottleneck could be anywhere, the application code is simpler if it relies on cues that are the same no matter where the bottleneck is located rather than adding extra code just to handle a local bottleneck.