Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=95c4922bf9330eb2c71b752359dd89c4e166f3c5
Commit:     95c4922bf9330eb2c71b752359dd89c4e166f3c5
Parent:     6408d206c7484615ecae54bf6474a02c94e9e862
Author:     Ilpo Järvinen <[EMAIL PROTECTED]>
AuthorDate: Wed Feb 21 23:05:18 2007 -0800
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Wed Apr 25 22:23:07 2007 -0700

    [TCP] FRTO: fixes fallback to conventional recovery
    
    The FRTO detection did not care how ACK pattern affects to cwnd
    calculation of the conventional recovery. This caused incorrect
    setting of cwnd when the fallback becames necessary. The
    knowledge tcp_process_frto() has about the incoming ACK is now
    passed on to tcp_enter_frto_loss() in allowed_segments parameter
    that gives the number of segments that must be added to
    packets-in-flight while calculating the new cwnd.
    
    Instead of snd_una we use FLAG_DATA_ACKED in duplicate ACK
    detection because RFC4138 states (in Section 2.2):
      If the first acknowledgment after the RTO retransmission
      does not acknowledge all of the data that was retransmitted
      in step 1, the TCP sender reverts to the conventional RTO
      recovery.  Otherwise, a malicious receiver acknowledging
      partial segments could cause the sender to declare the
      timeout spurious in a case where data was lost.
    
    If the next ACK after RTO is duplicate, we do not retransmit
    anything, which is equal to what conservative conventional
    recovery does in such case.
    
    Signed-off-by: Ilpo Järvinen <[EMAIL PROTECTED]>
    Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
---
 net/ipv4/tcp_input.c |   14 +++++++++-----
 1 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index e990d56..cc935c8 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1296,7 +1296,7 @@ void tcp_enter_frto(struct sock *sk)
  * which indicates that we should follow the traditional RTO recovery,
  * i.e. mark everything lost and do go-back-N retransmission.
  */
-static void tcp_enter_frto_loss(struct sock *sk)
+static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        struct sk_buff *skb;
@@ -1326,7 +1326,7 @@ static void tcp_enter_frto_loss(struct sock *sk)
        }
        tcp_sync_left_out(tp);
 
-       tp->snd_cwnd = tp->frto_counter + tcp_packets_in_flight(tp)+1;
+       tp->snd_cwnd = tcp_packets_in_flight(tp) + allowed_segments;
        tp->snd_cwnd_cnt = 0;
        tp->snd_cwnd_stamp = tcp_time_stamp;
        tp->undo_marker = 0;
@@ -2527,6 +2527,11 @@ static void tcp_process_frto(struct sock *sk, u32 
prior_snd_una, int flag)
        if (flag&FLAG_DATA_ACKED)
                inet_csk(sk)->icsk_retransmits = 0;
 
+       if (!before(tp->snd_una, tp->frto_highmark)) {
+               tcp_enter_frto_loss(sk, tp->frto_counter + 1);
+               return;
+       }
+
        /* RFC4138 shortcoming in step 2; should also have case c): ACK isn't
         * duplicate nor advances window, e.g., opposite dir data, winupdate
         */
@@ -2534,9 +2539,8 @@ static void tcp_process_frto(struct sock *sk, u32 
prior_snd_una, int flag)
            !(flag&FLAG_FORWARD_PROGRESS))
                return;
 
-       if (tp->snd_una == prior_snd_una ||
-           !before(tp->snd_una, tp->frto_highmark)) {
-               tcp_enter_frto_loss(sk);
+       if (!(flag&FLAG_DATA_ACKED)) {
+               tcp_enter_frto_loss(sk, (tp->frto_counter == 1 ? 0 : 3));
                return;
        }
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to