From: narten@cs.albany.edu (Thomas Narten)
Subject: Re: Why would a Sun take 1.5 seconds to retransmit a missed packet?
Originator: narten@percival.albany.edu
Organization: Computer Science Department, SUNY at Albany, Albany, NY 12222
Distribution: na
Date: Fri, 8 Jan 1993 20:49:12 GMT

In article <930108124846@cream.ftp.com> jbvb@vax.ftp.com  (James B. VanBokkelen) writes:

> In article <184841@pyramid.pyramid.com> lstowell@pyrnova.mis.pyramid.com (Lon Stowell) writes:
> 
>     In article <BARNETT.93Jan7091846@grymoire.crd.ge.com> barnett@crdgw1.ge.com writes:
> 
>     >Packets are missed by the archive system, so the Sun has to retransmit
>     >the missed packets. I have noticed large delays (0.5 - 1.5 seconds)
> 
>        Those are pretty typical numbers for TCP layer time-outs...
> 
> If so, it indicates that 1) the path is long, 2) the archive system is very
> slow or 3) the sending TCP has an inferior or broken adaptive retransmit
> algorithm.

The third answer is probably the best.  While one could argue that the
implementation is "inferior", the observed behavior makes sense given
the implementation. In the following, assume we are on a LAN, so that
actual RTTs are on the order of milliseconds.  It is still possible to
see retransmissions up to 1.5 seconds after a segment is sent.

Under BSD, the TCP retransmit timer clock ticks at a relatively slow
rate of .5 seconds.  Thus, the absolute minimum retransmit time one
can set is .5 seconds.  However, the time can be up to twice as long
even under normal circumstances.  One factor is that BSD only has one
retransmit timer going at a time, rather than one for each outstanding
segment.  If one transmits segments 1-4, for example, BSD starts a
single retransmit timer for segment 1.  When the ACK for segment 1
arrives, a timer needs to be started for segment 2.  Although segment
2 was sent in the past sometime (perhaps as long as just under one RTT
ago), the timer is reset to the full smoothed RTT value.  Thus, the
actual time that elapses before the retransmit timer for segment 2
expires could be as long as twice what it should be.

Finally, even though one can theoretically set a timer to go off in .5
seconds, that's not exactly the case.  BSD implements timers by having
a clock device driver call the routine tcp_slowtimeo() every .5
seconds. The actual retransmit timer is maintained as a counter in
units of .5 seconds, so that tcp_slowtimeo() simply decrements the
timer, and if it reaches 0, retransmits the segment in question.  Now,
if one wants to schedule a timer to go off in exactly .5 seconds, one
might think that setting the counter (timer) to 1 would do the trick.
Unfortunately, if tcp_slowtimeo() was last invoked 499 ms ago, it is
about to be invoked right away again and it would decrement a timer of
1 to 0 almost immediately, certainly before .5 seconds have elapsed.
Thus, when setting a timer for .5 seconds, one actually wants the
timer to go off *no sooner than* .5 seconds from now, and one may
actually have to wait .9999 seconds. That is, we want the timer to go
off during the second call of tcp_slowtimeo() rather than the first.

Even on a LAN, the above would account for the actual retransmit timer
for a segment varying from .5-1.5 seconds.  
-- 
Thomas Narten
narten@cs.albany.edu
Xref: sparky comp.protocols.tcp-ip:5928 comp.protocols.tcp-ip.ibmpc:7358