Bug 907 - NSC doesn't signal peer closing in any way - either via Closecallback or handing out empty packet
NSC doesn't signal peer closing in any way - either via Closecallback or hand...
Status: NEW
Product: ns-3
Classification: Unclassified
Component: internet
pre-release
All All
: P5 normal
Assigned To: ns-bugs
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2010-05-04 06:57 EDT by Antti Mäkelä
Modified: 2010-06-01 02:57 EDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Antti Mäkelä 2010-05-04 06:57:39 EDT
When using NSC and having an established TCP session, if the connection is closed by peer, either CloseCallback (which NSC ignores) should be called, or receive callback with an empty packet (comparable to recv() returning 0).

I simply inserted the following into ReadPendingData:

      NS_LOG_LOGIC ("ReadPendingData got EOF from socket");
      m_state = CLOSE_WAIT;
      Ptr<Packet> p = Create<Packet>();
      SocketAddressTag tag;
      tag.SetAddress (m_peerAddress);
      p->AddPacketTag (tag);
      m_deliveryQueue.push (p);
      NotifyDataRecv();
      return false;

I hope this would be appropriate fix.
Comment 1 Antti Mäkelä 2010-05-31 13:18:51 EDT
....as with the other TCP stack (bug #902), retransmissions after FIN has been sent result in similar behavior as there - the added "reading 0 bytes" signal never gets to the application. 

  It's almost as if NSC never even wakes the tcp-nsc-socket-impl up after a retransmit. I'm not sure why this happens - 

line NS_LOG_DEBUG (this << " invalid state: " << m_state);

is never reached, so I'm sure it's not a state machine issue as such. 

Upon further investigation, it seems that receivecallback never gets called "enough". My TCP transfer of 1 megabyte that has bunch of retransmits near the end never sends callbacks for more than 952kbytes...
Comment 2 Antti Mäkelä 2010-05-31 13:31:50 EDT
(In reply to comment #1)
> Upon further investigation, it seems that receivecallback never gets called
> "enough". My TCP transfer of 1 megabyte that has bunch of retransmits near the
> end never sends callbacks for more than 952kbytes...

  With even further checks, looks like even NSCWakeup doesn't get called (so that it would, in turn, call ReadPendingData(). 

  Oh how far down does the rabbit hole go...
Comment 3 Antti Mäkelä 2010-05-31 13:39:19 EDT
Ok, fix:

It seems to me that ReadPendingData()'s return value is not actually used for anything.

Anyway, I added

while (ReadPendingData()) {}

as the last line of ReadPendingData function, before the return statement, so that the darn thing would keep grabbing everything. Yeah, I realize this is recursion, but not sure how to do this best - I suppose I could just do a while (!err) for the inner portion.

Or use goto statement :)
Comment 4 Tom Henderson 2010-06-01 01:50:58 EDT
Antti, if I understand correctly, there are two problems you are reporting:

1) the normalClose socket callback is not invoked by NSC
2) the RecvCallback undercounts actual receive possibilities, especially upon retransmits

What do you think about trying to report (wake up) more accurately in the NSC code, rather than just rely on calling ReadPendingData repeatedly?  Perhaps we need to try both approaches to minimize the chance that a read opportunity is missed.
Comment 5 Antti Mäkelä 2010-06-01 02:57:05 EDT
(In reply to comment #4)
> What do you think about trying to report (wake up) more accurately in the NSC
> code, rather than just rely on calling ReadPendingData repeatedly?  Perhaps we

  That would probably be the best option since right now we are just grabbing everything we can whenever there's a wakeup, so there might be some remaining issues or specific cases where this approach fails.

I *do* know that repeatedly calling ReadPendingData solves other issue I saw earlier, namely with the pcaps I got out of the simulation - those pcaps resulted in some *very* funky tcptrace-curves which I initially just wrote off as part of CUBIC congestion algorithm since I'm not familiar with it, but then it appeared with Reno as well... 

Solving stuff at the source (NSC side) is worth studying - however, I won't be submitting those patches at least very soon, NSC's codebase is far too unfamiliar for me...