Bug 166 - Loss of Tag and change in size of Packet using TCP.
Loss of Tag and change in size of Packet using TCP.
Status: RESOLVED FIXED
Product: ns-3
Classification: Unclassified
Component: internet
pre-release
All Linux
: P1 normal
Assigned To: ns-bugs
: bug
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2008-04-11 12:59 UTC by evensky
Modified: 2008-06-09 11:57 UTC (History)
4 users (show)

See Also:


Attachments
test case, tcp-tester, that shows change in size and loss of tag (10.13 KB, text/plain)
2008-04-11 13:01 UTC, evensky
Details
tcp tester, send byte buffers, from src->sink and vice versa. (10.64 KB, text/plain)
2008-04-15 10:25 UTC, evensky
Details
test case from David Evensky for application layer tagging of data in TCP (14.79 KB, text/x-c++src)
2008-06-05 17:21 UTC, Rajib Bhattacharjea
Details
tests 2way tcp traffic including tagging, can test application headers too. (16.85 KB, text/plain)
2008-06-06 16:25 UTC, evensky
Details

Note You need to log in before you can comment on or make changes to this bug.
Description evensky 2008-04-11 12:59:48 UTC
I have a Packet that I send using a point-to-point TCP connection. I am seeing an attached Tag disappear on the receiving side and the size changes. I think these both may be bugs. I'll attach a test case below. 

I've used the component of internet-node, but thats just a wild guess.

Compile---%<-------------------%<----------%<----------%<----------%<---------%<
g++ -DNS3_ASSERT_ENABLE -DNS3_LOG_ENABLE -DDEBUG -g -O0 -I/.../ns-3-dev/build/debug -I/.../ns-3-dev/build/debug -I. -L/home/evensky/ns-3-dev/build/debug -lns3 -Wl,-rpath=/.../ns-3-dev/build/debug  -o tcp-tester tcp-tester.cc
Output---%<-------------------%<----------%<----------%<----------%<---------%<
evensky@waltz:~/tools/trunk$ ./tcp-tester 
TalkerApp::ConfRecv(0x62e360,00:00:00:00:20:00) Server
TalkerApp::ConfSend(0x62d9a0,0a:01:00:02:20:00) Client
TalkerApp::StartApplication() Server
TalkerApp::StartApplicationRecv() Server
TalkerApp::StartApplication() Client
TalkerApp::StartApplicationSend() Client
writing packet Client
   Payload (size=536)(tag=17)
TalkerApp::CloseConnection(): Client
TalkerApp::ConnectionRequested(): Server
TalkerApp::ConnectionSucceeded(): Client
TalkerApp::ConnectionCreated(): Server
Received 535 bytes from 10.1.0.1 [0a:01:00:01:01:c0]---''
   Payload (size=535)
TalkerApp::ConnectionCloseRequested(): Server
TalkerApp::CloseConnection(): Server

note, that the size changes from 536->535 and the tag is gone.

Thanks,
\dae
Comment 1 evensky 2008-04-11 13:01:40 UTC
Created attachment 125 [details]
test case, tcp-tester, that shows change in size and loss of tag
Comment 2 Liu Jian 2008-04-15 03:18:15 UTC
(In reply to comment #0)
> I have a Packet that I send using a point-to-point TCP connection. I am seeing
> an attached Tag disappear on the receiving side and the size changes. I think
> these both may be bugs. I'll attach a test case below. 
> I've used the component of internet-node, but thats just a wild guess.
> Compile---%<-------------------%<----------%<----------%<----------%<---------%<
> g++ -DNS3_ASSERT_ENABLE -DNS3_LOG_ENABLE -DDEBUG -g -O0
> -I/.../ns-3-dev/build/debug -I/.../ns-3-dev/build/debug -I.
> -L/home/evensky/ns-3-dev/build/debug -lns3 -Wl,-rpath=/.../ns-3-dev/build/debug
>  -o tcp-tester tcp-tester.cc
> Output---%<-------------------%<----------%<----------%<----------%<---------%<
> evensky@waltz:~/tools/trunk$ ./tcp-tester 
> TalkerApp::ConfRecv(0x62e360,00:00:00:00:20:00) Server
> TalkerApp::ConfSend(0x62d9a0,0a:01:00:02:20:00) Client
> TalkerApp::StartApplication() Server
> TalkerApp::StartApplicationRecv() Server
> TalkerApp::StartApplication() Client
> TalkerApp::StartApplicationSend() Client
> writing packet Client
>    Payload (size=536)(tag=17)
> TalkerApp::CloseConnection(): Client
> TalkerApp::ConnectionRequested(): Server
> TalkerApp::ConnectionSucceeded(): Client
> TalkerApp::ConnectionCreated(): Server
> Received 535 bytes from 10.1.0.1 [0a:01:00:01:01:c0]---''
>    Payload (size=535)
> TalkerApp::ConnectionCloseRequested(): Server
> TalkerApp::CloseConnection(): Server
> note, that the size changes from 536->535 and the tag is gone.

1, "536->535" caused in TcpSocket::SendPendingData ()::
Ptr<Packet> p = m_pendingData->CopyFromSeq (s, m_firstPendingSequence, 
        m_nextTxSequence);
when m_firstPendingSequence = 0, m_nextTxSequence = 1; the packet size decrease by 1. Actually i have no idea about how it works like that, maybe you should contact Raj Bhattacharjea <raj.b@gatech.edu> for more.

2,the tag is gone:: you cannot add packet header in application layer. TCP socket just send data by ptr,
TcpSocket::Send (const Ptr<Packet> p) //p here is just data, no headers
Application header shoud be added in application data ptr. 

wish it can help you.

Liu,

> Thanks,
> \dae

Comment 3 evensky 2008-04-15 09:59:58 UTC
Thanks. Regarding the missing Tag: I'm a little surprised that the functionality changes from UDP to TCP. Maybe it is because with UDP we are sending a real packet, and with TCP we aren't. Maybe this is really a documentation issue.

On the changing packet size: I have already converted my program to using buffers,
rather that Packets and I now add the data I want to send as part of the buffer. I see changes in packet size there too (but not both ways). Worse, I get a hang if I make the buffers very large (>100-200KB). I'll clean up that code a bit to make the output easier to see. Should that program get a new bug report, or should I post it under this bug, and reopen the bug?

\dae
Comment 4 Rajib Bhattacharjea 2008-04-15 10:08:45 UTC
(In reply to comment #3)
> Thanks. Regarding the missing Tag: I'm a little surprised that the
> functionality changes from UDP to TCP. Maybe it is because with UDP we are
> sending a real packet, and with TCP we aren't. Maybe this is really a
> documentation issue.
> 
> On the changing packet size: I have already converted my program to using
> buffers,
> rather that Packets and I now add the data I want to send as part of the
> buffer. I see changes in packet size there too (but not both ways). Worse, I
> get a hang if I make the buffers very large (>100-200KB). I'll clean up that
> code a bit to make the output easier to see. Should that program get a new bug
> report, or should I post it under this bug, and reopen the bug?
> 
> \dae
> 

This bug is still open, so please post your new test case under this bug.  This is my number one priority right now, so I hope to have a fix soon.

As for your large buffer case...are you using the latest ns-3-dev?  There was a fix pushed that addressed an issue that sounded identical.  The hang was in the PacketMetadata code.
Comment 5 Mathieu Lacage 2008-04-15 10:13:49 UTC
(In reply to comment #3)
> Thanks. Regarding the missing Tag: I'm a little surprised that the
> functionality changes from UDP to TCP. Maybe it is because with UDP we are
> sending a real packet, and with TCP we aren't. Maybe this is really a
> documentation issue.

Yes, I think that the issue is in the fact that UDP manages packets while TCP manages bytes. I have not yet investigated this issue but it is on my TODO today: it might be possible to make this work in a reasonable way even for TCP. So, stay tuned.

Comment 6 Rajib Bhattacharjea 2008-04-15 10:19:23 UTC
The tag being lost is a "feature" (but kind of a bug :-).  The implementation of TCP simply copies the data in a packet into an internal TX buffer.  Then TCP copies segments out of this buffer, packetizes them, and sends them according to its congestion control algorithm.  Unfortunately, this is where the tag is lost.  The way I conceived of the TCP API was that it dealt with real world buffers, not with ns3::Packets.  This is because even if you send a single tagged Packet with TCP, there is no guarantee that that information will go on the wire as one packet (in fact if the data is larger than an MSS, it WILL NOT hit the wire as one packet).

I think a solution that preserves tags might be possible if some kind of tag structure is kept in paralell to the TX buffer...but what about a case where the MSS boundaries overlap two differently tagged packets?  I'm not sure what to do in this case...
Comment 7 evensky 2008-04-15 10:25:12 UTC
Created attachment 130 [details]
tcp tester, send byte buffers, from src->sink and vice versa.

This is just my last test case, but sending byte buffers rather than Packets. I've played around a bit with sending large buffers and I get hangs. This one has a small (100byte) buffer send->rec, and a large buffer(>100K) rec->send. Look for the calls to SendPacket(). I now have a fill char, to show an errors a bit better and makes it easier to see direction. Please feel free to send and recv large buffers too.

With small buffers, all works great.
\dae
Comment 8 Mathieu Lacage 2008-04-15 11:16:43 UTC
(In reply to comment #6)
> The tag being lost is a "feature" (but kind of a bug :-).  The implementation
> of TCP simply copies the data in a packet into an internal TX buffer.  Then TCP
> copies segments out of this buffer, packetizes them, and sends them according
> to its congestion control algorithm.  Unfortunately, this is where the tag is
> lost.  The way I conceived of the TCP API was that it dealt with real world
> buffers, not with ns3::Packets.  This is because even if you send a single
> tagged Packet with TCP, there is no guarantee that that information will go on
> the wire as one packet (in fact if the data is larger than an MSS, it WILL NOT
> hit the wire as one packet).
> 
> I think a solution that preserves tags might be possible if some kind of tag
> structure is kept in paralell to the TX buffer...but what about a case where
> the MSS boundaries overlap two differently tagged packets?  I'm not sure what
> to do in this case...

What I expected your tcp implementation to do is to implement the byte buffer using a list of packet pointers to avoid the extra copy you do right now. If you do that, tags will be copied around transparently _and_ you will be highly efficient. One of the use-cases sally insisted a lot about is fast-tcp where doing what you do is just unacceptable because every simulation will become memory-bound almost immediately due to the high number of packet buffers in flight at the same time. If, instead, you use pointers to packets and instanciate these packets with Packet::Packet (uint32_t size), then, no memory will ever be allocated for the tcp payload.
Comment 9 evensky 2008-04-15 11:29:48 UTC
For our application (an MPI simulator working with ns3), I don't really need to move much data around --- tags would be fine if they are lightweight, but I do need to pretend to move a lot of data around and set message id's so that I can let the higher levels know when messages have been received and to trigger additional messages being sent. [not really part of a bug report, but it helps frame what I'm trying to do with ns3.]
Comment 10 Mathieu Lacage 2008-04-15 11:34:42 UTC
(In reply to comment #9)
> For our application (an MPI simulator working with ns3), I don't really need to

woow. _That_ is cool.

> move much data around --- tags would be fine if they are lightweight, but I do
> need to pretend to move a lot of data around and set message id's so that I can
> let the higher levels know when messages have been received and to trigger
> additional messages being sent. [not really part of a bug report, but it helps
> frame what I'm trying to do with ns3.]

I think that this is a valid use-case and I really hope that it can be supported with tcp sockets.

Comment 11 Rajib Bhattacharjea 2008-04-16 11:41:17 UTC
okay, the byte being dropped was a consequence of counting the SYN as a sequenced byte and then not updating the state of the data buffer to reflect this.  fix in:

2917:8ef8431d56d5

Output of first test case:
g++ -DNS3_ASSERT_ENABLE -DNS3_LOG_ENABLE -DDEBUG -g -O0 -I/home/raj/code.nsnam.org/ns-3-dev/build/debug -I. -L/home/raj/code.nsnam.org/ns-3-dev/build/debug -lns3 -Wl,-rpath=/home/raj/code.nsnam.org/ns-3-dev/build/debug -o tcp-tester tcp-tester.cc
raj@raj-desktop:~/Desktop/ns-3 Files/bug166$ ./tcp-tester 
TalkerApp::ConfRecv(0x8068ce0,00:00:00:00:20:00) Server
TalkerApp::ConfSend(0x8068750,0a:01:00:02:20:00) Client
TalkerApp::StartApplication() Server
TalkerApp::StartApplicationRecv() Server
TalkerApp::StartApplication() Client
TalkerApp::StartApplicationSend() Client
writing packet Client
   Payload (size=536)(tag=17)
TalkerApp::CloseConnection(): Client
TalkerApp::ConnectionRequested(): Server
TalkerApp::ConnectionSucceeded(): Client
TalkerApp::ConnectionCreated(): Server
Received 536 bytes from 10.1.0.1 [0a:01:00:01:01:c0]---''
   Payload (size=536)
TalkerApp::ConnectionCloseRequested(): Server
TalkerApp::CloseConnection(): Server


As can be seen, the tag issue however is still open.
Comment 12 Gustavo J. A. M. Carneiro 2008-04-19 11:55:47 UTC
I thought that packet tags were not supposed to propagate from one node to another?... Using this feature would be kind of like cheating the simulation...  I've always thought tags were only meant to pass data between layers within a node's stack.  For communicating between nodes one should use a _protocol_.
Comment 13 Tom Henderson 2008-04-19 12:16:07 UTC
(In reply to comment #12)
> I thought that packet tags were not supposed to propagate from one node to
> another?... Using this feature would be kind of like cheating the simulation...
>  I've always thought tags were only meant to pass data between layers within a
> node's stack.  For communicating between nodes one should use a _protocol_.
> 

I don't think we should enforce such a policy on tag use.  For instance, an often cited use is to mark an application flow with some kind of flow-id so it can be observed and traced throughout the network.  Another use case would be to compute statistics on the delay between point A and point B in a topology; point A could add timestamp tags to packets and point B could read them.  
Comment 14 Rajib Bhattacharjea 2008-06-05 16:55:36 UTC
Fixed (I think) in http://code.nsnam.org/raj/ns-3-dev-socket-helper/

David, do you have that tagging test case you mentioned?
Comment 15 Mathieu Lacage 2008-06-05 17:02:14 UTC
See the last example program in bug 174.
Comment 16 Rajib Bhattacharjea 2008-06-05 17:21:45 UTC
Created attachment 151 [details]
test case from David Evensky for application layer tagging of data in TCP

Looks like this one is still open (using the test case from bug 174, attached here for convenience):
...
 536 bytes from 10.1.0.1 [02-06-0a:01:00:01:01:c0]  Payload Fragment [0:536]|ns3::SocketRxAddressTag [0-536] address=00-00-00
TalkerApp::HandleRead(0x8074560): Client
 536 bytes from 10.1.0.2 [02-06-0a:01:00:02:20:00]  Payload Fragment [0:536]|ns3::SocketRxAddressTag [0-536] address=00-00-00
TalkerApp::HandleRead(0x80759b0): Server
  77 bytes from 10.1.0.1 [02-06-0a:01:00:01:01:c0]  Payload Fragment [536:613]|ns3::SocketRxAddressTag [0-77] address=00-00-00
TalkerApp::HandleRead(0x8074560): Client
 181 bytes from 10.1.0.2 [02-06-0a:01:00:02:20:00]  Payload Fragment [536:717]|ns3::SocketRxAddressTag [0-181] address=00-00-00
Comment 17 Rajib Bhattacharjea 2008-06-05 17:43:33 UTC
Whoops that was hasty, there are some more changes that have to trickle through for this to work...sit tight.
Comment 18 evensky 2008-06-06 16:25:05 UTC
Created attachment 158 [details]
tests 2way tcp traffic including tagging, can test application headers too.

Added copyright info, gpl, and cleaned up some code for use as regression testing. There is an issue with application header processing. If packets are delivered in order than it isn't an issue, but is a problem for out of order. If there are other authors/copyrights that should be added, bugs fixed, please feel free.
Comment 19 Rajib Bhattacharjea 2008-06-09 11:57:51 UTC
Merging raj/ns-3-dev-socket-helper and a few bugfixes in the Packet/Tags/Metadata code from Mathieu fixed this in ns-3-dev.