send(2) does not block, send(2) man page wrong?

Andre Oppermann andre at freebsd.org
Fri Jan 23 07:50:36 PST 2004


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



More information about the freebsd-hackers mailing list