Search code examples
socketstime-wait

What's the difference between TIME-WAIT Assassination and SO_REUSEADDR


I was reading about using the SO_LINGER socket option to intentionally 'assassinate' the time-wait state by setting the linger time to zero. The author of the book then goes on to say we should never do this and in general that we should never interfere with the time-wait state. He then immediately recommends using the SO_REUSEADDR option to bypass the time-wait state.

My question is, what's the difference? In both cases you're prematurely terminating the time-wait state and taking the risk of receiving duplicate segments. Why is one good and the other bad?


Solution

  • I did some more reading and this is my understanding of what happens (hopefully correct):

    When you call close on a socket which has SO_REUSEADDR set ( or your app crashes ) the following sequence occurs:

    1. TCP Sends any remaining data in the send buffer and a FIN
    2. If close was called it returns immediately without indicated if any remaining data was delivered successfully.
    3. If data was sent the peer sends a data ACK
    4. The peer sends an ACK of the FIN and sends it's own FIN packet
    5. The peer's FIN is acked and the socket resources are deallocated.
    6. The socket does not enter TIME-WAIT.

    When you close a socket with the SO_LINGER time set to zero:

    1. TCP discards any data in the send buffer
    2. TCP sends a RST packet to the peer
    3. The socket resource are deallocated.
    4. The socket does not enter TIME-WAIT

    So beyond the fact that setting linger to zero is a hack and bad style it's also bad manners as it doesn't go through a clean shutdown of the connection.