Linux Socket Linger Time is 60 seconds twice
From
moby dick@21:1/5 to
All on Tue Dec 21 01:08:46 2021
In case you have a port in use error, wait 2 minutes, no need for
reboot.
Linger Time. The Linger Time is globally configurable on most
systems and by default rather long (two minutes is a common value
you will find on many systems). It is also configurable per
socket using the socket option SO_LINGER which can be used to
make the timeout shorter or longer, and even to disable it
completely. Disabling it completely is a very bad idea, though,
since closing a TCP socket gracefully is a slightly complex
process and involves sending forth and back a couple of packets
(as well as resending those packets in case they got lost) and
this whole close process is also limited by the Linger Time. If
you disable lingering, your socket may not only lose data in
flight, it is also always closed forcefully instead of
gracefully, which is usually not recommended. The details about
how a TCP connection is closed gracefully are beyond the scope of
this answer, if you want to learn more about, I recommend you
have a look at this page. And even if you disabled lingering with
SO_LINGER, if your process dies without explicitly closing the
socket, BSD (and possibly other systems) will linger nonetheless,
ignoring what you have configured. This will happen for example
if your code just calls exit() (pretty common for tiny, simple
server programs) or the process is killed by a signal (which
includes the possibility that it simply crashes because of an
illegal memory access). So there is nothing you can do to make
sure a socket will never linger under all circumstances.
The question is, how does the system treat a socket in state
TIME_WAIT? If SO_REUSEADDR is not set, a socket in state
TIME_WAIT is considered to still be bound to the source address
and port and any attempt to bind a new socket to the same address
and port will fail until the socket has really been closed, which
may take as long as the configured Linger Time. So don't expect
that you can rebind the source address of a socket immediately
after closing it. In most cases this will fail. However, if
SO_REUSEADDR is set for the socket you are trying to bind,
another socket bound to the same address and port in state
TIME_WAIT is simply ignored, after all its already "half dead",
and your socket can bind to exactly the same address without any
problem. In that case it plays no role that the other socket may
have exactly the same address and port. Note that binding a
socket to exactly the same address and port as a dying socket in
TIME_WAIT state can have unexpected, and usually undesired, side
effects in case the other socket is still "at work", but that is
beyond the scope of this answer and fortunately those side
effects are rather rare in practice.
There is one final thing you should know about SO_REUSEADDR.
Everything written above will work as long as the socket you want
to bind to has address reuse enabled. It is not necessary that
the other socket, the one which is already bound or is in a
TIME_WAIT state, also had this flag set when it was bound. The
code that decides if the bind will succeed or fail only inspects
the SO_REUSEADDR flag of the socket fed into the bind() call, for
all other sockets inspected, this flag is not even looked
at.
SO_REUSEPORT
SO_REUSEPORT is what most people would expect SO_REUSEADDR to be.
Basically, SO_REUSEPORT allows you to bind an arbitrary number of
sockets to exactly the same source address and port as long as
all prior bound sockets also had SO_REUSEPORT set before they
were bound. If the first socket that is bound to an address and
port does not have SO_REUSEPORT set, no other socket can be bound
to exactly the same address and port, regardless if this other
socket has SO_REUSEPORT set or not, until the first socket
releases its binding again. Unlike in case of SO_REUESADDR the
code handling SO_REUSEPORT will not only verify that the
currently bound socket has SO_REUSEPORT set but it will also
verify that the socket with a conflicting address and port had
SO_REUSEPORT set when it was bound.
SO_REUSEPORT does not imply SO_REUSEADDR. This means if a socket
did not have SO_REUSEPORT set when it was bound and another
socket has SO_REUSEPORT set when it is bound to exactly the same
address and port, the bind fails, which is expected, but it also
fails if the other socket is already dying and is in TIME_WAIT
state. To be able to bind a socket to the same addresses and port
as another socket in TIME_WAIT state requires either SO_REUSEADDR
to be set on that socket or SO_REUSEPORT must have been set on
both sockets prior to binding them. Of course it is allowed to
set both, SO_REUSEPORT and SO_REUSEADDR, on a socket.
There is not much more to say about SO_REUSEPORT other than that
it was added later than SO_REUSEADDR, that's why you will not
find it in many socket implementations of other systems, which
"forked" the BSD code before this option was added, and that
there was no way to bind two sockets to exactly the same socket
address in BSD prior to this option.
--
The hungry rabbit jumps
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)