[lkml]   [1997]   [May]   [31]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
    Patch in this message
    SubjectTCP timer bug in 2.0.x
    There's an annoying bug in the TCP driver up thru 2.0.30 which can cause
    ftp sessions to hang. The general symptom is an ftp download that starts
    out fast, and gets slower, and slower, and slower until it's basically
    stuck. This only affects outgoing sends, so you might not notice
    yourself, but if you have a web/ftp server, your users likely will.

    The problem is in the retransmit timer backoff. The timer is set based
    on the roundtrip time when a packet is transmitted/acked. When a sent
    packet is not acked, it will retransmit, doubling the time between each
    retransmit, up to a maximum of 120 seconds.

    The bug is that when a retransmitted packet gets acked, the timer doesn't
    get reset. So if the timer was at 120 seconds, then we'll have to wait a
    whole 120 seconds before sending the next packet, no matter how quickly
    the packet was acked.

    Unfortulately, it's even worse than that. The retransmit flag will never
    get cleared as long as there's data in the send queue. This means that if
    the ftpd keeps the pipe full, the timer will never get reset, and your ftp
    session will be slowed to a rate of one packet every two minutes. Chances
    are, you aren't willing to wait that long.

    (If you want to test this, start a file transfer to somewhere then type
    route add somewhere dummy, wait for a few packets to get lost, then
    correct the routing, and notice how painfully slow your ftp transfer goes

    I'm not quite sure what is the best way to fix this. I patched my kernel
    so that whenever an ack comes in, it resets the timer to 200ms. This
    does solve the problem, but probably causes a lot of unnecessary
    retransmits. It would be better to calculate a timeout based on roundtrip
    time, but that won't work if you have to retransmit the packet.

    --- linux/net/ipv4/tcp_input.c.orig Mon Apr 21 14:53:17 1997
    +++ linux/net/ipv4/tcp_input.c Mon Apr 21 14:54:15 1997
    @@ -1654,6 +1654,9 @@

    if (sk->send_head != NULL && (flag&2) && sk->retransmits)
    + sk->rto = HZ/5; /* 200 ms */
    + tcp_reset_xmit_timer(sk, TIME_WRITE, sk->rto);
    tcp_do_retransmit(sk, 1);
     \ /
      Last update: 2005-03-22 13:39    [W:0.018 / U:7.396 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site