Bug 818 - TCP Socket implementation does not set ACK flag on retransmits
authorJosh Pelkey <jpelkey@gatech.edu>
Tue, 20 Apr 2010 12:40:00 -0400
changeset 6255 ca79ce283a19
parent 6254 e794047931fb
child 6256 a02c44146209
Bug 818 - TCP Socket implementation does not set ACK flag on retransmits
src/internet-stack/tcp-l4-protocol.cc
src/internet-stack/tcp-socket-impl.cc
src/internet-stack/tcp-typedefs.h
--- 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 {