--- a/src/internet-stack/tcp-l4-protocol.cc Tue Apr 20 11:31:54 2010 +0100
+++ b/src/internet-stack/tcp-l4-protocol.cc Tue Apr 20 12:40:00 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);
--- a/src/internet-stack/tcp-socket-impl.cc Tue Apr 20 11:31:54 2010 +0100
+++ b/src/internet-stack/tcp-socket-impl.cc Tue Apr 20 12:40:00 2010 -0400
@@ -694,6 +694,19 @@
m_rxWindowSize = tcpHeader.GetWindowSize (); //update the flow control window
Events_t event = SimulationSingleton<TcpStateMachine>::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)
--- a/src/internet-stack/tcp-typedefs.h Tue Apr 20 11:31:54 2010 +0100
+++ b/src/internet-stack/tcp-typedefs.h Tue Apr 20 12:40:00 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 {