Bug 559

Summary: TcpSocketImpl doesn’t free endpoint quickly enough after being closed
Product: ns-3 Reporter: Ewgenij Starostin <estar>
Component: internetAssignee: George Riley <riley>
Status: RESOLVED FIXED    
Severity: blocker CC: craigdo, jpelkey, mathieu.lacage, riley
Priority: P1    
Version: ns-3-dev   
Hardware: All   
OS: All   
Attachments: patch that attempts to free m_endPoint more quickly
Tests for Bind()/Close() behaviour
Linux equivalents of the tests

Description Ewgenij Starostin 2009-04-26 19:59:42 UTC
Hi,

while using TCP sockets in a context where they’re not deleted quickly after use inside my application, I’ve noticed that after binding a socket to a port, closing it, then attempting to bind another socket to the same port is unsuccessful. I’d expect this to work, even if the the first socket object hasn’t been deleted yet. (This is in the context of (unconnected) listening sockets being created and closed repeatedly on the same port.)

I’m attaching a patch (against the 3.4 release, but should work for current -dev too) that seems to work for me, which frees m_endPoint in TcpSocketImpl whenever the socket experiences a state transition into CLOSED; not at all certain whether it’s the right thing to do, though.
Comment 1 Ewgenij Starostin 2009-04-26 20:00:45 UTC
Created attachment 430 [details]
patch that attempts to free m_endPoint more quickly
Comment 2 Mathieu Lacage 2009-04-27 10:48:05 UTC
+1
Comment 3 Craig Dowell 2009-06-24 21:19:14 UTC
Pushed changeset:  a41b2894ccce

I thought it deserved a tad more comment but pushed essentially intact.
Comment 4 Craig Dowell 2009-06-29 17:36:58 UTC
changeset:  bb360763b0e2

Previous commit seems to have vanished.
Comment 5 Ewgenij Starostin 2009-06-30 03:34:20 UTC
Looking at it again, this change fixes the problem if the socket changed state between Bind() and Close(), but not if there was no Listen() or similar between those calls.

Removing the check for saveState != CLOSED would fix that, but would (probably) cause problems whenever actions occur in the CLOSED state without a state change, e. g. for
  aT[CLOSED][SYN_RX]      = SA (CLOSED,   RST_TX);
where the socket name shouldn’t be reset.

I can’t think of a nice way to fix it; maybe a new action to replace NO_ACT in
  aT[CLOSED][APP_CLOSE]   = SA (CLOSED,   NO_ACT);
would be the right place to free the endpoint explicitly in this case.

Attaching tests for NS3 and Linux to illustrate the difference in behaviour.
Comment 6 Ewgenij Starostin 2009-06-30 03:37:24 UTC
Created attachment 506 [details]
Tests for Bind()/Close() behaviour

Add two tests to src/internet-stack/tcp-test.cc.

Test4 checks
  sock1->Bind(); sock1->Listen(); sock1->Close(); sock2->Bind();
and works at the moment. Test5 checks
  sock1->Bind(); sock1->Close(); sock2->Bind();
and fails.
Comment 7 Ewgenij Starostin 2009-06-30 03:38:43 UTC
Created attachment 507 [details]
Linux equivalents of the tests

Equivalent (I hope) implementations of both tests for Linux; these ones pass.
Comment 8 Josh Pelkey 2009-10-07 23:13:22 UTC
changeset c54b36fb7317