diff -r ec4b512688d8 src/internet-stack/tcp-l4-protocol.cc --- a/src/internet-stack/tcp-l4-protocol.cc Mon Apr 19 14:49:13 2010 +0200 +++ b/src/internet-stack/tcp-l4-protocol.cc Mon Apr 19 11:34:01 2010 -0400 @@ -158,7 +158,8 @@ aT[LAST_ACK][SEQ_RECV] = SA (LAST_ACK, NEW_SEQ_RX); aT[LAST_ACK][APP_CLOSE] = SA (CLOSED, NO_ACT); aT[LAST_ACK][TIMEOUT] = SA (CLOSED, NO_ACT); - aT[LAST_ACK][ACK_RX] = SA (CLOSED, APP_CLOSED); + aT[LAST_ACK][ACK_RX] = SA (LAST_ACK, NO_ACT); + aT[LAST_ACK][FIN_ACKED] = SA (CLOSED, APP_CLOSED); aT[LAST_ACK][SYN_RX] = SA (CLOSED, RST_TX); aT[LAST_ACK][SYN_ACK_RX] = SA (CLOSED, RST_TX); aT[LAST_ACK][FIN_RX] = SA (LAST_ACK, FIN_ACK_TX); @@ -173,7 +174,8 @@ aT[FIN_WAIT_1][SEQ_RECV] = SA (FIN_WAIT_1, NEW_SEQ_RX); aT[FIN_WAIT_1][APP_CLOSE] = SA (FIN_WAIT_1, NO_ACT); aT[FIN_WAIT_1][TIMEOUT] = SA (FIN_WAIT_1, NO_ACT); - aT[FIN_WAIT_1][ACK_RX] = SA (FIN_WAIT_2, NEW_ACK); + aT[FIN_WAIT_1][ACK_RX] = SA (FIN_WAIT_1, NEW_ACK); + aT[FIN_WAIT_1][FIN_ACKED] = SA (FIN_WAIT_2, NEW_ACK); aT[FIN_WAIT_1][SYN_RX] = SA (CLOSED, RST_TX); aT[FIN_WAIT_1][SYN_ACK_RX] = SA (CLOSED, RST_TX); aT[FIN_WAIT_1][FIN_RX] = SA (CLOSING, ACK_TX); @@ -203,7 +205,8 @@ aT[CLOSING][SEQ_RECV] = SA (CLOSED, RST_TX); aT[CLOSING][APP_CLOSE] = SA (CLOSED, RST_TX); aT[CLOSING][TIMEOUT] = SA (CLOSING, NO_ACT); - aT[CLOSING][ACK_RX] = SA (TIMED_WAIT, NO_ACT); + aT[CLOSING][ACK_RX] = SA (CLOSING, NO_ACT); + aT[CLOSING][FIN_ACKED] = SA (TIMED_WAIT, NO_ACT); aT[CLOSING][SYN_RX] = SA (CLOSED, RST_TX); aT[CLOSING][SYN_ACK_RX] = SA (CLOSED, RST_TX); aT[CLOSING][FIN_RX] = SA (CLOSED, ACK_TX); diff -r ec4b512688d8 src/internet-stack/tcp-socket-impl.cc --- a/src/internet-stack/tcp-socket-impl.cc Mon Apr 19 14:49:13 2010 +0200 +++ b/src/internet-stack/tcp-socket-impl.cc Mon Apr 19 11:34:01 2010 -0400 @@ -694,6 +694,19 @@ m_rxWindowSize = tcpHeader.GetWindowSize (); //update the flow control window Events_t event = SimulationSingleton::Get ()->FlagsEvent (tcpHeader.GetFlags () ); + // Given an ACK_RX event and FIN_WAIT_1, CLOSING, or LAST_ACK state, + // we have to check the sequence numbers to determine if the + // ACK is for the FIN + if ((m_state == FIN_WAIT_1 || m_state == CLOSING + || m_state == LAST_ACK) && event == ACK_RX) + { + if (tcpHeader.GetSequenceNumber () == m_nextRxSequence) + { + // This ACK is for the fin, change event to + // recognize this + event = FIN_ACKED; + } + } Actions_t action = ProcessEvent (event); //updates the state NS_LOG_DEBUG("Socket " << this << " processing pkt action, " << action << @@ -1648,7 +1661,7 @@ void TcpSocketImpl::Retransmit () { NS_LOG_FUNCTION (this); - uint8_t flags = TcpHeader::NONE; + uint8_t flags = TcpHeader::ACK; if (m_state == SYN_SENT) { if (m_cnCount > 0) diff -r ec4b512688d8 src/internet-stack/tcp-typedefs.h --- a/src/internet-stack/tcp-typedefs.h Mon Apr 19 14:49:13 2010 +0200 +++ b/src/internet-stack/tcp-typedefs.h Mon Apr 19 11:34:01 2010 -0400 @@ -56,8 +56,9 @@ SYN_ACK_RX, // 8 FIN_RX, // 9 FIN_ACK_RX, // 10 - RST_RX, // 11 - BAD_FLAGS, // 12 + FIN_ACKED, // 11 + RST_RX, // 12 + BAD_FLAGS, // 13 LAST_EVENT } Events_t; typedef enum {