Bug 1729

Summary: NSC doesn't call the Send Callback
Product: nsc Reporter: Cristian Morales Vega <reddwarf>
Component: coreAssignee: Sam Jansen <sam.jansen>
Status: CONFIRMED ---    
Severity: major CC: ns-bugs, tomh, tschorsch
Priority: P5    
Version: unspecified   
Hardware: All   
OS: All   
Attachments: callback fix for bulk send application

Description Cristian Morales Vega 2013-07-08 09:27:36 EDT
Using the example "tcp-bulk-send.cc", and adding a

internet.SetTcp ("ns3::NscTcpL4Protocol","Library",StringValue ("liblinux2.6.26.so"));

line, it fails to work.

BulkSendApplication::SendData() is called only once. And BulkSendApplication::DataSend is never called.

BulkSendApplication uses
      m_socket->SetSendCallback (
        MakeCallback (&BulkSendApplication::DataSend, this));

which I guess should make DataSend be called every time data is sent (since it will mean there is new free space in the buffer).

This is with ns-3 3.17.
Comment 1 Cristian Morales Vega 2013-07-08 11:03:18 EDT
I just found bug#1711.

It's basically the same, but for NSC instead of DCE.
Comment 2 Tom Henderson 2013-07-08 13:16:10 EDT
I had a brief look at this and I think it needs to be looked at further.  Here are some brief notes:

There are two callbacks, "Send" callback and "DataSent" callback.  Send pertains to the I/O flow control from user-space program to socket.  "DataSent" callback is a non-standard (simulation-only) callback that is supposed to notify when bits hit the wire.  

The Nsc socket will buffer the data provided by the ns-3 application, and then tries to write into the NSC library.  


The below is from nsc-tcp-socket-impl.cc:

617 bool NscTcpSocketImpl::SendPendingData (void)
...
671   if (written > 0)
672     {
673       Simulator::ScheduleNow (&NscTcpSocketImpl::NotifyDataSent, this, ret);
674       return true;
675     }
676   return false;

Here, when data is written from the ns-3 object into NSC's library, NotifyDataSent is called, but NotifySend is never called.  I'm questioning both of these-- first, NotifyDataSent can't really be properly supported in this mode, because NSC stack code itself may hold the data for a while.  Second, NotifySend probably needs to be called to enable flow control-- otherwise, the application needs to opportunistically guess or meter out its data to send to avoid overrunning the TCP buffers.

I also wonder whether this used to work but was broken when the TCP code was refactored into TcpSocket -> TcpSocketBase (Nsc still uses TcpSocket)
Comment 3 Cristian Morales Vega 2013-07-10 12:49:19 EDT
The "Send" callback is clear. But to argue if the "DataSent" callback is correct (or correct enough) or not I guess we should know what the user case is.
I can't see a single user of "DataSent" callback. So I can't say what the needs are.
Comment 4 Tom Henderson 2013-07-12 17:45:40 EDT
(In reply to comment #3)
> The "Send" callback is clear. But to argue if the "DataSent" callback is
> correct (or correct enough) or not I guess we should know what the user case
> is.
> I can't see a single user of "DataSent" callback. So I can't say what the needs
> are.

This callback was proposed for simulation purposes, in case it was of use to log when bits were actually sent on the wire.  It doesn't correspond to normal socket I/O.

I'm not that concerned with that one since, as you said, the use case is not strong, but the Send() callback needs to work properly, IMO.
Comment 5 Florian Tschorsch 2013-11-13 10:40:08 EST
Created attachment 1709 [details]
callback fix for bulk send application

I ran into the same problem this bug report describes. For me the fix is simple: change the callbacks in the bulk send application from "Send" to "Sent". I think this is the actual intention of this kind of mechanism -- at least the comment suggests this:

      // We exit this loop when actual < toSend as the send side
      // buffer is full. The "DataSent" callback will pop when
      // some buffer space has freed ip.

Please note the "DataSent" in the comment. 

I attached a patch to fix this issue.