[e2e] tcp connection timeout

rick jones perfgeek at mac.com
Sat Mar 11 09:12:03 PST 2006


>> Is that why we had such "fun" with FIN_WAIT_2 and web servers?
>
> That was largely TIME_WAIT.

TIME_WAIT was a benchmarking issue with which we dealt reasonably 
easily simply by hashing the TCP connection list.  I was very 
deliberately picking FIN_WAIT_2.

> There were versions that had problems with FIN_WAIT_2, but mostly due 
> to
> poor application behavior.
>
>>> Starting a listen isn't a collision - it doesn't do anything at the 
>>> TCP
>>> level. The collision happens only when the new connection is 
>>> attempted,
>>> which, for that model, assumes the remote side sends the SYN. If the 
>>> SYN
>>> is from a different port, there's no interference and it proceeds as
>>> usual. It's only when the SYN received indicates the port from the 
>>> old
>>> connection that the state gets cleaned up - or needs to.
>>
>> Should the semantics of SO_REUSEADDR be the default then?
>
> That only helps if you're in TIME_WAIT.

Really?  I thought that in just about all implementations the 
SO_REUSEADDR would allow a new listen endpoint while there were others 
in anything but LISTEN.

> If you want to do a listen and your OS tells you there's an error
> (because you've bound to the whole tuple, rather than leaving some
> aspects open), you get an error which should help YOU decide to issue a
> corresponding abort call - IF YOU WANT.

That then would only be if you _didn't_ do the application close() so 
you still had a way to reach-out and touch the TCP endpoint.

>> _No_ reason?  Admittedly, the TCP connection state doesn't have to be
>> particularly large, but there can be a particularly large number of 
>> them.
>
> TCP is not optimized for this anywhere else. If you want to redesign 
> the
> WHOLE protocol to minimize the amount of spare state hanging around,
> that'd be interesting, but a significant redesign. TCP is currently
> designed to clean state _only_ when it interferes with a new 
> connection.

TCP doesn't have a hole anywhere else.  Any other state always has 
either a reference open to the application so will go away when the 
application goes away, or has a timer running that can get it along to 
the next state (perhaps closed).  Only with FIN_WAIT_2 is there the 
prospect of a TCP endpoint with no connection to an application on 
"this" end, and waiting on an action from the other end that may never 
happen.

>> So the receive-only side of a simplex TCP connection should have an an
>> application-level timeout that goes pop when no data has been received
>> from the remote side, since by definition it cannot send an
>> application-level keepalive yes?
>
> You chose to use TCP as a simplex channel by leaving it in half-closed
> and continuing to send new data and "it hurts when I do that"-- so 
> don't
> _do_ that.
>
> I.e., if your application decides to half-close the connection, it has
> little right to complain it no longer has that data channel to play 
> with.

It feels a bit like a trap set by TCP then - look, but don't touch the 
simplex functionality we provide, because if you do, you cannot do what 
we assert _you_ must do which is provide application-level probes to 
make sure everything remains OK.

rick jones
Wisdom teeth are impacted, people are affected by the effects of events.



More information about the end2end-interest mailing list