Bugzilla – Bug 559
TcpSocketImpl doesn’t free endpoint quickly enough after being closed
Last modified: 2009-10-07 23:13:22 EDT
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.
Created attachment 430 [details] patch that attempts to free m_endPoint more quickly
+1
Pushed changeset: a41b2894ccce I thought it deserved a tad more comment but pushed essentially intact.
changeset: bb360763b0e2 Previous commit seems to have vanished.
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.
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.
Created attachment 507 [details] Linux equivalents of the tests Equivalent (I hope) implementations of both tests for Linux; these ones pass.
changeset c54b36fb7317