Bug 1643 - Modifying a copy of a Packet corrupts the PacketMetadata of another Packet if the source packet was empty
Modifying a copy of a Packet corrupts the PacketMetadata of another Packet if...
Status: NEW
Product: ns-3
Classification: Unclassified
Component: network
ns-3.16
PC Linux
: P4 normal
Assigned To: Mathieu Lacage
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2013-04-24 17:07 EDT by Karsten Roscher
Modified: 2014-03-16 07:46 EDT (History)
3 users (show)

See Also:


Attachments
Example program to reproduce the issue. (1.31 KB, text/x-c++src)
2013-04-24 17:07 EDT, Karsten Roscher
Details
Changed Packet Meta Data File - possible fix (40.66 KB, text/x-c++src)
2014-03-11 01:23 EDT, ykrishnateja93@gmail.com
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Karsten Roscher 2013-04-24 17:07:33 EDT
Created attachment 1567 [details]
Example program to reproduce the issue.

If we have two independent copies of an empty packet, modifying one packet apparently corrupts the meta data of the other.

I have attached a simple example that illustrates the problem. If the packet size is set to zero, the program crashes with a failed assertion because it tries to read wrong header data. With a packet size larger than zero, it works.
Comment 1 ykrishnateja93@gmail.com 2014-03-11 01:00:10 EDT
Hi,

it is my first time please bare with me if I am wrong .

main part of the code:

1.  Ptr<Packet> packet = Create<Packet> ();
2.  Ptr<Packet> p1 = packet->Copy ();
3.  Ipv4Header ipv4;
4.  p1->AddHeader (ipv4);
5.  Ipv6Header ipv6;
6.  Ptr<Packet> p2 = packet->Copy ();
7.  p2->AddHeader (ipv6);

In the first line when we created packet. It creates packetmetadataobject also.

366 PacketMetadata::PacketMetadata (uint64_t uid, uint32_t size)
367  : m_data (PacketMetadata::Create (10)),
368  m_head (0xffff),
369  m_tail (0xffff),
370  m_used (0),
371  m_packetUid (uid)
372 {

here m_used value is set to zero.
we are using this to track the postion until which m_data is used.

In second line of main when copy is called
379 PacketMetadata::PacketMetadata (PacketMetadata const &o)
380  : m_data (o.m_data),
381  m_head (o.m_head),
382  m_tail (o.m_tail),
383  m_used (o.m_used),
384  m_packetUid (o.m_packetUid)
385 {
m_used=0 in p1

on adding header at  p1->AddHeader (ipv4); m_used is updated as data is written it to m_data.
370  m_used += written;

In the 6 th line in main we are again creating a copy !!!! Here we can see the mistake
we are getting old m_used value zero to p2.

So now when we add new header the m_data is being updated at zero where  
ipv4 packet information is stored.Resulting in overwriting .This is the problem
for the error .


390  uint8_t *buffer = &m_data->m_data[m_used];
So now when we add information of header to m_data buffer adds at
dirty area which must not be the case .We must create a new copy when this case 
occours .

383  if (m_used + n > m_data->m_size ||
384  (m_head != 0xffff &&
385  m_data->m_count != 1 &&
386  m_used != m_data->m_dirtyEnd))
387  {
388  ReserveCopy (n);
389  }
390  uint8_t *buffer = &m_data->m_data[m_used];

Here we can see that our case will not create a 
reserve copy so my solution is adding a statement
(m_head == 0xffff&&m_used < m_data->m_dirtyEnd)
which is exactly our problem

so my only edit is adding this case.
383  if (m_used + n > m_data->m_size ||
384  (m_head != 0xffff &&
385  m_data->m_count != 1 &&
386  m_used != m_data->m_dirtyEnd)||(m_head == 0xffff&&m_used < m_data->m_dirtyEnd))
387  {
388  ReserveCopy (n);
389  }
390  uint8_t *buffer = &m_data->m_data[m_used];
Comment 2 ykrishnateja93@gmail.com 2014-03-11 01:23:07 EDT
Created attachment 1798 [details]
Changed Packet Meta Data File - possible fix
Comment 3 ykrishnateja93@gmail.com 2014-03-16 07:46:06 EDT
(In reply to ykrishnateja93@gmail.com from comment #2)
> Created attachment 1798 [details]
> Changed Packet Meta Data File - possible fix

Is this correct ?