bug 1502 Shutdown on tcp socket seems to misbehave
authorBrian Swenson <bswenson3@gatech.edu>
Fri, 15 Mar 2013 11:33:30 -0400
changeset 9258 620eeaa0e173
parent 9257 bf7814af6638
child 9259 be33f29782ab
bug 1502 Shutdown on tcp socket seems to misbehave
src/internet/model/tcp-socket-base.cc
--- a/src/internet/model/tcp-socket-base.cc	Thu Mar 14 16:20:54 2013 -0700
+++ b/src/internet/model/tcp-socket-base.cc	Fri Mar 15 11:33:30 2013 -0400
@@ -450,9 +450,11 @@
   // Bug number 426 claims we should send reset in this case.
   if (m_rxBuffer.Size () != 0)
     {
+      NS_LOG_INFO ("Socket " << this << " << unread rx data during close.  Sending reset");
       SendRST ();
       return 0;
     }
+ 
   if (m_txBuffer.SizeFromSequence (m_nextTxSequence) > 0)
     { // App close with pending data must wait until all data transmitted
       if (m_closeOnEmpty == false)
@@ -470,7 +472,32 @@
 TcpSocketBase::ShutdownSend (void)
 {
   NS_LOG_FUNCTION (this);
+  
+  //this prevents data from being added to the buffer
   m_shutdownSend = true;
+  m_closeOnEmpty = true;
+  //if buffer is already empty, send a fin now
+  //otherwise fin will go when buffer empties.
+  if (m_txBuffer.Size () == 0)
+    {
+      if (m_state == ESTABLISHED || m_state == CLOSE_WAIT)
+        {
+          NS_LOG_INFO("Emtpy tx buffer, send fin");
+          SendEmptyPacket (TcpHeader::FIN);  
+
+          if (m_state == ESTABLISHED)
+            { // On active close: I am the first one to send FIN
+              NS_LOG_INFO ("ESTABLISHED -> FIN_WAIT_1");
+              m_state = FIN_WAIT_1;
+            }
+          else
+            { // On passive close: Peer sent me FIN already
+              NS_LOG_INFO ("CLOSE_WAIT -> LAST_ACK");
+              m_state = LAST_ACK;
+            }  
+        }
+    }
+ 
   return 0;
 }
 
@@ -498,6 +525,11 @@
           m_errno = ERROR_MSGSIZE;
           return -1;
         }
+      if (m_shutdownSend)
+        {
+          m_errno = ERROR_SHUTDOWN;
+          return -1;
+        }
       // Submit the data to lower layers
       NS_LOG_LOGIC ("txBufSize=" << m_txBuffer.Size () << " state " << TcpStateName[m_state]);
       if (m_state == ESTABLISHED || m_state == CLOSE_WAIT)
@@ -1922,12 +1954,6 @@
                     " highestRxAck " << m_txBuffer.HeadSequence () <<
                     " pd->Size " << m_txBuffer.Size () <<
                     " pd->SFS " << m_txBuffer.SizeFromSequence (m_nextTxSequence));
-      // Quit if send disallowed
-      if (m_shutdownSend)
-        {
-          m_errno = ERROR_SHUTDOWN;
-          return false;
-        }
       // Stop sending if we need to wait for a larger Tx window (prevent silly window syndrome)
       if (w < m_segmentSize && m_txBuffer.SizeFromSequence (m_nextTxSequence) > w)
         {