diff -r dfa8958e616e src/internet-stack/tcp-socket-impl.cc --- a/src/internet-stack/tcp-socket-impl.cc Sat Mar 20 21:58:06 2010 +0100 +++ b/src/internet-stack/tcp-socket-impl.cc Thu Mar 25 11:01:50 2010 -0400 @@ -79,6 +79,7 @@ m_closeRequestNotified (false), m_closeOnEmpty (false), m_pendingClose (false), + m_finAckRcvd (false), m_nextTxSequence (0), m_highTxMark (0), m_highestRxAck (0), @@ -116,6 +117,7 @@ m_closeRequestNotified (sock.m_closeRequestNotified), m_closeOnEmpty (sock.m_closeOnEmpty), m_pendingClose (sock.m_pendingClose), + m_finAckRcvd (sock.m_finAckRcvd), m_nextTxSequence (sock.m_nextTxSequence), m_highTxMark (sock.m_highTxMark), m_highestRxAck (sock.m_highestRxAck), @@ -700,6 +702,15 @@ m_rxWindowSize = tcpHeader.GetWindowSize (); //update the flow control window Events_t event = SimulationSingleton::Get ()->FlagsEvent (tcpHeader.GetFlags () ); + + if ((m_state == FIN_WAIT_1 || m_state == LAST_ACK) && event == ACK_RX) + { + if (tcpHeader.GetSequenceNumber () == m_nextRxSequence) + { + m_finAckRcvd = true; + } + } + Actions_t action = ProcessEvent (event); //updates the state NS_LOG_DEBUG("Socket " << this << " processing pkt action, " << action << @@ -719,7 +730,24 @@ bool needCloseNotify = (stateAction.state == CLOSED && m_state != CLOSED && e != TIMEOUT); - m_state = stateAction.state; + if (m_state == FIN_WAIT_1 && stateAction.state == FIN_WAIT_2) + { + if (m_finAckRcvd == true) + { + m_state = stateAction.state; + } + } + else if (m_state == LAST_ACK && stateAction.state == CLOSED) + { + if (m_finAckRcvd == true) + { + m_state = stateAction.state; + } + } + else + { + m_state = stateAction.state; + } NS_LOG_LOGIC ("TcpSocketImpl " << this << " moved from state " << saveState << " to state " < 0) diff -r dfa8958e616e src/internet-stack/tcp-socket-impl.h --- a/src/internet-stack/tcp-socket-impl.h Sat Mar 20 21:58:06 2010 +0100 +++ b/src/internet-stack/tcp-socket-impl.h Thu Mar 25 11:01:50 2010 -0400 @@ -191,6 +191,7 @@ bool m_closeRequestNotified; bool m_closeOnEmpty; bool m_pendingClose; + bool m_finAckRcvd; //sequence info, sender side