Small socket programming question

Karl Denninger karl at denninger.net
Mon Apr 17 13:34:48 UTC 2017


On 4/16/2017 22:01, Ronald F. Guilmette wrote:
> Sorry, I -think- I know that answer to this question, but
> I'd prefer to ask and make sure, in case I have misunderstood
> things.
>
> I am aware that for any open socket, the kernel sets aside
> some amount of buffer space for that socket.  (And yes, I
> *do* also know that the specific amount set aside may be
> programatically controlled.)
>
> So anyway, let's say that I have either a RAW or UDP
> (datagram) socket open and my program is running on a
> nice fast machine, but it's outbound connection is via
> a rather slow link.  So if my program writes and writes
> and writes to this socket, eventually, I'll have used up
> all of the buffer space that the kernel has associated
> with the socket.
>
> My question is just this:  What happens then?  Will further
> writes to the socket block until some more packets get sent
> out, you know, so that there is once again room in the
> outbound buffer that's associated with this socket?  Or will
> I instead get some error back from the call to write(), like
> for instance EAGAIN or ENOSPC or maybe ENOBUFS?
>
> Or does the kernel in such cases just silently discard
> one or more of my precious outbound packets without even
> telling me?  (I guess this is my way of asking whether or
> not the FreeBSD kernel may, in some cases, itself be a
> source of "packet loss".)
>
> Thanks in advance for any & all enlightening replies.
What happens depends on whether you have set the socket to nonblocking
or not.

If it is set to blocking then the call should block until space is
available. If it is set to nonblocking then you get a -1 back (instead
of the number of octets actually written) and errno is set to indicate
the reason.  EAGAIN should be returned if the call would have blocked if
the socket was set to blocking mode (the output buffer is full); you can
also get ENOBUFS, but that is supposed to mean system buffer congestion
(rather than your *specific* socket's buffer set being full.)

Note that you generally need to use sendto and friends instead of write
for connectionless operation since it specifies a destination and option
flags (in other words you don't need to call connect), and write()
doesn't return the full set of error conditions that sendto does.

A kernel (FreeBSD or otherwise) may be *forced* to discard data should
it run out of buffer space on the receive side and in that instance
there's nobody to notify since the cause of the overrun is not on the
local machine.  That's the "least bad" outcome for that involuntary
situation. But in the event that a local process *would* cause a buffer
overrun the kernel will instead return an error to the calling process
and *not* toss the data on the floor.

-- 
Karl Denninger
karl at denninger.net <mailto:karl at denninger.net>
/The Market Ticker/
/[S/MIME encrypted email preferred]/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 2993 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.freebsd.org/pipermail/freebsd-net/attachments/20170417/691c578c/attachment.bin>


More information about the freebsd-net mailing list