Index: src/internet/model/tcp-rx-buffer.cc |
=================================================================== |
--- a/src/internet/model/tcp-rx-buffer.cc |
+++ b/src/internet/model/tcp-rx-buffer.cc |
@@ -52,7 +52,11 @@ |
* initialized below is insignificant. |
*/ |
TcpRxBuffer::TcpRxBuffer (uint32_t n) |
- : m_nextRxSeq (n), m_gotFin (false), m_size (0), m_maxBuffer (32768), m_availBytes (0) |
+ : m_nextRxSeq (n), |
+ m_gotFin (false), |
+ m_size (0), |
+ m_maxBuffer (32768), |
+ m_availBytes (0) |
{ |
} |
@@ -128,7 +132,10 @@ |
m_gotFin = true; |
m_finSeq = s; |
- if (m_nextRxSeq == m_finSeq) ++m_nextRxSeq; |
+ if (m_nextRxSeq == m_finSeq) |
+ { |
+ ++m_nextRxSeq; |
+ } |
} |
bool |
@@ -149,12 +156,21 @@ |
<< ", when NextRxSeq=" << m_nextRxSeq << ", buffsize=" << m_size); |
// Trim packet to fit Rx window specification |
- if (headSeq < m_nextRxSeq) headSeq = m_nextRxSeq; |
+ if (headSeq < m_nextRxSeq) |
+ { |
+ headSeq = m_nextRxSeq; |
+ } |
if (m_data.size ()) |
{ |
SequenceNumber32 maxSeq = m_data.begin ()->first + SequenceNumber32 (m_maxBuffer); |
- if (maxSeq < tailSeq) tailSeq = maxSeq; |
- if (tailSeq < headSeq) headSeq = tailSeq; |
+ if (maxSeq < tailSeq) |
+ { |
+ tailSeq = maxSeq; |
+ } |
+ if (tailSeq < headSeq) |
+ { |
+ headSeq = tailSeq; |
+ } |
} |
// Remove overlapped bytes from packet |
BufIterator i = m_data.begin (); |
@@ -208,7 +224,7 @@ |
else if (i->first > m_nextRxSeq) |
{ |
break; |
- }; |
+ } |
m_nextRxSeq = i->first + SequenceNumber32 (i->second->GetSize ()); |
m_availBytes += i->second->GetSize (); |
} |
@@ -216,10 +232,71 @@ |
if (m_gotFin && m_nextRxSeq == m_finSeq) |
{ // Account for the FIN packet |
++m_nextRxSeq; |
- }; |
+ } |
return true; |
} |
+void |
+TcpRxBuffer::GetIsolatedDataChunks (List& list) |
+{ |
+ NS_LOG_FUNCTION (this); |
+ |
+ // Search the receiving buffer to enlist blocks of data with |
+ // sequence number greater than the next expected sequence number into a temporary SACK list |
+ for (BufIterator i = m_data.begin (); i != m_data.end (); ++i) |
+ { |
+ if (i->first < m_nextRxSeq) |
+ { |
+ continue; |
+ } |
+ else if (i->first > m_nextRxSeq) |
+ { |
+ list.push_back (std::make_pair (i->first, i->first + SequenceNumber32 (i->second->GetSize ()))); |
+ NS_LOG_LOGIC ("Enlist a data block into temporary SACK list: " << i->first << " " << i->first + SequenceNumber32 (i->second->GetSize ())); |
+ } |
+ } |
+ |
+ // Merge consecutive data blocks if needed |
+ List::iterator outer; |
+ List::iterator inner; |
+ bool isOuterChanged; |
+ List mergedList; |
+ |
+ if (list.size () > 1) |
+ { |
+ for (outer = list.begin (); outer != list.end (); ) |
+ { |
+ inner = outer; |
+ isOuterChanged = false; |
+ for (++inner; inner != list.end (); ) |
+ { |
+ if (outer->second == inner->first) |
+ { |
+ outer->second = inner->second; |
+ ++inner; |
+ } |
+ else |
+ { |
+ isOuterChanged = true; |
+ break; |
+ } |
+ } |
+ mergedList.push_back (std::make_pair (outer->first, outer->second)); |
+ NS_LOG_LOGIC ("Enlist an isolated chunk into SACK list: " << outer->first << " " << outer->second); |
+ |
+ if (isOuterChanged) |
+ { |
+ outer = inner; |
+ } |
+ else |
+ { |
+ break; |
+ } |
+ } |
+ list = mergedList; |
+ } |
+} |
+ |
Ptr<Packet> |
TcpRxBuffer::Extract (uint32_t maxSize) |
{ |
@@ -227,7 +304,10 @@ |
uint32_t extractSize = std::min (maxSize, m_availBytes); |
NS_LOG_LOGIC ("Requested to extract " << extractSize << " bytes from TcpRxBuffer of size=" << m_size); |
- if (extractSize == 0) return 0; // No contiguous block to return |
+ if (extractSize == 0) |
+ { |
+ return 0; // No contiguous block to return |
+ } |
NS_ASSERT (m_data.size ()); // At least we have something to extract |
Ptr<Packet> outPkt = Create<Packet> (); // The packet that contains all the data to return |
BufIterator i; |