Bug 663

Summary: RST from remote TCP crashes ns-3 TCP
Product: ns-3 Reporter: Craig Dowell <craigdo>
Component: internetAssignee: George Riley <riley>
Status: RESOLVED FIXED    
Severity: blocker CC: jpelkey
Priority: P1    
Version: pre-release   
Hardware: All   
OS: All   

Description Craig Dowell 2009-08-18 15:02:56 UTC
In another manifestation of incorrect ns-3 TCP shutdown problems(s), ff ns-3 receives a reset while sending data, it doesn't reset, it crashes.

If ns-3 gets a reset, it calls TcpSocketImpl::ProcessEvent() which eventually does:

  if (m_state == CLOSED && saveState != CLOSED && m_endPoint != 0)
    {
      NS_ASSERT (m_tcp != 0);
      /*
       * We want to deallocate the endpoint now.  We can't just naively call
       * Deallocate (see the comment in TcpSocketImpl::~TcpSocketImpl), we
       * have to turn off the DestroyCallback to keep it from calling back
       * into TcpSocketImpl::Destroy and closing pretty much everything down.
       * Once we have the callback disconnected, we can DeAllocate the
       * endpoint which actually deals with destroying the actual endpoint,
       * and then zero our member varible on general principles.
       */
      m_endPoint->SetDestroyCallback(MakeNullCallback<void>());
      m_tcp->DeAllocate (m_endPoint);
      m_endPoint = 0;
    }

Notice that the RST causes m_endPoint to be zeroed.  The ns-3 TCP may happily try to TcpSocketImpl::Retransmit after this happens.  In this case,

  tcpHeader.SetSourcePort (m_endPoint->GetLocalPort());

crashes since m_endPoint has been zeroed when the RST was received.

This can be worked around by detecting the condition and not actually trying to retransmit the bits in TcpSocketImpl::Retransmit()

  if (m_endPoint == 0)
    {
      return;
    }

This is just a hack, though.
Comment 1 Josh Pelkey 2009-10-07 23:13:36 UTC
changeset c54b36fb7317