The meaning of listen(2)
's backlog parameter
I was all set to write an entry where I was going to mention in passing
something about the effects of listen(2)
's backlog parameter. Then
I made the mistake of actually testing things to see if I understood
things correctly. Now I am writing a different entry.
If you read your typical Unix manpage for listen()
, it will say
something like:
The backlog argument defines the maximum length to which the queue of pending connections for sockfd may grow.
Ha ha. As if. In practice the only portable assumption that you can
make is that the backlog sets the minimum number of connections that
may be pending, where the minimal definition of 'pending' is 'the other
side has called connect()
and you have not yet called accept()
'. The
actual observed backlog that can build up depends on the specific
Unix version you are using and on at least some Unix versions, on the
specific type of sockets involved (on Linux, Unix domain sockets behave
quite differently from TCP IPv4 sockets). What happens when there are
too many pending connections is also system and perhaps socket type
dependent.
'Pending' may also have various different definitions. The minimal one
is 'the other side has had connect()
succeed', ie the kernel has
successfully accepted and established the connection on your behalf
(cf); it's just waiting for
you to get around to call accept()
. For TCP connections, incomplete
TCP connections (ones that have not completed the three-way handshake)
are not counted against this limit on basically any modern Unix.
However, your kernel may not complete the three-way handshake if doing
so would make the pending queue too high.
(In the distant early days of the modern Internet, Unixes did count incomplete TCP connections against socket backlog limits (for good reasons at the time). Then people discovered that SYN flooding was a great way to DoS servers that they didn't like. Nowadays any serious Unix has much better protections against SYN floods that don't chew up resources and so don't need limits.)
Note that most Unixes silently impose a maximum value on the backlog value. Some impose a minimum as well, and some impose different minimums depending on what the socket protocol is.
This leads to the obvious question: what should you set the backlog
value to when you call listen()
? My current view is that setting it
low doesn't reliably do anything so you probably should set it high.
Given that the kernel will clamp the value if you go too high I suggest
going for at least 128 or 256, maybe more; going high in your software
means that the actual number is up to whatever limit the local system
has set.
(There is an important consequence of setting it high, but that's the entry I was originally planning to write before I made the mistake of checking reality.)
By the way, all of the system and socket type dependent behavior of
listen()
's backlog means that you should never trust tuning advice
about what you should set it to from anyone who doesn't specify their
Unix, the specific version of their Unix, and the specific socket types
involved. If someone says 'oh, you want to set it to 64' without giving
you that information (and without any other explanation), you can ignore
them. Possibly this means you should ignore me too.
Comments on this page:
|
|