TCP not closing correctly (FIN_WAIT_2)

Posted by Liet on Thu 12 Aug 2004 04:53 AM — 5 posts, 23,685 views.

#0
I noticed this while writing my own mud server from scratch. Its mostly a coding exercise so while I was trying to get my async connections shut down properly I noticed mushclient was leaving its connections in FIN_WAIT_2 and CLOSE_WAIT. This only happens when using a "quit" command (ie the mud initiates closing the connection).

Quit command (server disconnecting client):

Proto Local Address Foreign Address State
TCP envy:4000 localhost:4977 FIN_WAIT_2
TCP envy:4977 localhost:4000 CLOSE_WAIT

And then when mushclient is closed netstat reports what it should have originally:

TCP envy:4000 localhost:4977 TIME_WAIT

Regular telnet and zMud both don't exhibit this behavior and it leaves its connection in close_wait for non-local servers as well so I'm pretty sure it's not my server. While this isn't the end of the world, FIN_WAIT_2 can have a fairly long timeout.
Australia Forum Administrator #1
Strangely enough, I am also writing my own MUD server from scratch. I hadn't noticed what you said, but you are right.

It must be closing the connection the wrong way, I'll look into it.
#2
A socket gets into CLOSE_WAIT when the remote side sends a FIN and the local side sends an ACK, but has not yet sent it's FIN.

A socket gets into FIN_WAIT_2 when the local side closes the socket and sends a FIN (FIN_WAIT_1) and then recieves an ACK for that FIN but has not yet recieved a FIN from the remote side.

See http://www.vs.inf.ethz.ch/edu/WS0102/VS/TCP-State-Diagram.html for details.

That said, I can see how MC could be leaving sockets in CLOSE_WAIT, but I can't see how a socket can get into FIN_WAIT_2 if the remote side closed the connection first. It shouldn't be possible.
Amended on Mon 16 Aug 2004 07:01 PM by godefroi
Australia Forum Administrator #3
I think MUSHclient sets the "no linger" flag on connections, thus after receiving the FIN it sends an ACK but doesn't send the final FIN.

I dumped a session (tcpdump port 4000):


07:35:10.546129 client.2468 > server.4000: P 18:24(6) ack 2680 win 8760

07:35:10.546222 server.4000 > client.2468: . ack 24 win 5840

07:35:10.595955 server.4000 > client.2468: P 2680:2901(221) ack 24 win 5840

07:35:10.596047 server.4000 > client.2468: F 2901:2901(0) ack 24 win 5840

07:35:10.596497 client.2468 > server.4000: . ack 2902 win 8539


I typed "quit" which was sent (first line), the server responded "Your surroundings begin to fade..." (second line) and "We await your return, Nick..." (third line), then the server sends FIN (fourth line), which the client ACKs (fifth line). After that, nothing.

I think you are reading the diagram from the wrong side. Look at the bottom-left corner and you will see:

  • ESTAB -> Server closes the session and sends FIN. Goes into FIN WAIT-1
  • FIN-WAIT-1 -> Server receives ACK of FIN, goes into FIN WAIT-2


At this point MUSHclient forcibly disconnects the connection (due to NO_LINGER being set) and drops its end. Thus the server is still in FIN-WAIT-2.

Amended on Wed 18 Aug 2004 10:23 PM by Nick Gammon
#4
I thought the CLIENT was stuck in FIN_WAIT_2.

Man, was I confused.