diff -r e4a750adf12c src/internet-stack/tcp-socket-impl.cc --- a/src/internet-stack/tcp-socket-impl.cc Mon May 24 10:52:58 2010 -0700 +++ b/src/internet-stack/tcp-socket-impl.cc Tue May 25 12:51:55 2010 -0400 @@ -82,6 +82,7 @@ m_highestRxAck (0), m_lastRxAck (0), m_nextRxSequence (0), + m_finSequence (0), m_rxAvailable (0), m_rxBufSize (0), m_pendingData (0), @@ -119,6 +120,7 @@ m_highestRxAck (sock.m_highestRxAck), m_lastRxAck (sock.m_lastRxAck), m_nextRxSequence (sock.m_nextRxSequence), + m_finSequence (sock.m_finSequence), m_rxAvailable (0), m_rxBufSize (0), m_pendingData (0), @@ -345,6 +347,7 @@ " deferring close, state " << m_state); return 0; } + m_finSequence = m_nextTxSequence + SequenceNumber (1); Actions_t action = ProcessEvent (APP_CLOSE); ProcessAction (action); return 0; @@ -943,6 +946,7 @@ if(tcpHeader.GetFlags() & TcpHeader::FIN) { ++m_nextRxSequence; //bump this to account for the FIN + m_nextTxSequence = m_finSequence; } SendEmptyPacket (TcpHeader::ACK); break; @@ -1037,19 +1041,27 @@ // out of sequence. If so, note pending close and process // new sequence rx if (tcpHeader.GetSequenceNumber () != m_nextRxSequence) - { // process close later - m_pendingClose = true; - NS_LOG_LOGIC ("TcpSocketImpl " << this << " setting pendingClose" - << " rxseq " << tcpHeader.GetSequenceNumber () - << " nextRxSeq " << m_nextRxSequence); - NewRx (p, tcpHeader, fromAddress, toAddress); - return true; + { + if (m_finSequence != m_nextRxSequence) + { + // process close later + m_finSequence = tcpHeader.GetSequenceNumber () + SequenceNumber (p->GetSize ()); + m_pendingClose = true; + NS_LOG_LOGIC ("TcpSocketImpl " << this << " setting pendingClose" + << " rxseq " << tcpHeader.GetSequenceNumber () + << " nextRxSeq " << m_nextRxSequence); + NewRx (p, tcpHeader, fromAddress, toAddress); + return true; + } } // Now we need to see if any data came with the FIN - // if so, call NewRx + // if so, call NewRx, unless NewRx was already called if (p->GetSize () != 0) { - NewRx (p, tcpHeader, fromAddress, toAddress); + if (m_finSequence != m_nextRxSequence) + { + NewRx (p, tcpHeader, fromAddress, toAddress); + } } ++m_nextRxSequence; //bump this to account for the FIN States_t saveState = m_state; // Used to see if app responds @@ -1159,6 +1171,7 @@ m_nextTxSequence + SequenceNumber (sz)); if (m_closeOnEmpty && (remainingData == 0)) { + m_finSequence = m_nextTxSequence + SequenceNumber (1 + sz); flags = TcpHeader::FIN; m_state = FIN_WAIT_1; } @@ -1322,6 +1335,7 @@ if (m_bufferedData.empty()) { ProcessPacketAction (PEER_CLOSE, p, tcpHeader, fromAddress, toAddress); + return; } } } diff -r e4a750adf12c src/internet-stack/tcp-socket-impl.h --- a/src/internet-stack/tcp-socket-impl.h Mon May 24 10:52:58 2010 -0700 +++ b/src/internet-stack/tcp-socket-impl.h Tue May 25 12:51:55 2010 -0400 @@ -202,6 +202,9 @@ //sequence info, receiver side SequenceNumber m_nextRxSequence; //next expected sequence + //sequence number where fin was sent or received + SequenceNumber m_finSequence; + //Rx buffer UnAckData_t m_bufferedData; //buffer which sorts out of sequence data //Rx buffer state