• 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)