diff --git a/src/network/model/byte-tag-list.h b/src/network/model/byte-tag-list.h index bf136f8b3..df7d8e2b1 100644 --- a/src/network/model/byte-tag-list.h +++ b/src/network/model/byte-tag-list.h @@ -50,21 +50,15 @@ struct ByteTagListData; * as-needed to emulate COW semantics. * * - Each tag tags a unique set of bytes identified by the pair of offsets - * (start,end). These offsets are provided by Buffer::GetCurrentStartOffset - * and Buffer::GetCurrentEndOffset which means that they are relative to - * the start of the 'virtual byte buffer' as explained in the documentation - * for the ns3::Buffer class. Whenever the origin of the offset of the Buffer - * instance associated to this ByteTagList instance changes, the Buffer class - * reports this to its container Packet class as a bool return value - * in Buffer::AddAtStart and Buffer::AddAtEnd. In both cases, when this happens - * the Packet class calls ByteTagList::AddAtEnd and ByteTagList::AddAtStart to update - * the byte offsets of each tag in the ByteTagList. + * (start,end). These offsets are relative to the start of the packet + * Whenever the origin of the offset changes, the Packet adjusts all + * byte tags using ByteTagList::Adjust method. * - * - Whenever bytes are removed from the packet byte buffer, the ByteTagList offsets - * are never updated because we rely on the fact that they will be updated in - * either the next call to Packet::AddHeader or Packet::AddTrailer or when - * the user iterates the tag list with Packet::GetTagIterator and - * TagIterator::Next. + * - When packet is reduced in size, byte tags that span outside the packet + * boundaries remain in ByteTagList. It is not a problem as iterator fixes + * the boundaries before returning item. However, when packet is extending, + * it calls ByteTagList::AddAtStart or ByteTagList::AddAtEnd to cut byte + * tags that will otherwise cover new bytes. */ class ByteTagList { diff --git a/src/network/model/packet.cc b/src/network/model/packet.cc index a1026002e..dc45eba26 100644 --- a/src/network/model/packet.cc +++ b/src/network/model/packet.cc @@ -229,12 +229,14 @@ Packet::CreateFragment (uint32_t start, uint32_t length) const { NS_LOG_FUNCTION (this << start << length); Buffer buffer = m_buffer.CreateFragment (start, length); + ByteTagList byteTagList = m_byteTagList; + byteTagList.Adjust (-start); NS_ASSERT (m_buffer.GetSize () >= start + length); uint32_t end = m_buffer.GetSize () - (start + length); PacketMetadata metadata = m_metadata.CreateFragment (start, end); // again, call the constructor directly rather than // through Create because it is private. - return Ptr (new Packet (buffer, m_byteTagList, m_packetTagList, metadata), false); + return Ptr (new Packet (buffer, byteTagList, m_packetTagList, metadata), false); } void @@ -254,10 +256,9 @@ Packet::AddHeader (const Header &header) { uint32_t size = header.GetSerializedSize (); NS_LOG_FUNCTION (this << header.GetInstanceTypeId ().GetName () << size); - uint32_t orgStart = m_buffer.GetCurrentStartOffset (); m_buffer.AddAtStart (size); - m_byteTagList.Adjust (m_buffer.GetCurrentStartOffset () + size - orgStart); - m_byteTagList.AddAtStart (m_buffer.GetCurrentStartOffset () + size); + m_byteTagList.Adjust (size); + m_byteTagList.AddAtStart (size); header.Serialize (m_buffer.Begin ()); m_metadata.AddHeader (header, size); } @@ -267,6 +268,7 @@ Packet::RemoveHeader (Header &header) uint32_t deserialized = header.Deserialize (m_buffer.Begin ()); NS_LOG_FUNCTION (this << header.GetInstanceTypeId ().GetName () << deserialized); m_buffer.RemoveAtStart (deserialized); + m_byteTagList.Adjust (-deserialized); m_metadata.RemoveHeader (header, deserialized); return deserialized; } @@ -282,10 +284,8 @@ Packet::AddTrailer (const Trailer &trailer) { uint32_t size = trailer.GetSerializedSize (); NS_LOG_FUNCTION (this << trailer.GetInstanceTypeId ().GetName () << size); - uint32_t orgStart = m_buffer.GetCurrentStartOffset (); + m_byteTagList.AddAtEnd (GetSize ()); m_buffer.AddAtEnd (size); - m_byteTagList.Adjust (m_buffer.GetCurrentStartOffset () - orgStart); - m_byteTagList.AddAtEnd (m_buffer.GetCurrentEndOffset () - size); Buffer::Iterator end = m_buffer.End (); trailer.Serialize (end); m_metadata.AddTrailer (trailer, size); @@ -311,26 +311,20 @@ void Packet::AddAtEnd (Ptr packet) { NS_LOG_FUNCTION (this << packet << packet->GetSize ()); - uint32_t aStart = m_buffer.GetCurrentStartOffset (); - uint32_t bEnd = packet->m_buffer.GetCurrentEndOffset (); - m_buffer.AddAtEnd (packet->m_buffer); - uint32_t appendPrependOffset = m_buffer.GetCurrentEndOffset () - packet->m_buffer.GetSize (); - m_byteTagList.Adjust (m_buffer.GetCurrentStartOffset () - aStart); - m_byteTagList.AddAtEnd (appendPrependOffset); + m_byteTagList.AddAtEnd (GetSize ()); ByteTagList copy = packet->m_byteTagList; - copy.Adjust (m_buffer.GetCurrentEndOffset () - bEnd); - copy.AddAtStart (appendPrependOffset); + copy.AddAtStart (0); + copy.Adjust (GetSize ()); m_byteTagList.Add (copy); + m_buffer.AddAtEnd (packet->m_buffer); m_metadata.AddAtEnd (packet->m_metadata); } void Packet::AddPaddingAtEnd (uint32_t size) { NS_LOG_FUNCTION (this << size); - uint32_t orgStart = m_buffer.GetCurrentStartOffset (); + m_byteTagList.AddAtEnd (GetSize ()); m_buffer.AddAtEnd (size); - m_byteTagList.Adjust (m_buffer.GetCurrentStartOffset () - orgStart); - m_byteTagList.AddAtEnd (m_buffer.GetCurrentEndOffset () - size); m_metadata.AddPaddingAtEnd (size); } void @@ -345,6 +339,7 @@ Packet::RemoveAtStart (uint32_t size) { NS_LOG_FUNCTION (this << size); m_buffer.RemoveAtStart (size); + m_byteTagList.Adjust (-size); m_metadata.RemoveAtStart (size); } @@ -796,14 +791,14 @@ Packet::AddByteTag (const Tag &tag) const NS_LOG_FUNCTION (this << tag.GetInstanceTypeId ().GetName () << tag.GetSerializedSize ()); ByteTagList *list = const_cast (&m_byteTagList); TagBuffer buffer = list->Add (tag.GetInstanceTypeId (), tag.GetSerializedSize (), - m_buffer.GetCurrentStartOffset (), - m_buffer.GetCurrentEndOffset ()); + 0, + GetSize ()); tag.Serialize (buffer); } ByteTagIterator Packet::GetByteTagIterator (void) const { - return ByteTagIterator (m_byteTagList.Begin (m_buffer.GetCurrentStartOffset (), m_buffer.GetCurrentEndOffset ())); + return ByteTagIterator (m_byteTagList.Begin (0, GetSize ())); } bool