I found that the reason the active closer enters TIME WAIT is to make sure that the final ACK is not lost. But how does it know if the final ACK is lost? Will the passive closer resend the FIN and then the active closer knows the ACK was lost? Here is a picture of the TCP FSM.
TCP TIME WAIT – Purpose of TIME WAIT in TCP Connection Tear Down
tcp
Related Solutions
Does that make any sense?
No.
The FIN is send because the sender decided that it wants to close the connection. Even if you would change the recipient that it will ignore the FIN the sender side of the application will still consider the connection closed and not send or receive any more data on it.
Just compare it to a phone call. If the other end decided to hang up the phone and no longer talk to you it does not matter if you are trying to ignore this, the other end still will not talk to you any more.
What are my options?
This must be fixed inside the application. For example the application could reuse the existing TCP connection like done with HTTP keep-alive.
A -----FIN-----> B
FIN_WAIT_1 CLOSE_WAIT
A <----ACK------ B
FIN_WAIT_2
(B can send more data here, this is half-close state)
A <----FIN------ B
TIME_WAIT LAST_ACK
A -----ACK-----> B
| CLOSED
2MSL Timer
|
CLOSED
The ACK to a FIN is required because the end sending the FIN will retransmit it until it receives an ACK. So, the question is, why TCP keeps sending the FIN if not ACK is received? My understanding is that given that a connection may be in a half-close state, the side that is receiving the last FIN (A in your diagram) may be waiting for data "indefinitely" wasting resources in that end when no more data will be received. B needs to be sure that A received the FIN (and closes the connection), hence it requires an ACK.
Edit
To be more precise about half-close. In your example, A can close its side of the connection sending the first FIN and receiving the first ACK, but B can keep sending more data at will for any period of time before closing the connection and sending the last FIN. So, the time between the first FIN/ACK sequence and the second one can't be determined or timed-out. A needs the last FIN to be sure B has closed its side of the connection.
Edit 2
What happen if the last FIN from B to A is lost? Then, B will not receive the ACK and will retransmit the FIN until it receives an ACK. So, A will eventually get the FIN and transition to the TIME_WAIT state.
A -----FIN-----> B
FIN_WAIT_1 CLOSE_WAIT
A <----ACK------ B
FIN_WAIT_2
(B can send more data here, this is half-close state)
A (Lost)X<--FIN------ B
FIN_WAIT_2 LAST_ACK
(timeout waiting for ACK)
A <----FIN------ B
TIME_WAIT
A -----ACK-----> B
| CLOSED
2MSL Timer
|
CLOSED
What happen if the last ACK is lost? Then, B will think that A did not receive the FIN and will retransmit the FIN. From B point of view this is the same as if the FIN was lost, from A point of view this different since A now is in the TIME_WAIT or CLOSED state. When A receives the new FIN from A if it is in the TIME_WAIT state it will send the ACK again.
A -----FIN-----> B
FIN_WAIT_1 CLOSE_WAIT
A <----ACK------ B
FIN_WAIT_2
(B can send more data here, this is half-close state)
A <----FIN------ B
TIME_WAIT LAST_ACK
A -----ACK-->X(Lost) B
TIME_WAIT LAST_ACK
(timeout waiting for ACK)
A <----FIN------ B
A -----ACK-----> B
| CLOSED
2MSL Timer
|
CLOSED
If A is in the CLOSED state it will send a RESET, in either case B will be able to close its side of the connection.
A -----FIN-----> B
FIN_WAIT_1 CLOSE_WAIT
A <----ACK------ B
FIN_WAIT_2
(B can send more data here, this is half-close state)
A <----FIN------ B
TIME_WAIT LAST_ACK
A -----ACK-->X(Lost) B
TIME_WAIT LAST_ACK
|
2MSL Timer
|
CLOSED
(timeout waiting for ACK)
A <----FIN------ B
A -----RST-----> B
CLOSED
Best Answer
Yes. Quoting from TCP/IP Illustrated Volume 1, in the TCP Connection Management section:
There is a timeout. When in
LAST_ACK
, the passive closer will resendFIN
when there is a timeout, assuming that it was lost. If it was indeed lost, then the active closer will eventually receive the retransmittedFIN
and enterTIME_WAIT
. If theFIN
was not lost but the finalACK
was lost, then the active closer is inTIME_WAIT
and receivesFIN
again. When this happens - receiving aFIN
inTIME_WAIT
- theACK
is retransmitted.The timeout value in
TIME_WAIT
is NOT used for retransmission purposes. When there is a timeout inTIME_WAIT
, it is assumed that the finalACK
was successfully delivered because the passive closer didn't retransmitFIN
packets. So, the timeout inTIME_WAIT
is just an amount of time after which we can safely assume that if the other end didn't send anything, then it's because he received the finalACK
and closed the connection.