]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/ipv4/tcp_output.c
tcp: don't backtrack to sacked skbs
[linux-2.6-omap-h63xx.git] / net / ipv4 / tcp_output.c
index da2c3b8794f2b39d3c5e4948b08cd78167f5ae2e..2471cd4f66db7f99a1855e7837f94b9cb4a3ed3c 100644 (file)
@@ -663,10 +663,14 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
        th->urg_ptr             = 0;
 
        /* The urg_mode check is necessary during a below snd_una win probe */
-       if (unlikely(tcp_urg_mode(tp) &&
-                    between(tp->snd_up, tcb->seq + 1, tcb->seq + 0xFFFF))) {
-               th->urg_ptr             = htons(tp->snd_up - tcb->seq);
-               th->urg                 = 1;
+       if (unlikely(tcp_urg_mode(tp) && before(tcb->seq, tp->snd_up))) {
+               if (before(tp->snd_up, tcb->seq + 0x10000)) {
+                       th->urg_ptr = htons(tp->snd_up - tcb->seq);
+                       th->urg = 1;
+               } else if (after(tcb->seq + 0xFFFF, tp->snd_nxt)) {
+                       th->urg_ptr = 0xFFFF;
+                       th->urg = 1;
+               }
        }
 
        tcp_options_write((__be32 *)(th + 1), tp, &opts, &md5_hash_location);
@@ -2061,7 +2065,7 @@ begin_fwd:
                        goto begin_fwd;
 
                } else if (!(sacked & TCPCB_LOST)) {
-                       if (hole == NULL && !(sacked & TCPCB_SACKED_RETRANS))
+                       if (hole == NULL && !(sacked & (TCPCB_SACKED_RETRANS|TCPCB_SACKED_ACKED)))
                                hole = skb;
                        continue;