Subject: Kicking TCP

From: Phil Karn <[email-masked]>
Date: Mon, 6 Mar 2000 23:27:26 -0800

Last week I attended an IAB workshop on wireless IP issues. One of the
topics of relevance to this group was making TCP work better over
links that can experience long outages.

Way back in the mid-to-late 1980s, when I was writing code to run
TCP/IP over amateur (ham) packet radio, I created something called a
"TCP kick" packet -- a UDP packet that would cause the recipient to
force a retransmission on all of its TCP connections to the sender. I
hooked it into a hot key so you could "kick" a connection by hitting
the key. Given TCP's exponential backoff mechanism and the flakiness
of our radio links, this was a real godsend.

I've been occasionally floating this idea in the IETF (usually
repackaged as an ICMP message), so at the workshop I was asked to
write it up as an Internet Draft. Allison Mankin suggested the term
"Source Encourage" (ICMP SE).

This scheme is designed to improve TCP performance by deliberately
short-circuiting TCP's congestion control in situations where it is
not needed. But in today's Internet, the potential for abuse of such a
scheme for denial of service mischief has to be taken seriously.  So
instead of allowing the ICMP SE message to "kick" any arbitrary set of
TCP connections, I included in it the header of the last packet to be
dropped by the router before the link came back up. The recipient of
the ICMP SE would check the fields to see that they corresponded to a
real TCP connection before forcing a retransmission. This blocks the
"blind" 3rd party denial of service attacks that are so easy to mount
today.

But then I realized that if the router is to hold onto a packet so it
can generate an ICMP SE when the link comes back up, it might as well
just forward that same packet onto its destination. This will get TCP
going again just as surely as the ICMP SE mechanism would.

So I'm thinking of inserting some text into the PILC LINK document
that would recommend that routers driving subnetworks subject to
lengthy outages (e.g., mobile radio) try to hold onto the last IP
packet of each flow when a link goes down and forward it to its
destination when the link comes back up.

A lot of storage would not be needed. One for each TCP connection is
all that's needed, with each packet overwriting the previous
one. (Obviously things are more complicated if IPSEC is in use, so the
router could store just the last packet seen between a given pair of
IP addresses). Simplifying things is the fact that most mobile radio
links carry only a small number of flows, often just one.

Note that this gives nearly all of the benefits claimed for totally
reliable link layer protocols with much less effort. The router would
not have to promise absolute reliability; if it dropped the stored
packet (e.g., due to insufficient memory), TCP would still recover
after the link comes back up, just not as quickly. Like all link layer
reliability mechanisms below TCP, this one is intended merely as
a performance enhancement, not as a reliability guarantee.

Comments?

Phil

---

From: Zachary Amsden <[email-masked]>
Date: Mon, 06 Mar 2000 23:53:41 -0800

Yes, kicking TCP is useful in limited situations, but you needn't go to much 
trouble at all to do it - you can easily add a kernel hack to reset the 
retransmission timer on the transmitting socket.  This will trigger 
retranmissions without losing any TCP state, and avoids any protocol 
modifications.

This serves a useful purpose on what I call "blackout" lines - lines of 
communication that temporarily go dead for several seconds and require 
complicated renegotiation (like some wireless links).  On public connections 
with interactive users, having a kick command is a very bad idea from a 
congestion point of view.

A neat solution to this problem would be to cache link characteristics with 
routes, and to tweak TCP strategy routines based on link types - i.e. a 
kick_timeout that limits the maximum retransmission backoff allowed, after 
which the retransmit timer starts it's cycle over again, or stays at the 
maximum.  (Modifying cwnd is also possible, but I wouldn't recommend it 
without analysis).

One would really need to do some serious simulation runs to analyze the 
effects of kicking connections under these circumstances.

If you still can't complete the transmission with this strategy, I can't think 
of any other strategy that would help - if you don't get any ACKs in return, 
kicking is useless.

-- 
Zachary Amsden  [email-masked]  3-6919  31-2-510  Core Protocols

---

From: Phil Karn <[email-masked]>
Date: Tue, 7 Mar 2000 23:20:15 -0800

>retranmissions without losing any TCP state, and avoids any protocol 

Yes, I know it's easy to reset the TCP retransmission timer, but what
would cause that to happen? That was the intent of my ICMP Source Encourage
message.

What I'm really looking for comment on is whether the same goal of
getting TCP going again quickly can be achieved more transparently by
having the subnet hold the last packet of a stream through a link
outage, and forward it normally when the link comes back up.

PHil

---

From: Reiner Ludwig <[email-masked]>
Date: Wed, 08 Mar 2000 16:48:37 +0100

At 08:27 3/7/00 , Phil Karn wrote:
>[...]

So why not do exactly that?

We have proposed a "link layer version" of that idea in
http://iceberg.cs.berkeley.edu/papers/Ludwig-WINET99/ (the server is 
currently not accessible - that will be fixed soon), and discuss the link 
outage issue in section 5 of that paper. I have additional TCP trace plots 
that show how nicely this appoach works in case of link outages. I can make 
those traces available if people are interested.

If you do this at the link layer instead of the network layer you are free 
to queue more than just a single packet, e.g., you can queue the entire 
flight of packets belonging to a TCP flow if resources allow for that. In 
situations where the link outage was not long enough to trigger a timeout, 
no packets need to retransmitted at all! And remember, with TCP's 
super-conservative retransmission timer you can afford quite some link 
outages without triggering a timeout.

>destination when the link comes back up.

Agree. However, I would leave it open whether this approach is implemented 
at the router level (only buffering a single packet) or the link layer. It 
should also be mentioned that no packet should be buffered longer than the 
Maximum Segment Lifetime (MSL), i.e., 240 seconds, at most.

>reliable link layer protocols with much less effort.

Don't agree. With the router level approach you need to change router 
implementation (deployment concern!). The link layer approach can be 
designed into upcoming wireless systems.

>The router would

With Dan's section referencing the e2e argument paper, we know that a 
reliability guarantee can only be provided by an end point, not a link 
layer. I.e., highly persistent link layer error recovery (limited to the 
class of reliable flows to avoid head-of-line blocking for delay-sensitive 
flows) does not provide a reliability guarantee but is also merely a 
performance enhancement.

///Reiner

---

From: Phil Karn <[email-masked]>
Date: Thu, 9 Mar 2000 15:22:02 -0800

>flight of packets belonging to a TCP flow if resources allow for that. In 

Well, I guess you could but I wouldn't want a short outage to result
in a lot of duplicate packets spewing out over the link after the link
comes back up. Seems to me you're better off holding onto just the
last packet or two per flow.

>at the router level (only buffering a single packet) or the link layer. It 

I agree with this too.

>Maximum Segment Lifetime (MSL), i.e., 240 seconds, at most.

Is the MSL a real thing, or is it just a fiction? In either case, I see
no need to hold onto any packet for longer than the sending TCP's likely
retransmission interval -- except for the very last packet
whose purpose is more to notify TCP that the channel is back up
than to avoid a retransmission. But since the subnet doesn't have any
way to know what TCP's retransmission timeout is, you
have to make a guess.

>designed into upcoming wireless systems.

Okay, I didn't mean to distinguish between a router implementation
and a link implementation of the "hold the last packet" technique,
and I'll try to explain in the draft that either is OK.

>flows) does not provide a reliability guarantee but is also merely a 

Exactly. In this case, the performance enhancement is to get TCP
going again more quickly after the link recovers.

Phil

---

From: Reiner Ludwig <[email-masked]>
Date: Fri, 10 Mar 2000 17:51:11 +0100

>last packet or two per flow.

You are right in the case where "standard" TCP gets a spurious timeout 
because the sender basically does a go-back-N. However, short link outages 
will often _not_ trigger a (spurious) timeout. In those cases it would be 
better to buffer all packets that arrive at the link during the outage. So 
I guess it's hard to say what is best to do given that the link layer has 
little knowledge of the sender's RTO. You're right for "standard" TCP, we 
have to do some guessing.

>Is the MSL a real thing, or is it just a fiction?

For example, RFC1122 uses the MSL as an upper limit for the reassembly 
timeout value in the case of IP fragmentation.

>In either case, I see

Basically agree. See above. Note though that with a TCP that is a bit more 
robust (http://iceberg.cs.berkeley.edu/papers/Ludwig-Eifel-Alg/index.html), 
i.e., that does not do a go-back-N after a spurious timeout, it is always 
better to buffer all packets.

///Reiner