[e2e] tcp connection timeout
avg at kotovnik.com
Thu Mar 2 00:19:48 PST 2006
On Wed, 1 Mar 2006, David P. Reed wrote:
> I was describing a historical perspective. TCP is what it is, and no
> one (not me) is suggesting it should be changed. Ideally it should be
> thrown away someday, because it continues to acquire barnicles.
> However, some comments regarding my points, below:
TCP spec is fine with regard to keepalives. The implementations (which
follow the misguided recommendation to impose ridiculously long shortest
> > The knowledge that connectivity is lost (i.e. that there's no *ability* to
> > send information before the need arises) is valuable.
> This cannot be well-defined. This is Jim Gettys' point above.
> "Connectivity" is NOT lost. The end-to-end probability of packet
> delivery just varies.
If it is not well-defined, there's no point in arguing about where exactly
the cut-off point should be.
In 99% cases if packets go through, there's adequate connectivity.
Besides, TCP does not provide any guarantees of latency or bandwidth. So
the objection that "connectivity lost" condition does not match any
application-specified threshold of network quality is irrelevant.
> This is a classic example
> of the "end to end argument" - you can't define this function
> "connectivity being lost" at the network layer, because connectivity
> isn't lost, only packets are lost.
Sorry, but we're talking not about network, but about transport layer. I'm
not arguing about design of packet transport, I'm arguing about design of
OS kernel and applications.
> > Just an example (with somewhat militarized slant): it does make a lot of
> > difference if you know that you don't know your enemy's position, or if
> > you falsely think that you know where they are, and meanwhile they moved
> > and you simply didn't hear about it because some wire is cut.
> You never know your enemies' position unless you are God. You only know
> *where they were* not where they are now. You can waste all your time
> sending radar pulses every microsecond, and you still won't know where
> they are,
You know better than to twist analogies to the point of absurdity. There's
a notion of "good enough". If I know the max speed and max turn
acceleration of the target I have an envelope of the possible target
positions. It is enough to launch a missile, which will refine its bearing
as it gets closer. That's how things work with the real-life missiles
(the guidance and targeting systems happen to be my military specialty).
And in the real life, there's a lot of sources which get fixes unreliably,
fail, etc. One of the points of failure is comm system. So all
adequately designed comm systems provide fault indication.
> > What is needed is an API which lets applications to specify maximal
> > duration of loss of connectivity which is acceptable to them. This part
> > is broken-as-designed in all BSD-ish stacks, so few people use it.
> It's so easy to do this at the application level, and you can do it
> exactly as you wish - so why implement a slightly general and
> always-wrong model in the lower layer, especially since most users don't
> even need it, and some, like Jim Gettys end up having to patch around
> its false alarms!
I've seen hundreds of app-level protocols. Nearly all of them get
keepalives wrong. Besides, I do not want a protocol which can easily
convert a transient fault when I'm not sending any data into long delays
when I want to send - even after the fault went away - and that is exactly
what you get when you send keepalives over reliable transport protocol.
Loss of a keepalive packet shouldn't collapse window or increase timeouts.
Neither should keepalives be retransmitted.
Now, how exactly do you propose to implement that on top of TCP?
Besides, there's a lot of situations when *network* layer should be able
to tell a keepalive from a payload packet - dial-on-demand or cellular
links, for example. Move keepalives to application land, and you have a
choice between wasting your battery or having the modem to know about all
kinds of applications.
How about an app-level keepalive message being stuck behind a large piece
of data (in high delay - low bandwidth situation)? It is kind of hard to
get that situation sorted out right when you have a serialized stream.
Finally, TCP stack has RTT estimates. Application doesn't. So it has no
way to know if its loss detector is sane.
> > Keepalives, arguably, is the crudest method for detection of loss of
> > connectivity, and they load the network with extra traffic and do not
> > provide for the fast detection of the loss. But, because of their
> > crudity, they always work.
> They NEVER work. (except if you define working as doing something, even
> if it is not what you want it to do).
Sure. That's because all you see is broken implementations of keepalives.
All I'm arguing about is that we need only one implementation - but which
is designed by someone who has a clue, so all apps can then simply use it.
> > A good idea would be to fix standard socket API and demand that all TCP
> > stacks allow useful minimal keepalive times (down to seconds), rather than
> > have application-level protocol designers to implement workarounds at the
> > application level.
> There you go - you think that you can demand that protocol engineers
> know more than application designers about "usefulness".
The "loss of some percentage of probe packets" (in TCP land 20% loss seems
to be a threshold of useability, and not in any way application specific)
"observed during a period not exceeding given timeout" (which *is*
applicaion-specific) is generic enough.
There is *no* way to monitor network conditions with probes in such a way
so as not to load it significantly by the probes and get any more specific
at the same time. So no application I'm aware of even tries. (Hint: the
measurement precision is proportional to measurement duration divided by
probe frequency; measurement makes no sense if measured system changes
significantly at a rate faster than the measurement period - so unless
you're loading the network with probes, the precision is misleading, as
measured conditions shoot way outside of the stationary-case error margins
while you measure).
It follows that most actively probing network monitoring tools produce
> That's why my cellphone says "call is lost" 20 times a day, requiring me
> to redial over and over, instead of keeping the call alive until I press
> hangup. Some network engineer decided that a momentary outage should
> be treated as a permanent one. Foo.
You're complaining about non-configurable threshold. Well, I said that
there should be API for application to say what the timeout is (or if it
wants to let user to drop circuit manually). Manual timeout works only if
you have a human in the loop - and fails because of human, too. In case of
cell phone _not_ dropping a call because of bad conditions and leaving it
to the human to worry about can easily cause a situation like that link
droppes for a few minutes (common when driving in a hilly countryside) -
by the time it comes back one may forget about it, and miss subsequent
incoming calls. While keeping the other party wondering how long he's
supposed to wait with the receiver glued to his ear.
> > And, yes, provide the TCP stack with a way to probe the application to
> > check if it is alive and not deadlocked (that being another reason to do
> > app-level keepalives).
> Oh yeah. Put TCP in charge of the application. Sure. And put the
> fox in charge of the chicken coop.
It exactly the same sense as receiving a block of data from TCP puts it
"in charge" of application. It is totally irrelevant if you get an "are
you still there?" query in the middle of TCP data and have to reply to it,
or if you get "are you still there?" exception and have to reply to it.
The only difference is that in the second case you don't have to obfuscate
your application-level protocol to allow for these queries in different
states and in the middle of half-completed ops. Better yet, you may have
OS to do some useful guessing by default if you don't care to implement
watchdog code in the application.
(Digressing... frankly, I'm rather amused by the fact that no "modern" OS
provides an exception on reaching a limit to number of operations between
wait states; I guess one knows of usefulness of such things only if he
has some experience with real-life fault-tolerant systems - as I had, at
my father's design bureau; a critical fault in the kind of systems he
designed more often than not entailed some obituaries).
Of course, one may argue that properly designed applications never get
stuck... well, good luck, and pray for the miraculous salvation when they
> The purpose of the network is to support applications, not the
> applications to support the network's needs. Perhaps this is because
> network protocol designers want to feel powerful?
Precisely, and that's why network shouldn't force application developers
to make their code any more complicated than it should be. Setting a
timeout once is an awful lot simpler than keeping asynchronous timers
needed for application-level keepalives. Oh, and there's a small issue of
significantly more complicated app. protocol FSMs which have to deal with
asynchronous timing. Add timeout negotiation (the shorter period of both
ends should be used) - know any application-level protocols which do that?
And, again, most application developers can not implement the keepalives
properly - because they are not network protocol designers. A lot of app.
developers out there don't bother with keepalives at all - a five-minute
talk to a sysadmin in a large company yields heaps of yarns about
stuck backups which didn't time out for a couple of hours and so the whole
night's run was ruined, and so on.
Transport layer has timers. Applications, in most cases, shouldn't.
Majority of application-level protocols are synchronous anyway; why force
app developers to do asynchronous coding?
More information about the end2end-interest