Bugzilla – Bug 166
Loss of Tag and change in size of Packet using TCP.
Last modified: 2008-06-09 11:57:51 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
Created attachment 125 [details] test case, tcp-tester, that shows change in size and loss of tag
(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
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
(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.
(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.
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...
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
(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.
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.]
(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.
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.
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_.
(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.
Fixed (I think) in http://code.nsnam.org/raj/ns-3-dev-socket-helper/ David, do you have that tagging test case you mentioned?
See the last example program in bug 174.
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
Whoops that was hasty, there are some more changes that have to trickle through for this to work...sit tight.
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.
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.